Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

MCNode.h

Go to the documentation of this file.
00001 //-*-c++-*-
00002 #ifndef INCLUDED_MCNode_h_
00003 #define INCLUDED_MCNode_h_
00004 
00005 #include "Behaviors/StateNode.h"
00006 #include "Motion/MotionManager.h"
00007 #include "Motion/MMAccessor.h"
00008 
00009 //! Common parent class for all the templated MCNode, which is what you want to instantiate.
00010 class MCNodeBase : public StateNode {
00011 public:
00012   static const char defName[]; //!< the default name for MCNodes -- can be overridden via MCNode's template arguments
00013   static const char defDesc[]; //!< the default description for MCNodes -- can be overridden via MCNode's template arguments
00014 
00015   //! destructor, free #mc
00016   virtual ~MCNodeBase() { delete mc; }
00017   
00018   //! Adds the motion command to the motion manager, add a listener for the motion's completion event
00019   virtual void DoStart();
00020   
00021   //! Assumes the event is a completion event from the motion, throws a corresponding state node completion event
00022   virtual void processEvent(const EventBase& /*e*/);
00023   
00024   //! Removes the motion command from the motion manager if it was our own creation
00025   virtual void DoStop();  
00026   
00027   //! Allows you to assign a previously created motion, which might be shared among several MCNodes
00028   /*! If this node already has an #mc, then it will be freed, removing from MotionManager if necessary */
00029   virtual void setMC(MotionManager::MC_ID mcid);
00030   
00031   //! reveal the MC_ID; if the motion isn't currently active, returns MotionManager::invalid_MC_ID
00032   virtual MotionManager::MC_ID getMC_ID() { return mc_id; }
00033   
00034   static std::string getClassDescription() { return defName; }
00035   virtual std::string getDescription() const { return getClassDescription(); }
00036   
00037 protected:
00038   //! constructor for subclasses (which would need to provide a different class name)
00039   MCNodeBase(const std::string &class_name, const std::string &node_name, bool expectCompletion=true)
00040     : StateNode(class_name,node_name), mc(NULL), mc_id(MotionManager::invalid_MC_ID), mcCompletes(expectCompletion)
00041   {}
00042   
00043   //! returns reference to #mc or a new SharedObject<T> if #mc is currently NULL (so it will always return a valid value)
00044   /*! if a particular motion command needs some initial setup besides the default constructor,
00045    *  overriding this function is a good opportunity to do so */
00046   virtual SharedObjectBase& getPrivateMC()=0;
00047 
00048   //! returns true if the motion command being used was created internally via getPrivateMC()
00049   virtual bool hasPrivateMC() { return mc!=NULL; }
00050 
00051   SharedObjectBase* mc;    //!< MotionCommand used by this node (may be NULL if sharing the MC with other nodes)
00052   MotionManager::MC_ID mc_id;  //!< id number for the MotionCommand
00053   bool mcCompletes; //!< if true, will post a completion when the underlying MotionCommand posts a status
00054 
00055 private:
00056   MCNodeBase(const MCNodeBase&); //!< don't call (copy constructor)
00057   MCNodeBase& operator=(const MCNodeBase&); //!< don't call (assignment operator)
00058 };
00059 
00060 //! A generic wrapper for any MotionCommand, note that some functions are provided by the MCNodeBase common base class, namely MCNodeBase::setMC() and MCNodeBase::getMC_ID()
00061 template<class T, const char* mcName=MCNodeBase::defName, const char* mcDesc=MCNodeBase::defDesc, bool completes=true>
00062 class MCNode : public MCNodeBase {
00063 public:
00064   //! default constructor, use type name as instance name
00065   MCNode()
00066     : MCNodeBase(mcName,mcName,completes)
00067   {}
00068   
00069   //! constructor, take an instance name
00070   MCNode(const std::string& nm)
00071     : MCNodeBase(mcName,nm,completes)
00072   {}
00073   
00074   //! destructor
00075   virtual ~MCNode() {}
00076   
00077   //! reveal the MotionCommand through an MMAccessor
00078   /*! This is a no-op if the motion command hasn't been added to motion manager yet, and enforces mutual exclusion if it has */
00079   virtual MMAccessor<T> getMC();
00080   
00081   static std::string getClassDescription() { return mcDesc; }
00082   virtual std::string getDescription() const { return getClassDescription(); }
00083 
00084 protected:
00085   //! constructor for subclasses (which would need to provide a different class name)
00086   MCNode(const std::string &class_name, const std::string &node_name)
00087     : MCNodeBase(class_name,node_name)
00088   {}
00089   
00090   virtual SharedObject<T>& getPrivateMC();
00091 };
00092 
00093 
00094 // ****************************
00095 // ******* IMPLEMENTATION *******
00096 // ****************************
00097 
00098 template<class T, const char* mcName, const char* mcDesc, bool completes>
00099 MMAccessor<T> MCNode<T,mcName,mcDesc,completes>::getMC() {
00100   if(mc_id==MotionManager::invalid_MC_ID) {
00101     // motion hasn't been added to motion manager yet
00102     return MMAccessor<T>(*getPrivateMC());
00103   } else {
00104     // motion has been added to motion manager, check it out
00105     return MMAccessor<T>(mc_id);
00106   }
00107 }
00108 
00109 template<class T, const char* mcName, const char* mcDesc, bool completes>
00110 SharedObject<T>& MCNode<T,mcName,mcDesc,completes>::getPrivateMC() {
00111   if(mc==NULL)
00112     mc=new SharedObject<T>;
00113   return dynamic_cast<SharedObject<T>&>(*mc);
00114 }
00115 
00116 
00117 /*! @file
00118  * @brief Defines MCNode, which provides generic wrapper for any MotionCommand
00119  * @author Ethan Tira-Thompson (ejt) (Creator)
00120  *
00121  * $Author: ejt $
00122  * $Name: tekkotsu-4_0 $
00123  * $Revision: 1.6 $
00124  * $State: Exp $
00125  * $Date: 2006/09/27 20:12:37 $
00126  */
00127 
00128 #endif

Tekkotsu v4.0
Generated Thu Nov 22 00:54:53 2007 by Doxygen 1.5.4