Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

StateNode.h

Go to the documentation of this file.
00001 //-*-c++-*-
00002 #ifndef INCLUDED_StateNode_h_
00003 #define INCLUDED_StateNode_h_
00004 
00005 #include "Transition.h"
00006 #include "Behaviors/BehaviorBase.h"
00007 #include <vector>
00008 #include <string>
00009 
00010 //! Recursive data structure - both a state machine controller as well as a node within a state machine itself
00011 /*!
00012  *  Override setup() to build your own Transition and StateNode network if you want
00013  *  this node to contain a state machine.
00014  *
00015  *  Override DoStart() / DoStop() as you would a normal BehaviorBase subclass to
00016  *  have this node add some functionality of its own.
00017  *  
00018  *  You can override setup to create a sub-network, as well as overriding DoStart and DoStop, in the same class.
00019  *  
00020  *  See also the <a href="http://www.cs.cmu.edu/~dst/Tekkotsu/Tutorial/state.shtml">tutorial page on State Machines</a>.
00021  *  
00022  *  There are two StateNode templates in <a href="http://cvs.tekkotsu.org/cgi/viewcvs.cgi/Tekkotsu/project/templates/"><i>project</i><tt>/templates/</tt></a>:
00023  *  - <a href="http://cvs.tekkotsu.org/cgi/viewcvs.cgi/Tekkotsu/project/templates/statenode.h?rev=HEAD&content-type=text/vnd.viewcvs-markup">statenode.h</a>
00024  *    is intended for leaf nodes, which directly implement the execution of a task.
00025  *  - <a href="http://cvs.tekkotsu.org/cgi/viewcvs.cgi/Tekkotsu/project/templates/statemachine.h?rev=HEAD&content-type=text/vnd.viewcvs-markup">statemachine.h</a>
00026  *    is intended for nodes which contain a network of transitions and subnodes, which together solve the task.
00027  */
00028 class StateNode  : public BehaviorBase {
00029 public:
00030   //!constructor, pass a name to use
00031   StateNode(const std::string& name) : BehaviorBase("StateNode",name), parent(NULL), transitions(), issetup(false), retain(true), startedTime(0), nodes() {}
00032 
00033   //!destructor, removes references to its outgoing transitions (be careful of incoming ones - they're still around!), and calls RemoveReference() on subnodes
00034   virtual ~StateNode();
00035 
00036   //!Adds the specified StateTransition to the transition table
00037   virtual Transition* addTransition(Transition* trans);
00038 
00039   //!Returns the std::vector of transitions so you can modify them yourself if need be
00040   std::vector<Transition*>& getTransitions() { return transitions; }
00041 
00042   //!Returns the const std::vector of transitions so you can read through them if need be
00043   const std::vector<Transition*>& getTransitions() const { return transitions; }
00044 
00045   //!Adds a StateNode to #nodes so it can be automatically dereferenced later, returns what it's passed (for convenience), calls AddReference() on @a node.  Also sets the node's parent to @c this if it is null.
00046   virtual StateNode* addNode(StateNode* node);
00047 
00048   //!Returns the std::vector of sub-nodes so you can modify them yourself if need be
00049   std::vector<StateNode*>& getNodes() { return nodes; }
00050 
00051   //!Returns the const std::vector of sub-nodes so you can read through them if need be
00052   const std::vector<StateNode*>& getNodes() const { return nodes; }
00053 
00054   //!Sets the retain flag - if not retained, will RemoveReference() subnodes upon DoStop() and recreate them on DoStart (by calling setup()) - may be too expensive to be worth saving memory...
00055   void setRetain(bool f) { retain=f; }
00056 
00057   //!Transitions should call this when you are entering the state, so it can enable its transitions
00058   virtual void DoStart();
00059 
00060   //!This is called by DoStart() when you should setup the network of subnodes (if any)
00061   virtual void setup() {issetup=true;}
00062 
00063   //!Transitions should call this when you are leaving the state, so it can disable its transitions
00064   virtual void DoStop();
00065   
00066   //!This is called by DoStop() when you should destruct subnodes
00067   /*!Default implementation will take care of the subnodes and their
00068    * transitions, you only need to worry about any *other* memory
00069    * which may have been allocated.  If none, you may not need
00070    * implement this function at all. */
00071   virtual void teardown();
00072 
00073   //!returns #parent
00074   virtual StateNode* getParent() const { return parent; }
00075 
00076 protected:
00077   //!constructor, pass the class name and instance name to use 
00078   StateNode(const std::string& classname, const std::string& name) : BehaviorBase(classname,name), parent(NULL), transitions(), issetup(false), retain(true), startedTime(0), nodes() {}
00079 
00080   //!will throw an activation event through stateMachineEGID, used when DoStart() is called
00081   virtual void postStartEvent();
00082 
00083   //!will throw a status event through stateMachineEGID to signal "completion" of the node
00084   /*! "completion" is defined by your subclass - will mean different things to different
00085    *  nodes depending on the actions they are performing.  So call this yourself if there
00086    *  is a natural ending point for your state.
00087    * @param magnitude the value to use for EventBase::magnitude -- generally is 1 for status events, but since this is to signal completion, 0 (the default) may be more appropriate; if your node is doing something repetitive however, 1 (or the loop count) may be better */
00088   virtual void postCompletionEvent(float magnitude=0);
00089 
00090   //!will throw an deactivation event through stateMachineEGID, used when DoStop() is called
00091   /* @param duration the value to use for EventBase::duration -- nice but not generally used */
00092   virtual void postStopEvent();
00093 
00094   //Node Stuff:
00095   //! pointer to the machine that contains this node
00096   StateNode* parent;
00097   //! a vector of outgoing transitions
00098   std::vector<Transition*> transitions;
00099   
00100   //Machine Stuff:
00101   //! this is set to true if the network has been setup but not destroyed (i.e. don't need to call setupSubNodes again)
00102   bool issetup;
00103   //! this is set to true if the network should be retained between activations.  Otherwise it's dereferenced upon DoStop(). (or at least RemoveReference() is called on subnodes)
00104   bool retain;
00105   //! the timestamp of last call to DoStart()
00106   unsigned int startedTime;
00107   //! vector of StateNodes, just so they can be dereferenced again on DoStop() (unless retained) or ~StateNode()
00108   std::vector<StateNode*> nodes;
00109 
00110 private:
00111   StateNode(const StateNode& node); //!< don't call this
00112   StateNode operator=(const StateNode& node); //!< don't call this
00113 };
00114 
00115 /*! @file
00116  * @brief Describes StateNode, which is both a state machine controller as well as a node within a state machine itself
00117  * @author ejt (Creator)
00118  *
00119  * $Author: ejt $
00120  * $Name: tekkotsu-4_0 $
00121  * $Revision: 1.23 $
00122  * $State: Exp $
00123  * $Date: 2007/08/14 18:23:27 $
00124  */
00125 
00126 #endif

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