Homepage Demos Overview Downloads Tutorials Reference
Credits

BehaviorBase.h

Go to the documentation of this file.
00001 //-*-c++-*-
00002 #ifndef INCLUDED_BehaviorBase_h_
00003 #define INCLUDED_BehaviorBase_h_
00004 
00005 #include "Events/EventListener.h"
00006 #include "Shared/ReferenceCounter.h"
00007 #include <string>
00008 #include <set>
00009 
00010 //! The basis from which all other Behaviors should inherit
00011 /*! Makes use of ReferenceCounter so that behaviors can automatically delete themselves if
00012  *  wanted.
00013  *
00014  *  Make sure your own DoStart and DoStop call BehaviorBase::DoStart (or Stop) to allow
00015  *  the auto-deletion from reference counting... otherwise you'll get memory leaks if you
00016  *  rely on the reference counting.
00017  *
00018  *  For an empty behavior boilerplate file to help you get started quickly, try
00019  *  <a href="http://cvs.tekkotsu.org/cgi-bin/viewcvs.cgi/Tekkotsu/docs/behavior_header.h?rev=HEAD&content-type=text/vnd.viewcvs-markup"><i>Tekkotsu</i><tt>/docs/behavior_header.h</tt></a>:
00020  * 
00021  *  But it would probably still be a good idea to go through the "<a
00022  *  href="../FirstBehavior.html">First Behavior</a>" tutorial to get a better idea of
00023  *  what's going on.
00024  */
00025 class BehaviorBase : public ReferenceCounter, public EventListener {
00026 public:
00027   //! destructor - if is active when deleted, will call DoStop() first
00028   virtual ~BehaviorBase();
00029   
00030   //! By default, merely adds to the reference counter (through AddReference()); Note you should still call this from your overriding methods
00031   virtual void DoStart();
00032 
00033   //! By default, subtracts from the reference counter (RemoveReference()), and thus may deletex if zero;  Don't forget to still call this when you override this; <b>Warning:</b> call this at the <i>end</i> of your DoStop(), not beginning (it might @c delete @c this )
00034   virtual void DoStop();
00035   
00036   //! By defining here, allows you to get away with not supplying a processEvent() function for the EventListener interface.  By default, does nothing.
00037   virtual void processEvent(const EventBase& /*event*/) {}
00038 
00039   //! Identifies the behavior in menus and such
00040   virtual std::string getName() const { return instanceName; }
00041 
00042   //! Allows dynamic renaming of behaviors
00043   virtual void setName(const std::string& name) { instanceName=name; }
00044 
00045   //! Gives a short description of what this particular instantiation does (in case a more specific description is needed on an individual basis)
00046   /*! By default simply returns getName(), because any calls from a
00047    *  BehaviorBase function to getClassDescription() are going to call
00048    *  BehaviorBase::getClassDescription(), not
00049    *  ~YourSubClass~::getClassDescription(), because static functions
00050    *  can't be virtual in C++ (doh!)
00051    *
00052    *  This means that getDescription called on a pointer to a
00053    *  BehaviorBase of unknown subtype would always return an empty
00054    *  string, which is pretty useless.  So instead we return the name
00055    *  in this situation.  If you want getDescription to return
00056    *  getClassDescription, you'll have to override it in your subclass
00057    *  to do so. */
00058   virtual std::string getDescription() const {
00059     std::string d=getClassDescription();
00060     return (d.size()==0)?getName():d;
00061   }
00062 
00063   //! Returns the name of the class of this behavior (aka its type)
00064   /*! Note that this isn't static to avoid the problems we found with
00065    *  getDescription/getClassDescription.  So instead we wind up
00066    *  wasting some memory in each instance of the class to store the
00067    *  className, but at least it will work the way you expect. */
00068   virtual std::string getClassName() const { return className; }
00069   
00070   //! Gives a short description of what this class of behaviors does... you should override this (but don't have to)
00071   /*! If you do override this, also consider overriding getDescription() to return it */
00072   static std::string getClassDescription() { return ""; }
00073 
00074   //! Returns true if the behavior is currently running
00075   virtual bool isActive() const { return started; }
00076   
00077   //! Allows read-only access to the set of currently instantiated behaviors
00078   /*! Not all of these behaviors are necessarily active, this is everything that has been allocated and not yet deallocated */
00079   static const std::set<BehaviorBase*>& getRegistry() { return registry; }
00080 
00081   // Just some debugging stuff in stasis
00082   /*  virtual void AddReference() {
00083       std::cout << getName() << " AddReference()==" << GetReferences() << ' ' << this << std::endl;
00084       ReferenceCounter::AddReference();
00085       }
00086       
00087       virtual void RemoveReference() {
00088       std::cout << getName() << " RemoveReference()==" << GetReferences() << ' ' << this << std::endl;
00089       ReferenceCounter::RemoveReference();
00090       }
00091   */
00092   
00093 protected:
00094   //! deprecated, behavior constructors should take a name argument (which by default should be the name of the type of the class)
00095   BehaviorBase() __attribute__((deprecated));
00096   //! constructor, @a name is used as both instance name and class name
00097   explicit BehaviorBase(const std::string& name);
00098   //! constructor, allows different initial values for class name and instance name
00099   BehaviorBase(const std::string& classname, const std::string& instancename);
00100   //! copy constructor; assumes subclass handles copying approriately - i.e. if @a b is active, the copy will be as well, even though DoStart was never called..
00101   BehaviorBase(const BehaviorBase& b);
00102   //! assignment operator; assumes subclass handles assignment appropriately - i.e. if @a b is active, the copy will be as well, even though DoStart was never called..
00103   BehaviorBase& operator=(const BehaviorBase& b);
00104 
00105   bool started; //!< true when the behavior is active
00106   std::string instanceName; //!< holds the name of this instance of behavior
00107   const std::string className; //!< holds the type of the subclass of this behavior as a string
00108   static std::set<BehaviorBase*> registry; //!< allows us to keep track of all the current behaviors
00109 };
00110 
00111 /*! @file
00112  * @brief Defines BehaviorBase from which all Behaviors should inherit
00113  * @author ejt (Creator)
00114  *
00115  * $Author: ejt $
00116  * $Name: tekkotsu-2_2_2 $
00117  * $Revision: 1.17 $
00118  * $State: Exp $
00119  * $Date: 2004/11/15 22:46:19 $
00120  */
00121 
00122 #endif

Tekkotsu v2.2.2
Generated Tue Jan 4 15:43:13 2005 by Doxygen 1.4.0