第二次修改把狀態機引擎獨立出來,解決函數的可重入問題,同時可以支持多個狀態機。 下面貼出代碼:
//main.c#include <stdlib.h>#include <stdio.h>#include "state_engine.h"#include "fsm1.h" #include "fsm2.h"extern struct fsm_T fsm1;extern struct fsm_T fsm2;int main(int argc, char *argv[]){ char c=0x00; while(1) { c = getchar(); PRintf ("%c input./n", c); switch(c) { case '1': state_change(msg_pause,&fsm1); break; case 'p': state_change(msg_play,&fsm1); break; case 'r': state_change(msg_record,&fsm1); break; case 's': state_change(msg_stop,&fsm1); break; case 'f': state_change(msg_forward,&fsm1); break; case 'b': state_change(msg_backward,&fsm1); break; case '2': state_change(msg_pause2,&fsm2); break; case 'P': state_change(msg_play2,&fsm2); break; case 'R': state_change(msg_record2,&fsm2); break; case 'S': state_change(msg_stop2,&fsm2); break; case 'F': state_change(msg_forward2,&fsm2); break; case 'B': state_change(msg_backward2,&fsm2); break; case 'Q': return EXIT_SUCCESS; } } return EXIT_SUCCESS;}//state_engin.c/*上層需要維護 enum state//狀態類型枚舉 enum message//消息類型枚舉 struct transition fsm[]狀態轉移表 實現轉移函數 */ #include <stdlib.h>//debug#include <stdio.h>//debug#include "state_engine.h"int const ERR = -1;//int lookup_transition (int state, int msg, struct transition * fsmList)static int lookup_transition (int state, int msg, struct fsm_T * fsm){ int ret=ERR; int i; for(i=0;i<fsm->listSize;++i) { if(fsm->pList[i].current == state && fsm->pList[i].msg == msg) { ret = i; return ret; } } return ret;}/* transition ends*/void state_change(int msg,struct fsm_T * fsm){ int next; int index = 0; index = lookup_transition(fsm->state, msg, fsm); if(index!=ERR) { fsm->state =fsm->pList[index].next; fsm->pList[index]. transAction(); } printf("Null state");//debug return;}//state_engine.h#ifndef _STATE_ENGINE_H#define _STATE_ENGINE_Htypedef void (*action_foo)(void) ;struct transition //狀態轉換表結構 { int current; int msg; int next; action_foo transAction;};struct fsm_T //狀態機結構 { struct transition * pList; int listSize; //可傳進engine int state;}; //進行狀態轉換并且執行轉換函數 void state_change(int msg,struct fsm_T * fsm); #endif//fsm1.c//該文件需要用戶自己實現 #include <stdlib.h>#include <stdio.h>#include "state_engine.h"#include "fsm1.h" /* 動作轉換函數定義*/void do_stop(void) { printf ("I am in fsm1 state stop and should doing something here./n");}void do_play(void) { printf ("I am in fsm1 state play and should doing something here./n");}void do_forward(void) { printf ("I am in fsm1 state forward and should doing something here./n");}void do_backward(void) { printf ("I am in fsm1 state backward and should doing something here./n");}void do_pause(void) { printf ("I am in fsm1 state pause and should doing something here./n");}void do_record(void) { printf ("I am in fsm1 state record and should doing something here./n");}struct transition fsm1_list[] = { /* current_state, message/event, next_state, transAction*/ {s_play, msg_stop, s_stop ,do_stop}, {s_play, msg_pause, s_pause ,do_pause}, {s_pause, msg_pause, s_play ,do_play}, {s_pause, msg_stop, s_stop ,do_stop}, {s_stop, msg_forward, s_forward ,do_forward}, {s_stop, msg_play, s_play ,do_play}, {s_stop, msg_backward, s_backward ,do_backward}, {s_stop, msg_record, s_record ,do_record}, {s_forward, msg_stop, s_stop ,do_stop}, {s_backward, msg_stop, s_stop ,do_stop}, {s_record, msg_stop, s_stop ,do_stop},};struct fsm_T fsm1={fsm1_list,sizeof(fsm1_list)/sizeof(struct transition),0}; //狀態機初始化 //fsm1.h#ifndef _FSM_1_H#define _FSM_1_Henum state { s_stop, s_play, s_forward, s_backward, s_pause, s_record };enum message { msg_play, msg_stop, msg_forward, msg_backward, msg_record, msg_pause };/* action starts */void do_stop(void);void do_play(void);void do_forward(void);void do_backward(void);void do_pause(void);void do_record(void);#endif//fsm2.c//該文件需要用戶自己實現 #include <stdlib.h>#include <stdio.h>#include "state_engine.h"#include "fsm2.h" /* 動作轉換函數定義*/void do_stop2(void) { printf ("I am in fsm2 state stop and should doing something here./n");}void do_play2(void) { printf ("I am in fsm2 state play and should doing something here./n");}void do_forward2(void) { printf ("I am in fsm2 state forward and should doing something here./n");}void do_backward2(void) { printf ("I am in fsm2 state backward and should doing something here./n");}void do_pause2(void) { printf ("I am in fsm2 state pause and should doing something here./n");}void do_record2(void) { printf ("I am in fsm2 state record and should doing something here./n");}struct transition fsm2_list[] = { /* current_state, message/event, next_state, transAction*/ {s_play2, msg_stop2, s_stop2 ,do_stop2}, {s_play2, msg_pause2, s_pause2 ,do_pause2}, {s_pause2, msg_pause2, s_play2 ,do_play2}, {s_pause2, msg_stop2, s_stop2 ,do_stop2}, {s_stop2, msg_forward2, s_forward2 ,do_forward2}, {s_stop2, msg_play2, s_play2 ,do_play2}, {s_stop2, msg_backward2, s_backward2 ,do_backward2}, {s_stop2, msg_record2, s_record2 ,do_record2}, {s_forward2, msg_stop2, s_stop2 ,do_stop2}, {s_backward2, msg_stop2, s_stop2 ,do_stop2}, {s_record2, msg_stop2, s_stop2 ,do_stop2},};struct fsm_T fsm2={fsm2_list,sizeof(fsm2_list)/sizeof(struct transition),0}; //狀態機初始化 //fsm2.h#ifndef _FSM_2_H#define _FSM_2_Henum state2 { s_stop2, s_play2, s_forward2, s_backward2, s_pause2, s_record2 };enum message2 { msg_play2, msg_stop2, msg_forward2, msg_backward2, msg_record2, msg_pause2 };/* action starts */void do_stop2(void);void do_play2(void);void do_forward2(void);void do_backward2(void);void do_pause2(void);void do_record2(void);#endif下面是第一次修改的鏈接 http://blog.csdn.net/happyorzking/article/details/60580751
下面是楊福貴老師的講解鏈接 http://blog.csdn.net/younggift/article/details/35848677
新聞熱點
疑難解答