25 #include <type_traits>
40 static_assert(std::is_enum_v<EnumT>);
59 bool _is_initial_state{
true};
63 class simple_state_machine
65 static_assert(std::is_enum_v<EnumT>);
79 template<enum_t state>
83 _states[state] = std::move(f);
86 template<enum_t state0, enum_t state1>
90 _transitions[ {state0, state1}] = std::move(f);
95 _post_transition_callback = std::move(f);
100 _pre_transition_callback = std::move(f);
105 _post_state_exit_callback = std::move(f);
110 _pre_state_enter_callback = std::move(f);
112 template<enum_t state0>
116 for (
const auto& [edge, _] : _transitions)
119 const auto [f, t] = edge;
124 state._previous_state = state0;
125 state._current_state = state0;
126 state._is_initial_state =
true;
132 _pre_state_enter_callback(state);
134 const auto next = _states.at(state._current_state)(state);
135 state._previous_state = state._current_state;
136 state._current_state = next;
137 state._is_initial_state =
false;
138 _post_state_exit_callback(state);
143 const std::pair<enum_t, enum_t> t{state._previous_state, state._current_state};
145 <<
"No transition from " << state._previous_state <<
" to " << state._current_state;
146 _pre_transition_callback(state);
147 ARMARX_IMPORTANT <<
"Taking transition '" << state._previous_state <<
"' -> '" << state._current_state <<
"'";
148 _transitions.at(t)(state);
149 _post_transition_callback(state);
151 ARMARX_IMPORTANT <<
"Exiting while in state '" << state._current_state <<
"'";
156 std::unordered_map<enum_t, state_function_t> _states;