A Dynamic StateMachine where states and transitions are created runtime.
- Flat-style and enclosed-style setup
- Unlimited number of states and transitions
- Hierarchical states
- Entry and exit actions
- Internal and external transitions
- Transition actions
- Transition guard conditions
- State history (deep and shallow)
- Event processing
- Event deferring
- Event posting
- Orthogonal regions
- Optional shared storage
- Visitable
- Observable (check current active states)
- Exception handling
- Platform independent, C++17
- Header only
- No external dependencies except STL
- Moderate use of templates
cmake -B build -DCMAKE_INSTALL_PREFIX=/path/to/install/directory
cmake --build build --target install
Either build and install dsm package and then use cmake's findPackage to include it in your project:
cmake_minimum_required(VERSION 3.16)
project(your_project
LANGUAGES CXX
)
add_executable(your_target ${CMAKE_CURRENT_LIST_DIR}/main.cpp)
findPackage(dsm VERSION 0.1.1 REQUIRED)
target_link_libraries(your_target PRIVATE dsm::dsm)
Or include it directly in you project using CPM:
cmake_minimum_required(VERSION 3.16)
project(your_project
LANGUAGES CXX
)
# download CPM.cmake
file(
DOWNLOAD
https://github.com/cpm-cmake/CPM.cmake/releases/download/v0.40.2/CPM.cmake
${CMAKE_CURRENT_BINARY_DIR}/cmake/CPM.cmake
EXPECTED_HASH SHA256=c8cdc32c03816538ce22781ed72964dc864b2a34a310d3b7104812a5ca2d835d
)
include(${CMAKE_CURRENT_BINARY_DIR}/cmake/CPM.cmake)
CPMAddPackage("gh:jfayot/dynamic-state-machine@0.1.1")
add_executable(your_target ${CMAKE_CURRENT_LIST_DIR}/main.cpp)
target_link_libraries(your_target PRIVATE dsm::dsm)
Considering the following minimal state machine, it can be coded as follows:
#include "dsm/dsm.hpp"
#include <cassert>
using namespace dsm;
struct e1 : Event<e1> {};
struct minimal : StateMachine<minimal> {};
struct s0 : State<s0, minimal> {};
struct s1 : State<s1, minimal> {};
int main()
{
minimal sm;
sm.addState<s0, Entry>();
sm.addState<s1>();
sm.addTransition<s0, e1, s1>();
sm.start();
assert(sm.checkStates<s0>());
std::cout << sm << std::endl;
sm.processEvent(e1{});
assert(sm.checkStates<s1>());
std::cout << sm << std::endl;
}
#include "dsm/dsm.hpp"
#include <cassert>
using namespace dsm;
struct minimal;
struct e1 : Event<e1> {};
struct s1 : State<s1, minimal> {};
struct s0 : State<s0, minimal> {
TTransitions getTransitions() override {
return { createTransition<e1, s1>() };
}
};
struct minimal : StateMachine<minimal> {
TStates getStates() override {
return { createState<s0, Entry>(), createState<s1>() };
}
};
int main()
{
minimal sm;
sm.setup();
sm.start();
assert(sm.checkStates<s0>());
std::cout << sm << std::endl;
sm.processEvent(e1{});
assert(sm.checkStates<s1>());
std::cout << sm << std::endl;
}
Title | UML | Source file |
---|---|---|
entry/exit actions | entry_exit_actions.cpp | |
transition action | transition_action.cpp | |
transition guard | transition_guard.cpp | |
self transition | self_transition.cpp | |
composite state | composite_state.cpp | |
shallow history | shallow_history.cpp | |
deep history | deep_history.cpp | |
orthogonal regions | orthogonal_regions.cpp |