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 liketo 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 (seePerformance)
- Huge resulting binaries (seePerformance)
- Based on too many macros
- Long error messages (seeError 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 (seePerformance)
- Memory usage (seePerformance)
- eUML DSL (src_state + event [ guard ] / action -> dst_state)
- UML standard compliant (As much as possible)
- Eliminate Boost.MSM - eUML problems
- Compilation times (seePerformance)
- Binary size (seePerformance)
- Reduce complexity by eliminating less used features
- Short and informative error messages (seeError Messages)
- Less boilerplate / no macros (seeHello World)
- Improve visibility by having all actions on transition table (seeStates)
- Allows loosely coupled design (seeDependency Injection)
- Functional programming support using lamda expressions (seeAction/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 (seeTransitions,Events)
- Actions / Guards (seeAction/Guards)
- State entry / exit actions (seeStates)
- Orthogonal regions (seeOrthogonal Regions)
- Sub / Composite state machines (seeComposite)
- History (seeHistory)
- Defer/Process (seeDefer/Process)
Additional features
- Logging (seeLogging)
- Testing (seeTesting)
- Runtime Dispatcher (seeRuntime Dispatcher)
- Dependency Injection integration (seeDependency 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 toChristophe Henry for a greatBoost.MSM - eUML library
- Thanks toDeniz Bahadir for all his constributions and support
- Thanks toTakatoshi Kondo for testing, improving the library and for a greatBoost.MSM guide!
- Thanks toUlenspiegel for insuring the quality of the library
- Thanks toJean Davy for the cmake support
- Thanks tofeltech for improvements and bug fixes
- Thanks toVicente J. Botet Escriba for useful suggestions how to improve the library
- Thanks toAnthonyVH for all contributions
- Thanks toOliver Daniell for all contributions
- Thanks toJulius Gelšvartas for bug fixes
- Thanks toChristopher Motl for documentation fixes