sttcl  v0.9c
STTCL C++ template state machine framework
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ConcurrentCompositeState.h
Go to the documentation of this file.
1 
25 #ifndef CONCURRENTCOMPOSITESTATE_H_
26 #define CONCURRENTCOMPOSITESTATE_H_
27 
28 #include "CompositeState.h"
29 #include "Region.h"
30 
31 namespace sttcl
32 {
33 namespace internal
34 {
35 
36 template
37 < class CompositeStateImpl
38 , class IInnerState
39 , class EventArgs
40 >
42 {
43 public:
48 
52  virtual ~RegionContainer() {}
53 
58  virtual void regionCompleted(RegionBaseType* region) = 0;
59 };
60 
61 
62 template
63 < class CompositeStateImpl
64 , class StateMachineImpl
65 , class IInnerState
66 , unsigned int NumOfRegions
67 , class EventArgs
68 , class StateBaseImpl
69 >
71 : public StateBaseImpl
72 {
73 public:
74 // void changeStateImpl(StateMachineImpl* context,StateBaseImpl* newState)
75 // {
76 // StateBaseImpl::changeState(context,newState);
77 // }
78 
79 protected:
80 
88  typedef RegionBaseType* RegionsArray[NumOfRegions];
89 
93  typedef StateMachineImpl Context;
94 
96 
101 
105  typedef typename StateMachineImpl::StateInterface OuterEventHandler;
106 
111 
113  : regions(argRegions)
114  {
115  }
116 
123  void broadcastEvent(Context* context,InnerEventHandler eventHandler,RefCountPtr eventArgs)
124  {
125  bool allRegionsFinalized = true;
126  for(unsigned int i = 0; i < NumOfRegions; ++i)
127  {
128  if(!regions[i]->isRegionFinalized())
129  {
130  allRegionsFinalized = false;
131  regions[i]->handleBroadcastedEvent(static_cast<CompositeStateImpl*>(this),eventHandler,eventArgs);
132  }
133  else
134  {
135  if(regions[i]->isRegionThreadRunning())
136  {
137  regions[i]->endDoRegion(static_cast<CompositeStateImpl*>(this));
138  regions[i]->joinRegionThread();
139  }
140  }
141  }
142  if(allRegionsFinalized)
143  {
144  context->subStateMachineCompleted(this);
145  }
146  }
147 
149 
150 };
151 
152 template
153 < class CompositeStateImpl
154 , class StateMachineImpl
155 , class IInnerState
156 , unsigned int NumOfRegions
157 , class StateBaseImpl
158 >
160 : public StateBaseImpl
161 {
162 public:
163 // void changeStateImpl(StateMachineImpl* context,StateBaseImpl* newState)
164 // {
165 // StateBaseImpl::changeState(context,newState);
166 // }
167 protected:
168 
173 
177  typedef RegionBaseType* RegionsArray[NumOfRegions];
178 
182  typedef StateMachineImpl Context;
183 
185 
190 
194  typedef typename StateMachineImpl::StateInterface OuterEventHandler;
195 
200 
202  : regions(argRegions)
203  {
204  }
205 
211  void broadcastEvent(Context* context,InnerEventHandler eventHandler)
212  {
213  bool allRegionsFinalized = true;
214  for(unsigned int i = 0; i < NumOfRegions; ++i)
215  {
216  if(!regions[i]->isRegionFinalized())
217  {
218  allRegionsFinalized = false;
219  regions[i]->handleBroadcastedEvent(static_cast<CompositeStateImpl*>(this),eventHandler);
220  }
221  else
222  {
223  if(regions[i]->isRegionThreadRunning())
224  {
225  regions[i]->endDoRegion(static_cast<CompositeStateImpl*>(this));
226  regions[i]->joinRegionThread();
227  }
228  }
229  }
230  if(allRegionsFinalized)
231  {
232  context->subStateMachineCompleted(this);
233  }
234  }
235 
237 };
238 
245 template
246 < class CompositeStateImpl
247 , class StateMachineImpl
248 , class IInnerState
249 , unsigned int NumOfRegions
250 , class EventArgs
251 , class StateBaseImpl
252 >
254 {
259 
260 };
261 
265 template
266 < class CompositeStateImpl
267 , class StateMachineImpl
268 , class IInnerState
269 , unsigned int NumOfRegions
270 , class StateBaseImpl
271 >
272 struct ConcurrentCompositeBaseImplementationSelector<CompositeStateImpl,StateMachineImpl,IInnerState,NumOfRegions,void,StateBaseImpl>
273 {
278 
279 };
280 
290 template
291 < class CompositeStateImpl
292 , class StateMachineImpl
293 , class IInnerState
294 , unsigned int NumOfRegions
295 , class EventArgs
296 , class StateBaseImpl
297 >
300  < CompositeStateImpl
301  , StateMachineImpl
302  , IInnerState
303  , NumOfRegions
304  , EventArgs
305  , StateBaseImpl
306  >::RESULT_TYPE
307 , public RegionContainer<CompositeStateImpl,IInnerState,EventArgs>
308 {
309 public:
311  < CompositeStateImpl
312  , StateMachineImpl
313  , IInnerState
314  , NumOfRegions
315  , EventArgs
316  , StateBaseImpl
318 
320 
324  typedef StateBaseImpl StateImplementationBase;
328  typedef typename StateMachineImpl::StateInterface StateInterface;
332  typedef typename StateMachineImpl::StateBaseClass StateBaseClass;
344  typedef StateMachineImpl Context;
345 
347 
352 
356  typedef typename StateMachineImpl::StateInterface OuterEventHandler;
357 
362 
369  ConcurrentCompositeStateBase(Context* argContextStateMachine, const RegionsArray& argRegions)
370  : BaseClassType(argRegions)
371  , contextStateMachine_(argContextStateMachine)
372  {
373  }
374 
379  {
380  }
381 
387  inline void entryImpl(Context* context)
388  {
390  for(unsigned int i = 0; i < NumOfRegions; ++i)
391  {
392  if(BaseClassType::regions[i]->isRegionInitialized())
393  {
394  BaseClassType::regions[i]->enterRegion(static_cast<CompositeStateImpl*>(this));
395  }
396  }
397  }
398 
404  inline void exitImpl(Context* context)
405  {
406  for(unsigned int i = 0; i < NumOfRegions; ++i)
407  {
408  if(BaseClassType::regions[i]->isRegionInitialized())
409  {
410  BaseClassType::regions[i]->exitRegion(static_cast<CompositeStateImpl*>(this));
411  }
412  }
414  }
415 
420  virtual void finalizeSubStateMachines(bool recursive)
421  {
422  static_cast<CompositeStateImpl*>(this)->finalizeImpl(recursive);
423  }
424 
429  virtual void initSubStateMachines(bool recursive)
430  {
431  static_cast<CompositeStateImpl*>(this)->initializeImpl(recursive);
432  }
433 
439  bool initializeImpl(bool recursive)
440  {
441  bool result = true;
442  for(unsigned int i = 0; i < NumOfRegions; ++i)
443  {
444  if(!BaseClassType::regions[i]->initializeRegion(recursive))
445  {
446  result = false;
447  }
448  }
449  return result;
450  }
451 
453  {
455  }
456 
461  void finalizeImpl(bool recursive)
462  {
463  for(unsigned int i = 0; i < NumOfRegions; ++i)
464  {
465  if(!BaseClassType::regions[i]->isRegionFinalized())
466  {
467  BaseClassType::regions[i]->finalizeRegion(recursive);
468  }
469  }
470  }
471 
478  {
479  for(unsigned int i = 0; i < NumOfRegions; ++i)
480  {
481  BaseClassType::regions[i]->startDoRegion(static_cast<CompositeStateImpl*>(this));
482  }
483  }
484 
491  {
492  for(unsigned int i = 0; i < NumOfRegions; ++i)
493  {
494  if(BaseClassType::regions[i]->isRegionThreadRunning())
495  {
496  BaseClassType::regions[i]->endDoRegion(static_cast<CompositeStateImpl*>(this));
497  }
498  }
499  }
500 
506  {
507  bool allRegionsCompleted = true;
508  for(unsigned int i = 0; i < NumOfRegions; ++i)
509  {
510  if(!BaseClassType::regions[i]->isRegionFinalized())
511  {
512  allRegionsCompleted = false;
513  }
514  }
515  if(allRegionsCompleted)
516  {
517  context()->subStateMachineCompleted(this);
518  }
519  }
520 
521  Context* context() const { return contextStateMachine_; }
522 
523 private:
524  virtual void regionCompleted(RegionBaseType* region)
525  {
526  static_cast<CompositeStateImpl*>(this)->regionCompletedImpl(region);
527  }
528 
529  Context* contextStateMachine_;
530 };
531 
532 }
533 
544 template
545 < class CompositeStateImpl
546 , class StateMachineImpl
547 , class IInnerState
548 , unsigned int NumOfRegions = 1
549 , class EventArgs = void
550 , class StateBaseImpl = State<CompositeStateImpl,StateMachineImpl,typename StateMachineImpl::StateInterface>
551 >
554  < CompositeStateImpl
555  , StateMachineImpl
556  , IInnerState
557  , NumOfRegions
558  , EventArgs
559  , StateBaseImpl
560  >
561 {
562 public:
564  < CompositeStateImpl
565  , StateMachineImpl
566  , IInnerState
567  , NumOfRegions
568  , EventArgs
569  , StateBaseImpl
571 
572  typedef StateMachineImpl StateMachineClass;
573 
575 
577 
579 
580  typedef typename StateMachineImpl::StateInterface OuterStateInterface;
587  ConcurrentCompositeState(StateMachineImpl* context, const RegionsArray& argRegions)
588  : ConcurrenCompositeStateBaseType(context,argRegions)
589  {
590  }
591 
596  {
597  }
598 
605  {
606  static_cast<CompositeStateImpl*>(this)->changeStateImpl(context,newState);
607  }
608 
609 };
610 }
611 
612 #endif /* CONCURRENTCOMPOSITESTATE_H_ */