NorthFrame是基于非UML极简理念的状态机框架
配合NF_FsmDesigner图形化开发工具,可无负担替代传统switch-case状态机开发
1、NorthFrame的组件
NF_FSM :
极简非UML状态机框架
NF_FsmDesigner :
基于C# Winform开发的状态机图形化开发工具,可直接生成C代码
NF_Signal :
用于代替全局变量的动态信号机制
NF_Signal :代替全局变量,使用方便:
- <font face="微软雅黑" size="3">NF_Signal_Set("flag_connect", 1);
- NF_Signal_Set("blink_cnt", 3);
- NF_SignalValue flag_connect = NF_Signal_Get("flag_connect");</font>
复制代码
2、NorthFrame图形化状态机开发
以下例程在VS2012环境中运行一个判断QE组合键的状态机:
Step1 : 使用NF_FsmDesigner工具设计绘制状态转换图,并保存为XML文件
Step2 : 点击生成代码,生成如下C语言代码
- <font face="微软雅黑" size="3">#include <n_frame.h>
- #include <fsm_qande.h>
- /* 转换执行的外部函数声明 */
- extern void IDLE_TO_Q(void);
- extern void Q_TO_QE(void);
- extern void QE_TO_IDLE(void);
- extern void QE_TO_Q(void);
- extern void Q_TO_IDLE(void);
- /* 状态处理函数声明 */
- void FSM_QandE_IDLE(NF_FSM* me, NF_Event event);
- void FSM_QandE_Q_DOWN(NF_FSM* me, NF_Event event);
- void FSM_QandE_QE_DOWN(NF_FSM* me, NF_Event event);
- /* 状态机对象 */
- NF_FSM FSM_QandE = {
- FSM_QandE_IDLE
- };
- /* IDLE状态处理函数 */
- void FSM_QandE_IDLE(NF_FSM* me, NF_Event event)
- {
- if (NF_FSM_NameIs(event.Name, "Q_DOWN"))
- {
- IDLE_TO_Q();
- NF_FSM_TRAN(FSM_QandE_Q_DOWN);
- return ;
- }
- if (NF_FSM_NameIs(event.Name, "test"))
- {
- NF_FSM_TRAN(FSM_QandE_IDLE);
- return ;
- }
- }
- /* Q_DOWN状态处理函数 */
- void FSM_QandE_Q_DOWN(NF_FSM* me, NF_Event event)
- {
- if (NF_FSM_NameIs(event.Name, "E_DOWN"))
- {
- Q_TO_QE();
- NF_FSM_TRAN(FSM_QandE_QE_DOWN);
- return ;
- }
- if (NF_FSM_NameIs(event.Name, "Q_UP"))
- {
- Q_TO_IDLE();
- NF_FSM_TRAN(FSM_QandE_IDLE);
- return ;
- }
- }
- /* QE_DOWN状态处理函数 */
- void FSM_QandE_QE_DOWN(NF_FSM* me, NF_Event event)
- {
- if (NF_FSM_NameIs(event.Name, "Q_UP"))
- {
- QE_TO_IDLE();
- NF_FSM_TRAN(FSM_QandE_IDLE);
- return ;
- }
- if (NF_FSM_NameIs(event.Name, "E_UP"))
- {
- QE_TO_Q();
- NF_FSM_TRAN(FSM_QandE_Q_DOWN);
- return ;
- }
- }</font>
复制代码Step3 : 在main.c文件中实现按键处理,并发送事件给状态机 备注 : 后续版本会加入发布-订阅机制,目前仅支持直接派发 - <font face="微软雅黑" size="3">#include "n_frame.h"
- #include "windows.h"
- #include "stdio.h"
- #include "fsm_qande.h"
- #define KEY_VALUE(_key) ((GetKeyState(_key) >= 0) ? NF_Bool_False : NF_Bool_True )
- /* 信号产生者 */
- void Test_Key_Process(void)
- {
- static NF_Bool last_q_val = NF_Bool_False;
- static NF_Bool last_e_val = NF_Bool_False;
- NF_Bool then_q_val;
- NF_Bool then_e_val;
- then_q_val = KEY_VALUE('Q');
- then_e_val = KEY_VALUE('E');
- /* Q键事件处理 */
- if ((last_q_val == NF_Bool_False) && (KEY_VALUE('Q') == NF_Bool_True))
- {
- NF_FSM_Dispatch(&FSM_QandE, NF_FSM_Event("Q_DOWN"));
- }
- else if ((last_q_val == NF_Bool_True) && (KEY_VALUE('Q') == NF_Bool_False))
- {
- NF_FSM_Dispatch(&FSM_QandE, NF_FSM_Event("Q_UP"));
- }
- /* E键事件处理 */
- if ((last_e_val == NF_Bool_False) && (KEY_VALUE('E') == NF_Bool_True))
- {
- NF_FSM_Dispatch(&FSM_QandE, NF_FSM_Event("E_DOWN"));
- }
- else if ((last_e_val == NF_Bool_True) && (KEY_VALUE('E') == NF_Bool_False))
- {
- NF_FSM_Dispatch(&FSM_QandE, NF_FSM_Event("E_UP"));
- }
- last_q_val = then_q_val;
- last_e_val = then_e_val;
- }
- void IDLE_TO_Q(void)
- {
- printf("state translate : IDLE -> Q_DOWN\n");
- }
- void Q_TO_QE(void)
- {
- printf("state translate : Q_DOWN -> QE_DOWN\n");
- }
- void QE_TO_IDLE(void)
- {
- printf("state translate : QE_DOWN -> IDLE\n");
- }
- void QE_TO_Q(void)
- {
- printf("state translate : QE_DOWN -> Q_DOWN\n");
- }
- void Q_TO_IDLE(void)
- {
- printf("state translate : Q_DOWN -> IDLE\n");
- }
- int main(void)
- {
- for (;;)
- {
- Test_Key_Process();
- }
- }</font>
复制代码克隆链接: - <font face="微软雅黑" size="3">git clone https://gitee.com/PISCES_X/NorthFrame.git</font>
复制代码
|