Board logo

标题: 技术系列之 状态机(3) [打印本页]

作者: yuyang911220    时间: 2016-8-4 20:11     标题: 技术系列之 状态机(3)

void fsm_do_event(FSM &fsm, FSM_EVENT &event)
  {
     FSM_STATE *state;
     FSM_STATE_ID state_id,old_state_id,new_state_id;
     FSM_STATE_ID oldStack[STATE_TREE_DEPTH],newStack[STATE_TREE_DEPTH];
     int old_cur=0,new_cur=0;
     
     bool isMatch=false;
     FSM_FUNC match_func=NULL;
     int i=0;
     state_id=old_state_id=fsm.state_id;
     do
      {
         i=0;
         state=&(fsm.state_tables[state_id]);
         while(state->event_table[i].event!=END_EVENT_ID)
          {
             if(state->event_table[i].event==event.id)
              {
                 isMatch=true;
                 match_func=state->event_table[i].func;
                 new_state_id=state->event_table[i].state;
                 break;
             }
             i++;
         }
         if(isMatch==false)
             state_id=state->parent;
         else
             break;
     }while(state->parent!=END_STATE_ID);
     if(isMatch==false)
      {
         if(fsm.default_func)
             fsm.default_func(&event);
         return;
     }
     if(new_state_id==old_state_id)
      {
         if(match_func)
             match_func(&event);
         return;
     }
     state_id=old_state_id;
     do
      {
         oldStack[old_cur++]=state_id;
         state=&(fsm.state_tables[state_id]);
         state_id=state->parent;
     }while(state->parent!=END_STATE_ID);
     state_id=new_state_id;
     do
      {
         newStack[new_cur++]=state_id;
         state=&(fsm.state_tables[state_id]);
         state_id=state->parent;
     }while(state->parent!=END_STATE_ID);
     while(oldStack[old_cur-1]==newStack[new_cur-1])
      {
         old_cur--;
         new_cur--;
     }
     for(i=0;i      {
         if(fsm.state_tables[oldStack[i]].exit_func)
             fsm.state_tables[oldStack[i]].exit_func(&event);
     }
     if(match_func)
         match_func(&event);
     for(i=new_cur;i>0;i--)
      {
         if(fsm.state_tables[newStack[i-1]].enter_func)
             fsm.state_tables[newStack[i-1]].enter_func(&event);
     }
     state=&(fsm.state_tables[new_state_id]);
     while(state->default_child!=END_STATE_ID)
      {
         state=&(fsm.state_tables[state->default_child]);
         if(state->enter_func)
             state->enter_func(&event);
     }
     fsm.state_id=state->id;
}
使用举例,仅仅列举一个状态表和简单的状态机初始化,状态和事件应该为enum,当前使用数字,仅为了举例,操作的实现不在写出。
BEGIN_FSM_STATE_TABLE(my_state_table)
     BEGIN_STATE(0,"first",END_STATE_ID,2,enter_fsm,exit_fsm)
         STATE_EVENT_ITEM(func_fsm,1,1)
         STATE_EVENT_ITEM(func_fsm,2,2)
     END_STATE(0)
     
     BEGIN_STATE(1,"second",0,END_STATE_ID,enter_fsm,exit_fsm)
         STATE_EVENT_ITEM(func_fsm,1,3)
         STATE_EVENT_ITEM(func_fsm,2,0)
     END_STATE(1)
     
     BEGIN_STATE(2,"third",0,3,enter_fsm,exit_fsm)
         STATE_EVENT_ITEM(func_fsm,1,0)
         STATE_EVENT_ITEM(func_fsm,2,1)
     END_STATE(2)
     BEGIN_STATE(3,"third",2,END_STATE_ID,enter_fsm,exit_fsm)
         STATE_EVENT_ITEM(func_fsm,1,4)
         STATE_EVENT_ITEM(func_fsm,2,1)
     END_STATE(3)
     BEGIN_STATE(4,"third",2,END_STATE_ID,enter_fsm,exit_fsm)
         STATE_EVENT_ITEM(func_fsm,1,2)
         STATE_EVENT_ITEM(func_fsm,2,1)
     END_STATE(4)
END_FSM_STATE_TABLE(my_state_table)  FSM fsm={0,default_fsm,my_state_table};
fsm_init(fsm);
FSM_EVENT event;
event.id=1;
event.data.i=1;
fsm_do_event(fsm,event);

后续提纲:
三、状态机实现
(3)面向对象方式 常规&层次
四、状态机分析
五、状态机回路检测
六、状态机使用
另介绍boost中同步异步状态机




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0