一个完整的状态机包括:
state(状态):就是系统在其生命周期中某一时刻的运行情况,此时,系统会执行一些动作,或者等待一些外部输入。
guard(条件):状态机对外部消息进行响应的时候,除了需要判断当前的状态,还要判断跟这个状态相关的一些条件是否成立。
event(事件):就是在一定的时间和空间发生的对系统有意义的事情。
action(动作):当一个Event被状态机系统分发的时候,状态机用action来进行响应,比如修改一下变量的值,进行输入输出,产生另一个event或者迁移到另一个状态等。
transition(迁移):从一个状态切换到另一个状态成为transition。引起状态迁移的事件称为triggering event(触发事件)。
对于我的理解就是,一个不完整的状态机把条件干掉。
此时就有,不同的state执行不同的event,产生不同的action,根据不同的action引发不同的transition 。
假如要实现如下图的一个具有3级深度共13个界面的UI界面。
初始界面为UI0(event),在这个界面下有四个不同的botton(输入),不同的botton将引发不同的(action)。
此时就有:创建13个state对应13个UI界面(event),对不同的botton进行处理之后,返回不同的action,然后引发状态的迁移。
处理便有:
13个state定义如下:
/************状态****************/
typedef enum __STATES
{
_ui0 = 0,
_ui1,
_ui2,
_ui3,
_ui4,
_ui5,
_ui6,
_ui7,
_ui8,
_ui9,
_ui10,
_ui11,
_ui12
}_STATES;
对应的event如下:
_RTACTIONS(*event[13])(void) = {
UI0,UI1,UI2,UI3,UI4,UI5,UI6,UI7,\
UI8, UI9, UI10, UI11, UI12
};
引发的action如下:
/**************动作**********************/
typedef enum __RTACTIONS
{
rtact0 = 0,
rtact1,
rtact2,
rtact3
}_RTACTIONS;
state transition(状态迁移)如下:
_STATES state_tab[13][4] = {
/* rtact0 rtact1 rtact2 rtact3 返回的action*/
{
_ui1, _ui2, _ui3, _ui0}, //_ui0,在_ui0状态下因为不同的action将产生的不同的transition
{
_ui4, _ui5, _ui6, _ui0}, //_ui1
{
_ui7, _ui8, _ui9, _ui0}, //_ui2
{
_ui10, _ui11, _ui12, _ui0}, //_ui3
{
_ui1, _ui2, _ui3, _ui0}, //_ui4
{
_ui1, _ui2, _ui3, _ui0}, //_ui5
{
_ui1, _ui2, _ui3, _ui0}, //_ui6
{
_ui1, _ui2, _ui3, _ui0}, //_ui7
{
_ui1, _ui2, _ui3, _ui0}, //_ui8
{
_ui1, _ui2, _ui3, _ui0}, //_ui9
{
_ui1, _ui2, _ui3, _ui0}, //_ui10
{
_ui1, _ui2, _ui3, _ui0}, //_ui11
{
_ui1, _ui2, _ui3, _ui0}, //_ui12
};
state->event->action->transition过程如下:
int main()
{
_STATES cur_state = _ui0; //当前状态
_RTACTIONS rt_act; //返回的动作
_RTACTIONS (*cur_event)(void);
while (1)
{
cur_event = event[cur_state]; //当前state对应的event
rt_act = cur_event(); //执行当前的event产生不同的action
cur_state = state_tab[cur_state][rt_act]; //根据不同的action进行不同的state transition
}
}
完整代码如下:使用printf大法模拟
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
/************状态****************/
typedef enum __STATES
{
_ui0 = 0,
_ui1,
_ui2,
_ui3,
_ui4,
_ui5,
_ui6,
_ui7,
_ui8,
_ui9,
_ui10,
_ui11,
_ui12
}_STATES;
/**************动作**********************/
typedef enum __RTACTIONS
{
rtact0 = 0,
rtact1,
rtact2,
rtact3
}_RTACTIONS;
int rtsc;
/*************event0***************/
_RTACTIONS UI0(void)
{
int action;
printf("创建UI0界面\n按下0->UI1\n按下1->UI2\n按下2->UI3\n按下3->UI0\n");
while (1)
{
rtsc = scanf("%d", &action);
switch (action)
{
case 0:
printf("跳至UI1\n");
return rtact0;
break;
case 1:
printf("跳至UI2\n");
return rtact1;
break;
case 2:
printf("跳至UI3\n");
return rtact2;
break;
case 3:
printf("跳至UI0\n");
return rtact3;
break;
}
}
return rtact0;
}
/*************event1***************/
_RTACTIONS UI1(void)
{
int action;
printf("创建UI1界面\n按下0->UI4\n按下1->UI5\n按下2->UI6\n按下3->UI0\n");
while (1)
{
rtsc = scanf("%d", &action);
switch (action)
{
case 0:
printf("跳至UI4\n");
return rtact0;
break;
case 1:
printf("跳至UI5\n");
return rtact1;
break;
case 2:
printf("跳至UI6\n");
return rtact2;
break;
case 3:
printf("跳至UI0\n");
return rtact3;
break;
}
}
}
/*************event2***************/
_RTACTIONS UI2(void)
{
int action;
printf("创建UI2界面\n按下0->UI7\n按下1->UI8\n按下2->UI9\n按下3->UI0\n");
while (1)
{
rtsc = scanf("%d", &action);
switch (action)
{
case 0:
printf("跳至UI7\n");
return rtact0;
break;
case 1:
printf("跳至UI8\n");
return rtact1;
break;
case 2:
printf("跳至UI9\n");
return rtact2;
break;
case 3:
printf("跳至UI0\n");
return rtact3;
break;
}
}
}
/*************event3***************/
_RTACTIONS UI3(void)
{
int action;
printf("创建UI3界面\n按下0->UI10\n按下1->UI11\n按下2->UI12\n按下3->UI0\n");
while (1)
{
rtsc = scanf("%d", &action);
switch (action)
{
case 0:
printf("跳至UI10\n");
return rtact0;
break;
case 1:
printf("跳至UI11\n");
return rtact1;
break;
case 2:
printf("跳至UI12\n");
return rtact2;
break;
case 3:
printf("跳至UI0\n");
return rtact3;
break;
}
}
}
/*************event4***************/
_RTACTIONS UI4(void)
{
int action;
printf("创建UI4界面\n按下0->UI1\n按下1->UI2\n按下2->UI3\n按下3->UI0\n");
while (1)
{
rtsc = scanf("%d", &action);
switch (action)
{
case 0:
printf("跳至UI1\n");
return rtact0;
break;
case 1:
printf("跳至UI2\n");
return rtact1;
break;
case 2:
printf("跳至UI3\n");
return rtact2;
break;
case 3:
printf("跳至U0\n");
return rtact3;
break;
}
}
}
/*************event5***************/
_RTACTIONS UI5(void)
{
int action;
printf("创建UI5界面\n按下0->UI1\n按下1->UI2\n按下2->UI3\n按下3->UI0\n");
while (1)
{
rtsc = scanf("%d", &action);
switch (action)
{
case 0:
printf("跳至UI1\n");
return rtact0;
break;
case 1:
printf("跳至UI2\n");
return rtact1;
break;
case 2:
printf("跳至UI3\n");
return rtact2;
break;
case 3:
printf("跳至U0\n");
return rtact3;
break;
}
}
}
/*************event6***************/
_RTACTIONS UI6(void)
{
int action;
printf("创建UI6界面\n按下0->UI1\n按下1->UI2\n按下2->UI3\n按下3->UI0\n");
while (1)
{
rtsc = scanf("%d", &action);
switch (action)
{
case 0:
printf("跳至UI1\n");
return rtact0;
break;
case 1:
printf("跳至UI2\n");
return rtact1;
break;
case 2:
printf("跳至UI3\n");
return rtact2;
break;
case 3:
printf("跳至U0\n");
return rtact3;
break;
}
}
}
/*************event7***************/
_RTACTIONS UI7(void)
{
int action;
printf("创建UI7界面\n按下0->UI1\n按下1->UI2\n按下2->UI3\n按下3->UI0\n");
while (1)
{
rtsc = scanf("%d", &action);
switch (action)
{
case 0:
printf("跳至UI1\n");
return rtact0;
break;
case 1:
printf("跳至UI2\n");
return rtact1;
break;
case 2:
printf("跳至UI3\n");
return rtact2;
break;
case 3:
printf("跳至U0\n");
return rtact3;
break;
}
}
}
/*************event8***************/
_RTACTIONS UI8(void)
{
int action;
printf("创建UI8界面\n按下0->UI1\n按下1->UI2\n按下2->UI3\n按下3->UI0\n");
while (1)
{
rtsc = scanf("%d", &action);
switch (action)
{
case 0:
printf("跳至UI1\n");
return rtact0;
break;
case 1:
printf("跳至UI2\n");
return rtact1;
break;
case 2:
printf("跳至UI3\n");
return rtact2;
break;
case 3:
printf("跳至U0\n");
return rtact3;
break;
}
}
}
/*************event9***************/
_RTACTIONS UI9(void)
{
int action;
printf("创建UI9界面\n按下0->UI1\n按下1->UI2\n按下2->UI3\n按下3->UI0\n");
while (1)
{
rtsc = scanf("%d", &action);
switch (action)
{
case 0:
printf("跳至UI1\n");
return rtact0;
break;
case 1:
printf("跳至UI2\n");
return rtact1;
break;
case 2:
printf("跳至UI3\n");
return rtact2;
break;
case 3:
printf("跳至U0\n");
return rtact3;
break;
}
}
}
/*************event10***************/
_RTACTIONS UI10(void)
{
int action;
printf("创建UI10界面\n按下0->UI1\n按下1->UI2\n按下2->UI3\n按下3->UI0\n");
while (1)
{
rtsc = scanf("%d", &action);
switch (action)
{
case 0:
printf("跳至UI1\n");
return rtact0;
break;
case 1:
printf("跳至UI2\n");
return rtact1;
break;
case 2:
printf("跳至UI3\n");
return rtact2;
break;
case 3:
printf("跳至U0\n");
return rtact3;
break;
}
}
}
/*************event11***************/
_RTACTIONS UI11(void)
{
int action;
printf("创建UI11界面\n按下0->UI1\n按下1->UI2\n按下2->UI3\n按下3->UI0\n");
while (1)
{
rtsc = scanf("%d", &action);
switch (action)
{
case 0:
printf("跳至UI1\n");
return rtact0;
break;
case 1:
printf("跳至UI2\n");
return rtact1;
break;
case 2:
printf("跳至UI3\n");
return rtact2;
break;
case 3:
printf("跳至U0\n");
return rtact3;
break;
}
}
}
/*************event12***************/
_RTACTIONS UI12(void)
{
int action;
printf("创建UI12界面\n按下0->UI1\n按下1->UI2\n按下2->UI3\n按下3->UI0\n");
while (1)
{
rtsc = scanf("%d", &action);
switch (action)
{
case 0:
printf("跳至UI1\n");
return rtact0;
break;
case 1:
printf("跳至UI2\n");
return rtact1;
break;
case 2:
printf("跳至UI3\n");
return rtact2;
break;
case 3:
printf("跳至U0\n");
return rtact3;
break;
}
}
}
/* rtact0 rtact1 rtact2 rtact3 */
_STATES state_tab[13][4] = {
/* rtact0 rtact1 rtact2 rtact3 */
{
_ui1, _ui2, _ui3, _ui0}, //_ui0
{
_ui4, _ui5, _ui6, _ui0}, //_ui1
{
_ui7, _ui8, _ui9, _ui0}, //_ui2
{
_ui10, _ui11, _ui12, _ui0}, //_ui3
{
_ui1, _ui2, _ui3, _ui0}, //_ui4
{
_ui1, _ui2, _ui3, _ui0}, //_ui5
{
_ui1, _ui2, _ui3, _ui0}, //_ui6
{
_ui1, _ui2, _ui3, _ui0}, //_ui7
{
_ui1, _ui2, _ui3, _ui0}, //_ui8
{
_ui1, _ui2, _ui3, _ui0}, //_ui9
{
_ui1, _ui2, _ui3, _ui0}, //_ui10
{
_ui1, _ui2, _ui3, _ui0}, //_ui11
{
_ui1, _ui2, _ui3, _ui0}, //_ui12
};
_RTACTIONS(*event[13])(void) = {
UI0,UI1,UI2,UI3,UI4,UI5,UI6,UI7,\
UI8, UI9, UI10, UI11, UI12
};
int main()
{
_STATES cur_state = _ui0; //当前状态
_RTACTIONS rt_act; //返回的动作
_RTACTIONS (*cur_event)(void);
while (1)
{
cur_event = event[cur_state]; //当前state对应的event
rt_act = cur_event(); //执行当前的event产生不同的action
cur_state = state_tab[cur_state][rt_act]; //根据不同的action进行不同的state transition
}
}
不知道对不对,先这么理解先,被我误导了的概不负责。