SFBReactor Class Reference

The SFBReactor manages the SFB reflex triggering system: It determines how an SFB will react to any given packet type. More...

#include <SFBReactor.h>

Collaboration diagram for SFBReactor:

Collaboration graph
[legend]

Public Types

enum  {
  TRIGGER_IF_BROKEN = 0x01,
  TRIGGER_EMPTY = 0x02,
  TRIGGER_SUPPRESSED = 0x04,
  TRIGGER_RESERVED3 = 0x08,
  TRIGGER_RESERVED4 = 0x10,
  TRIGGER_RESERVED5 = 0x20,
  TRIGGER_RESERVED6 = 0x40,
  TRIGGER_RESERVED7 = 0x80,
  TRIGGER_FIRST_PARTITION = 0x100,
  TRIGGER_NORTH = TRIGGER_FIRST_PARTITION<<NORTH,
  TRIGGER_SOUTH = TRIGGER_FIRST_PARTITION<<SOUTH,
  TRIGGER_EAST = TRIGGER_FIRST_PARTITION<<EAST,
  TRIGGER_WEST = TRIGGER_FIRST_PARTITION<<WEST,
  TRIGGER_SPINE = TRIGGER_FIRST_PARTITION<<SPINE,
  TRIGGER_MEMORY = TRIGGER_FIRST_PARTITION<<WMEM,
  TRIGGER_BRAIN = TRIGGER_FIRST_PARTITION<<BRAIN,
  TRIGGER_ALL_PARTITIONS
}

Public Member Functions

void reset ()
int faceToFlag (const u32 face)
u8 reflexes (const PacketHandler *table, int length)
 Make an array of PacketHandler's available for use as reflex handlers.
void reflex (const char type, PacketHandler pfunc, int partitions=TRIGGER_SPINE, bool ifBroken=false)
 Create a reflex association between a particular character type, and a particular PacketHandler function pfunc.
void reflexReflex (const char type, PacketHandler pfunc, int partitions=TRIGGER_SPINE, bool ifBroken=false)
void implReflex (const char type, PacketHandler pfunc, int partitions=TRIGGER_SPINE, bool ifBroken=false)
bool reflexExists (const char type, int partitions=TRIGGER_ALL_PARTITIONS)
void suppress (const char type, int partitions)
void allow (const char type, int partitions)
void otherwise (PacketHandler pfunc, int partitions=TRIGGER_BRAIN, bool allowBroken=false)
 Add a 'catch-all' handler.
void empty (PacketHandler pfunc, int partitions=TRIGGER_SPINE, bool allowBroken=false)
void triggerUp ()
bool inHandler ()
 Are we currently executing inside a packet handler function?
u8 source ()
u8 getFlags (const char type)
void trigger (u8 *packet, u8 face)
 Attempt to trigger reflexes on packet, as though it had arrived on face.
bool canTrigger ()
 Check if it is possible to trigger reflexes on a packet at this time.

Friends

void reflex (const char type, PacketHandler ph, int flags)
 Equivalent to Body.reflex(type,ph,flags).

Detailed Description

The SFBReactor manages the SFB reflex triggering system: It determines how an SFB will react to any given packet type.

Member Enumeration Documentation

anonymous enum

Enumerator:
TRIGGER_IF_BROKEN  This handler wants packets even with errors.

TRIGGER_EMPTY  This handler wants only empty packets.

TRIGGER_SUPPRESSED  This reflex is currently suppressed.

TRIGGER_RESERVED3  Reserved for future use; should not be set or read.

TRIGGER_RESERVED4  Reserved for future use; should not be set or read.

TRIGGER_RESERVED5  Reserved for future use; should not be set or read.

TRIGGER_RESERVED6  Reserved for future use; should not be set or read.

TRIGGER_RESERVED7  Reserved for future use; should not be set or read.

TRIGGER_NORTH  Trigger if packet came from NORTH.
TRIGGER_SOUTH  Trigger if packet came from SOUTH.
TRIGGER_EAST  Trigger if packet came from EAST.
TRIGGER_WEST  Trigger if packet came from WEST.
TRIGGER_SPINE  Trigger if packet reaches the Spine (from any face).
TRIGGER_MEMORY  Trigger if packet came from working memory.
TRIGGER_BRAIN  Trigger if packet reaches the Brain (from Spine or memory).


Member Function Documentation

bool SFBReactor::canTrigger (  ) 

Check if it is possible to trigger reflexes on a packet at this time.

It is possible to trigger reflexes on a packet when already inside a packet handler, but only a limited amount of such 'reflex nesting' is allowed.

Returns:
true if a trigger() call will actually attempt to find and execute an appropriate packet handler; false if the max reflex nesting limit has been reached.

bool SFBReactor::inHandler (  ) 

Are we currently executing inside a packet handler function?

Returns:
true if we are in (or were called directly or indirectly) from a packet handler; false if not (which, at sketch level, most commonly means in (code called from) setup(), loop(), or an alarm handler).

