# 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