• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

spl/math/StateMachine.h

00001 /*
00002  *   This file is part of the Standard Portable Library (SPL).
00003  *
00004  *   SPL is free software: you can redistribute it and/or modify
00005  *   it under the terms of the GNU General Public License as published by
00006  *   the Free Software Foundation, either version 3 of the License, or
00007  *   (at your option) any later version.
00008  *
00009  *   SPL is distributed in the hope that it will be useful,
00010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *   GNU General Public License for more details.
00013  *
00014  *   You should have received a copy of the GNU General Public License
00015  *   along with SPL.  If not, see <http://www.gnu.org/licenses/>.
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         // I suppose we should allow the copy constructor ...
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