Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

CompletionTrans.h

Go to the documentation of this file.
00001 //-*-c++-*-
00002 #ifndef INCLUDED_CompletionTrans_h_
00003 #define INCLUDED_CompletionTrans_h_
00004 
00005 #include "Behaviors/StateNode.h"
00006 #include "Behaviors/Transition.h"
00007 #include "Events/EventRouter.h"
00008 
00009 //! causes a transition when at least @e n sources have signalled completion;  @e n = 0 means "all" (default)
00010 class CompletionTrans : public Transition {
00011 protected:
00012   int minsrcs; //!< the minimum number of sources which must signal completion before this transition will fire
00013   bool *completions;  //!< pointer to array for recording completion events for all sources
00014   EventBase savedEvent; //!< Copy of current event to be used after timer expires
00015   
00016 public:
00017   //! constructor, pass @a destination and the minimum number of sources which must signal completion before this transition will fire
00018   CompletionTrans(StateNode* destination, int n=0) :
00019     Transition(destination), minsrcs(n), completions(NULL), savedEvent() {};
00020   
00021   //! constructor, pass @a name, @a destination and the minimum number of times the source must signal completion beyond the first (@a n)
00022   CompletionTrans(const std::string& name, StateNode* destination, int n=0) :
00023     Transition(name,destination), minsrcs(n), completions(NULL), savedEvent() {};
00024   
00025   //! starts listening
00026   virtual void postStart() {
00027     Transition::postStart();
00028     unsigned int const numsrcs = getSources().size();
00029     completions = new bool[numsrcs];
00030     for (unsigned int i = 0; i < numsrcs; i++) {
00031       completions[i] = false;
00032       erouter->addListener(this, EventBase::stateMachineEGID, reinterpret_cast<size_t>(getSources()[i]), EventBase::statusETID);
00033     };
00034   }
00035   
00036   //! stops listening
00037   virtual void stop() {
00038     erouter->removeListener(this);
00039     delete completions;
00040     completions = NULL;
00041     Transition::stop();
00042   }
00043   
00044   //! record completions, and fire the transition if all sources have completed
00045   virtual void doEvent() {
00046     switch ( event->getGeneratorID() ) {
00047 
00048     case EventBase::stateMachineEGID: {
00049       int numcomplete = 0;
00050       for ( unsigned int i=0; i<getSources().size(); i++ ) {
00051   if ( event->getSourceID() == reinterpret_cast<size_t>(getSources()[i]) )
00052     completions[i] = true;
00053   if ( completions[i] )
00054     ++numcomplete;
00055       }
00056       int const threshold = (minsrcs > 0 ? minsrcs : (int)getSources().size());
00057       if (numcomplete >= threshold) {
00058   savedEvent = *event;
00059   erouter->addTimer(this, 9999, 0, false);
00060   return;
00061       }
00062       break;
00063     }
00064 
00065     case EventBase::timerEGID:
00066     fire(savedEvent);
00067     break;
00068 
00069   default:
00070     std::cout << "CompletionTrans received unexpected event type: " << event->getDescription() << std::endl;
00071     }
00072   }
00073   
00074 protected:
00075   //!@name Dummy functions to satisfy the compiler
00076   CompletionTrans(const CompletionTrans&);  //!< don't call this
00077   CompletionTrans& operator=(const CompletionTrans&);  //!< don't call this
00078   //@}
00079   
00080 };
00081 
00082 /*! @file
00083  * @brief Defines Completiontrans, which causes a transition if all sources have signalled completion
00084  * @author dst (Creator)
00085  */
00086 
00087 #endif

Tekkotsu v5.1CVS
Generated Fri Mar 16 05:26:36 2012 by Doxygen 1.6.3