Tekkotsu Homepage | Demos | Overview | Downloads | Dev. Resources | Reference | Credits |
StateNode.hGo 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 |