26 #include <type_traits>
34 template <
class EnumT>
37 template <
class EnumT>
40 static_assert(std::is_enum_v<EnumT>);
49 return _previous_state;
55 return _current_state;
61 return _is_initial_state;
76 bool _is_initial_state{
true};
79 template <
class EnumT>
80 class simple_state_machine
82 static_assert(std::is_enum_v<EnumT>);
100 template <enum_t state>
105 _states[state] = std::move(f);
108 template <enum_t state0, enum_t state1>
113 _transitions[{state0, state1}] = std::move(f);
119 _post_transition_callback = std::move(f);
125 _pre_transition_callback = std::move(f);
131 _post_state_exit_callback = std::move(f);
137 _pre_state_enter_callback = std::move(f);
140 template <enum_t state0>
145 for (
const auto& [edge, _] : _transitions)
148 const auto [f, t] = edge;
153 state._previous_state = state0;
154 state._current_state = state0;
155 state._is_initial_state =
true;
161 _pre_state_enter_callback(state);
163 const auto next = _states.at(state._current_state)(state);
164 state._previous_state = state._current_state;
165 state._current_state = next;
166 state._is_initial_state =
false;
167 _post_state_exit_callback(state);
172 const std::pair<enum_t, enum_t> t{state._previous_state, state._current_state};
174 <<
"No transition from " << state._previous_state <<
" to "
175 << state._current_state;
176 _pre_transition_callback(state);
177 ARMARX_IMPORTANT <<
"Taking transition '" << state._previous_state <<
"' -> '"
178 << state._current_state <<
"'";
179 _transitions.at(t)(state);
180 _post_transition_callback(state);
182 ARMARX_IMPORTANT <<
"Exiting while in state '" << state._current_state <<
"'";
187 std::unordered_map<enum_t, state_function_t> _states;