实现状态机框架,可以继承此框架的基类实现自定义功能,需要QuickHash头文件,源码如下,请尊重原创!欢迎批评指正!
FSM.h
#ifndef FSM_H
#define FSM_H
#include <vector>
#include "QuickHash.h"
#include "FSMState.h"
#include "TypeTag.h"
/**@file FSM.h
* 实现状态机
* @author xiaoxing.zhou
* @date 2012.4.27
* @version v1.0
*/
class EventBase;
class FSM
{
public:
/**构造函数*/
FSM();
~FSM();
/**设置初始和结束状态*/
bool SetInit(const char* pName);
bool SetExit(const char* pName);
/**添加状态机状态*/
bool AddState(FSMState* pState);
/**获取当前状态*/
FSMState* GetState(){return m_pState;}
/**启动状态机*/
bool StartRun();
/**停止状态机*/
bool StopRun();
/**处理Event*/
void Process(EventBase* pEvent);
/**缺省执行方法*/
virtual bool Default();
void TransitState(TypeTag* pTag);
/**事件与状态注册方法*/
static void RegisterEvent(const char* pName, int id);
static void RegisterState(const char* pName, int id);
static TypeTag* RetriveState(const char* pName);
static TypeTag* RetriveEvent(const char* pName);
protected:
/**查找状态*/
FSMState* FindState(TypeTag* pTag);
private:
//!保存State和Event标识
typedef QuickHash<const char*, TypeTag*,Equal, Hash,100> HashTable;
static HashTable m_StateTag;
static HashTable m_EventTag;
typedef TypeTag EventTag;
typedef TypeTag StateTag;
FSMState* m_pState;
FSMState* m_pExitState;
std::vector<FSMState*>m_StateVect;
};
#endif
FSM.cpp
#include "FSM.h"
#include "EventBase.h"
FSM::HashTable FSM::m_StateTag;
FSM::HashTable FSM::m_EventTag;
FSM::FSM()
{
m_pState=NULL;
}
FSM::~FSM()
{
for(int i=0; i<m_StateVect.size(); ++i)delete m_StateVect[i];
}
bool FSM::SetInit(const char* pName)
{
m_pState=FindState(m_StateTag.Find(pName)->GetValue());
if(m_pState)return true;
else return false;
}
bool FSM::SetExit(const char* pName)
{
m_pExitState=FindState(m_StateTag.Find(pName)->GetValue());
if(m_pExitState)return true;
else return false;
}
bool FSM::AddState(FSMState* pState)
{
m_StateVect.push_back(pState);
return true;
}
bool FSM::StartRun()
{
if(m_pState){
m_pState->Enter();
return true;
}
return false;
}
bool FSM::StopRun()
{
if(m_pState==m_pExitState){
m_pState->Exit();
return true;
}
return false;
}
void FSM::Process(EventBase* pEvent)
{
if(m_pState->FindEvent(pEvent->GetTag())){
TypeTag* pTag=pEvent->GetNextState();
if(pTag){
if(m_pState->Match(pTag))
{
pEvent->Handler();
}
else
{//要进行状态切换
m_pState->Exit();
pEvent->Handler();
TransitState(pTag);
m_pState->Enter();
}
}
else{
pEvent->Handler();
}
}
else{
if(!m_pState->Default()){
Default();
}
}
}
bool FSM::Default(){return false;}
void FSM::TransitState(TypeTag* pTag)
{
for(int i=0; i<m_StateVect.size(); ++i){
if(m_StateVect[i]->Match(pTag)){
m_pState=m_StateVect[i];
break;
}
}
}
void FSM::RegisterEvent(const char* pName, int id)
{
TypeTag* pTag=new TypeTag(pName, id);
m_EventTag.Insert(pTag->GetName(),pTag);
}
void FSM::RegisterState(const char* pName, int id)
{
TypeTag* pTag=new TypeTag(pName, id);
m_StateTag.Insert(pTag->GetName(),pTag);
}
TypeTag* FSM::RetriveState(const char* pName)
{
HashTable::Node* pNode=m_StateTag.Find(pName);
if(pNode)return pNode->GetValue();
else return NULL;
}
TypeTag* FSM::RetriveEvent(const char* pName)
{
HashTable::Node* pNode=m_EventTag.Find(pName);
if(pNode)return pNode->GetValue();
else return NULL;
}
FSMState* FSM::FindState(TypeTag* pTag){
for(int i=0; i<m_StateVect.size(); ++i){
if(m_StateVect[i]->Match(pTag)){
return m_StateVect[i];
}
}
return NULL;
}
FSMState.h
#ifndef FSM_STATE_H
#define FSM_STATE_H
#include <vector>
#include "TypeTag.h"
/**@file FSMState.h
* 定义状态机状态基类.
* @author xiaoxing.zhou
* @date 2012.4.27
* @version v1.0
*/
/**@class EventBase
* 声明事件基类.
*/
class EventBase;
class FSMState
{
public:
FSMState(const char* pName);
virtual ~FSMState(){};
/**状态进入执行方法*/
virtual void Enter(){printf("%s enter\n",m_pTag->GetName());};
/**状态离开执行方法*/
virtual void Exit(){printf("%s exit\n",m_pTag->GetName());};
/**未定义事件发生执行方法*/
virtual bool Default(){printf("%s default call\n",m_pTag->GetName());return true;};
/**添加状态允许发生事件列表*/
void AddEvent(const char* pName);
/**匹配函数*/
bool Match(TypeTag* pTag){return m_pTag==pTag?true:false;}
/**判断是否允许事件*/
bool FindEvent(TypeTag* pTag);
private:
TypeTag* m_pTag;
std::vector<TypeTag*> m_EventVect;//!< 事件列表
};
#endif
FSMState.cpp
#include "FSMState.h"
#include "FSM.h"
#include "EventBase.h"
FSMState::FSMState(const char* pName)
{
m_pTag=FSM::RetriveState(pName);
}
void FSMState::AddEvent(const char* pName)
{
TypeTag* pTag=FSM::RetriveEvent(pName);
m_EventVect.push_back(pTag);
}
bool FSMState::FindEvent(TypeTag* pTag)
{
for(int i=0; i<m_EventVect.size(); ++i){
if(m_EventVect[i]==pTag){
return true;
}
}
return false;
}
EventBase.h
#ifndef EVENT_BASE_H
#define EVENT_BASE_H
#include <string>
#include <vector>
#include "TypeTag.h"
#include "FSM.h"
/**@file EventBase.h
* 定义事件基类.
* @author xiaoxing.zhou
* @date 2012.4.27
* @version v1.0
*/
/**@class EventBase
* 自定义事件需要基础此基类.
*/
class EventBase
{
public:
EventBase(const char* pName,const char* pState=NULL)
{
m_pEventTag=FSM::RetriveEvent(pName);
if(pState)m_pStateTag=FSM::RetriveState(pState);
else m_pStateTag=NULL;
}
virtual ~EventBase(){};
/**事件发生时候执行的操作*/
virtual void Handler(){printf("%s happen\n",m_pEventTag->GetName());};
/**匹配函数*/
bool Match(TypeTag* pTag){return m_pEventTag==pTag?true:false;}
/**获取事件标识*/
TypeTag* GetTag(){return m_pEventTag;}
/**获取转移状态标识*/
TypeTag* GetNextState(){return m_pStateTag;}
private:
TypeTag* m_pEventTag;
TypeTag* m_pStateTag;
};
#endif
TypeTag.h
#ifndef TYPE_TAG_H
#define TYPE_TAG_H
#include <string>
/**@file TypeTag.h
* 定义标识类,用于标识Event和State.
* @author xiaoxing.zhou
* @date 2012.4.27
* @version v1.0
*/
class TypeTag
{
public:
TypeTag(const char* pName, int id){m_id=id; m_name=pName;}
/**获取ID*/
int GetID(){return m_id;}
/**获取名称*/
const char* GetName(){return m_name.c_str();}
/**匹配函数*/
bool Match(int id){return id==m_id?true:false;}
bool Match(const char* pName){return m_name.compare(pName)==0?true:false;}
private:
int m_id;
std::string m_name;
};
#endif
简单测试代码Main.cpp
#include "FSM.h"
#include "EventBase.h"
int main(void)
{
FSM::RegisterState("S0",0);
FSM::RegisterState("S2",-1);
FSM::RegisterState("S1",1);
FSM::RegisterEvent("zero",0);
FSM::RegisterEvent("one",1);
FSM fsm;
FSMState* pState=new FSMState("S0");
pState->AddEvent("zero");
pState->AddEvent("one");
fsm.AddState(pState);
pState=new FSMState("S1");
pState->AddEvent("zero");
pState->AddEvent("one");
fsm.AddState(pState);
pState=new FSMState("S2");
fsm.AddState(pState);
fsm.SetInit("S0");
fsm.SetExit("S2");
fsm.StartRun();
EventBase* pEvent=new EventBase("zero","S1");
fsm.Process(pEvent);
delete pEvent;
pEvent=new EventBase("one","S2");
fsm.Process(pEvent);
delete pEvent;
fsm.StopRun();
return 0;
}