如上图,如何用状态机去实现。
方法1:可以用switch case语句实现
enum state { s_stop, s_play, s_forward, s_backward, s_pause, s_record };
enum message { play, stop, forward, backward, record, pause };
void state_change(enum message m)
{
static enum state s=s_stop;
switch (s)
{
case s_play:
if(m==stop)
{
s = s_stop;
printf("stop.\n");
}
else if (m==pause)
{
s = s_pause;
printf("pause");
}
break;
case s_pause:
if(m==pause)
{
s = s_play;
printf("play.\n");
}
else if(m==stop)
{
s = s_stop;
printf("stop.\n");
}
break;
case s_stop:
if(m==play)
{
s = s_play;
printf("play.\n");
}
if(m==backward)
{
s = s_backward;
printf("backward.\n");
}
if(m==forward)
{
s = s_forward;
printf("forward.\n");
}
if(m==record)
{
s = s_record;
printf("record.\n");
}
break;
case s_forward:
if(m==stop)
{
s = s_stop;
printf("stop.\n");
}
break;
case s_backward:
if(m==stop)
{
s = s_stop;
printf("stop.\n");
}
break;
case s_record:
if(m==stop)
{
s = s_stop;
printf("stop.\n");
}
break;
}
}
int main(int argc, char *argv[])
{
char c=0x00;
while(1)
{
c = getchar();
switch(c)
{
case ' ': state_change(pause); break;
case 'p': state_change(play); break;
case 'r': state_change(record); break;
case 's': state_change(stop); break;
case 'f': state_change(forward); break;
case 'b': state_change(backward); break;
case 'q': return EXIT_SUCCESS;
}
}
return EXIT_SUCCESS;
}
方法二:使用列表
#define transition_num 11
#define state_num 6
typedef void (*action_foo)() ;
enum state { s_stop='s', s_play='p', s_forward='f', s_backward='b', s_pause='_', s_record='r' };
enum message { play, stop, forward, backward, record, pause };
/* action starts */
void do_stop() {printf ("I am in state stop and should doing something here.\n");}
void do_play() {printf ("I am in state play and should doing something here.\n");}
void do_forward() {printf ("I am in state forward and should doing something here.\n");}
void do_backward() {printf ("I am in state backward and should doing something here.\n");}
void do_pause() {printf ("I am in state pause and should doing something here.\n");}
void do_record() {printf ("I am in state record and should doing something here.\n");}
struct state_action {
enum state m_state;
action_foo foo;
};
//列表,到达了该步骤需要做什么
struct state_action state_action_map[state_num] =
{
{s_stop, do_stop},
{s_play, do_play},
{s_forward, do_forward},
{s_backward, do_backward},
{s_pause, do_pause},
{s_record, do_record}
};
action_foo ACTION_NOT_FOUND = NULL;
action_foo lookup_action(enum state s, struct state_action* a)
{
action_foo ret = ACTION_NOT_FOUND;
int i=0;
for (i=0;i<state_num;++i)
{
if(s == a[i].m_state)
{
ret = a[i].foo;
}
}
return ret;
}
/* action ends. */
/* transition starts*/
struct transition {
enum state current;
enum message m;
enum state next;
};
//列表列出所有状态:当前状态,对应收到的消息,对应的下要给状态
struct transition fsm[transition_num] = {
/* current_state, message/event, next_state*/
{s_play, stop, s_stop},
{s_play, pause, s_pause},
{s_pause, pause, s_play},
{s_pause, stop, s_stop},
{s_stop, forward, s_forward},
{s_stop, play, s_play},
{s_stop, backward, s_backward},
{s_stop, record, s_record},
{s_forward, stop, s_stop},
{s_backward, stop, s_stop},
{s_record, stop, s_stop} };
int const ERR = -1;
int lookup_transition (enum state s, enum message m, struct transition * t)
{
int ret=ERR;
int i;
for(i=0;i<transition_num;++i)
{
if(t[i].current == s && t[i].m == m)
{
ret = i;
}
}
return ret;
}
/* transition ends*/
void state_change(enum message m)
{
static state state = s_stop;
enum state next;
int index = 0;
index = lookup_transition(state, m, fsm);//查FSM表单
if(index!=ERR)
{
state = fsm[index].next;
lookup_action(state, state_action_map)();//查寻到结果后对应需要执行的函数
}
return;
}
int main(int argc, char *argv[])
{
char c=0x00;
while(1)
{
c = getchar();
printf ("%c input.\n", c);
switch(c)
{
case ' ': state_change(pause); break;
case 'p': state_change(play); break;
case 'r': state_change(record); break;
case 's': state_change(stop); break;
case 'f': state_change(forward); break;
case 'b': state_change(backward); break;
case 'q': return EXIT_SUCCESS;
}
}
return EXIT_SUCCESS;
}
摘一段别人的话
“使用列表的好处在于,他始终如一,不管遇到的情形是多么糟糕多么恶劣,他始终没有变化。这个世界上,总须要一些因素,一些承诺,不随不论什么易变的感情、不论什么旁人不能承受的痛苦或诱惑而变化,稳定地坚持。
这才让我们对这个世界保留一丝希望。未来才可以和值得期待。”