# 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