3、状态机实现
(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;
}
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<old_cur;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、状态机实现
(3)面向对象方式 常规&层次异步
4、状态机分析
5、状态机回路检测
6、状态机使用
另介绍boost中同步异步状态机spa