sttcl  v0.9c
STTCL C++ template state machine framework
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Region.h
Go to the documentation of this file.
1 
25 #ifndef REGION_H_
26 #define REGION_H_
27 
28 #include "CompositeState.h"
29 #include "ActiveState.h"
30 #include "RefCountPtr.h"
31 #include "SttclMutex.h"
32 #include "SttclSemaphore.h"
33 #include "EventQueue.h"
34 
35 namespace sttcl
36 {
37 
38 template
39 < class RegionContainerImpl
40 , class IInnerState
41 , class EventArgs = void
42 >
43 class RegionBase;
44 
45 namespace internal
46 {
52 template
53 < class RegionContainerImpl
54 , class IInnerState
55 , class EventArgsType
56 >
58 {
63 
72 };
73 
77 template
78 < class RegionContainerImpl
79 , class IInnerState
80 >
81 struct EventArgsInterfaceSelector<RegionContainerImpl,IInnerState,void>
82 {
87 
95 };
96 
97 template
98 < class RegionContainerImpl
99 , class IInnerState
100 , class EventArgs
102 {
103 public:
105 
110 
115 
122  virtual void handleBroadcastedEvent(RegionContainerImpl* context,InnerEventHandler eventHandler, RefCountPtr eventArgs) = 0;
123 
125 };
126 
127 template
128 < class RegionContainerImpl
129 , class IInnerState
130 , class EventArgs
132 {
133 public:
135 
140 
145 
151  virtual void handleBroadcastedEvent(RegionContainerImpl* context,InnerEventHandler eventHandler) = 0;
152 
154 };
155 
162 template
163 < class RegionContainerImpl
164 , class IInnerState
165 , class EventArgs
166 >
168 {
173 
174 };
175 
179 template
180 < class RegionContainerImpl
181 , class IInnerState
182 >
183 struct RegionEventDispatchInterfaceSelector<RegionContainerImpl,IInnerState,void>
184 {
189 
190 };
191 
192 template
193 < class RegionContainerImpl
194 , class IInnerState
195 , class EventArgs
196 >
197 struct DispatchedEvent;
198 
199 template
200 < class RegionContainerImpl
201 , class IInnerState
202 , class EventArgs
203 >
204 class RegionContainer;
205 
206 }
207 
214 template
215 < class RegionContainerImpl
216 , class IInnerState
217 , class EventArgs //= void
218 >
220 : public sttcl::internal::RegionEventDispatchInterfaceSelector<RegionContainerImpl,IInnerState,EventArgs>::RESULT_TYPE
221 {
222 public:
223 
225 
230 
238 
242  RegionBase(RegionContainerImpl* argRegionContainer)
243  : regionContainer(argRegionContainer)
244  {
245  }
246 
250  virtual ~RegionBase()
251  {
252  }
253 
258  virtual void enterRegion(RegionContainerImpl* context) = 0;
263  virtual void exitRegion(RegionContainerImpl* context) = 0;
268  virtual void finalizeRegion(bool recursive) = 0;
274  virtual bool initializeRegion(bool recursive) = 0;
279  virtual void startDoRegion(RegionContainerImpl* context) = 0;
284  virtual void endDoRegion(RegionContainerImpl* context) = 0;
289  virtual bool isRegionInitialized() = 0;
294  virtual bool isRegionFinalized() = 0;
299  virtual bool isRegionThreadRunning() const = 0;
303  virtual void joinRegionThread() = 0;
304 
309  template<class RegionImpl>
310  RegionImpl* getRegionContext()
311  {
312  return static_cast<RegionImpl*>(this);
313  }
314 
319  virtual void internalInitialize(bool recursive) = 0;
320 
321  virtual void internalFinalize(bool recursive) = 0;
322 
324 
325 protected:
326  RegionContainerImpl* regionContainer;
327 };
328 
329 namespace internal
330 {
331 
335 template
336 < class RegionContainerImpl
337 , class IInnerState
338 , class EventArgs
339 >
341 {
346 
347 
349 
354 
359 
363  typedef void (RegionBaseClass::*InternalEventHandler)(bool);
364 
368  RegionContainerImpl* context;
389 
397  DispatchedEvent(RegionContainerImpl* argContext, IInnerState* argState, InnerEventHandler argHandler, RefCountPtr argEventArgs)
398  : context(argContext)
399  , state(argState)
400  , handler(argHandler)
401  , eventArgs(argEventArgs)
402  , internalHandler(0)
403  , recursiveInternalEvent(false)
404  {
405  }
406 
412  DispatchedEvent(InternalEventHandler argInternalHandler, bool argRecursiveInternalEvent)
413  : context(0)
414  , state(0)
415  , handler(0)
416  , eventArgs()
417  , internalHandler(argInternalHandler)
418  , recursiveInternalEvent(argRecursiveInternalEvent)
419  {
420  }
421 
427  : context(rhs.context)
428  , state(rhs.state)
429  , handler(rhs.handler)
430  , eventArgs(rhs.eventArgs)
433  {
434  }
435 
441  {
442  context = rhs.context;
443  state = rhs.state;
444  handler = rhs.handler;
445  eventArgs = rhs.eventArgs;
448  return *this;
449  }
450 
451 private:
452  DispatchedEvent(); // Forbidden
453 };
454 
462 template
463 < class RegionImpl
464 , class RegionContainerImpl
465 , class IInnerState
466 , class EventArgs
467 >
469 : public RegionBase<RegionContainerImpl,IInnerState,EventArgs>
470 {
471 public:
475  typedef RegionImpl Implementation;
476 
481 
483 
485 
486  RegionBaseImplWithEventArgs(RegionContainerImpl* argRegionContainer)
487  : RegionBaseClass(argRegionContainer)
488  {}
489 
491 
492  virtual void handleBroadcastedEvent(RegionContainerImpl* context,InnerEventHandler eventHandler, RefCountPtr eventArgs)
493  {
494  (static_cast<Implementation*>(this)->*eventHandler)(context,this,eventArgs);
495  }
496 
505  void dispatchEvent(RegionContainerImpl* context,IInnerState* state, InnerEventHandler eventHandler, RefCountPtr eventArgs)
506  {
507  if(state)
508  {
510  }
511  }
512 
513 protected:
514  void callDispatchedEventHandler(RegionContainerImpl* context,IInnerState* state,InnerEventHandler eventHandler,RefCountPtr eventArgs)
515  {
516  (state->*eventHandler)(context,this,eventArgs);
517  }
518 
519 };
520 
528 template
529 < class RegionImpl
530 , class RegionContainerImpl
531 , class IInnerState
532 , class EventArgs
533 >
535 : public RegionBase<RegionContainerImpl,IInnerState,EventArgs>
536 {
537 public:
541  typedef RegionImpl Implementation;
542 
547 
548 // typedef typename RegionBaseClass::RegionContainerClass RegionContainerClass;
549 
551 
553 
554  RegionBaseImplWithoutEventArgs(RegionContainerImpl* argRegionContainer)
555  : RegionBaseClass(argRegionContainer)
556  {}
557 
559 
560  virtual void handleBroadcastedEvent(RegionContainerImpl* context,InnerEventHandler eventHandler)
561  {
562  (static_cast<Implementation*>(this)->*eventHandler)(context,this);
563  }
564 
572  void dispatchEvent(RegionContainerImpl* context,IInnerState* state, InnerEventHandler eventHandler)
573  {
574  if(state)
575  {
576  RegionContainerImpl* regionContainerContext = static_cast<RegionContainerImpl*>(context);
578  }
579  }
580 
581 protected:
582  void callDispatchedEventHandler(RegionContainerImpl* context,IInnerState* state,InnerEventHandler eventHandler,RefCountPtr eventArgs)
583  {
584  (state->*eventHandler)(context,this);
585  }
586 };
587 
594 template
595 < class RegionImpl
596 , class RegionContainerImpl
597 , class IInnerState
598 , class EventArgs
599 >
601 {
606 
607 };
608 
612 template
613 < class RegionImpl
614 , class RegionContainerImpl
615 , class IInnerState
616 >
617 struct RegionBaseImplementationSelector<RegionImpl,RegionContainerImpl,IInnerState,void>
618 {
623 
624 };
625 }
626 
650 template
651 < class RegionImpl
652 , class RegionContainerImpl
653 , class IInnerState
654 , class EventArgs = void
656 , class StateThreadType = sttcl::internal::SttclThread<>
657 , class TimeDurationType = TimeDuration<STTCL_DEFAULT_TIMEDURATIONIMPL>
660 , class EventQueueType = sttcl::EventQueue<sttcl::internal::DispatchedEvent<RegionContainerImpl,IInnerState,EventArgs>,TimeDurationType,SemaphoreType,MutexType>
661 >
662 class Region
663 : public CompositeState
664  < Region<RegionImpl,RegionContainerImpl,IInnerState,EventArgs,HistoryType,StateThreadType,TimeDurationType,SemaphoreType,MutexType,EventQueueType>
665  , RegionContainerImpl
666  , IInnerState
667  , HistoryType
668  , ActiveState
669  < Region<RegionImpl,RegionContainerImpl,IInnerState,EventArgs,HistoryType,StateThreadType,TimeDurationType,SemaphoreType,MutexType,EventQueueType>
670  , RegionContainerImpl
671  , IInnerState
672  , StateThreadType
673  , TimeDurationType
674  , SemaphoreType
675  , MutexType
676  >
677  , StateMachine<RegionImpl, IInnerState>
678  >
680  < RegionImpl
681  , RegionContainerImpl
682  , IInnerState
683  , EventArgs
684  >::RESULT_TYPE
685 {
686 public:
687  friend class RegionBase<RegionContainerImpl,IInnerState,EventArgs>;
688 
692  typedef RegionImpl Implementation;
693 
697  typedef RegionContainerImpl Context;
698 
702  typedef Region
703  < RegionImpl
704  , RegionContainerImpl
705  , IInnerState
706  , EventArgs
707  , HistoryType
708  , StateThreadType
709  , TimeDurationType
710  , SemaphoreType
711  , MutexType
712  , EventQueueType
718  typedef ActiveState
719  < SelfClassType
720  , RegionContainerImpl
721  , IInnerState
722  , StateThreadType
723  , TimeDurationType
724  , SemaphoreType
725  , MutexType
727 
731  typedef CompositeState
732  < SelfClassType
733  , RegionContainerImpl
734  , IInnerState
735  , HistoryType
739 
744 
746 
748 
753 
758 
762  typedef void (RegionBaseClass::*InternalEventHandler)(bool);
763 
768 
773 
778 
783 
787  //typedef StateBase<RegionImpl,InnerEventHandler> InnerStateClass;
789 
794 
799 
804 
809 
813  typedef typename StateImplementationBase::StateThreadImpl RegionThreadImpl;
814 
820  Region(RegionContainerImpl* argRegionContainer, TimeDurationType argDoActionFrequency = TimeDurationType::Zero)
821  : CompositeStateBase(&SelfClassType::regionDoAction)
822  , SelectedRegionBase(argRegionContainer)
823  , eventDispatchQueue()
824  , checkEventFrequency(argDoActionFrequency)
825  {
826  }
827 
831  virtual ~Region()
832  {
833  }
834 
841  void dispatchInternalEvent(InternalEventHandler internalEventHandler, bool recursive)
842  {
843  eventDispatchQueue.push_back(sttcl::internal::DispatchedEvent<RegionContainerImpl,IInnerState,EventArgs>(internalEventHandler,recursive));
844  }
845 
851  void changeStateImpl(RegionContainerImpl* context,IInnerState* newState)
852  {
853  }
854 
859  void changeState(RegionStateBase* newState)
860  {
862  }
863 
868  {
869 
870  }
871 
876  {
877 
878  }
879 
884  void entryImpl(Context* context)
885  {
887  }
888 
893  void exitImpl(Context* context)
894  {
896  }
897 
903  bool initializeImpl(bool force)
904  {
905  if(!RegionThreadImpl::isSelf(static_cast<StateImplementationBase*>(this)->getStateThread()))
906  {
907  // dispatch initialization to region thread
909  }
910  else
911  {
912  internalInitialize(force);
913  }
914  return true;
915  }
916 
923  {
924  if(!RegionThreadImpl::isSelf(static_cast<StateImplementationBase*>(this)->getStateThread()))
925  {
926  // dispatch finalization to region thread
927  dispatchInternalEvent(&RegionBaseClass::internalFinalize,finalizeSubStateMachines);
928  }
929  else
930  {
931  internalFinalize(finalizeSubStateMachines);
932  }
933  }
934 
940  {
941  return //static_cast<RegionContainerImplementationBase*>(this)->isFinalized() ||
942  static_cast<StateImplementationBase*>(this)->endDoActionRequestedImpl();
943  }
944 
949  {
950  static_cast<RegionImpl*>(this)->endingRegionThread();
951  }
952 
957  {
958  static_cast<StateImplementationBase*>(this)->joinDoActionThreadImpl();
959  }
960 
966  {
967  static_cast<StateImplementationBase*>(this)->unblockDoActionImpl();
968  unblockEventsAvailable();
969  }
970 
975  void endDoImpl(RegionContainerImpl* context)
976  {
977  if(!RegionThreadImpl::isSelf(static_cast<StateImplementationBase*>(this)->getStateThread()))
978  {
979  static_cast<StateImplementationBase*>(this)->endDoImpl(context);
980  }
981  }
982 
983 private:
984  virtual void queueDispatchedEvent(const sttcl::internal::DispatchedEvent<RegionContainerImpl,IInnerState,EventArgs>& dispatchedEvent)
985  {
986  eventDispatchQueue.push_back(dispatchedEvent);
987  }
988 
989  virtual void enterRegion(RegionContainerImpl* context)
990  {
991  static_cast<StateBase<RegionContainerImpl,IInnerState>*>(this)->entry(context);
992  }
993 
994  virtual void exitRegion(RegionContainerImpl* context)
995  {
996  static_cast<StateBase<RegionContainerImpl,IInnerState>*>(this)->exit(context);
997  }
998 
999  virtual void startDoRegion(RegionContainerImpl* context)
1000  {
1001  static_cast<RegionImpl*>(this)->startingRegionThread();
1002  static_cast<StateBase<RegionContainerImpl,IInnerState>*>(this)->startDo(context);
1003  }
1004 
1005  virtual void endDoRegion(RegionContainerImpl* context)
1006  {
1007  static_cast<StateBase<RegionContainerImpl,IInnerState>*>(this)->endDo(context);
1008  }
1009 
1010  virtual void finalizeRegion(bool recursive)
1011  {
1012  static_cast<RegionImpl*>(this)->finalize(recursive);
1013  }
1014 
1015  virtual bool initializeRegion(bool recursive)
1016  {
1017  static_cast<RegionImpl*>(this)->initialize(recursive);
1018  return static_cast<RegionImpl*>(this)->isReady();
1019  }
1020 
1021  virtual bool isRegionInitialized()
1022  {
1023  return static_cast<RegionImpl*>(this)->isInitialized();
1024  }
1025 
1026  virtual bool isRegionFinalized()
1027  {
1028  return static_cast<RegionImpl*>(this)->isFinalized();
1029  }
1030 
1031  virtual bool isRegionThreadRunning() const
1032  {
1033  return static_cast<const RegionImpl*>(this)->isDoActionRunning();
1034  }
1035 
1036  virtual void joinRegionThread()
1037  {
1038  static_cast<RegionImpl*>(this)->joinDoActionThreadImpl();
1039  }
1040 
1041  virtual void internalInitialize(bool recursive)
1042  {
1043  static_cast<RegionStateMachine*>(this)->initializeImpl(recursive);
1044  }
1045 
1046  virtual void internalFinalize(bool recursive)
1047  {
1048  static_cast<RegionStateMachine*>(this)->finalizeImpl(recursive);
1050  IRegionContainer* iregionContainer = static_cast<IRegionContainer*>(RegionBaseClass::regionContainer);
1051  iregionContainer->regionCompleted(static_cast<RegionBase<RegionContainerImpl,IInnerState,EventArgs>*>(this));
1052  }
1053 
1054  void unblockEventsAvailable()
1055  {
1056  eventDispatchQueue.unblock();
1057  }
1058 
1059  bool checkEventsAvailable()
1060  {
1061  return eventDispatchQueue.waitForEvents(checkEventFrequency);
1062  }
1063 
1064  void regionDoAction(typename ActiveStateImpl::Context* context, bool firstCall)
1065  {
1066  if(checkEventsAvailable())
1067  {
1068  while(!eventDispatchQueue.empty())
1069  {
1070  sttcl::internal::DispatchedEvent<RegionContainerImpl,IInnerState,EventArgs> dispatchedEvent = eventDispatchQueue.front();
1071  eventDispatchQueue.pop_front();
1072  if(dispatchedEvent.internalHandler)
1073  {
1074  (this->*dispatchedEvent.internalHandler)(dispatchedEvent.recursiveInternalEvent);
1075  }
1076  else
1077  {
1078  this->callDispatchedEventHandler(dispatchedEvent.context,dispatchedEvent.state,dispatchedEvent.handler,dispatchedEvent.eventArgs);
1079  }
1080  }
1081  }
1082  }
1083 
1084  EventQueueType eventDispatchQueue;
1085  TimeDurationType checkEventFrequency;
1086 };
1087 
1088 }
1089 
1090 #endif /* REGION_H_ */