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 
00037 typedef void (*PacketHandler)(u8 * packet) ;
00038 
00039 typedef void (*DispatchHandler)(u8 * packet, u8 face);
00040 
00055 struct GRL {
00056   u8 tableIndex;
00057   u8 entryIndex;
00058 };
00059 extern bool isNone(GRL g) ;
00060 extern GRL makeGRL(u8 table, u8 entry) ;
00061 extern void initGRL(GRL & g, u8 table = 0, u8 entry = 0) ;
00062 
00067 #define MAX_GRL_TABLES 7
00068 
00072 struct SFBGRLMasterTable {
00073   const PacketHandler *(tables[MAX_GRL_TABLES]);
00074   u8 lengths[MAX_GRL_TABLES];
00075   u8 inUse;
00076 
00077   SFBGRLMasterTable() ;
00078   u8 addTable(const PacketHandler * table, int length) ;
00079 
00080   GRL find(PacketHandler ph) ;
00081 
00082   PacketHandler find(GRL index) ;
00083 };
00084 
00085 #define MAX_REACTORS 200
00086 
00090 struct SFBDispatchEntry {
00091   SFBDispatchEntry() ;
00092   GRL grl;
00093   u8 type;
00094   u8 flags;
00095 };
00100 #define MAX_CASUAL_REFLEXES 10 
00101 
00102 #define TRIGGER_SET_TYPE s16
00103 #define MAX_NESTED_TRIGGERS (sizeof(TRIGGER_SET_TYPE)*8)
00104 
00109 class SFBReactor {
00110 
00111   // The partitions
00112   enum {
00113     END_PARTITION=BRAIN+1,
00114     PARTITION_COUNT
00115   };
00116   int nextPartition(int partition) ;
00117 
00118   int partitionLength(const u8 partition) ;
00119   bool inPartition(const u8 partition, const u8 type);
00120   void openUp(const u8 inPartition, const u8 atPosition);
00121   void addToPartition(const u8 partition, const u8 type, GRL grl, u8 flags);
00122 
00123   GRL addToCasual(PacketHandler ph) ;
00124 
00125   GRL findOrAdd(PacketHandler ph) ;
00126 
00127 public:
00128 
00129   enum { 
00130     TRIGGER_IF_BROKEN  = 0x01,  
00131     TRIGGER_EMPTY =      0x02,  
00132     TRIGGER_SUPPRESSED = 0x04,  
00133     TRIGGER_RESERVED3 =  0x08,  
00134     TRIGGER_RESERVED4 =  0x10,  
00135     TRIGGER_RESERVED5 =  0x20,  
00136     TRIGGER_RESERVED6 =  0x40,  
00137     TRIGGER_RESERVED7 =  0x80,  
00139     // The rest of these triggers are not stored in the flags: Instead
00140     // they determine which partition(s) the reflex is in.
00141     TRIGGER_FIRST_PARTITION = 0x100,
00142     TRIGGER_NORTH =  TRIGGER_FIRST_PARTITION<<NORTH, 
00143     TRIGGER_SOUTH =  TRIGGER_FIRST_PARTITION<<SOUTH, 
00144     TRIGGER_EAST =   TRIGGER_FIRST_PARTITION<<EAST,  
00145     TRIGGER_WEST =   TRIGGER_FIRST_PARTITION<<WEST,  
00146     TRIGGER_SPINE =  TRIGGER_FIRST_PARTITION<<SPINE, 
00147     TRIGGER_MEMORY = TRIGGER_FIRST_PARTITION<<WMEM,  
00148     TRIGGER_BRAIN =  TRIGGER_FIRST_PARTITION<<BRAIN, 
00150     TRIGGER_ALL_PARTITIONS =
00151       TRIGGER_NORTH|TRIGGER_SOUTH|TRIGGER_EAST|TRIGGER_WEST|TRIGGER_SPINE|TRIGGER_MEMORY|TRIGGER_BRAIN
00152   };
00153 
00154   void reset() ;
00155 
00156   int faceToFlag(const u32 face) ;
00157 
00205   u8 reflexes(const PacketHandler * table, int length) ;
00206 
00233   void reflex(const char type, PacketHandler pfunc, int partitions = TRIGGER_SPINE, bool ifBroken = false) ;
00234 
00235   void reflexReflex(const char type, PacketHandler pfunc, int partitions = TRIGGER_SPINE, bool ifBroken = false) ;
00236 
00237   void implReflex(const char type, PacketHandler pfunc, int partitions = TRIGGER_SPINE, bool ifBroken = false) ;
00238 
00239   bool reflexExists(const char type, int partitions = TRIGGER_ALL_PARTITIONS) ;
00240 
00241   void suppress(const char type, int partitions);  /* No default on partitions, you have to say.. */
00242   void allow(const char type, int partitions);  /* No default on partitions, you have to say.. */
00243 
00245   void otherwise(PacketHandler pfunc, int partitions = TRIGGER_BRAIN, bool allowBroken = false) ;
00246 
00247   void empty(PacketHandler pfunc, int partitions = TRIGGER_SPINE, bool allowBroken = false) ;
00248 
00249   void triggerUp() ;
00250 
00258   bool inHandler() ;
00259 
00260   u8 source() ;
00261 
00262   u8 getFlags(const char type) ;
00263 
00279   void trigger(u8 * packet, u8 face) ;
00280 
00281   SFBReactor() ;
00282 
00291   bool canTrigger() ;
00292 
00293 private:
00294 
00295   void setSpecial(const u8 offset, u8 flags, GRL grl, int partitions) ;
00296 
00297   bool fireTrigger(u8 * packet, PacketHandler ph, u8 face) ;
00298 
00299   int positionInPartition(const u8 partition, const u8 type) ;
00300 
00301   GRL findInPartitions(const u8 type, int flags) ;
00302 
00303 
00304   SFBGRLMasterTable masterTable;
00305   SFBDispatchEntry entries[MAX_REACTORS];
00306   PacketHandler casualTable[MAX_CASUAL_REFLEXES];
00307   u16 partitionStarts[PARTITION_COUNT];
00308   u8 casualTableInUse;
00309 
00310   u8 triggerSources[MAX_NESTED_TRIGGERS];
00311   TRIGGER_SET_TYPE triggerUpFlags;
00312   s8 topTrigger;
00313 
00314   friend void reflex(const char type, PacketHandler ph, int flags);
00315 };
00316 
00320 void reflex(const char type, PacketHandler ph, int flags = SFBReactor::TRIGGER_SPINE);
00321 
00325 extern SFBReactor Body;
00326 
00341 class SFBBrainReflex {
00342  public:
00343   void reflex(const char type, PacketHandler ph) {
00344     ::reflex(type, ph, SFBReactor::TRIGGER_BRAIN);
00345   }
00346 };
00350 extern SFBBrainReflex Brain;
00351 
00366 class SFBSpineReflex {
00367  public:
00380   void reflex(const char type, PacketHandler ph) {
00381     ::reflex(type, ph, SFBReactor::TRIGGER_SPINE);
00382   }
00383 };
00387 extern SFBSpineReflex Spine;
00388 
00389 #endif /* SFBREACTOR_H_ */
00390 

Generated on Fri Apr 22 06:54:12 2011 for SFB by doxygen 1.5.9