BWAPI
ExampleAIModule/Source/StateMachine.h
Go to the documentation of this file.
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines