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.
Currently the following features are supported:
- Initial pseudo state
- External transitions with guards and actions
- Anonymous transitions
- Submachines
- Entry/exit pseudo states
- History pseudo state
- Entry/exit actions
- Direct transitions
- Orthogonal regions
- Internal transitions
- Unexpected event handler
- Dependency injection
- Defer events
- eUML frontend
Simple Example (Turnstile)
#include "hsm/hsm.h"
#include <cassert>
// States
struct Locked {
};
struct Unlocked {
};
// Events
struct Push {
};
struct Coin {
};
// Guards
const auto noError = [](auto /*event*/){return true;};
// Actions
const auto beep = [](auto /*event*/){ std::cout << "beep!" << std::endl;};
const auto blink = [](auto /*event*/){ std::cout << "blink, blink, blink!" << std::endl;};
struct Turnstile {
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
}
constexpr auto initial_state()
{
return hsm::initial(Locked {});
}
};
int main()
{
hsm::Sm<Turnstile> turnstileSm;
// The turnstile is initially locked
assert(turnstileSm.is(Locked {}));
// Inserting a coin unlocks it
turnstileSm.process_event(Coin {});
assert(turnstileSm.is(Unlocked {}));
// Entering the turnstile will lock it again
turnstileSm.process_event(Push {});
a
6573
ssert(turnstileSm.is(Locked {}));
return 0;
}
mkdir src/build
cd src/build
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/tmp/
cmake --build . --target install
mkdir test/build/
cd test/build/
cmake .. -DCMAkE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/tmp/
cmake --build . --target hsmTests
ctest -VV
- erikzenker(at)hotmail.com