# 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