# 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
    00202   u8 reflexes(const PacketHandler * table, int length) ;
    00203
    00230   void reflex(const char type, PacketHandler pfunc, int partitions = TRIGGER_SPINE, bool ifBroken = false) ;
    00231
    00232   void reflexReflex(const char type, PacketHandler pfunc, int partitions = TRIGGER_SPINE, bool ifBroken = false) ;
    00233
    00234   void implReflex(const char type, PacketHandler pfunc, int partitions = TRIGGER_SPINE, bool ifBroken = false) ;
    00235
    00236   bool reflexExists(const char type, int partitions = TRIGGER_ALL_PARTITIONS) ;
    00237
    00238   void suppress(const char type, int partitions);  /* No default on partitions, you have to say.. */
    00239   void allow(const char type, int partitions);  /* No default on partitions, you have to say.. */
    00240
    00242   void otherwise(PacketHandler pfunc, int partitions = TRIGGER_BRAIN, bool allowBroken = false) ;
    00243
    00244   void empty(PacketHandler pfunc, int partitions = TRIGGER_SPINE, bool allowBroken = false) ;
    00245
    00246   void triggerUp() ;
    00247
    00255   bool inHandler() ;
    00256
    00257   u8 source() ;
    00258
    00259   u8 getFlags(const char type) ;
    00260
    00276   void trigger(u8 * packet, u8 face) ;
    00277
    00278   SFBReactor() ;
    00279
    00288   bool canTrigger() ;
    00289
    00290 private:
    00291
    00292   void setSpecial(const u8 offset, u8 flags, GRL grl, int partitions) ;
    00293
    00294   bool fireTrigger(u8 * packet, PacketHandler ph, u8 face) ;
    00295
    00296   int positionInPartition(const u8 partition, const u8 type) ;
    00297
    00298   GRL findInPartitions(const u8 type, int flags) ;
    00299
    00300
    00301   SFBGRLMasterTable masterTable;
    00302   SFBDispatchEntry entries[MAX_REACTORS];
    00303   PacketHandler casualTable[MAX_CASUAL_REFLEXES];
    00304   u16 partitionStarts[PARTITION_COUNT];
    00305   u8 casualTableInUse;
    00306
    00307   u8 triggerSources[MAX_NESTED_TRIGGERS];
    00308   TRIGGER_SET_TYPE triggerUpFlags;
    00309   s8 topTrigger;
    00310
    00311   friend void reflex(const char type, PacketHandler ph, int flags);
    00312 };
    00313
    00317 void reflex(const char type, PacketHandler ph, int flags = SFBReactor::TRIGGER_SPINE);
    00318
    00322 extern SFBReactor Body;
    00323
    00338 class SFBBrainReflex {
    00339  public:
    00340   void reflex(const char type, PacketHandler ph) {
    00341     ::reflex(type, ph, SFBReactor::TRIGGER_BRAIN);
    00342   }
    00343 };
    00344 extern SFBBrainReflex Brain;
    00345
    00360 class SFBSpineReflex {
    00361  public:
    00374   void reflex(const char type, PacketHandler ph) {
    00375     ::reflex(type, ph, SFBReactor::TRIGGER_SPINE);
    00376   }
    00377 };
    00378 extern SFBSpineReflex Spine;
    00379
    00380 #endif /* SFBREACTOR_H_ */
    00381