Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/hedzr/fsm-cxx
a finite state machine within c++17
https://github.com/hedzr/fsm-cxx
cpp cpp17 cpp17-library design-patterns finite-state-machine fsm fsm-engine fsm-library memento-pattern state-machine state-management statemachine
Last synced: about 2 months ago
JSON representation
a finite state machine within c++17
- Host: GitHub
- URL: https://github.com/hedzr/fsm-cxx
- Owner: hedzr
- License: apache-2.0
- Created: 2021-09-29T05:13:44.000Z (over 3 years ago)
- Default Branch: master
- Last Pushed: 2024-09-07T11:41:44.000Z (4 months ago)
- Last Synced: 2024-09-07T12:41:50.244Z (4 months ago)
- Topics: cpp, cpp17, cpp17-library, design-patterns, finite-state-machine, fsm, fsm-engine, fsm-library, memento-pattern, state-machine, state-management, statemachine
- Language: C++
- Homepage: https://hedzr.com/c++/algorithm/cxx17-state-pattern/
- Size: 118 KB
- Stars: 13
- Watchers: 2
- Forks: 4
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG
- Funding: .github/FUNDING.yml
- License: LICENSE
- Codeowners: .github/CODEOWNERS
Awesome Lists containing this project
README
# fsm-cxx
![CMake Build Matrix](https://github.com/hedzr/fsm-cxx/workflows/CMake%20Build%20Matrix/badge.svg) [![GitHub tag (latest SemVer)](https://img.shields.io/github/tag/hedzr/fsm-cxx.svg?label=release)](https://github.com/hedzr/fsm-cxx/releases)
`fsm-cxx` is a finite state machina library for C++17/C++20.
It is header-only, light-weight but full-featured.
It is designed for easy binding and friendly programmatic interface.## Features
- Entry/exit actions
- Event actions, guards
- Transition actions
- Transition conditions (input action)
- Event payload (classes)
- Thread Safe (`safe_machine_t<>`)
- ~~[ ] Inheritance of states and action functions~~
- ~~[ ] Documentations (NOT YET)~~
- ~~[ ] Examples (NOT YET)~~---
[See CHANGELOG](https://github.com/hedzr/fsm-cxx/blob/master/CHANGELOG)
## Usages
Here is a simple state machine:
```cpp
#include
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 {
virtual ~begin() {}
int val{9};
};
struct end : public fsm_cxx::event_type {
virtual ~end() {}
};
struct open : public fsm_cxx::event_type {
virtual ~open() {}
};
// Or:
// FSM_DEFINE_EVENT(close)
struct close : public fsm_cxx::event_type {
virtual ~close() {}
};void test_state_meta() {
fsm_cxx::machine_t 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 << " .. 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 << " .. entering" << '\n'; })
.exit_action([](M::Event const &, M::Context &, M::State const &, M::Payload const &) { std::cout << " .. exiting" << '\n'; })
.build();
m.state().set(my_state::Closed)
.entry_action([](M::Event const &, M::Context &, M::State const &, M::Payload const &) { std::cout << " .. entering" << '\n'; })
.exit_action([](M::Event const &, M::Context &, M::State const &, M::Payload const &) { std::cout << " .. 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 << " .. opened> entering" << '\n'; })
.exit_action([](M::Event const &, M::Context &, M::State const &, M::Payload const &) { std::cout << " .. 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 << " .. " << '\n'; })
.build();
// @formatter:onm.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;
}
```## Build Options
### Build with CMake
> 1. gcc 10+: passed
> 2. clang 12+: passed
> 3. msvc build tool 16.7.2, 16.8.5 (VS2019 or Build Tool) passedninja is optional for faster building.
```bash
# 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/
```### Other CMake Options
1. `FSM_CXX_BUILD_TESTS_EXAMPLES`=OFF
2. `FSM_CXX_BUILD_DOCS`=OFF
3. ...## Thanks to JODL
Thanks to [JetBrains](https://www.jetbrains.com/?from=fsm-cxx) for donating product licenses to help develop **fsm-cxx** [![jetbrains](https://gist.githubusercontent.com/hedzr/447849cb44138885e75fe46f1e35b4a0/raw/bedfe6923510405ade4c034c5c5085487532dee4/jetbrains-variant-4.svg)](https://www.jetbrains.com/?from=hedzr/fsm-cxx)
## LICENSE
Apache 2.0