StateNode.cc
Go to the documentation of this file.00001 #include "StateNode.h"
00002 #include "Transition.h"
00003 #include "Events/EventRouter.h"
00004 #include "Sound/SoundManager.h"
00005 #include "Wireless/Wireless.h"
00006 #include "Shared/debuget.h"
00007
00008 StateNode::~StateNode() {
00009 ASSERT(!isActive(), "Destructing while active?")
00010 for(std::vector<Transition*>::iterator it=transitions.begin(); it!=transitions.end(); it++)
00011 (*it)->removeReference();
00012 if(issetup) {
00013 teardown();
00014 if(issetup) {
00015 serr->printf("WARNING %s doesn't seem to call StateNode::teardown() in its\n"
00016 " implementation of the function: issetup=%d, nodes.size()=%lu\n"
00017 " Attempting to recover...\n",getClassName().c_str(),issetup,(unsigned long)nodes.size());
00018 StateNode::teardown();
00019 }
00020 }
00021 }
00022
00023 Transition* StateNode::addTransition(Transition* trans) {
00024 transitions.push_back(trans);
00025 trans->addReference();
00026 trans->addSource(this);
00027 return trans;
00028 }
00029
00030 StateNode* StateNode::addNode(StateNode* node) {
00031 nodes.push_back(node);
00032 node->addReference();
00033 if ( node->parent == NULL )
00034 node->parent = this;
00035 return node;
00036 }
00037
00038 StateNode* StateNode::getChild(const std::string& name) const {
00039 for (std::vector<StateNode*>::const_iterator it = nodes.begin(); it != nodes.end(); it++)
00040 if ( name == (*it)->getName() ) return *it;
00041 return NULL;
00042 }
00043
00044 StateNode* StateNode::getSibling(const std::string& name) const {
00045 if ( parent == NULL )
00046 return parent;
00047 for (std::vector<StateNode*>::const_iterator it = parent->nodes.begin(); it != parent->nodes.end(); it++)
00048 if ( name == (*it)->getName() ) return *it;
00049 return parent->getSibling(name);
00050 }
00051
00052 struct ScopeReference {
00053 ScopeReference(ReferenceCounter& rc) : ref(rc) { ref.addReference(); }
00054 ~ScopeReference() { ref.removeReference(); }
00055 ReferenceCounter& ref;
00056 };
00057
00058
00059
00060
00061
00062 void StateNode::start() {
00063 if(started)
00064 return;
00065 started=true;
00066 ScopeReference ref(*this);
00067 postStateStart();
00068 #ifdef PLATFORM_APERIOS
00069 if ( !speechText.empty() )
00070 sout->printf("Speak: %s\n",speechText.c_str());
00071 #else
00072 if ( !speechText.empty() )
00073 sndman->speak(speechText);
00074 #endif
00075 if ( parent == NULL && transitions.size() > 0 )
00076 serr->printf("WARNING StateNode '%s' has transitions but no parent; you probably forgot to call addNode().\n",getName().c_str());
00077 if ( ! issetup ) {
00078 setup();
00079 issetup = true;
00080 }
00081
00082
00083
00084 for(std::vector<Transition*>::iterator it=transitions.begin(); it!=transitions.end(); it++) {
00085 if ( !(*it)->isActive() )
00086 (*it)->start();
00087 if(!isActive())
00088 return;
00089 }
00090 started=false;
00091 BehaviorBase::start();
00092 if ( isActive() && startnode )
00093 startnode->start();
00094 }
00095
00096 void StateNode::stop() {
00097 for(std::vector<Transition*>::iterator it=transitions.begin(); it!=transitions.end(); it++) {
00098 if((*it)->isActive())
00099 (*it)->stop();
00100 }
00101 for(std::vector<StateNode*>::iterator it=nodes.begin(); it!=nodes.end(); it++)
00102 if((*it)->isActive())
00103 (*it)->stop();
00104 if(!retain && issetup) {
00105 teardown();
00106 if(issetup) {
00107 serr->printf("WARNING %s doesn't seem to call StateNode::teardown() in its\n"
00108 " implementation of the function: issetup=%d, nodes.size()=%lu\n"
00109 " Attempting to recover...\n",getClassName().c_str(),issetup,(unsigned long)nodes.size());
00110 StateNode::teardown();
00111 }
00112 }
00113 postStateStop();
00114 BehaviorBase::stop();
00115 }
00116
00117 void StateNode::teardown() {
00118 for(std::vector<StateNode*>::iterator it=nodes.begin(); it!=nodes.end(); it++)
00119 (*it)->removeReference();
00120 startnode = NULL;
00121 nodes.clear();
00122 issetup=false;
00123
00124 }
00125
00126 void StateNode::postStateStart() {
00127 erouter->postEvent(EventBase::stateMachineEGID,reinterpret_cast<size_t>(this),EventBase::activateETID,0,getName(),1);
00128 }
00129
00130 void StateNode::postStateStop() {
00131 erouter->postEvent(EventBase::stateMachineEGID,reinterpret_cast<size_t>(this),EventBase::deactivateETID,get_time()-startedTime,getName(),0);
00132 }
00133
00134 void StateNode::postStateCompletion(float magnitude) {
00135 erouter->postEvent(EventBase::stateMachineEGID,reinterpret_cast<size_t>(this),EventBase::statusETID,get_time()-startedTime,getName(),magnitude);
00136 }
00137
00138
00139
00140
00141
00142
00143