# hsm-cpp **Repository Path**: liudegui/hsm-cpp ## Basic Information - **Project Name**: hsm-cpp - **Description**: 轻量级 C++14 header-only 层次状态机库,专为嵌入式系统设计 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-02-13 - **Last Updated**: 2026-02-21 ## Categories & Tags **Categories**: Uncategorized **Tags**: cpp14, 状态机, header-only, 嵌入式, hsm ## README **中文** | [English](README.md) # HSM - 层次状态机 (C++14) 轻量级、仅头文件的层次状态机库,面向嵌入式系统设计。 ![C++](https://img.shields.io/badge/C%2B%2B-14-blue) ![License](https://img.shields.io/badge/License-MIT-yellow) ![Platform](https://img.shields.io/badge/Platform-ARM%20%7C%20x86-green) ![Header Only](https://img.shields.io/badge/Header--Only-yes-brightgreen) ## 特性 - **仅头文件**: 单文件 `hsm/state_machine.hpp`,零外部依赖 - **C++14 标准**: 无需 C++17 - **层次状态**: 基于 LCA 的状态转移,正确的进入/退出顺序 - **守卫条件**: 条件性允许或阻止转移 - **内部转移**: 执行动作但不触发进入/退出 - **自转移**: 重新进入当前状态(退出 + 进入) - **默认处理器**: HSM 父状态可处理子状态未匹配的事件 - **类型安全上下文**: 模板参数消除 `void*` 类型转换 - **兼容 `-fno-exceptions`、`-fno-rtti`** - **MISRA C++ 合规**子集 (Rules 5-0-13, 6-3-1, 12-8-1) ## 快速开始 ### FetchContent 集成 ```cmake include(FetchContent) FetchContent_Declare( hsm GIT_REPOSITORY https://gitee.com/liudegui/hsm-cpp.git GIT_TAG master GIT_SHALLOW TRUE ) FetchContent_MakeAvailable(hsm) target_link_libraries(your_target PRIVATE hsm) ``` ### 复制头文件 将 `include/hsm/state_machine.hpp` 复制到你的项目中即可。 ### 最小示例 ```cpp #include #include struct AppContext { int count = 0; }; int main() { AppContext ctx; hsm::State idle("Idle"); hsm::State running("Running"); idle.set_on_entry([](AppContext&, const hsm::Event&) { std::printf("[Idle]\n"); }) .AddTransition(1, running); running.set_on_entry([](AppContext&, const hsm::Event&) { std::printf("[Running]\n"); }) .AddTransition(2, idle); hsm::StateMachine sm(idle, ctx); // 进入 Idle sm.Dispatch(hsm::Event(1)); // Idle -> Running sm.Dispatch(hsm::Event(2)); // Running -> Idle return 0; } ``` ## API 参考 ### Event ```cpp class Event final { explicit constexpr Event(uint32_t id) noexcept; constexpr uint32_t id() const noexcept; }; ``` ### State\ ```cpp // 配置 API(链式调用,返回 *this) State& set_parent(State& parent) noexcept; State& set_on_entry(ActionFn action); State& set_on_exit(ActionFn action); State& set_default_handler(DefaultHandlerFn handler); // 转移 API State& AddTransition(uint32_t event_id, State& target, ActionFn action = nullptr); State& AddTransition(uint32_t event_id, State& target, GuardFn guard, ActionFn action); State& AddInternalTransition(uint32_t event_id, ActionFn action); State& AddInternalTransition(uint32_t event_id, GuardFn guard, ActionFn action); // 查询 API const char* name() const noexcept; State* parent() const noexcept; bool has_parent() const noexcept; bool has_entry_action() const noexcept; bool has_exit_action() const noexcept; bool has_default_handler() const noexcept; uint8_t depth() const noexcept; size_t transition_count() const noexcept; ``` ### StateMachine\ ```cpp explicit StateMachine(StateType& initial_state, Context& context, uint32_t max_depth = 16U); bool Dispatch(const Event& event) noexcept; // 分发事件 void Reset() noexcept; // 重置到初始状态 bool IsInState(const StateType& state) const noexcept; // 查询状态 StateType& current_state() const noexcept; const char* current_state_name() const noexcept; StateType& initial_state() const noexcept; StateType* previous_state() const noexcept; // 首次转移前为 nullptr Context& context() noexcept; // 运行时统计 uint32_t dispatch_count() const noexcept; // Dispatch() 调用总次数 uint32_t transition_count() const noexcept; // 状态转移总次数 uint32_t unhandled_count() const noexcept; // 未处理事件总次数 void set_unhandled_event_handler(UnhandledEventFn fn) noexcept; ``` ### 回调类型 ```cpp using ActionFn = std::function; using GuardFn = std::function; using DefaultHandlerFn = std::function; using UnhandledEventFn = std::function; ``` ## 层次状态机 ``` Off On(父状态) +-- Idle +-- Running +-- Normal +-- Degraded Error ``` **事件分发顺序:** 1. 从当前状态向上冒泡,尝试特定转移 2. 从当前状态向上冒泡,尝试默认处理器 3. 调用未处理事件处理器 **转移执行顺序:** 1. 从源状态到 LCA 执行退出动作(叶到根) 2. 执行转移动作 3. 从 LCA 到目标状态执行进入动作(根到叶) ## 示例 | 示例 | 说明 | |------|------| | [basic_example.cpp](examples/basic_example.cpp) | 最小扁平状态机:Off/Idle/Running | | [hsm_example.cpp](examples/hsm_example.cpp) | 层次状态机:守卫条件、内部转移 | ## 编译与测试 ```bash mkdir -p build && cd build cmake .. -DCMAKE_BUILD_TYPE=Release cmake --build . -j$(nproc) ctest --output-on-failure ./examples/hsm_basic_example ./examples/hsm_example ``` ## 相关项目 - [state_machine](https://gitee.com/liudegui/state_machine) -- 本库的 C 语言版本 - [mccc](https://github.com/DeguiLiu/mccc) -- 无锁 MPSC 消息总线,集成 HSM ## 许可证 MIT