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   if ( ! valueSupplied ) {
00054     // wait to see if some other SignalTrans matches the value
00055     savedEvent = *d_event;
00056     erouter->addTimer(this, 9999, 0, false);
00057     return;
00058   }
00059   else if ( d_event->getData() == val )
00060     fire(*d_event);
00061       }
00062       break;
00063     }
00064 
00065     case EventBase::timerEGID:
00066       fire(savedEvent);
00067       break;
00068 
00069     default:
00070       std::cout << "SignalTrans received unexpected event type: " << event->getDescription() << std::endl;
00071     }
00072   }
00073 
00074   //! Copy constructor required in case we're storing a pointer
00075   SignalTrans<T>(const SignalTrans<T> &src) : Transition(src), val(T(src.val)), valueSupplied(src.valueSupplied) {}
00076 
00077   //! Assignment operator required in case we're storing a pointer
00078   SignalTrans<T>& operator=(const SignalTrans<T>& src) {
00079     val = src.val;
00080     valueSupplied = src.valueSupplied;
00081     return *this;
00082   }
00083 
00084 protected:
00085   T val; //!< value to compare against
00086   bool valueSupplied;  //!< true if a value was supplied in the constructor
00087   DataEvent<T> savedEvent; //!< Copy of current event to be used after timer expires
00088 };
00089 
00090 #endif

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