系统设计之 状态机(二)

三、状态机实现(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 10typedef 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;}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;elsebreak;}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;i0;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中同步异步状态机

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/7338284/viewspace-219094/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/7338284/viewspace-219094/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值