TRC Library for FRC (2011) 2011
TRC Library Code Project

C:/Users/Michael/Frc/2011/code/trclib/StateMachine.h

Go to the documentation of this file.
00001 #if 0
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 #endif
00015 
00016 #ifndef _STATEMACHINE_H
00017 #define _STATEMACHINE_H
00018 
00019 #ifdef MOD_ID
00020     #undef MOD_ID
00021 #endif
00022 #define MOD_ID                  MOD_SM
00023 #ifdef MOD_NAME
00024     #undef MOD_NAME
00025 #endif
00026 #define MOD_NAME                "StateMachine"
00027 
00028 //
00029 // Constants.
00030 //
00031 #define SMF_READY               0x80000000
00032 #define SMF_MASK                0x0000ffff
00033 #define SMF_WAIT_ALL            0x00000001
00034 
00035 #define SMSTATE_DISABLED        0
00036 #define SMSTATE_STARTED         1
00037 
00041 class StateMachine
00042 {
00043 private:
00044     Event **m_pEvents;
00045     UINT32  m_cEvents;
00046     UINT32  m_nextState;
00047     UINT32  m_flagsSM;
00048     UINT32  m_currState;
00049 
00050 public:
00055     StateMachine(
00056         void
00057         ): m_pEvents(NULL),
00058            m_cEvents(0),
00059            m_nextState(SMSTATE_DISABLED),
00060            m_flagsSM(0),
00061            m_currState(SMSTATE_DISABLED)
00062     {
00063         TLevel(INIT);
00064         TEnter();
00065         TExit();
00066     }   //StateMachine
00067 
00071     ~StateMachine(
00072         void
00073         )
00074     {
00075         TLevel(INIT);
00076         TEnter();
00077         TExit();
00078     }   //~StateMachine
00079 
00085     void
00086     Start(
00087         __in UINT32 state = SMSTATE_STARTED
00088         )
00089     {
00090         TLevel(API);
00091         TEnter();
00092 
00093         m_pEvents = NULL;
00094         m_cEvents = 0;
00095         m_currState = state;
00096         m_nextState = state;
00097         m_flagsSM = SMF_READY;
00098 
00099         TExit();
00100     }   //Start
00101 
00105     void
00106     Stop(
00107         void
00108         )
00109     {
00110         TLevel(API);
00111         TEnter();
00112 
00113         m_pEvents = NULL;
00114         m_cEvents = 0;
00115         m_currState = SMSTATE_DISABLED;
00116         m_nextState = SMSTATE_DISABLED;
00117         m_flagsSM = 0;
00118 
00119         TExit();
00120     }   //Stop
00121 
00127     bool
00128     IsEnabled(
00129         void
00130         )
00131     {
00132         TLevel(API);
00133         TEnter();
00134         bool rc = m_currState != SMSTATE_DISABLED;
00135         TExitMsg(("=%d", rc));
00136         return rc;
00137     }   //IsEnabled
00138 
00152     bool
00153     IsReady(
00154         void
00155         )
00156     {
00157         bool fReady = false;
00158         TLevel(API);
00159         TEnter();
00160         
00161         if (m_currState != SMSTATE_DISABLED)
00162         {
00163             if (m_flagsSM & SMF_READY)
00164             {
00165                 fReady = true;
00166             }
00167             else
00168             {
00169                 UINT cSignaledEvents = 0;
00170 
00171                 for (UINT32 i = 0; i < m_cEvents; i++)
00172                 {
00173                     if (m_pEvents[i]->IsSignaled())
00174                     {
00175                         cSignaledEvents++;
00176                     }
00177                 }
00178 
00179                 if (!(m_flagsSM & SMF_WAIT_ALL))
00180                 {
00181                     if (cSignaledEvents > 0)
00182                     {
00183                         fReady = true;
00184                     }
00185                 }
00186                 else if (cSignaledEvents == m_cEvents)
00187                 {
00188                     fReady = true;
00189                 }
00190 
00191                 if (fReady)
00192                 {
00193                     ClearAllEvents();
00194                     m_pEvents = NULL;
00195                     m_cEvents = 0;
00196                     m_currState = m_nextState;
00197                     m_flagsSM |= SMF_READY;
00198                 }
00199             }
00200         }
00201 
00202         TExitMsg(("=%d", fReady));
00203         return fReady;
00204     }   //IsReady
00205 
00211     UINT32 GetCurrentState(
00212         void
00213         )
00214     {
00215         TLevel(UTIL);
00216         TEnter();
00217         TExitMsg(("=%d", m_currState));
00218         return m_currState;
00219     }   //GetCurrentState
00220 
00224     void
00225     ClearAllEvents(
00226         void
00227         )
00228     {
00229         TLevel(API);
00230         TEnter();
00231 
00232         for (UINT32 i = 0; i < m_cEvents; i++)
00233         {
00234             m_pEvents[i]->ClearEvent();
00235         }
00236 
00237         TExit();
00238     }   //ClearAllEvents
00239 
00256     bool
00257     WaitForEvents(
00258         __in Event **pEvents,
00259         __in UINT32  cEvents,
00260         __in UINT32  nextState,
00261         __in UINT32  flags
00262         )
00263     {
00264         bool rc = false;
00265 
00266         TLevel(API);
00267         TEnterMsg(("pEvents=%p,cEvents=%d,NextState=%d,flags=%x",
00268                    pEvents, cEvents, nextState, flags));
00269 
00270         if ((pEvents == NULL) || (cEvents == 0))
00271         {
00272             TErr(("Must have at least one event."));
00273         }
00274         else
00275         {
00276             m_pEvents = pEvents;
00277             m_cEvents = cEvents;
00278             ClearAllEvents();
00279             m_nextState = nextState;
00280             m_flagsSM &= ~SMF_MASK;
00281             m_flagsSM |= flags & SMF_MASK;
00282             m_flagsSM &= ~SMF_READY;
00283             rc = true;
00284         }
00285 
00286         TExitMsg(("=%d", rc));
00287         return rc;
00288     }   //WaitForEvents
00289 };  //class StateMachine
00290 
00291 #endif  //ifndef _STATEMACHINE_H
 All Classes Files Functions Variables Defines