输入事件到状态机
#include"stdio.h"#define EXECUTE_VOID(func) {if((func)!=NULL) (func());}
typedefvoid(*select_machine_t)(void);
typedefenum _event_index{ event_index_1 = 0, event_index_2, event_index_3, event_index_end} event_index_e;
typedefenum _status_index{ status_index_1 = 0, status_index_2, status_index_end} status_index_e;
voidmachine_1(void);voidmachine_2(void);voidmachine_3(void);voidmachine_4(void);
select_machine_t select_machine[event_index_end][status_index_end] = { {machine_1, machine_2}, {NULL, machine_3}, {machine_4, NULL}};
voidmachine_1(void){printf("machine_1\r\n");}
voidmachine_2(void){printf("machine_2\r\n");}
voidmachine_3(void){printf("machine_3\r\n");}
voidmachine_4(void){printf("machine_4\r\n");}
intmain(void){ EXECUTE_VOID(select_machine[0][1]);}
对应:
(1)条件A:status_index_e
(2)条件B:event_index_e
(3)switch:
EXECUTE_VOID(select_machine[0][1] );
当一个外部事件来的时候(比如按键输入),通过一个全局的结构体变量(C语言中最常用的方法)引入当前的实时状态,由条件导向各种状态机。
这里的实现是通过二维数组即两个下标代表两个条件,两个条件的交点就是具体的状态机。
状态机到面向过程
以上实现的是“输入外部事件>>>>引流到>>>>状态机”
那如何实现“状态机>>>>执行>>>>具体地操作”呢?状态机有一个固定的执行流程(当然也有根据条件执行不同的运行流程的分支),其实这些个流程都是非常确定的执行过程。
在开发过程中的经验体现:就是对所有执行流程的精确完整的分析,然后将其全部罗列出来。“全部罗列出来”这个执行流程在程序中有两种体现方式:
1、把所有的执行流程以“空函数”的形式罗列出来。
2、把所有的执行流程以“函数指针”的形式罗列出来:
好处一:
可以把软件框架写出来,具体逻辑流程已经做好。
好处二:
具体的函数的接口可以先空着(NULL),待写好了函数就把函数名赋值给它(sys_api_func* = you_func ;)。
好处三:
通用性更高,逻辑性更强。
void (sys_api_func1)(void);void (sys_api_func2)(void);void (sys_api_func3)(void);...
voidsys_api_init(void){ sys_api_func1 = NULL; // 还没有写好实现函数就先赋为NULL sys_api_func2 = NULL; sys_api_func3 = NULL; ...}
// 状态机1voidmachine_1(void){ execute_api_void(sys_api_func1); // 状态机:步骤一 execute_api_void(sys_api_func2); // 状态机:步骤二 ... // 状态机:步骤....}
文章来源于网络,版权归原作者所有,如有侵权,请联系删除。
‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧ END ‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧
关注我的微信公众号,回复“星球”加入知识星球,有问必答。
点击“阅读原文”查看知识星球详情,欢迎点分享、收藏、点赞、在看。