Introduction
[Boost::ext].SML (State Machine Language/Lite/Library) | |
---|---|
Your scalable C++14 one header only State Machine Library with no dependencies (Try it online!) | GitHub |
UML State Machine
Do I need a State Machine?
State Machine design pattern prevents you from creating and maintaining spaghetti code.
void some_function() {
...
if ((is_running && !is_jumping) || just_started) {
...
} else if (is_boss_level && extra_feature_enabled && !ab_test) {
...
} else {
...
}
}
If above code looks somewhat similar to your code base or if you like
to avoid it [Boost].SML
may suit you!
Real Life examples?
Why [Boost].SML?
- Boost.MSM - eUML is awesome, however it has a few huge limitations making it unusable on a large scale projects; [Boost].SML, therefore, is trying to address those issues.
Problems with Boost.MSM - eUML
- Long compilation times (see Performance)
- Huge resulting binaries (see Performance)
- Based on too many macros
- Long error messages (see Error Messages)
- Sometimes hard to follow as not all actions might be seen on transition table (ex. initial states, state entry/exit actions)
- A lot of boilerplate code with actions/guards (requires fsm, event, source state, target state)
- Data in states makes it harder to share/encapsulate (UML compliant though)
- Loosely coupled design is hard to achieve
- Functional programming emulation
- Huge complexity may overwhelm in the beginning
- A lot of Boost dependencies
[Boost].SML design goals
- Keep the Boost.MSM - eUML 'goodies'
- Performance (see Performance)
- Memory usage (see Performance)
- eUML DSL (src_state + event [ guard ] / action -> dst_state)
- UML standard compliant (As much as possible)
- Eliminate Boost.MSM - eUML problems
- Compilation times (see Performance)
- Binary size (see Performance)
- Reduce complexity by eliminating less used features
- Short and informative error messages (see Error Messages)
- Less boilerplate / no macros (see Hello World)
- Improve visibility by having all actions on transition table (see States)
- Allows loosely coupled design (see Dependency Injection)
- Functional programming support using lamda expressions (see Action/Guards)
- No dependencies / one header (2k LOC)
What 'lite' implies?
- Guaranteed quick compilation times
- Maximized performance
- No dependencies
- Easy/Intuitive to use
Supported UML features
- Transitions / Anonymous transitions / Internal transitions / Self transitions / No transition (see Transitions, Events)
- Actions / Guards (see Action/Guards)
- State entry / exit actions (see States)
- Orthogonal regions (see Orthogonal Regions)
- Sub / Composite state machines (see Composite)
- History (see History)
- Defer/Process (see Defer/Process)
Additional features
- Logging (see Logging)
- Testing (see Testing)
- Runtime Dispatcher (see Runtime Dispatcher)
- Dependency Injection integration (see Dependency Injection)
Related materials
- C++Now 2019 - Kris Jusiak - Rise of the State Machines
- C++Now 2019 - Michael Caisse - Embedded Domain Specific Languages for Embedded Bare Metal Projects
- CppCast - Boost DI and SML
- CppCon 2018 - Ben Deane - Operator Overloading: History, Principles and Practice
- CppCon 2018 - Kris Jusiak - State Machines Battlefield - Naive vs STL vs Boost
- C++Now 2018 - Michael Caisse - “Modern C++ in Embedded Systems”
- EmBO++ 2018 - Kris Jusiak - Workshop - 'Embedding' a Meta State Machine
- EmBO++ 2018 - Simon Brand - Embedded DSLs for embedded programming
- EmBO++ 2017 - Kris Jusiak - 'Embedding' a Meta State Machine
- C++Now 2017 - Kris Jusiak - State Machine Language
- C++Now 2016 - Kris Jusiak - C++14 version of Boost.MSM-eUML
- Meeting C++ 2016 - Kris Jusiak - Implementing a web game in C++14
Acknowledgements
- Thanks to Christophe Henry for a great Boost.MSM - eUML library
- Thanks to Deniz Bahadir for all his constributions and support
- Thanks to Takatoshi Kondo for testing, improving the library and for a great Boost.MSM guide!
- Thanks to Ulenspiegel for insuring the quality of the library
- Thanks to Jean Davy for the cmake support
- Thanks to feltech for improvements and bug fixes
- Thanks to Vicente J. Botet Escriba for useful suggestions how to improve the library
- Thanks to AnthonyVH for all contributions
- Thanks to Oliver Daniell for all contributions
- Thanks to Julius Gelšvartas for bug fixes
- Thanks to Christopher Motl for documentation fixes