void SFBReactor::otherwise ( PacketHandler  pfunc,
int  partitions = TRIGGER_BRAIN,
bool  allowBroken = false 
)

Add a 'catch-all' handler.

void SFBReactor::reflex ( const char  type,
PacketHandler  pfunc,
int  partitions = TRIGGER_SPINE,
bool  ifBroken = false 
)

Create a reflex association between a particular character type, and a particular PacketHandler function pfunc.

Optionally, one may specify which partition(s) the reflex should be created within; by default reflexes are created in the spine (which is searched after the individual faces, but before the brain). Also optionally, one may specify that pfunc should be invoked on packets even ifBroken, where 'broken' means the packet had some kind of error in transmission or receipt; by default broken packets are not passed to pfunc.

Parameters:
type The byte value to trigger the reflex on. Can be any of the 230 possible byte value excluding the uppercase alphabetics (i.e., anything that is NOT 'A'-'Z'), because those are reserved for core software reflexes.
pfunc The 'packet handler' function to invoke when a type packet is dispatched (in any of the partitions, if supplied). pfunc is a pointer to a function taking a u8* argument -- the packet to handle -- and returning void.
Blinks:
E_API_BAD_REFLEX If type is 'A'..'Z'.
Blinks:
E_API_REFLEX_FULL If enough reflexes have been defined that the 'casual reflex table' has run out of room. (See reflexes() for how to fix this problem if it occurs.)
Examples:
blinkySync.cpp, eeprom1.cpp, eeprom3.cpp, fifthdirection.cpp, hallucination.cpp, i2cEeprom.cpp, netled.cpp, pingpong.cpp, pingpong2.cpp, profile2.cpp, profile3.cpp, qled1.cpp, reorder.cpp, sdcard2.cpp, sdcard3.cpp, speed2.cpp, speed3.cpp, speed4.cpp, trigger.cpp, zformat1.cpp, zformat2.cpp, and zformat3.cpp.

u8 SFBReactor::reflexes ( const PacketHandler table,
int  length 
)

Make an array of PacketHandler's available for use as reflex handlers.

To conserve base RAM usage, the core software allocates only a small table of pointers to packet-handling functions. If a sketch has more than MAX_CASUAL_REFLEXES packet handlers, the sketch is liable to trip the E_API_REFLEX_FULL blink code. To avoid that, the sketch makes a table of packet handlers, and calls this method to tell the core software about it. After that, the core software will refer to that table whenever a reflex is created mentioning one of the packet handlers in that table.

Example:
     void handleTypeA(u8 * packet) { ..respond to 'a' packets.. }
     void handleTypeE(u8 * packet) { ..respond to 'e' packets.. }
     void handleTypeI(u8 * packet) { ..respond to 'i' packets.. }
     void handleTypeO(u8 * packet) { ..respond to 'o' packets.. }
     void handleTypeU(u8 * packet) { ..respond to 'u' packets.. }
     void handleTypeY(u8 * packet) { ..respond to 'y' packets.. }

     // Getting to be a lot of handlers -- let's make a handler table for them
     const PacketHandler myHandlers[] = { // Note the 'const' -- important!  Makes the table go into flash
       handleTypeO,   // Note that the order handlers are
       handleTypeY,   // listed in a table is _not_ important
       handleTypeI,
       handleTypeA,
       handleTypeE,
       handleTypeU
     };
  
     void setup() {
       // Tell the core about my table, using the 'array size trick' to compute the length of my
       // table (the number of elements in any array is the array's total size in bytes divided by
       // the size in bytes of one array element, say, element[0]).
       Body.reflexes(myHandlers,sizeof(myHandlers)/sizeof(myHandlers[0]));  

       // Note we still have to create each reflex!
       Body.reflex('a',handleTypeA);
       Body.reflex('e',handleTypeE);
       Body.reflex('i',handleTypeI);
       Body.reflex('o',handleTypeO);
       Body.reflex('u',handleTypeU);
       Body.reflex('y',handleTypeY);
     }

     void loop() { ..whatever.. }

void SFBReactor::trigger ( u8 packet,
u8  face 
)

Attempt to trigger reflexes on packet, as though it had arrived on face.

Note that if calls on this method are nested within active packet handlers, the triggering may or may not occur, depending on the depth of nesting. If this is a problem, a sketch should check canTrigger() first to determine if another level of reflex nesting is possible.

Note that the core software performs no locking of data structures nor any enforcement of mutual exclusion or critical sections. If a sketch's packet handlers are not prepared to be reentered recursively, then this method should only be called from the loop() method, and never be called from inside any packet handler.

If canTrigger() is false, this method invokes no packet handlers.

Blinks:
E_API_INVALID_PACKET if packet is null or invalid
Examples:
hallucination.cpp, and trigger.cpp.


The documentation for this class was generated from the following files:

Generated on Fri Apr 22 06:57:26 2011 for SFB by doxygen 1.5.9