00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef _statemachine_h
00018 #define _statemachine_h
00019
00020 #include <spl/Debug.h>
00021 #include <spl/Exception.h>
00022 #include <spl/collection/Hashtable.h>
00023 #include <spl/collection/List.h>
00024 #include <spl/Memory.h>
00025 #include <spl/String.h>
00026 #include <spl/collection/Vector.h>
00027
00028
00029 class State;
00030 class Transition;
00031
00038 class IStateEventListener : public IMemoryValidate
00039 {
00040 public:
00041 virtual ~IStateEventListener();
00042 virtual void OnStateEnter( const String &input, State *from, State *to ) = 0;
00043 virtual void OnStateLeave( const String &input, State *from, State *to ) = 0;
00044 virtual void OnStateTransition( const String &input, Transition *trans ) = 0;
00045
00046 #ifdef DEBUG
00047 virtual void ValidateMem() const = 0;
00048 virtual void CheckMem() const = 0;
00049 #endif
00050 };
00051
00055 class TransitionActionResolver : public IMemoryValidate
00056 {
00057 protected:
00058 Hashtable<String, IStateEventListener *> m_map;
00059
00060 public:
00061 TransitionActionResolver();
00062 TransitionActionResolver(const TransitionActionResolver& resolver);
00063 virtual ~TransitionActionResolver();
00064
00065 inline void Add(String& name, IStateEventListener *handler) { m_map.Set(name, handler); }
00066 inline IStateEventListener *Get(String& name) { return m_map.Get(name); }
00067 inline bool Has(String& name) { return m_map.ContainsKey(name); }
00068 inline void Add(const char *name, IStateEventListener *handler) { m_map.Set(String(name), handler); }
00069 inline IStateEventListener *Get(const char *name) { return m_map.Get(String(name)); }
00070 inline bool Has(const char *name) { return m_map.ContainsKey(String(name)); }
00071
00072 #ifdef DEBUG
00073 virtual void ValidateMem() const;
00074 virtual void CheckMem() const;
00075 #endif
00076 };
00077
00081 class Transition : public IMemoryValidate
00082 {
00083 protected:
00084 String m_onInput;
00085 State *m_from;
00086 State *m_to;
00087 String m_actionName;
00088 IStateEventListener *m_transitionAction;
00089
00090 public:
00091 Transition(const char *onInput, State *from, State *to, const char *actionName, IStateEventListener *transitionAction);
00092 virtual ~Transition();
00093
00094 inline String &InputText() { return m_onInput; }
00095 inline State *GetFromState() { return m_from; }
00096 inline State *GetToState() { return m_to; }
00097
00098 void FireOnTransition(const String& input);
00099
00100 #ifdef DEBUG
00101 virtual void ValidateMem() const;
00102 virtual void CheckMem() const;
00103 #endif
00104 };
00105
00109 class State : public IMemoryValidate
00110 {
00111 protected:
00112 String m_name;
00113 String m_enterActionName;
00114 String m_leaveActionName;
00115
00116 IStateEventListener *m_enterAction;
00117 IStateEventListener *m_leaveAction;
00118
00119 Hashtable<String, Transition *> m_fromThisState;
00120 Vector<Transition *> m_transitionList;
00121
00122 public:
00123 State(const char *name, const char *enterActionName, const char *leaveActionName, IStateEventListener *enterAction, IStateEventListener *leaveAction);
00124 virtual ~State();
00125
00126 void FireOnLeave(const String& input, State *to);
00127 void FireOnEnter(const String& input, State *to);
00128
00129 inline void AddTransitionFromThisState( Transition *trans )
00130 {
00131 ASSERT_MEM(trans, sizeof(Transition));
00132 m_transitionList.Add(trans);
00133 m_fromThisState.Set( trans->InputText(), trans );
00134 }
00135
00136 inline bool ContainsTransition( const String& inputText )
00137 {
00138 return m_fromThisState.ContainsKey( inputText );
00139 }
00140
00141 inline bool ContainsTransition( const char *inputText )
00142 {
00143 return m_fromThisState.ContainsKey( String(inputText) );
00144 }
00145
00146 Transition *GetTransition( const String& inputText );
00147 String &Name() { return m_name; }
00148
00149 inline Transition *GetTransition( const char *inputText )
00150 {
00151 return GetTransition( String(inputText) );
00152 }
00153
00154 #ifdef DEBUG
00155 virtual void ValidateMem() const;
00156 virtual void CheckMem() const;
00157 #endif
00158 };
00159
00161 class StateMachine : public IMemoryValidate
00162 {
00163 private:
00164
00165 inline StateMachine(const StateMachine& s) {}
00166 inline void operator =(const StateMachine& s) {}
00167
00168 protected:
00169 TransitionActionResolver m_resolver;
00170 State *m_currentState;
00171 Hashtable<String, State *> m_stateIdx;
00172 List<State *> m_states;
00173
00174 public:
00175 StateMachine();
00176 virtual ~StateMachine();
00177
00178 inline TransitionActionResolver& GetResolver() { return m_resolver; }
00179
00180 void SetState( const char *statename );
00181 void DefineState( const char *name, const char *enterActionName, const char *leaveActionName );
00182 void DefineTransition( const char *onInput, const char *from, const char *to, const char *actionName );
00183
00184 void ChangeState(const char *input);
00185 inline String CurrentStateName() { return (NULL == m_currentState) ? String() : m_currentState->Name(); }
00186
00187 void Load( const char *filename );
00188
00189 #ifdef DEBUG
00190 virtual void ValidateMem() const;
00191 virtual void CheckMem() const;
00192 #endif
00193 };
00194
00197 #endif