📄 mason.txt
字号:
A Finite State Machine Framework
by P. Dale Mason
Listing 1:
// C-style method of doing a simple Finite State Machine
#define INVALID_EVENT -1
#define INVALID_STATE -1
typedef int event_t;
typedef int state_t;
typedef void (*FPAction)(void*);
typedef struct State_ State;
// State Machine components
typedef struct Transition_
{
const event_t event;
FPAction action;
const State* state;
} Transition;
struct State_
{
const Transition* table;
FPAction entry;
FPAction exit;
};
// Create the State Transition Table
#define DEFINE_TRANSITION_TABLE(name) \
Transition name##_TransitionTable[] = {
#define ADD_TRANSITION(ev,ac,st) \
{ ev, ac, st },
#define END_TRANSITION_TABLE \
{ INVALID_EVENT, NULL, INVALID_STATE } }
// DEFINE_STATE_TABLE
#define DEFINE_STATE_TABLE(name) \
State name##_StateTable[] = {
#define ADD_STATE(name,entry,exit) \
{ name##_TransitionTable, entry, exit },
#define END_STATE_TABLE \
{ NULL, NULL, NULL } }
// Access operations
#define GET_STATE_TABLE_ENTRY(name,st) \
name##_StateTable[st]
#define GET_STATE_TRANSITION_TABLE(name,st) \
(name##_StateTable[st]).table
#define GET_STATE_ENTRY_CRITERIA(name,st) \
(name##_StateTable[st]).entry
#define GET_STATE_EXIT_CRITERIA(name,st) \
(name##_StateTable[st]).exit
Listing 2:
#ifdef DERIVE_STATE_MACHINE
#define THIS (*this)
template <class T, class EV, class CMP = std::less<EV> >
class StateMachine : private T
{
public:
explicit StateMachine( State<T,EV,CMP>* const stStart ) :
T(), m_stStart(stStart), m_stCurrent(stStart), m_stThis(eStopped) {}
// Aggregated Version of State Machine
#else
#define THIS (*m_T)
template <class T, class EV, class CMP = std::less<EV> >
class StateMachine
{
private:
T* m_T;
public:
explicit StateMachine( T* _T, State<T,EV,CMP>* const stStart ) :
m_T(_T), m_stStart(stStart), m_stCurrent(stStart), m_stThis(eStopped) {}
~StateMachine() { delete m_T; }
#endif // DERIVE_STATE_MACHINE
... // other API functions not shown
private:
State<T,EV,CMP>* const m_stStart;
State<T,EV,CMP>* m_stCurrent;
};
Listing 3:
template <class T, class EV, class CMP>
class Transition
{
friend State<T,EV,CMP>;
public:
State<T,EV,CMP>* operator()( const T& _T, const EV& ev ) throw() {
(*m_evAction)(_T,ev);
return m_stNext;
}
protected:
Transition( const State<T,EV,CMP>& stNext, Action<T,EV>* evAction ) :
m_stNext(const_cast<State<T,EV,CMP>*>(&stNext)), m_evAction(evAction) {
}
... // Other member information
};
template <class T, class EV, class CMP = std::less<EV> >
class State
{
// State Transition Table Type
typedef std::map<const EV,const Transition<T,EV,CMP>*,CMP>
TransitionTable;
public:
typedef State<T,EV,CMP> state_type;
typedef EventAction<T,EV>::HANDLE HANDLE;
public:
State( HANDLE hEnter = 0, HANDLE hExit = 0 ); {
if ( hEnter == 0 ) {
m_evEnter = new NoAction<T,EV>;
}
else { m_evEnter = new EventAction<T,EV>(hEnter); }
if ( hExit == 0 ) {
m_evExit = new NoAction<T,EV>;
}
else { m_evExit = new EventAction<T,EV>(hExit); }
}
~State() {
TransitionTable::iterator iter;
for ( iter = m_stTable.begin(); iter != m_stTable.end(); iter++ ) {
delete const_cast<Transition<T,EV,CMP>*>( iter->second );
}
delete m_evEnter; delete m_evExit;
}
... // other API functions not shown
private:
TransitionTable m_stTable;
Action<T,EV>* m_evEnter;
Action<T,EV>* m_evExit;
};
Listing 4:
// Base action class
template <class T, class EV>
struct Action
{
virtual void operator()( const T&, const EV& ) throw() = 0;
};
// No Action default
template <class T, class EV>
struct NoAction : public Action<T,EV>
{
void operator()( const T&, const EV& ) throw() {};
};
// Action Handler for "T"
template <class T, class EV>
struct EventAction : public Action<T,EV>
{
typedef void (T::*HANDLE)( const EV& ev );
explicit EventAction( HANDLE hAction ) :
m_hAction(hAction) {}
void operator()( const T& _T, const EV& ev ) throw() {
(_T.*m_hAction)(ev);
}
private:
HANDLE m_hAction;
};
3
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -