有限状态机(FSM)是表示有限个状态及在这些状态之间的转移和动做等行为的数学模型,在计算机领域有着普遍的应用。一般FSM包含几个要素:状态的管理、状态的监控、状态的触发、状态触发后引起的动做。本文主要阐述一下状态机的几种设计方法。函数
1:switch case/if else设计方法spa
curEvent = getEvent(); curState = getCurState();switch(curState) { case state1: { switch(curEvent ) { TODO... setCurState(); break; } break; } ... }
这种设计方法最简单,经过一大堆判断来处理,适合小规模的状态切换流程,但若是规模扩大难以扩展和维护。.net
2:基于表结构的状态机设计方法:创建相应的状态表和动做查询表,根据状态表、事件、动做表定位相应的动做处理函数,执行完成后再进行状态的切换。设计
一个通用的状态机处理模块的设计以下:code
/*状态表注册*/ void FSM_Regist(FSM_T* pFsm,STATE_TABLE_S* pStateTable) { pFsm->FsmTable = pStateTable; return; } /*状态迁移*/void FSM_MoveState(FSM_T* pFsm,int state) { pFsm->curState = state; return; } /*事件处理*/void FSM_EventHandle(FSM_T* pFsm,int event) { ACT_TABLE_T* pActTable = NULL; ActFun eventActFun = NULL; /*获取当前状态动做表*/ pActTable = FSM_getActTable(pFsm); /*获取当前动做函数*/ for(int i=0;i<MAX_ACT_NUM;i++) { if(event == pActTable[i].event) { eventActFun = pActTable[i].eventActFun; break; } } /*动做执行*/ if(eventActFun) { eventActFun(pFsm); } }
假设咱们的状态图以下:blog
相应的状态机设置以下:事件
/*状态1的动做表*/ ACT_TABLE_T state1ActTable[] = { {EVENT1,state1Event1Fun}, {EVENT3,state1Event3Fun}, };/*状态2的动做表*/ ACT_TABLE_T state2ActTable[] = { {EVENT2,state2Event2Fun}, };/*状态表*/ STATE_TABLE_T FsmTable[] = { {STATE1,state1ActTable}, {STATE2,state2ActTable}, };int main(int argc, _TCHAR* argv[]) { FSM_T fsm; /*状态表注册*/ FSM_Regist(&fsm,FsmTable); FSM_MoveState(&fsm,STATE1); FSM_EventHandle(&fsm,EVENT1); FSM_EventHandle(&fsm,EVENT2); return 0; } /*客户端提供的状态处理函数*/void state1Event1Fun(void* pFsm) { FSM_MoveState((FSM_T*)pFsm,STATE2); return; }void state1Event3Fun(void* pFsm) { FSM_MoveState((FSM_T*)pFsm,STATE3); return; }void state2Event2Fun(void* pFsm) { FSM_MoveState((FSM_T*)pFsm,STATE3); return; }
经过设计一个通用的基于表结构的状态机模块,针对不一样的状态图,咱们只须要根据状态图获得其状态表结构,而后经过FSM_Regist注册,就能够方便的使用了状态机的功能了。这种机制便于咱们添加新的状态流程,而且能够很好的进行分层状态机的设计。get