c++ - 用于嵌入式系统的 C++ 事件驱动状态机
问题描述
在 C++ 中实现状态机的最简单方法是什么?
我的第一个想法是创建一个抽象类并从它派生出每个状态机。使用指向函数的指针,我可以跟踪当前状态。
使用派生类的构造函数,我可以设置初始状态。这个例子展示了我将如何做。
派生类中的每个方法都代表一个状态。
下一个出现在我脑海中的设计是使用一个State
带有虚函数的类,onEntry
, onExit
, handleEvent
, 和一个指针State * currentState
。然而,这种方法很大程度上基于继承,因为每个状态都必须从类派生State
。所以,如果我有 50 个州,我将需要 50 个新课程!我猜这很多?
我目前在 C 中的实现只是一个指向结构内函数的指针。在变量下,我只是在同一个文件static state_machine_t state_machine_one
中定义了所有功能状态。.c
因此,当我想向所有状态机发送一个事件时,我只需将每个结构放入一个指针数组中,然后运行一个循环。这就是我在 C++ 中尝试做的事情。
编辑:系统依赖于分层状态机。当前嵌套级别最多为 8 个状态。并且可执行文件在 Cortex-M0 8MHz - 48MHz 上运行。
解决方案
最简单的状态机是:
#include <functional>
#include <iostream>
template<class...Message>
struct State:
std::function< State<Message...>( Message... )>
{
using Base=std::function< State<Message...>( Message... )>;
using Base::Base;
};
int main(){
State<int> end=[](int x){
std::cout<<"end\n";
return nullptr;
};
State<int> odd=[&](int x){
if (x%2) return odd;
return end;
};
State<int> even=[&](int x){
if (x%2) return odd;
return even;
};
State<int> start=[&](int x){
std::cout << "Start "<<x<<'\n';
if (x%2) return odd;
return even;
};
int buff[]={0,2,3,5,9,10,33};
int* inp=buff;
auto state=start;
while(state){
std::cout<<*inp<<'\n';
state=state(*inp++);
}
}
状态是一个接收消息并返回新状态的函数。
这没有进入/退出时,也没有不处理消息的状态。如果您的消息是对您可以弹出的队列的引用,您可以轻松地模拟这一点。
推荐阅读
- paypal-adaptive-payments - Paypal Adaptive Payments 查找应用程序 ID
- html - CSS过滤器:反转不适用于背景色
- java - junit 中的 ArrayList 相等性不起作用,尽管预期和实际相似
- image - 当 stride>1 时使用 FFT-Convolution
- amazon-web-services - 为每个应用程序用户动态创建 IAM 角色
- sql - 需要对一列进行分组添加获取 Hive 中其他列的计数
- swift - 属性别名(可以说是 Identifiable 最优雅的解决方案)
- c - 将正确的参数传递给 strtok
- python - 如何使用 Python 和 BeautifulSoup 将数据抓取到下一页
- r - 针对模型引入新数据,但产生错误测试数据与模型不匹配!”