第二次修改状态机源码

3/8/2017来源:ASP.NET技巧人气:1847

第二次修改把状态机引擎独立出来,解决函数的可重入问题,同时可以支持多个状态机。 下面贴出代码:

//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_H typedef 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_H enum 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_H enum 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