有些场景下,状态机可以使得我们的程序代码变得简洁,可扩展,可维护。
先看下状态迁移图。
代码设计分为五个步骤完成状态机。
#include <stdio.h>
// 第一步:定义两个事件
typedef enum {
STOP,
PLAY_PAUSE,
EVE_MAX
} EVENT;
// 第二步:定义三种状态
typedef enum {
PLAY_STA,
PAUSE_STA,
STOP_SAT,
STA_MAX
} STA;
typedef void (*func)(void *p);
// 第三步:定义状态机结构体
typedef struct
{
EVENT evn;
STA currentSta;
STA nextSta;
func handle;
} M_TB;
void func_1(void *p) {};
void func_2(void *p) {};
void func_3(void *p) {};
void func_4(void *p) {};
void func_5(void *p) {};
void func_none(void *p) {};
// 第四步:定义状态迁移表
const M_TB statFunc[STA_MAX][EVE_MAX] = {
{
{STOP, PLAY_STA, STOP_SAT, func_1},
{PLAY_PAUSE, PLAY_STA, PAUSE_STA, func_2},
},
{
{STOP, PAUSE_STA, STOP_SAT, func_3},
{PLAY_PAUSE, PAUSE_STA, PLAY_STA, func_4},
},
{
{STOP, STOP_SAT, STOP_SAT, func_none},
{PLAY_PAUSE, STOP_SAT, PLAY_STA, func_5},
},
};
typedef struct MP3
{
STA sta;
} MP3;
// 第五步:定义事件驱动处理函数
void process(EVENT eve, MP3 *mp3, void *pmsg) {
statFunc[mp3->sta][eve].handle(pmsg);
mp3->sta = statFunc[mp3->sta][eve].nextSta;
}
int main() {
int msg = 10;
MP3 mp3 = {PAUSE_STA};
printf("%d \n", mp3.sta);
process(PLAY_PAUSE, &mp3, (void *)&msg);
printf("%d \n", mp3.sta);
process(PLAY_PAUSE, &mp3, (void *)&msg);
printf("%d \n", mp3.sta);
process(PLAY_PAUSE, &mp3, (void *)&msg);
printf("%d \n", mp3.sta);
process(STOP, &mp3, (void *)&msg);
printf("%d \n", mp3.sta);
return 0;
}