Skip to content
forked from erikzenker/hsm

Finite state machine library based on the boost hana meta programming library. It follows the principles of the boost msm and boost sml libraries, but tries to reduce own complex meta programming code to a minimum.

License

Notifications You must be signed in to change notification settings

brinkqiang2cpp/hsm

 
 

Repository files navigation

Hana State Machine (HSM)

Linux CI MacOs CI Windows CI

codecov GitHub license GitHub contributors GitHub release Donate Join the chat at https://gitter.im/hsm-gitter/community

The hana state machine (hsm) is a finite state machine library based on the boost hana meta programming library. It follows the principles of the boost msm and boost sml libraries, but tries to reduce own complex meta programming code to a minimum.

The following table compares features among popular c++ state machine libraries. A click on a particular feature check mark will forward to the feature documentation.

Feature Hsm Sml Msm Statechart
External transition
Anonymous transition (Completion)
Internal transition
Direct transition
Guards / actions
Entry / exit actions
Orthogonal regions
Hierachies / sub state machines
Event defering
Transition logging ?
Initial pseudo state
History pseudo state
eUml postfix frontend
eUml prefix frontend
Entry / exit pseudo state
State data members
Unexpected event / no transition handler
Dependency injection
Single amalgamation header
Custom target state construction
Chain actions ?

Example (Run)

#include "hsm/hsm.h" #include <iostream> #include <cassert> // States struct Locked { }; struct Unlocked { }; // Events struct Push { }; struct Coin { }; // Guards const auto noError = [](auto /*event*/, auto /*source*/, auto /*target*/) { return true; }; // Actions constexpr auto beep = [](auto /*event*/, auto /*source*/, auto /*target*/) { std::cout << "beep!" << std::endl; }; constexpr auto blink = [](auto /*event*/, auto /*source*/, auto /*target*/) { std::cout << "blink, blink, blink!" << std::endl; }; struct Turnstile { static constexpr auto make_transition_table() { // clang-format off return hsm::transition_table( // Source + Event [Guard] / Action = Target // +-------------------+-----------------+---------+--------+----------------------+ * hsm::state<Locked> + hsm::event<Push> / beep = hsm::state<Locked> , hsm::state<Locked> + hsm::event<Coin> [noError] / blink = hsm::state<Unlocked>, // +--------------------+---------------------+---------+--------+------------------------+ hsm::state<Unlocked> + hsm::event<Push> [noError] = hsm::state<Locked> , hsm::state<Unlocked> + hsm::event<Coin> / blink = hsm::state<Unlocked> // +--------------------+---------------------+---------+--------+------------------------+  ); // clang-format on } }; auto main() -> int { hsm::sm<Turnstile> turnstileSm; // The turnstile is initially locked assert(turnstileSm.is(hsm::state<Locked>)); // Inserting a coin unlocks it turnstileSm.process_event(Coin {}); assert(turnstileSm.is(hsm::state<Unlocked>)); // Entering the turnstile will lock it again turnstileSm.process_event(Push {}); assert(turnstileSm.is(hsm::state<Locked>)); return 0; }

Play with it Online

Runtime Benchmark Results

The benchmark result are taken from the state machine benchmark repository.

Benchmark Hsm Sml Msm Statechart
Simple state machine 99 ms 17 ms 18 ms 443 ms
Complex state machine 818 ms 978 ms 881 ms 1374 ms

Compiletime Benchmark Results

Benchmark Hsm Sml Msm Statechart
Simple state machine 6.41 s 0.62 s 5.17 s 1.52 s
Complex state machine 41.99 s 3.01 s 25.54 s 4.27 s

Dependencies

  • Boost 1.72
  • C++17
  • >= g++-8
  • >= clang-8
  • Cmake 3.14

Dev Dependencies

  • Gtest

Integration

Usage as Single Header

  • Download amalgamation header and put it into your project src folder
  • Include amalgamation header:
    #include "path/to/amalgamation/header/hsm.h"

CMake

To use this library from a CMake project, you can locate it directly with find_package() and use the namespaced imported target from the generated package configuration:

# CMakeLists.txt find_package(hsm 1.3.5 REQUIRED) ... add_library(foo ...) ... target_link_libraries(foo PRIVATE hsm::hsm)

Since CMake v3.11, FetchContent can be used to automatically download the repository as a dependency at configure time. You can follow this example and implement the following snippet:

include(FetchContent) FetchContent_Declare(hsm GIT_REPOSITORY https://github.com/erikzenker/hsm.git GIT_TAG v1.4.7) FetchContent_GetProperties(hsm) if(NOT hsm_POPULATED) FetchContent_Populate(hsm)  add_subdirectory(${hsm_SOURCE_DIR} ${hsm_BINARY_DIR} EXCLUDE_FROM_ALL) endif() target_link_libraries(foo PRIVATE hsm::hsm)

If you are using CPM.cmake, you can follow this example. Implement the following snippet:

include(cmake/CPM.cmake) CPMAddPackage( NAME hsm GITHUB_REPOSITORY erikzenker/hsm VERSION 1.4.7) target_link_libraries(foo PRIVATE hsm::hsm)

Package Managers

If you are using Conan to manage your dependencies, merely add hsm/x.y.z to your conanfile's requires, where x.y.z is the release version you want to use. Please file issues here if you experience problems with the packages.

Install

CMake

cmake -S . -B build cmake --install build/ --prefix /tmp/

Conan/Cmake

mkdir -p build/dependencies/conan conan install . -if build/dependencies/conan -s compiler.libcxx=libstdc++11 --build missing cmake -S . -B build cmake --install build/ --prefix /tmp/ -D "CMAKE_MODULE_PATH=${PWD}/build/dependencies/conan"

Conan Download

conan remote add conan-erikzenker https://api.bintray.com/conan/erikzenker/conan-erikzenker conan install hsm/1.0@erikzenker/testing --build missing

Install from Arch Linux AUR

pacaur -S hsm-git

Compile and Run the Tests Using the Installed Library

cmake -S test -B build cmake --build build/test cd build/test ctest --output-on-failure

Author

  • erikzenker(at)hotmail.com

About

Finite state machine library based on the boost hana meta programming library. It follows the principles of the boost msm and boost sml libraries, but tries to reduce own complex meta programming code to a minimum.

Resources

License

Contributing

Stars

Watchers

Forks

Packages

No packages published

Languages

  • C++ 91.6%
  • CMake 7.7%
  • Other 0.7%