Skip to content
/ hsm Public
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

gjasny/hsm

 
 

Repository files navigation

Hana State Machine (HSM)

CI Build Status 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

Example

#include "hsm/hsm.h"

#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
const auto beep = [](auto /*event*/, auto /*source*/, auto /*target*/){ 
  std::cout << "beep!" << std::endl;
};

const 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
    }
};

int main()
{
    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;
}

Runtime Benchmark Results

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

Benchmark Hsm Sml Msm Statechart
Simple state machine 49 ms 26 ms 38 ms 414ms
Complex state machine 526 ms 528 ms 541 ms 877 ms

Compiletime Benchmark Results

Benchmark Hsm Sml Msm Statechart
Simple state machine 10.010 s 0.786 s 5.380 s 1.480 s
Complex state machine 77.120 s 3.130 s 26.820 s 5.190 s

Dependencies

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

Play with it Online

Usage as Single Header

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

Install with CMake

mkdir src/build && cd src/build
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/tmp/
cmake --build . --target install

Install with Conan/Cmake

mkdir src/build && cd src/build
conan install ../..
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/tmp/
cmake --build . --target install

Install from 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 AUR

pacaur -S hsm-git

Compile and Run the Tests Using the Installed Library

mkdir test/build/ && cd test/build/
cmake .. -DCMAKE_BUILD_TYPE=Release
cmake --build . --target hsmTests
ctest -VV

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

Stars

Watchers

Forks

Packages

No packages published

Languages

  • C++ 96.8%
  • CMake 2.3%
  • Other 0.9%