21 #ifndef __XBOT_FINITE_STATE_MACHINE_H__
22 #define __XBOT_FINITE_STATE_MACHINE_H__
27 #include <unordered_map>
54 template <
typename StateType,
typename SharedDataType>
class State;
62 #ifdef XBOT_MULTIPLE_FSM_MODE
63 template <
typename EventType>
64 bool broadcast_event(
const EventType& e);
73 template <
typename StateType,
typename SharedDataType = SharedDataBase>
78 friend class State<StateType, SharedDataType>;
83 _data(std::make_shared<SharedDataType>()),
84 _console_logger(
"fsm")
87 bool init(
const std::string& initial_state_name ){
91 template <
typename MessageType>
92 bool init(
const std::string& initial_state_name,
const MessageType& msg )
94 auto it = _registered_states.find(initial_state_name);
96 if( it == _registered_states.end() )
98 std::cerr <<
"ERROR in " << __PRETTY_FUNCTION__ <<
"! Initial state " <<
100 " was not registered with this state machine! Call register_state()!" << std::endl;
106 _current_state = _previous_state = it->second;
107 _current_state->entry(msg);
116 if( _registered_states.count(state->get_name()) ){
117 std::cerr <<
"ERROR in " << __PRETTY_FUNCTION__ <<
"! State " <<
119 " has already beed registered with this state machine!" << std::endl;
124 state->_parent_fsm = fsm_ptr;
125 state->_data = _data;
126 _registered_states[state->get_name()] = state;
132 template <
typename EventType>
136 std::cerr <<
"ERROR in " << __PRETTY_FUNCTION__ <<
"! State machine " <<
137 " has not been initialized! Call init()!" << std::endl;
142 _current_state->react(event);
146 bool run(
double time,
double period){
149 std::cerr <<
"ERROR in " << __PRETTY_FUNCTION__ <<
"! State machine " <<
150 " has not been initialized! Call init()!" << std::endl;
155 _current_state->run(time, period);
161 return _current_state;
174 template <
typename MessageType>
175 bool transit(
const std::string& next_state_name,
const MessageType& msg )
177 auto it = _registered_states.find(next_state_name);
179 if( it == _registered_states.end() )
181 std::cerr <<
"ERROR in " << __PRETTY_FUNCTION__ <<
"! State " <<
183 " was not registered with this state machine! Call register_state()!" << std::endl;
188 _current_state->exit();
189 _previous_state = _current_state;
190 _current_state = it->second;
191 _current_state->entry(msg);
196 std::shared_ptr<StateType> _current_state, _previous_state;
198 StateMachine<StateType, SharedDataType> * fsm_ptr;
200 std::unordered_map<std::string, std::shared_ptr<StateType>> _registered_states;
204 std::shared_ptr<SharedDataType> _data;
220 template <
typename StateType,
typename SharedDataType = SharedDataBase>
227 virtual std::string
get_name()
const = 0;
229 virtual void run(
double time,
double period) {}
244 return *_parent_fsm->_console_logger;
247 template <
typename MessageType>
248 bool transit(
const std::string& next_state_name,
const MessageType& msg )
250 return _parent_fsm->transit(next_state_name, msg);
253 bool transit(
const std::string& next_state_name )
255 return _parent_fsm->transit(next_state_name,
Message());
260 _parent_fsm->_previous_state->get_name();
263 template <
typename EventType>
266 #ifdef XBOT_MULTIPLE_FSM_MODE
269 _parent_fsm->send_event(e);
277 std::shared_ptr<SharedDataType> _data;