NorthFrame是一种基于非UML的极简理念的状态机框架,它能够帮助开发者更轻松地使用状态机来进行开发。配合NF_FsmDesigner图形化开发工具,NorthFrame可以无负担地替代传统的switch-case状态机开发方式。
下面是关于NorthFrame框架的组件介绍:
-
NF_FSM:这是一个极简非UML状态机框架,用于实现状态机的功能。 -
NF_FsmDesigner:这是一个基于C# Winform开发的状态机图形化开发工具。使用这个工具,开发者可以直接设计和绘制状态转换图,并且可以生成对应的C代码。 -
NF_Signal:这是一种用于代替全局变量的动态信号机制。通过使用NF_Signal,开发者可以方便地设置和获取信号值,而不需要依赖全局变量。
使用NF_Signal替代全局变量非常方便,下面是一个例子:
NF_Signal_Set("flag_connect", 1);
NF_Signal_Set("blink_cnt", 3);
NF_SignalValue flag_connect = NF_Signal_Get("flag_connect");
除了上述组件,NorthFrame还提供了图形化状态机开发的功能。下面是一个在VS2012环境中运行的判断QE组合键的状态机的示例:
Step1:使用NF_FsmDesigner工具设计和绘制状态转换图,并将其保存为XML文件。
Step2 : 点击生成代码,生成如下C语言代码
#include
#include
/* 转换执行的外部函数声明 */
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 ;
}
}
Step3 : 在main.c文件中实现按键处理,并发送事件给状态机
备注 : 后续版本会加入发布-订阅机制,目前仅支持直接派发
#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();
}
}
克隆链接:
git clone https://gitee.com/PISCES_X/NorthFrame.git
以上就是良许教程网为各位朋友分享的Linu系统相关内容。想要了解更多Linux相关知识记得关注公众号“良许Linux”,或扫描下方二维码进行关注,更多干货等着你 !