BehaviorBase.cc
Go to the documentation of this file.00001 #include "BehaviorBase.h"
00002 #include "Events/EventRouter.h"
00003 #include "IPC/SharedObject.h"
00004 #include "Shared/string_util.h"
00005 #include "Motion/MotionManager.h"
00006 #include "Shared/MarkScope.h"
00007
00008 BehaviorBase::BehaviorBase()
00009 : ReferenceCounter(), EventListener(), autoMotions(), started(false), instanceName(), event(NULL)
00010 {
00011 getRegistryInstance().insert(this);
00012 }
00013
00014 BehaviorBase::BehaviorBase(const std::string& name)
00015 : ReferenceCounter(), EventListener(), autoMotions(), started(false), instanceName(name), event(NULL)
00016 {
00017 getRegistryInstance().insert(this);
00018 }
00019
00020 BehaviorBase::BehaviorBase(const BehaviorBase& b)
00021 : ReferenceCounter(b), EventListener(b), autoMotions(), started(b.started), instanceName(b.instanceName), event(NULL)
00022 {
00023 getRegistryInstance().insert(this);
00024 }
00025
00026 BehaviorBase&
00027 BehaviorBase::operator=(const BehaviorBase& b) {
00028 ReferenceCounter::operator=(b);
00029 EventListener::operator=(b);
00030 started=b.started;
00031 instanceName=b.instanceName;
00032 return *this;
00033 }
00034
00035 BehaviorBase::~BehaviorBase() {
00036 setAutoDelete(false);
00037 if(started)
00038 std::cerr << "Behavior " << getName() << " deleted while running: use 'removeReference', not 'delete'" << std::endl;
00039 if(erouter!=NULL)
00040 erouter->removeListener(this);
00041 autoMotions.clear();
00042 getRegistryInstance().erase(this);
00043 }
00044
00045 void
00046 BehaviorBase::start() {
00047
00048 if(!started) {
00049 started=true;
00050 addReference();
00051 try {
00052 preStart();
00053 if(started)
00054 doStart();
00055 if(started)
00056 postStart();
00057 } catch(...) {
00058
00059 bool prevAD = getAutoDelete();
00060 setAutoDelete(false);
00061 removeReference();
00062 setAutoDelete(prevAD);
00063 throw;
00064 }
00065 }
00066 }
00067
00068 void
00069 BehaviorBase::stop() {
00070
00071 if(started) {
00072 doStop();
00073 autoMotions.clear();
00074 started=false;
00075 erouter->remove(this);
00076 removeReference();
00077 }
00078 }
00079
00080 void BehaviorBase::processEvent(const EventBase& curEvent) {
00081 const EventBase* prevEvent = event;
00082 event=&curEvent;
00083 if(prevEvent==event) {
00084 std::cerr << "Warning: blocking recursive event posting of " << event->getDescription() << " to behavior " << getName() << std::endl;
00085 } else {
00086 doEvent();
00087 event=prevEvent;
00088 }
00089 }
00090
00091 void BehaviorBase::doEvent() {
00092 if(event->getGeneratorID()==EventBase::textmsgEGID && event->getSourceID()==1)
00093 erouter->postEvent(*event);
00094 }
00095
00096 std::string BehaviorBase::getClassName() const {
00097 return string_util::demangle(typeid(*this).name());
00098 }
00099
00100 std::set<BehaviorBase*>&
00101 BehaviorBase::getRegistryInstance() {
00102 static std::set<BehaviorBase*> registry;
00103 return registry;
00104 }
00105
00106 std::string
00107 BehaviorBase::humanifyClassName(const std::string& name) {
00108 std::string name2 = name;
00109 std::string name3;
00110 unsigned int rightEdge = name2.size();
00111 if ( rightEdge == 0 ) return name3;
00112 while ( !isalpha(name2[rightEdge-1]) && (--rightEdge > 0) );
00113 for(unsigned int i=0; i<rightEdge; ++i) {
00114
00115
00116
00117
00118
00119
00120
00121 if(!islower(name2[i]) && i>1 &&
00122 ( (i+1<rightEdge && islower(name2[i+1]) && isalpha(name2[i-1])) || islower(name2[i-1]) ))
00123 name3.append(1,' ');
00124 name3.append(1,name2[i]);
00125 }
00126 name3.append(name2.substr(rightEdge));
00127 return name3;
00128 }
00129
00130
00131
00132 BehaviorBase::MC_ID
00133 BehaviorBase::addMotion(const SharedObjectBase& mc, Prunability_t prune) {
00134 return addMotion(mc,prune,MotionManager::kStdPriority);
00135 }
00136
00137 BehaviorBase::MC_ID
00138 BehaviorBase::addMotion(const SharedObjectBase& mc, Prunability_t prune, float priority) {
00139 MotionManager::MC_ID mcid = MotionManager::invalid_MC_ID;
00140 if(prune==PERSISTENT)
00141 mcid = motman->addPersistentMotion(mc, priority);
00142 else if(prune==PRUNABLE)
00143 mcid = motman->addPrunableMotion(mc, priority);
00144 else
00145 throw std::runtime_error("Invalid prunability value for BehaviorBase::addMotion");
00146 if(mcid!=MotionManager::invalid_MC_ID)
00147 autoMotions[mcid].monitor(*this,mcid,mc.getRegion());
00148 return mcid;
00149 }
00150
00151 void
00152 BehaviorBase::removeMotion(MotionManager::MC_ID mcid) {
00153 autoMotions.erase(mcid);
00154 }
00155
00156 BehaviorBase::MonitorMotion::~MonitorMotion() {
00157 if(mcid!=MotionManager::invalid_MC_ID) {
00158 erouter->removeListener(this,EventBase::motmanEGID,mcid,EventBase::deactivateETID);
00159 motman->removeMotion(mcid);
00160 }
00161 if(mcregion!=NULL)
00162 mcregion->RemoveReference();
00163 }
00164 void BehaviorBase::MonitorMotion::monitor(BehaviorBase& parent, MotionManager::MC_ID mc_id, RCRegion* region) {
00165 owner=&parent; mcid=mc_id; mcregion=region;
00166 if(mcregion!=NULL)
00167 mcregion->AddReference();
00168 if(mcid!=MotionManager::invalid_MC_ID)
00169 erouter->addListener(this,EventBase::motmanEGID,mcid,EventBase::deactivateETID);
00170 }
00171 void BehaviorBase::MonitorMotion::processEvent(const EventBase&) {
00172
00173 MotionManager::MC_ID tmp = mcid;
00174 mcid=MotionManager::invalid_MC_ID;
00175 mcregion->RemoveReference();
00176 mcregion=NULL;
00177 owner->autoMotions.erase(tmp);
00178
00179 }
00180
00181
00182
00183
00184
00185
00186