17 template<
class DataType,
typename StateType,
typename TransitionType>
20 std::shared_ptr<DataType>
data;
52 virtual bool updateState(
const double delta, TransitionType& transition_type) {
return false; }
66 virtual StateType
react(
const TransitionType transition) {
return (StateType)0; }
77 template<
typename DataType,
typename StateType,
typename TransitionType,
typename... Reactor>
78 class FSM :
public std::enable_shared_from_this<FSM<DataType, StateType, TransitionType, Reactor...>> {
80 std::shared_ptr<DataType> data;
82 StateType current_state;
86 std::map<StateType, std::shared_ptr<StateReactor<DataType, StateType, TransitionType>>> states;
90 void unpackReactorAndMakeShared(
const std::shared_ptr<T>& t) {
91 states[t->getStateType()] = t;
94 template<
typename T,
typename... R>
95 void unpackReactorAndMakeShared(
const std::shared_ptr<T>& t,
const std::shared_ptr<R>&... reactors) {
96 states[t->getStateType()] = t;
98 unpackReactorAndMakeShared(reactors...);
101 template<
typename... R>
102 void unpackAndConstructReactors() {
103 unpackReactorAndMakeShared<R...>(std::make_shared<R>(data, subject)...);
115 FSM(
const std::shared_ptr<DataType>& data_to_mutate,
const StateType& begin_state,
Subject* subject) : data(data_to_mutate), subject(subject), current_state(begin_state), is_terminated(false), running(false) {
116 if(data_to_mutate ==
nullptr) {
117 throw std::invalid_argument(
"FSM::data_to_mutate cannot be nullptr");
120 unpackAndConstructReactors<Reactor...>();
131 FSM(
const std::shared_ptr<DataType>& data_to_mutate,
const StateType& begin_state,
const StateType& end_state,
Subject* subject) : data(data_to_mutate), current_state(begin_state), end_state(end_state), is_terminated(true), subject(subject) {
132 if(data_to_mutate ==
nullptr) {
133 throw std::invalid_argument(
"FSM::data_to_mutate cannot be nullptr");
136 unpackAndConstructReactors<Reactor...>();
146 auto new_state_type = states[current_state]->react(transition_type);
147 if(new_state_type != current_state) {
148 states[current_state]->leaveState();
149 current_state = new_state_type;
150 states[current_state]->enterState();
152 if(is_terminated && current_state == end_state) {
164 return is_terminated && current_state == end_state;
182 if(states[current_state]->updateState(delta, t)) {
StateReactor(const StateType &state_type, const std::shared_ptr< DataType > &data_to_mutate, Subject *subject)
StateReactor constructor. This sets which state this reactor is for and sets the data to be mutated...
Definition: fsm.hpp:33
Class for state reactor.
Definition: fsm.hpp:18
StateType state_type
Definition: fsm.hpp:22
constexpr StateType getStateType() const noexcept
Definition: fsm.hpp:35
virtual StateType react(const TransitionType transition)
This function is used to set up reactions for different types of transitions for this state...
Definition: fsm.hpp:66
Class for a subject that an observer would observe for changes.
Definition: subject.h:13
void transition(const TransitionType transition_type)
Sends a transition value to the FSM, causing the current state to react, and possible transition...
Definition: fsm.hpp:145
constexpr bool inFinalState() const noexcept
Check to see if the FSM is in it's final state.
Definition: fsm.hpp:163
virtual void leaveState()
leaveState is called upon triggering of a new state from this state.
Definition: fsm.hpp:56
FSM(const std::shared_ptr< DataType > &data_to_mutate, const StateType &begin_state, Subject *subject)
Finite state machine constructor.
Definition: fsm.hpp:115
void stop()
Stops the FSM.
Definition: fsm.hpp:191
void start()
Starts the FSM.
Definition: fsm.hpp:170
FSM(const std::shared_ptr< DataType > &data_to_mutate, const StateType &begin_state, const StateType &end_state, Subject *subject)
Finite state machine constructor for a terminated FSM.
Definition: fsm.hpp:131
Subject * subject
Definition: fsm.hpp:21
virtual bool updateState(const double delta, TransitionType &transition_type)
updateState is called once per engine loop for timed updates
Definition: fsm.hpp:52
void update(const double delta)
Update is called once per update loop in the engine.
Definition: fsm.hpp:179
virtual void enterState()
enterState is called upon triggering of this state
Definition: fsm.hpp:42
std::shared_ptr< DataType > data
Definition: fsm.hpp:20
Generic Finite State Machine.
Definition: fsm.hpp:78