Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

SignalTrans.h

Go to the documentation of this file.
00001 //-*-c++-*-
00002 #ifndef INCLUDED_SignalTrans_h_
00003 #define INCLUDED_SignalTrans_h_
00004 
00005 #include "Behaviors/Transition.h"
00006 #include "Events/DataEvent.h"
00007 #include "Events/EventRouter.h"
00008 
00009 //! causes a transition if a DataEvent<T> from stateSignalEGID occurs, and checks for a specific value if one is specified
00010 /*! This allows a state node to signal a transition to another state
00011  *  in a clean symbolic way.  Only the transition itself needs to know
00012  *  the address of the destination node.  The value passed in the
00013  *  DataEvent will be supplied to the destination node's doStart
00014  *  method.  A SignalTrans with no value supplied acts like a
00015  *  default case and will fire if no other SignalTrans fires first.
00016  */
00017 
00018 template<class T>
00019 class SignalTrans : public Transition {
00020 public:
00021   //! Constructor
00022   SignalTrans(StateNode *destination) :
00023     Transition(destination), val(), valueSupplied(false), savedEvent()
00024   { }
00025 
00026   //! Constructor
00027   SignalTrans(StateNode *destination, const T &value) :
00028     Transition(destination), val(value), valueSupplied(true), savedEvent()
00029   { }
00030 
00031   //! Constructor
00032   SignalTrans(const std::string &name, StateNode *destination) :
00033     Transition(name,destination), val(), valueSupplied(false), savedEvent()
00034   { }
00035 
00036   //! Constructor
00037   SignalTrans(const std::string &name, StateNode *destination, const T &value) :
00038     Transition(name,destination), val(value), valueSupplied(true), savedEvent()
00039   { }
00040 
00041   virtual void postStart() {
00042     Transition::postStart();
00043     for ( std::vector<StateNode*>::const_iterator it = srcs.begin(); it != srcs.end(); it++ )
00044       erouter->addListener(this,EventBase::stateSignalEGID,(size_t)*it);
00045   }
00046 
00047   virtual void doEvent() {
00048     switch ( event->getGeneratorID() ) {
00049 
00050     case EventBase::stateSignalEGID: {
00051       const DataEvent<T> *d_event = dynamic_cast<const DataEvent<T>*>(event);
00052       if ( d_event != NULL ) {
00053         savedEvent = *d_event;
00054         if ( ! valueSupplied )
00055           // wildcard case: wait 2 msec to see if some other SignalTrans matches the value
00056           erouter->addTimer(this, 9999, 1, false);
00057         // not wildcard: if supplied value matches the event, queue for firing
00058         else if ( d_event->getData() == val )
00059           erouter->addTimer(this, 9999, 0, false);
00060       }
00061       break;
00062     }
00063 
00064     case EventBase::timerEGID:
00065       fire(savedEvent);
00066       break;
00067 
00068     default:
00069       std::cout << "SignalTrans received unexpected event type: " << event->getDescription() << std::endl;
00070     }
00071   }
00072 
00073   //! Copy constructor required in case we're storing a pointer
00074   SignalTrans<T>(const SignalTrans<T> &src) : Transition(src), val(T(src.val)), valueSupplied(src.valueSupplied) {}
00075 
00076   //! Assignment operator required in case we're storing a pointer
00077   SignalTrans<T>& operator=(const SignalTrans<T>& src) {
00078     val = src.val;
00079     valueSupplied = src.valueSupplied;
00080     return *this;
00081   }
00082 
00083 protected:
00084   T val; //!< value to compare against
00085   bool valueSupplied;  //!< true if a value was supplied in the constructor
00086   DataEvent<T> savedEvent; //!< Copy of current event to be used after timer expires
00087 };
00088 
00089 #endif

Tekkotsu v5.1CVS
Generated Mon May 9 04:58:51 2016 by Doxygen 1.6.3