Main Page   Modules   Class Hierarchy   Compound List   File List   Compound Members  

cfsm.h

00001 //==========================================================================
00002 //   CFSM.H  -  header for
00003 //                             OMNeT++
00004 //            Discrete System Simulation in C++
00005 //
00006 //  Contents:
00007 //    FSM building macros
00008 //    class cFSM: stores the state of an FSM
00009 //
00010 //==========================================================================
00011 
00012 /*--------------------------------------------------------------*
00013   Copyright (C) 1992-2003 Andras Varga
00014 
00015   This file is distributed WITHOUT ANY WARRANTY. See the file
00016   `license' for details on this and other legal matters.
00017 *--------------------------------------------------------------*/
00018 
00019 #ifndef __CFSM_H
00020 #define __CFSM_H
00021 
00022 #include "cobject.h"
00023 
00029 
00034 #define FSM_MAXT  64
00035 
00076 //
00077 // operation:
00078 // - __i counts up (starting from 1) until the FSM reaches a steady state.
00079 // - at __i=1,3,5,7,etc, FSM_Exit code is executed
00080 // - at __i=2,4,6,8,etc, FSM_Enter code is executed
00081 // - FSM_Enter code must not contain state change (this is verified)
00082 // - state changes should be encoded in FSM_Exit code
00083 // - infinite loops (when control never reaches steady state) are detected (FSM_MAXT)
00084 //
00085 #define FSM_Switch(fsm)  \
00086    for (int __i=1, __savedstate;  \
00087         (__i<3 || (__i&1)==0 || (fsm).inTransientState()) &&  \
00088         (__i<2*FSM_MAXT || (opp_error(eINFLOOP,(fsm).stateName()),0));  \
00089         ((__i&1)==0 && __savedstate!=(fsm).state() &&  \
00090          (opp_error(eSTATECHG,(fsm).stateName()),0)),  \
00091          __savedstate=(fsm).state(),++__i)  \
00092      switch (FSM_Print(fsm,__i&1),(((fsm).state()<<1)|(__i&1)))
00093 
00113 #define FSM_Transient(state)   (-(state))
00114 
00122 #define FSM_Steady(state)      (state)
00123 
00132 #define FSM_Enter(state)  ((state)<<1)
00133 
00141 #define FSM_Exit(state)   (((state)<<1)|1)
00142 
00153 #define FSM_Goto(fsm,state)   (fsm).setState(state,#state)
00154 
00155 #ifdef FSM_DEBUG
00156 
00163 #define FSM_Print(fsm,exiting) \
00164     (ev << "FSM " << (fsm).name() \
00165         << ((exiting) ? ": leaving state  " : ": entering state ") \
00166         << (fsm).stateName() << endl)
00167 // this may also be useful as third line:
00168 //      << ((fsm).inTransientState() ? "transient state " : "steady state ")
00169 #else
00170 #define FSM_Print(fsm,entering) ((void)0)
00171 #endif
00172 
00174 
00175 //-----------------------------------------------------
00176 
00184 class SIM_API cFSM : public cObject
00185 {
00186   private:
00187     //
00188     // About state codes:
00189     //  initial state is number 0
00190     //  negative state codes are transient states
00191     //  positive state codes are steady states
00192     //
00193     int _state;
00194     const char *_statename;   // just a ptr to an external string
00195 
00196   public:
00199 
00203     explicit cFSM(const char *name=NULL);
00204 
00208     cFSM(const cFSM& vs) {setName(vs.name());operator=(vs);}
00209 
00214     cFSM& operator=(const cFSM& vs);
00216 
00219 
00224     virtual cObject *dup() const   {return new cFSM(*this);}
00225 
00230     virtual void info(char *buf);
00231 
00236     virtual void writeContents(ostream& os);
00237 
00243     virtual int netPack();
00244 
00250     virtual int netUnpack();
00252 
00255 
00259     int state() const  {return _state;}
00260 
00264     const char *stateName() const {return _statename?_statename:"";}
00265 
00269     int inTransientState() const  {return _state<0;}
00270 
00281     void setState(int state, const char *stn=NULL)  {_state=state;_statename=stn;}
00283 };
00284 
00285 #endif

Generated at Mon Jun 16 23:37:31 2003 for OMNeT++ by doxygen1.2.8.1 written by Dimitri van Heesch, © 1997-2001