cfsm.h

00001 //==========================================================================
00002 //   CFSM.H  -  header for
00003 //                     OMNeT++/OMNEST
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-2008 Andras Varga
00014   Copyright (C) 2006-2008 OpenSim Ltd.
00015 
00016   This file is distributed WITHOUT ANY WARRANTY. See the file
00017   `license' for details on this and other legal matters.
00018 *--------------------------------------------------------------*/
00019 
00020 #ifndef __CFSM_H
00021 #define __CFSM_H
00022 
00023 #include "cownedobject.h"
00024 
00025 NAMESPACE_BEGIN
00026 
00032 
00037 #define FSM_MAXT  64
00038 
00079 //
00080 // operation:
00081 // - __i counts up (starting from 1) until the FSM reaches a steady state.
00082 // - at __i=1,3,5,7,etc, FSM_Exit code is executed
00083 // - at __i=2,4,6,8,etc, FSM_Enter code is executed
00084 // - FSM_Enter code must not contain state change (this is verified)
00085 // - state changes should be encoded in FSM_Exit code
00086 // - infinite loops (when control never reaches steady state) are detected (FSM_MAXT)
00087 //
00088 #define FSM_Switch(fsm)  \
00089    for (int __i=1, __savedstate;  \
00090         (__i<3 || (__i&1)==0 || (fsm).isInTransientState()) &&  \
00091         (__i<2*FSM_MAXT || (opp_error(eINFLOOP,(fsm).getStateName()),0));  \
00092         ((__i&1)==0 && __savedstate!=(fsm).getState() &&  \
00093          (opp_error(eSTATECHG,(fsm).getStateName()),0)),  \
00094          __savedstate=(fsm).getState(),++__i)  \
00095      switch (FSM_Print(fsm,__i&1),(((fsm).getState()<<1)|(__i&1)))
00096 
00116 #define FSM_Transient(state)   (-(state))
00117 
00125 #define FSM_Steady(state)      (state)
00126 
00134 #define FSM_EnterExit(state)  ( ((state)<0) ? -((-state)<<1) : (state)<<1 )
00135 
00144 #define FSM_Enter(state)  (FSM_EnterExit(state)|0)
00145 
00153 #define FSM_Exit(state)   (FSM_EnterExit(state)|1)
00154 
00165 #define FSM_Goto(fsm,state)   (fsm).setState(state,#state)
00166 
00167 #ifdef FSM_DEBUG
00168 
00175 #define FSM_Print(fsm,exiting) \
00176     (ev << "FSM " << (fsm).getName() \
00177         << ((exiting) ? ": leaving state  " : ": entering state ") \
00178         << (fsm).getStateName() << endl)
00179 // this may also be useful as third line:
00180 //      << ((fsm).isInTransientState() ? "transient state " : "steady state ")
00181 #else
00182 #define FSM_Print(fsm,entering) ((void)0)
00183 #endif
00184 
00186 
00187 //-----------------------------------------------------
00188 
00196 class SIM_API cFSM : public cOwnedObject
00197 {
00198   private:
00199     //
00200     // About state codes:
00201     //  initial state is number 0
00202     //  negative state codes are transient states
00203     //  positive state codes are steady states
00204     //
00205     int _state;
00206     const char *_statename;   // just a ptr to an external string
00207 
00208   private:
00209     void copy(const cFSM& other);
00210 
00211   public:
00214 
00218     explicit cFSM(const char *name=NULL);
00219 
00223     cFSM(const cFSM& other) : cOwnedObject(other) {copy(other);}
00224 
00229     cFSM& operator=(const cFSM& vs);
00231 
00234 
00239     virtual cFSM *dup() const  {return new cFSM(*this);}
00240 
00245     virtual std::string info() const;
00246 
00252     virtual void parsimPack(cCommBuffer *buffer);
00253 
00259     virtual void parsimUnpack(cCommBuffer *buffer);
00261 
00264 
00268     int getState() const  {return _state;}
00269 
00273     const char *getStateName() const {return _statename?_statename:"";}
00274 
00278     int isInTransientState() const  {return _state<0;}
00279 
00290     void setState(int state, const char *stn=NULL)  {_state=state;_statename=stn;}
00292 };
00293 
00294 NAMESPACE_END
00295 
00296 
00297 #endif
Generated on Tue Dec 2 11:16:27 2014 for OMNeT++ Simulation Library by  doxygen 1.6.3