有限狀態機(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