SFBReactor.h

Go to the documentation of this file.
00001 /*                                       -*- mode:C++; fill-column: 100 -*-
00002   SFBReactor.h - Register packet handlers and dispatch packets
00003   Copyright (C) 2009 The Regents of the University of New Mexico.  All rights reserved.
00004 
00005   This library is free software; you can redistribute it and/or
00006   modify it under the terms of the GNU Lesser General Public
00007   License as published by the Free Software Foundation; either
00008   version 2.1 of the License, or (at your option) any later version.
00009 
00010   This library is distributed in the hope that it will be useful,
00011   but WITHOUT ANY WARRANTY; without even the implied warranty of
00012   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013   Lesser General Public License for more details.
00014 
00015   You should have received a copy of the GNU General Public License
00016   along with this library; if not, write to the Free Software
00017   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
00018   USA
00019 */
00020 
00028 #ifndef SFBREACTOR_H_
00029 #define SFBREACTOR_H_
00030 
00031 #include "SFBTypes.h"
00032 #include "SFBAssert.h"
00033 
00034 typedef void (*PacketHandler)(u8 * packet) ;
00035 
00036 typedef void (*DispatchHandler)(u8 * packet, u8 face);
00037 
00052 struct GRL {
00053   u8 tableIndex;
00054   u8 entryIndex;
00055 };
00056 extern bool isNone(GRL g) ;
00057 extern GRL makeGRL(u8 table, u8 entry) ;
00058 extern void initGRL(GRL & g, u8 table = 0, u8 entry = 0) ;
00059 
00064 #define MAX_GRL_TABLES 7
00065 
00069 struct SFBGRLMasterTable {
00070   const PacketHandler *(tables[MAX_GRL_TABLES]);
00071   u8 lengths[MAX_GRL_TABLES];
00072   u8 inUse;
00073 
00074   SFBGRLMasterTable() ;
00075   u8 addTable(const PacketHandler * table, int length) ;
00076 
00077   GRL find(PacketHandler ph) ;
00078 
00079   PacketHandler find(GRL index) ;
00080 };
00081 
00082 #define MAX_REACTORS 200
00083 
00087 struct SFBDispatchEntry {
00088   SFBDispatchEntry() ;
00089   GRL grl;
00090   u8 type;
00091   u8 flags;
00092 };
00097 #define MAX_CASUAL_REFLEXES 10 
00098 
00099 #define TRIGGER_SET_TYPE s16
00100 #define MAX_NESTED_TRIGGERS (sizeof(TRIGGER_SET_TYPE)*8)
00101 
00106 class SFBReactor {
00107 
00108   // The partitions
00109   enum {
00110     END_PARTITION=BRAIN+1,
00111     PARTITION_COUNT
00112   };
00113   int nextPartition(int partition) ;
00114 
00115   int partitionLength(const u8 partition) ;
00116   bool inPartition(const u8 partition, const u8 type);
00117   void openUp(const u8 inPartition, const u8 atPosition);
00118   void addToPartition(const u8 partition, const u8 type, GRL grl, u8 flags);
00119 
00120   GRL addToCasual(PacketHandler ph) ;
00121 
00122   GRL findOrAdd(PacketHandler ph) ;
00123 
00124 public:
00125 
00126   enum { 
00127     TRIGGER_IF_BROKEN  = 0x01,  
00128     TRIGGER_EMPTY =      0x02,  
00129     TRIGGER_SUPPRESSED = 0x04,  
00130     TRIGGER_RESERVED3 =  0x08,  
00131     TRIGGER_RESERVED4 =  0x10,  
00132     TRIGGER_RESERVED5 =  0x20,  
00133     TRIGGER_RESERVED6 =  0x40,  
00134     TRIGGER_RESERVED7 =  0x80,  
00136     // The rest of these triggers are not stored in the flags: Instead
00137     // they determine which partition(s) the reflex is in.
00138     TRIGGER_FIRST_PARTITION = 0x100,
00139     TRIGGER_NORTH =  TRIGGER_FIRST_PARTITION<<NORTH, 
00140     TRIGGER_SOUTH =  TRIGGER_FIRST_PARTITION<<SOUTH, 
00141     TRIGGER_EAST =   TRIGGER_FIRST_PARTITION<<EAST,  
00142     TRIGGER_WEST =   TRIGGER_FIRST_PARTITION<<WEST,  
00143     TRIGGER_SPINE =  TRIGGER_FIRST_PARTITION<<SPINE, 
00144     TRIGGER_MEMORY = TRIGGER_FIRST_PARTITION<<WMEM,  
00145     TRIGGER_BRAIN =  TRIGGER_FIRST_PARTITION<<BRAIN, 
00147     TRIGGER_ALL_PARTITIONS =
00148       TRIGGER_NORTH|TRIGGER_SOUTH|TRIGGER_EAST|TRIGGER_WEST|TRIGGER_SPINE|TRIGGER_MEMORY|TRIGGER_BRAIN
00149   };
00150 
00151   void reset() ;
00152 
00153   int faceToFlag(const u32 face) ;
00154 
00201   u8 reflexes(const PacketHandler * table, int length) ;
00202 
00229   void reflex(const char type, PacketHandler pfunc, int partitions = TRIGGER_SPINE, bool ifBroken = false) ;
00230 
00231   void reflexReflex(const char type, PacketHandler pfunc, int partitions = TRIGGER_SPINE, bool ifBroken = false) ;
00232 
00233   void implReflex(const char type, PacketHandler pfunc, int partitions = TRIGGER_SPINE, bool ifBroken = false) ;
00234 
00235   bool reflexExists(const char type, int partitions = TRIGGER_ALL_PARTITIONS) ;
00236 
00237   void suppress(const char type, int partitions);  /* No default on partitions, you have to say.. */
00238   void allow(const char type, int partitions);  /* No default on partitions, you have to say.. */
00239 
00241   void otherwise(PacketHandler pfunc, int partitions = TRIGGER_BRAIN, bool allowBroken = false) ;
00242 
00243   void empty(PacketHandler pfunc, int partitions = TRIGGER_SPINE, bool allowBroken = false) ;
00244 
00245   void triggerUp() ;
00246 
00254   bool inHandler() ;
00255 
00256   u8 source() ;
00257 
00258   u8 getFlags(const char type) ;
00259 
00275   void trigger(u8 * packet, u8 face) ;
00276 
00277   SFBReactor() ;
00278 
00287   bool canTrigger() ;
00288 
00289 private:
00290 
00291   void setSpecial(const u8 offset, u8 flags, GRL grl, int partitions) ;
00292 
00293   bool fireTrigger(u8 * packet, PacketHandler ph, u8 face) ;
00294 
00295   int positionInPartition(const u8 partition, const u8 type) ;
00296 
00297   GRL findInPartitions(const u8 type, int flags) ;
00298 
00299 
00300   SFBGRLMasterTable masterTable;
00301   SFBDispatchEntry entries[MAX_REACTORS];
00302   PacketHandler casualTable[MAX_CASUAL_REFLEXES];
00303   u16 partitionStarts[PARTITION_COUNT];
00304   u8 casualTableInUse;
00305 
00306   u8 triggerSources[MAX_NESTED_TRIGGERS];
00307   TRIGGER_SET_TYPE triggerUpFlags;
00308   s8 topTrigger;
00309 
00310   friend void reflex(const char type, PacketHandler ph, int flags);
00311 };
00312 
00316 void reflex(const char type, PacketHandler ph, int flags = SFBReactor::TRIGGER_SPINE);
00317 
00321 extern SFBReactor Body;
00322 
00337 class SFBBrainReflex {
00338  public:
00339   void reflex(const char type, PacketHandler ph) {
00340     ::reflex(type, ph, SFBReactor::TRIGGER_BRAIN);
00341   }
00342 };
00343 extern SFBBrainReflex Brain;
00344 
00359 class SFBSpineReflex {
00360  public:
00373   void reflex(const char type, PacketHandler ph) {
00374     ::reflex(type, ph, SFBReactor::TRIGGER_SPINE);
00375   }
00376 };
00377 extern SFBSpineReflex Spine;
00378 
00379 #endif /* SFBREACTOR_H_ */
00380 

Generated on Sun Oct 18 09:58:55 2009 for SFB by doxygen 1.5.9