Project Name | Stars | Downloads | Repos Using This | Packages Using This | Most Recent Commit | Total Releases | Latest Release | Open Issues | License | Language |
---|---|---|---|---|---|---|---|---|---|---|
Xstate | 23,900 | 6,706 | 474 | 12 hours ago | 140 | September 09, 2022 | 211 | mit | TypeScript | |
State machines and statecharts for the modern web. | ||||||||||
Django Fsm | 2,187 | 302 | 28 | 4 months ago | 23 | November 05, 2021 | 24 | mit | Python | |
Django friendly finite state machine support | ||||||||||
Fsm | 2,120 | 73 | 91 | 4 months ago | 6 | September 28, 2021 | 21 | apache-2.0 | Go | |
Finite State Machine for Go | ||||||||||
Stateless4j | 795 | 47 | 3 | 7 months ago | 8 | October 30, 2014 | 7 | apache-2.0 | Java | |
Lightweight Java State Machine | ||||||||||
Unityhfsm | 519 | 13 days ago | 10 | mit | C# | |||||
A simple yet powerful class based hierarchical finite state machine for Unity3D | ||||||||||
Micromachine | 499 | 77 | 12 | 6 years ago | 16 | August 20, 2017 | 2 | mit | Ruby | |
Minimal Finite State Machine | ||||||||||
Fsm As Promised | 452 | 89 | 43 | 2 years ago | 43 | November 24, 2021 | 6 | mit | JavaScript | |
A finite state machine library using ES6 promises | ||||||||||
Python Statemachine | 423 | 1 | 2 | 5 days ago | 15 | January 23, 2020 | 6 | mit | Python | |
Python Finite State Machines made easy. | ||||||||||
Easyflow | 419 | 13 | 3 months ago | 3 | January 11, 2014 | 14 | apache-2.0 | Java | ||
EasyFlow - Simple and lightweight Finite State Machine for Java | ||||||||||
Statig | 405 | 2 months ago | 1 | mit | Rust | |||||
Hierarchical state machines for designing event-driven systems |
fsm-cxx
is a finite state machina library for C++17, header-only, light-weight but full-featured, and designed for easy binding and friendly programmatic interface.
safe_machine_t<>
)Here is a simple state machine:
#include <fsm_cxx.hh>
namespace fsm_cxx { namespace test {
// states
AWESOME_MAKE_ENUM(my_state,
Empty,
Error,
Initial,
Terminated,
Opened,
Closed)
// event
// Or:
// FSM_DEFINE_EVENT_BEGIN(begin)
// int val{9}
// FSM_DEFINE_EVENT_END()
struct begin : public fsm_cxx::event_type<begin> {
virtual ~begin() {}
int val{9};
};
struct end : public fsm_cxx::event_type<end> {
virtual ~end() {}
};
struct open : public fsm_cxx::event_type<open> {
virtual ~open() {}
};
// Or:
// FSM_DEFINE_EVENT(close)
struct close : public fsm_cxx::event_type<close> {
virtual ~close() {}
};
void test_state_meta() {
fsm_cxx::machine_t<my_state> m;
using M = decltype(m);
// @formatter:off
// states
m.state().set(my_state::Initial).as_initial().build();
m.state().set(my_state::Terminated).as_terminated().build();
m.state().set(my_state::Error).as_error()
.entry_action([](M::Event const &, M::Context &, M::State const &, M::Payload const &) { std::cerr << " .. <error> entering" << '\n'; })
.build();
m.state().set(my_state::Opened)
.guard([](M::Event const &, M::Context &, M::State const &, M::Payload const &) -> bool { return true; })
.guard([](M::Event const &, M::Context &, M::State const &, M::Payload const &p) -> bool { return p._ok; })
.entry_action([](M::Event const &, M::Context &, M::State const &, M::Payload const &) { std::cout << " .. <opened> entering" << '\n'; })
.exit_action([](M::Event const &, M::Context &, M::State const &, M::Payload const &) { std::cout << " .. <opened> exiting" << '\n'; })
.build();
m.state().set(my_state::Closed)
.entry_action([](M::Event const &, M::Context &, M::State const &, M::Payload const &) { std::cout << " .. <closed> entering" << '\n'; })
.exit_action([](M::Event const &, M::Context &, M::State const &, M::Payload const &) { std::cout << " .. <closed> exiting" << '\n'; })
.build();
// transitions
m.transition().set(my_state::Initial, begin{}, my_state::Closed).build();
m.transition()
.set(my_state::Closed, open{}, my_state::Opened)
.guard([](M::Event const &, M::Context &, M::State const &, M::Payload const &p) -> bool { return p._ok; })
.entry_action([](M::Event const &, M::Context &, M::State const &, M::Payload const &) { std::cout << " .. <closed -> opened> entering" << '\n'; })
.exit_action([](M::Event const &, M::Context &, M::State const &, M::Payload const &) { std::cout << " .. <closed -> opened> exiting" << '\n'; })
.build();
m.transition().set(my_state::Opened, close{}, my_state::Closed).build()
.transition().set(my_state::Closed, end{}, my_state::Terminated).build();
m.transition().set(my_state::Opened, end{}, my_state::Terminated)
.entry_action([](M::Event const &, M::Context &, M::State const &, M::Payload const &) { std::cout << " .. <T><END>" << '\n'; })
.build();
// @formatter:on
m.on_error([](fsm_cxx::Reason reason, M::State const &, M::Context &, M::Event const &, M::Payload const &) {
std::cout << " Error: reason = " << reason << '\n';
});
// debug log
m.on_transition([&m](auto const &from, fsm_cxx::event_t const &ev, auto const &to, auto const &actions, auto const &payload) {
std::printf(" [%s] -- %s --> [%s] (payload = %s)\n", m.state_to_sting(from).c_str(), ev.to_string().c_str(), m.state_to_sting(to).c_str(), to_string(payload).c_str());
UNUSED(actions);
});
// processing
m.step_by(begin{});
if (!m.step_by(open{}, fsm_cxx::payload_t{false}))
std::cout << " E. cannot step to next with a false payload\n";
m.step_by(open{});
m.step_by(close{});
m.step_by(open{});
m.step_by(end{});
std::printf("---- END OF test_state_meta()\n\n\n");
}
}
int main() {
fsm_cxx::test::test_state_meta();
return 0;
}
- gcc 10+: passed
- clang 12+: passed
- msvc build tool 16.7.2, 16.8.5 (VS2019 or Build Tool) passed
ninja is optional for faster building.
# configure
cmake -S . -B build/ -G Ninja
# build
cmake --build build/
# install
cmake --install build/
# Or:cmake --build build/ --target install
#
# Sometimes sudo it:
# sudo cmake --build build/ --target install
# Or:
# cmake --install build/ --prefix ./install --strip
# sudo cp -R ./install/include/* /usr/local/include/
# sudo cp -R ./install/lib/cmake/fsm_cxx /usr/local/lib/cmake/
FSM_CXX_BUILD_TESTS_EXAMPLES
=OFFFSM_CXX_BUILD_DOCS
=OFFThanks to JetBrains for donating product licenses to help develop fsm-cxx
Apache 2.0