sttcl  v0.9c
STTCL C++ template state machine framework
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
State.h
Go to the documentation of this file.
1 
25 #ifndef STATE_H_
26 #define STATE_H_
27 
28 namespace sttcl
29 {
30 
31 template<class StateMachineImpl, class IState>
32 class StateMachine;
33 
41 template<class StateMachineImpl,class IState>
42 class StateBase
43 : public IState
44 {
45  friend class StateMachine<StateMachineImpl,IState>;
46 
47 public:
51  typedef StateMachineImpl Context;
52 
56  typedef IState StateInterface;
57 
63  virtual void finalizeSubStateMachines(bool recursive) = 0;
64 
70  virtual void initSubStateMachines(bool recursive) = 0;
71 
76  virtual void entry(Context* context) = 0;
81  virtual void exit(Context* context) = 0;
86  virtual void startDo(Context* context) = 0;
91  virtual void endDo(Context* context) = 0;
92 
99  {
100  context->changeState(newState);
101  }
102 
108  template<class StateMachineContext>
109  void changeStateImpl(StateMachineContext* context,StateBase<StateMachineImpl,IState>* newState)
110  {
111  context->changeState(newState);
112  }
113 protected:
114 
122  virtual ~StateBase() {}
123 
124 };
125 
134 template<class StateImpl,class StateMachineImpl,class IState>
135 class State
136 : public StateBase<StateMachineImpl,IState>
137 {
138 public:
142  typedef StateMachineImpl Context;
143 
147  typedef StateImpl Implementation;
148 
153 
159  typedef void (Implementation::*StateDoAction)(Context*,bool);
160 
165  inline void entryImpl(Context* context)
166  {
167  }
168 
173  inline void exitImpl(Context* context)
174  {
175  }
176 
181  inline void startDoImpl(Context* context)
182  {
183  if(doAction)
184  {
185  (static_cast<Implementation*>(this)->*doAction)(context,true);
186  }
187  }
188 
193  inline void endDoImpl(Context* context)
194  {
195  }
196 
202  void finalizeSubStateMachinesImpl(bool recursive)
203  {
204  }
205 
211  void initSubStateMachinesImpl(bool recursive)
212  {
213  }
214 
222  bool checkDirectTransitionImpl(Context* context, bool& finalize, StateBaseType*& nextState)
223  {
224  nextState = 0;
225  finalize = false;
226  return false;
227  }
228 
229 protected:
235  State(StateDoAction argDoAction = 0)
236  : doAction(argDoAction)
237  {
238  }
239 
243  virtual ~State()
244  {
245  }
246 
252  void changeState(Context* context,StateBaseType* newState)
253  {
254  static_cast<Implementation*>(this)->changeStateImpl(context,newState);
255  }
256 
262  template<class StateMachineContext>
263  void changeState(StateMachineContext* context,StateBaseType* newState)
264  {
265  static_cast<Implementation*>(this)->changeStateImpl(context,newState);
266  }
267 
272 
273 private:
274  virtual void entry(Context* context)
275  {
276  static_cast<Implementation*>(this)->entryImpl(context);
277  }
278 
279  virtual void exit(Context* context)
280  {
281  static_cast<Implementation*>(this)->exitImpl(context);
282  }
283 
284 // template<class StateMachineContext>
285 // virtual void entry(StateMachineContext* context)
286 // {
287 // static_cast<Implementation*>(this)->entryImpl(context);
288 // }
289 //
290 // template<class StateMachineContext>
291 // virtual void exit(StateMachineContext* context)
292 // {
293 // static_cast<Implementation*>(this)->exitImpl(context);
294 // }
295 
296  virtual void startDo(Context* context)
297  {
298  // Run the do action
299  static_cast<Implementation*>(this)->startDoImpl(context);
300 
301  // Handle direct transitions
302  StateBaseType* nextState = 0;
303  bool finalize = false;
304  if(static_cast<Implementation*>(this)->checkDirectTransitionImpl(context,finalize,nextState))
305  {
306  if(finalize)
307  {
308  context->finalize();
309  }
310  else if(nextState)
311  {
312  changeState(context,nextState);
313  }
314  }
315  }
316 
317  virtual void endDo(Context* context)
318  {
319  static_cast<Implementation*>(this)->endDoImpl(context);
320  }
321 
322  virtual void finalizeSubStateMachines(bool recursive)
323  {
324  static_cast<Implementation*>(this)->finalizeSubStateMachinesImpl(recursive);
325  }
326 
327  virtual void initSubStateMachines(bool recursive)
328  {
329  static_cast<Implementation*>(this)->initSubStateMachinesImpl(recursive);
330  }
331 
332 };
333 }
334 
335 #endif /* STATE_H_ */