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