首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

技术系列之 状态机(2)

技术系列之 状态机(2)

BEGIN_FSM_STATE_TABLE(my_state_table)
     BEGIN_STATE(0,"first",enter_fsm,exit_fsm,defualt_fsm)
         STATE_EVENT_ITEM(func_fsm,1,1)
         STATE_EVENT_ITEM(func_fsm,2,2)
     END_STATE(0)
     
     BEGIN_STATE(1,"second",enter_fsm,exit_fsm,defualt_fsm)
         STATE_EVENT_ITEM(func_fsm,1,2)
         STATE_EVENT_ITEM(func_fsm,2,0)
     END_STATE(1)
     
     BEGIN_STATE(2,"third",enter_fsm,exit_fsm,defualt_fsm)
         STATE_EVENT_ITEM(func_fsm,1,0)
         STATE_EVENT_ITEM(func_fsm,2,1)
     END_STATE(2)
END_FSM_STATE_TABLE(my_state_table) void enter_fsm(FSM_EVENT * event)
  {
     printf("enter me\n");
}
void exit_fsm(FSM_EVENT * event)
  {
     printf("exit me\n");
}
void defualt_fsm(FSM_EVENT * event)
  {
     printf("i am defualt_fsm\n");
}
void func_fsm(FSM_EVENT * event)
  {
     printf("i am func_fsm\n");
}
int main()
  {
     printf("i am main\n");
      FSM fsm={0,defualt_fsm,my_state_table};
     printf("state[%d],name[%s]\n",fsm.state_id,fsm.state_tables[fsm.state_id].name);
     FSM_EVENT event;
     event.id=1;
     event.data.i=1;
     fsm_do_event(fsm,event);
     printf("state[%d],name[%s]\n",fsm.state_id,fsm.state_tables[fsm.state_id].name);
}
三、状态机实现
(2)面向过程方式
2、层次状态机模块实现。
与常规状态机相比,它的FSM_STATE结构没有default_func,多了 FSM_STATE_ID parent; FSM_STATE_ID default_child;两个结构。状态机初始化的时候可以指定默认状态,为了防止指定的状态非叶结点,增加fsm_init方法。该状态机的事件处理算法简单描述如下:(1)首先在当前状态以及其祖先状态的状态事件表中搜索匹配事件,如果搜索到,保存操作以及目的状态标识;(2)在old栈中保存当前状态到根节点的路径,在new栈中保存目的状态到根节点的路径;(3)将old栈中的顶层元素依次与new栈的顶层元素匹配,如果匹配则都出栈,不匹配,停止;(4)当前的old栈中节点即为该事件导致的退出状态,从栈低扫描到栈顶,依次执行exit_func;(5)执行以前保存的操作;(6)扫描new栈,从栈顶到栈低依次执行enter_func;(7)最后检测目的状态是否是叶节点状态,否,则依次进入default_child节点,并执行enter_func。模块实现代码如下:
#define SINGLE_STATE_MAX_EVENT 10
#define STATE_TREE_DEPTH 10
typedef  int FSM_EVENT_ID;
typedef struct event_param_st
  {
     FSM_EVENT_ID id;
      union{
         int i;
     }data;
}FSM_EVENT;
typedef  int FSM_STATE_ID;
typedef void (*FSM_FUNC)(FSM_EVENT *);
typedef struct state_event_st
  {
     FSM_FUNC func;
     FSM_EVENT_ID event;
     FSM_STATE_ID state;
}FSM_STATE_EVENT;
typedef struct state_st
  {
     FSM_STATE_ID id;
     char *name;
     FSM_STATE_ID parent;
     FSM_STATE_ID default_child;
     FSM_FUNC enter_func;
     FSM_FUNC exit_func;
     FSM_STATE_EVENT event_table[SINGLE_STATE_MAX_EVENT];
}FSM_STATE;
typedef FSM_STATE STATE_TABLE[];
typedef FSM_STATE * PTR_STATE_TABLE;

#define END_EVENT_ID -1
#define END_STATE_ID -1
  #define BEGIN_FSM_STATE_TABLE(state_stable) static STATE_TABLE state_stable={
  #define BEGIN_STATE(id,name,parent,default_child,enter_func,exit_func) {id,name,parent,default_child,enter_func,exit_func,{
  #define STATE_EVENT_ITEM(func,event,state) {func,event,state},
  #define END_STATE(id) {NULL,END_EVENT_ID,END_STATE_ID}}},
  #define END_FSM_STATE_TABLE(state_stable) {END_STATE_ID,NULL,END_STATE_ID,END_STATE_ID,NULL,NULL,NULL}};

typedef struct fsm_st
  {
     FSM_STATE_ID state_id;
     FSM_FUNC default_func;
     PTR_STATE_TABLE state_tables;
}FSM;

void fsm_init(FSM &fsm)
  {
     FSM_STATE *state=&(fsm.state_tables[fsm.state_id]);
     while(state->default_child!=END_STATE_ID)
      {
         state=&(fsm.state_tables[state->default_child]);
         if(state->enter_func)
             state->enter_func(NULL);
     }
     fsm.state_id=state->id;
}
继承事业,薪火相传
返回列表