cpp-tbox项目链接 https://gitee.com/cpp-master/cpp-tbox
更多精彩内容欢迎关注微信公众号:码农练功房
往期精彩内容:
Linux应用框架cpp-tbox之弱定义
Linux应用框架cpp-tbox之日志系统设计
Linux应用框架cpp-tbox之事件驱动EventLoop
Linux应用框架cpp-tbox之事件驱动Event
Linux应用框架cpp-tbox之线程池
Linux应用框架cpp-tbox之应用层缓冲
Linux应用框架cpp-tbox之串口通信
Linux应用框架cpp-tbox之TCP通信(上篇)
Linux应用框架cpp-tbox之TCP通信(下篇)
Linux应用框架cpp-tbox之UDP通信
Linux应用框架cpp-tbox之HTTP
Linux应用框架cpp-tbox之jsonrpc
在经验谈|在C++状态模式中如何优雅解决状态间共用数据访问问题?
一文中,我们谈到了状态机(FSM),并且从最朴素的实现方式进化到基于状态模式的实现。
但随着状态的增多,各种状态之间的切换控制也越来越复杂,基于状态模式的实现已经不能适应此类变化。
多层级有限状态机(HFMS)扩展了传统有限状态机(FSM)的概念,通过引入层次结构来组织状态,使得状态机的设计更为模块化和易于管理。
HFMS在许多领域都有广泛的应用,比如软件工程、游戏开发、机器人控制等,特别是在复杂系统的状态转换逻辑设计中非常有用。
cpp-tbox实现了HFMS,接下来一览其实现。
状态和事件
cpp-tbox中状态和事件都会有一个编号,这个编号是一个整数,定义如下:
using StateID = int; //! StateID 为 0 与 1 的两个状态为特定状态
//! StateID = 0 的状态为终止状态,用户可以不用定义
//! StateID = 1 的状态为默认的初始状态。也可以通过 setInitState() 重新指定
//! StateID < 0 表示无效状态
using EventID = int; //! EventID = 0 表示任意事件,仅在 addRoute(), addEvent() 时使用
状态机的状态随着事件的到来,按照业务规则进行状态跳转(或者保持在当前状态)。我们使用枚举来定义状态和事件的编号:
enum StateId {
STATE_TERM = 0,
STATE_A,
STATE_B,
STATE_C,
STATE_D,
};
enum EventId {
EVENT_ANY = 0,
EVENT_1,
EVENT_2,
EVENT_3,
EVENT_4,
};
状态创建
状态创建需要调用newState
接口,接口定义如下:
//! 动作执行函数
using ActionFunc = std::function<void(Event)>;
bool newState(StateID state_id,
const ActionFunc &enter_action,
const ActionFunc &exit_action,
const std::string &label = "");
-
支持用户定义
进入状态enter_action
和退出状态exit_action
的动作 -
label用于在图形化中使用
-
状态创建成功返回true,失败返回false
实现十分简单:
bool StateMachine::Impl::newState(StateID state_id,
const ActionFunc &enter_action,
const ActionFunc &exit_action,
const std::string &label)
{
if (is_running_) {
LogWarn("[%s]: it's already started", name_.c_str()