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 
00203   void reflex(const char type, PacketHandler pfunc, int partitions = TRIGGER_SPINE, bool ifBroken = false) ;
00204 
00205   void reflexReflex(const char type, PacketHandler pfunc, int partitions = TRIGGER_SPINE, bool ifBroken = false) ;
00206 
00207   void implReflex(const char type, PacketHandler pfunc, int partitions = TRIGGER_SPINE, bool ifBroken = false) ;
00208 
00209   bool reflexExists(const char type, int partitions = TRIGGER_ALL_PARTITIONS) ;
00210 
00211   void suppress(const char type, int partitions);  /* No default on partitions, you have to say.. */
00212   void allow(const char type, int partitions);  /* No default on partitions, you have to say.. */
00213 
00215   void otherwise(PacketHandler pfunc, int partitions = TRIGGER_BRAIN, bool allowBroken = false) ;
00216 
00217   void empty(PacketHandler pfunc, int partitions = TRIGGER_SPINE, bool allowBroken = false) ;
00218 
00219   void triggerUp() ;
00220 
00228   bool inHandler() ;
00229 
00230   u8 source() ;
00231 
00232   u8 getFlags(const char type) ;
00233 
00234   void trigger(u8 * packet, u8 face) ;
00235 
00236   SFBReactor() ;
00237 
00238   bool canTrigger() ;
00239 
00240 private:
00241 
00242   void setSpecial(const u8 offset, u8 flags, GRL grl, int partitions) ;
00243 
00244   bool fireTrigger(u8 * packet, PacketHandler ph, u8 face) ;
00245 
00246   int positionInPartition(const u8 partition, const u8 type) ;
00247 
00248   GRL findInPartitions(const u8 type, int flags) ;
00249 
00250 
00251   SFBGRLMasterTable masterTable;
00252   SFBDispatchEntry entries[MAX_REACTORS];
00253   PacketHandler casualTable[MAX_CASUAL_REFLEXES];
00254   u16 partitionStarts[PARTITION_COUNT];
00255   u8 casualTableInUse;
00256 
00257   u8 triggerSources[MAX_NESTED_TRIGGERS];
00258   TRIGGER_SET_TYPE triggerUpFlags;
00259   s8 topTrigger;
00260 
00261   friend void reflex(const char type, PacketHandler ph, int flags);
00262 };
00263 
00264 void reflex(const char type, PacketHandler ph, int flags = SFBReactor::TRIGGER_SPINE);
00265 
00266 extern SFBReactor Body;
00267 
00282 class SFBBrainReflex {
00283  public:
00284   void reflex(const char type, PacketHandler ph) {
00285     ::reflex(type, ph, SFBReactor::TRIGGER_BRAIN);
00286   }
00287 };
00288 extern SFBBrainReflex Brain;
00289 
00304 class SFBSpineReflex {
00305  public:
00318   void reflex(const char type, PacketHandler ph) {
00319     ::reflex(type, ph, SFBReactor::TRIGGER_SPINE);
00320   }
00321 };
00322 extern SFBSpineReflex Spine;
00323 
00324 #endif /* SFBREACTOR_H_ */
00325 

Generated on Thu Sep 17 07:37:51 2009 for SFB by doxygen 1.5.9