Pyrogenesis  trunk
FSM.h
Go to the documentation of this file.
1 /* Copyright (C) 2023 Wildfire Games.
2  * This file is part of 0 A.D.
3  *
4  * 0 A.D. is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * 0 A.D. is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef FSM_H
19 #define FSM_H
20 
21 #include <limits>
22 #include <map>
23 #include <set>
24 #include <vector>
25 
26 
27 constexpr unsigned int FSM_INVALID_STATE{std::numeric_limits<unsigned int>::max()};
28 
29 class CFsmEvent;
30 class CFsmTransition;
31 class CFsm;
32 
33 using Condition = bool(void* pContext);
34 using Action = bool(void* pContext, const CFsmEvent* pEvent);
35 
37 {
38  void* pFunction;
39  void* pContext;
40 };
41 
42 using StateSet = std::set<unsigned int>;
43 using EventMap = std::map<unsigned int, CFsmEvent*>;
44 using TransitionList = std::vector<CFsmTransition*>;
45 using CallbackList = std::vector<CallbackFunction>;
46 
47 /**
48  * Represents a signal in the state machine that a change has occurred.
49  * The CFsmEvent objects are under the control of CFsm so
50  * they are created and deleted via CFsm.
51  */
52 class CFsmEvent
53 {
55 public:
56 
57  CFsmEvent(unsigned int type);
58  ~CFsmEvent();
59 
60  unsigned int GetType() const
61  {
62  return m_Type;
63  }
64 
65  void* GetParamRef()
66  {
67  return m_Param;
68  }
69 
70  void SetParamRef(void* pParam);
71 
72 private:
73  unsigned int m_Type; // Event type
74  void* m_Param; // Event paramater
75 };
76 
77 
78 /**
79  * An association of event, condition, action and next state.
80  */
82 {
84 public:
85 
86  CFsmTransition(unsigned int state);
87  ~CFsmTransition();
88 
89  /**
90  * Registers an action that will be executed when the transition occurs.
91  * @param pAction the function which will be executed.
92  * @param pContext data passed to the function.
93  */
94  void RegisterAction(void* pAction, void* pContext);
95 
96  /**
97  * Registers a condition which will be evaluated when the transition occurs.
98  * @param pCondition the predicate which will be executed.
99  * @param pContext data passed to the predicate.
100  */
101  void RegisterCondition(void* pCondition, void* pContext);
102 
103  /**
104  * Set event for which transition will occur.
105  */
106  void SetEvent(CFsmEvent* pEvent);
108  {
109  return m_Event;
110  }
111 
112  /**
113  * Set next state the transition will switch the system to.
114  */
115  void SetNextState(unsigned int nextState);
116  unsigned int GetNextState() const
117  {
118  return m_NextState;
119  }
120 
121  unsigned int GetCurrState() const
122  {
123  return m_CurrState;
124  }
125 
126  const CallbackList& GetActions() const
127  {
128  return m_Actions;
129  }
130 
132  {
133  return m_Conditions;
134  }
135 
136  /**
137  * Evaluates conditions for the transition.
138  * @return whether all the conditions are true.
139  */
140  bool ApplyConditions() const;
141 
142  /**
143  * Executes actions for the transition.
144  * @note If there are no actions, assume true.
145  * @return whether all the actions returned true.
146  */
147  bool RunActions() const;
148 
149 private:
150  unsigned int m_CurrState;
151  unsigned int m_NextState;
155 };
156 
157 /**
158  * Manages states, events, actions and transitions
159  * between states. It provides an interface for advertising
160  * events and track the current state. The implementation is
161  * a Mealy state machine, so the system respond to events
162  * and execute some action.
163  *
164  * A Mealy state machine has behaviour associated with state
165  * transitions; Mealy machines are event driven where an
166  * event triggers a state transition.
167  */
168 class CFsm
169 {
170  NONCOPYABLE(CFsm);
171 public:
172 
173  CFsm();
174  virtual ~CFsm();
175 
176  /**
177  * Constructs the state machine. This method must be overriden so that
178  * connections are constructed for the particular state machine implemented.
179  */
180  virtual void Setup();
181 
182  /**
183  * Clear event, action and condition lists and reset state machine.
184  */
185  void Shutdown();
186 
187  /**
188  * Adds the specified state to the internal list of states.
189  * @note If a state with the specified ID exists, the state is not added.
190  */
191  void AddState(unsigned int state);
192 
193  /**
194  * Adds the specified event to the internal list of events.
195  * @note If an eveny with the specified ID exists, the event is not added.
196  * @return a pointer to the new event.
197  */
198  CFsmEvent* AddEvent(unsigned int eventType);
199 
200  /**
201  * Adds a new transistion to the state machine.
202  * @return a pointer to the new transition.
203  */
204  CFsmTransition* AddTransition(unsigned int state, unsigned int eventType, unsigned int nextState );
205 
206  /**
207  * Adds a new transition to the state machine.
208  * @return a pointer to the new transition.
209  */
210  CFsmTransition* AddTransition(unsigned int state, unsigned int eventType, unsigned int nextState,
211  void* pAction, void* pContext);
212 
213  /**
214  * Looks up the transition given the state, event and next state to transition to.
215  */
216  CFsmTransition* GetTransition(unsigned int state, unsigned int eventType) const;
217  CFsmTransition* GetEventTransition (unsigned int eventType) const;
218 
219  /**
220  * Sets the initial state for FSM.
221  */
222  void SetFirstState(unsigned int firstState);
223 
224  /**
225  * Sets the current state and update the last state to the current state.
226  */
227  void SetCurrState(unsigned int state);
228  unsigned int GetCurrState() const
229  {
230  return m_CurrState;
231  }
232 
233  void SetNextState(unsigned int nextState)
234  {
235  m_NextState = nextState;
236  }
237 
238  unsigned int GetNextState() const
239  {
240  return m_NextState;
241  }
242 
243  const StateSet& GetStates() const
244  {
245  return m_States;
246  }
247 
248  const EventMap& GetEvents() const
249  {
250  return m_Events;
251  }
252 
254  {
255  return m_Transitions;
256  }
257 
258  /**
259  * Updates the FSM and retrieves next state.
260  * @return whether the state was changed.
261  */
262  bool Update(unsigned int eventType, void* pEventData);
263 
264  /**
265  * Verifies whether the specified state is managed by the FSM.
266  */
267  bool IsValidState(unsigned int state) const;
268 
269  /**
270  * Verifies whether the specified event is managed by the FSM.
271  */
272  bool IsValidEvent(unsigned int eventType) const;
273 
274  /**
275  * Tests whether the state machine has finished its work.
276  * @note This is state machine specific.
277  */
278  virtual bool IsDone() const;
279 
280 private:
281  /**
282  * Verifies whether state machine has already been updated.
283  */
284  bool IsFirstTime() const;
285 
286  bool m_Done;
287  unsigned int m_FirstState;
288  unsigned int m_CurrState;
289  unsigned int m_NextState;
293 };
294 
295 #endif // FSM_H
#define NONCOPYABLE(className)
Indicates that a class is noncopyable (usually due to const or reference members, or because the clas...
Definition: code_annotation.h:227
CFsmEvent * GetEvent() const
Definition: FSM.h:107
Manages states, events, actions and transitions between states.
Definition: FSM.h:168
unsigned int m_NextState
Definition: FSM.h:289
void Shutdown(int flags)
Definition: GameSetup.cpp:339
const CallbackList & GetConditions() const
Definition: FSM.h:131
Represents a signal in the state machine that a change has occurred.
Definition: FSM.h:52
static enum @32 state
CFsmEvent * m_Event
Definition: FSM.h:152
bool(void *pContext, const CFsmEvent *pEvent) Action
Definition: FSM.h:34
unsigned int m_Type
Definition: FSM.h:73
void * pFunction
Definition: FSM.h:38
bool m_Done
Definition: FSM.h:286
unsigned int GetCurrState() const
Definition: FSM.h:121
void * pContext
Definition: FSM.h:39
const TransitionList & GetTransitions() const
Definition: FSM.h:253
unsigned int GetCurrState() const
Definition: FSM.h:228
unsigned int GetType() const
Definition: FSM.h:60
const StateSet & GetStates() const
Definition: FSM.h:243
bool(void *pContext) Condition
Definition: FSM.h:33
void * m_Param
Definition: FSM.h:74
void SetNextState(unsigned int nextState)
Definition: FSM.h:233
unsigned int m_CurrState
Definition: FSM.h:150
std::set< unsigned int > StateSet
Definition: FSM.h:42
unsigned int m_CurrState
Definition: FSM.h:288
void * GetParamRef()
Definition: FSM.h:65
std::vector< CallbackFunction > CallbackList
Definition: FSM.h:45
const EventMap & GetEvents() const
Definition: FSM.h:248
CallbackList m_Conditions
Definition: FSM.h:154
unsigned int GetNextState() const
Definition: FSM.h:116
std::vector< CFsmTransition * > TransitionList
Definition: FSM.h:44
EventMap m_Events
Definition: FSM.h:291
const CallbackList & GetActions() const
Definition: FSM.h:126
TransitionList m_Transitions
Definition: FSM.h:292
Definition: FSM.h:36
StateSet m_States
Definition: FSM.h:290
unsigned int m_FirstState
Definition: FSM.h:287
constexpr unsigned int FSM_INVALID_STATE
Definition: FSM.h:27
unsigned int m_NextState
Definition: FSM.h:151
CallbackList m_Actions
Definition: FSM.h:153
unsigned int GetNextState() const
Definition: FSM.h:238
An association of event, condition, action and next state.
Definition: FSM.h:81
std::map< unsigned int, CFsmEvent * > EventMap
Definition: FSM.h:43