BWAPI
|
00001 #ifndef STATEMACHINE_H 00002 #define STATEMACHINE_H 00003 00004 //------------------------------------------------------------------------ 00005 // Name: StateMachine.h 00006 // Desc: State machine class. Inherit from this class and create some 00007 // states to give your agents FSM functionality 00008 // Author: Mat Buckland 2002 (fup@ai-junkie.com) 00009 //------------------------------------------------------------------------ 00010 #include <cassert> 00011 #include <string> 00012 00013 #include "State.h" 00014 00015 template <class entity_type> 00016 class StateMachine 00017 { 00018 private: 00019 00020 //a pointer to the agent that owns this instance 00021 entity_type* m_pOwner; 00022 00023 State<entity_type>* m_pCurrentState; 00024 00025 //a record of the last state the agent was in 00026 State<entity_type>* m_pPreviousState; 00027 00028 //this is called every time the FSM is updated 00029 State<entity_type>* m_pGlobalState; 00030 00031 public: 00032 00033 StateMachine(entity_type* owner):m_pOwner(owner), 00034 m_pCurrentState(NULL), 00035 m_pPreviousState(NULL), 00036 m_pGlobalState(NULL) 00037 {} 00038 00039 virtual ~StateMachine(){} 00040 00041 //use these methods to initialize the FSM 00042 void SetCurrentState(State<entity_type>* s){m_pCurrentState = s;} 00043 void SetGlobalState(State<entity_type>* s) {m_pGlobalState = s;} 00044 void SetPreviousState(State<entity_type>* s){m_pPreviousState = s;} 00045 00046 //call this to update the FSM 00047 void Update()const 00048 { 00049 //if a global state exists, call its execute method, else do nothing 00050 if(m_pGlobalState) m_pGlobalState->Execute(m_pOwner); 00051 00052 //same for the current state 00053 if (m_pCurrentState) m_pCurrentState->Execute(m_pOwner); 00054 } 00055 00056 //change to a new state 00057 void ChangeState(State<entity_type>* pNewState) 00058 { 00059 assert(pNewState && 00060 "<StateMachine::ChangeState>: trying to change to NULL state"); 00061 00062 //keep a record of the previous state 00063 m_pPreviousState = m_pCurrentState; 00064 00065 //call the exit method of the existing state 00066 if (m_pCurrentState) m_pCurrentState->Exit(m_pOwner); 00067 00068 //change state to the new state 00069 m_pCurrentState = pNewState; 00070 00071 //call the entry method of the new state 00072 m_pCurrentState->Enter(m_pOwner); 00073 } 00074 00075 //change state back to the previous state 00076 void RevertToPreviousState() 00077 { 00078 ChangeState(m_pPreviousState); 00079 } 00080 00081 //returns true if the current state's type is equal to the type of the 00082 //class passed as a parameter. 00083 bool isInState(const State<entity_type>& st)const 00084 { 00085 return typeid(*m_pCurrentState) == typeid(st); 00086 } 00087 00088 State<entity_type>* GetCurrentState() const{return m_pCurrentState;} 00089 State<entity_type>* GetGlobalState() const{return m_pGlobalState;} 00090 State<entity_type>* GetPreviousState() const{return m_pPreviousState;} 00091 }; 00092 00093 00094 #endif 00095 00096