#include <SFBReactor.h>
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). |
anonymous enum |
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.
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 | ( | ) |
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.
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 . |
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.
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.. }
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.