00001
00002 #ifndef INCLUDED_BehaviorSwitchControl_h_
00003 #define INCLUDED_BehaviorSwitchControl_h_
00004
00005 #include "ControlBase.h"
00006 #include "Behaviors/BehaviorBase.h"
00007 #include "Shared/ReferenceCounter.h"
00008 #include "Shared/Factories.h"
00009 #include "Shared/debuget.h"
00010 #include "Events/TextMsgEvent.h"
00011
00012
00013 class BehaviorSwitchControlBase : public ControlBase {
00014 public:
00015
00016
00017
00018
00019
00020
00021
00022 class BehaviorGroup : public ReferenceCounter {
00023 public:
00024 BehaviorGroup() : curBehavior(NULL), members() { }
00025 ~BehaviorGroup() { if(curBehavior!=NULL) curBehavior->DoStop(); }
00026 BehaviorBase * curBehavior;
00027 std::set<BehaviorSwitchControlBase*> members;
00028 private:
00029 BehaviorGroup(const BehaviorGroup&);
00030 BehaviorGroup operator=(const BehaviorGroup&);
00031 };
00032
00033
00034 BehaviorSwitchControlBase(const std::string& n, BehaviorBase* beh, BehaviorGroup* bg=NULL)
00035 : ControlBase(n), behgrp(bg), mybeh(beh) {
00036 if(mybeh!=NULL) {
00037 mybeh->AddReference();
00038 mybeh->setName(n);
00039 if(mybeh->isActive())
00040 mybeh->AddReference();
00041 }
00042 if(behgrp!=NULL) {
00043 behgrp->AddReference();
00044 behgrp->members.insert(this);
00045 if(mybeh!=NULL && mybeh->isActive()) {
00046 if(behgrp->curBehavior!=NULL) {
00047 behgrp->curBehavior->DoStop();
00048 notifyGroupMembers();
00049 }
00050 behgrp->curBehavior=mybeh;
00051 }
00052 }
00053 }
00054
00055 BehaviorSwitchControlBase(BehaviorBase* beh, BehaviorGroup* bg=NULL)
00056 : ControlBase(beh->getName()), behgrp(bg), mybeh(beh) {
00057 mybeh->AddReference();
00058 if(mybeh->isActive())
00059 mybeh->AddReference();
00060 if(behgrp!=NULL) {
00061 behgrp->AddReference();
00062 behgrp->members.insert(this);
00063 if(mybeh!=NULL && mybeh->isActive()) {
00064 if(behgrp->curBehavior!=NULL) {
00065 behgrp->curBehavior->DoStop();
00066 notifyGroupMembers();
00067 }
00068 behgrp->curBehavior=mybeh;
00069 }
00070 }
00071 }
00072
00073
00074 virtual ~BehaviorSwitchControlBase() {
00075
00076 if(mybeh!=NULL)
00077 stop();
00078 if(behgrp!=NULL) {
00079 behgrp->members.erase(this);
00080 behgrp->RemoveReference();
00081 behgrp=NULL;
00082 }
00083 if(mybeh!=NULL)
00084 mybeh->RemoveReference();
00085 }
00086
00087
00088
00089 virtual BehaviorSwitchControlBase* start() { if(!isRunning()) { stopother(); startmine(); } return this; }
00090
00091
00092 virtual BehaviorSwitchControlBase* stop() { if(isRunning()) stopother(); return this; }
00093
00094
00095 virtual BehaviorSwitchControlBase* toggle() { if(isRunning()) stopother(); else { stopother(); startmine(); } return this; }
00096
00097 virtual ControlBase * takeInput(const std::string& msg) {
00098 if(options.size()>0)
00099 return ControlBase::takeInput(msg);
00100 if(!isRunning())
00101 startmine();
00102 mybeh->processEvent(TextMsgEvent(msg,1));
00103 return NULL;
00104 }
00105
00106
00107
00108 virtual ControlBase * activate(MotionManager::MC_ID display, Socket * gui) {
00109 if(slotsSize()==0) {
00110 toggle();
00111 return NULL;
00112 } else
00113 return ControlBase::activate(display,gui);
00114 }
00115
00116
00117 virtual std::string getName() const {
00118 if(mybeh==NULL)
00119 return ControlBase::getName();
00120 return (mybeh->isActive()?'#':'-')+mybeh->getName();
00121 }
00122 virtual std::string getDescription() const {
00123 if(mybeh==NULL)
00124 return ControlBase::getDescription();
00125 return "Class "+mybeh->getClassName()+": "+mybeh->getDescription();
00126 }
00127
00128
00129 virtual bool isRunning() const {
00130 if(mybeh==NULL)
00131 return false;
00132
00133 return mybeh->isActive();
00134 }
00135
00136 protected:
00137
00138 virtual void stopother() {
00139 if(behgrp==NULL) {
00140 if(mybeh!=NULL && mybeh->isActive()) {
00141 mybeh->DoStop();
00142 behaviorStopped();
00143 }
00144 } else if(behgrp->curBehavior!=NULL) {
00145 if(behgrp->curBehavior->isActive()) {
00146 behgrp->curBehavior->DoStop();
00147 notifyGroupMembers();
00148 }
00149 behgrp->curBehavior=NULL;
00150 }
00151 }
00152
00153
00154 virtual void startmine() {
00155 if(behgrp!=NULL)
00156 behgrp->curBehavior=mybeh;
00157 mybeh->DoStart();
00158 }
00159
00160
00161 virtual void notifyGroupMembers() {
00162 for(std::set<BehaviorSwitchControlBase*>::iterator it=behgrp->members.begin(); it!=behgrp->members.end(); ++it)
00163 if((*it)->mybeh==behgrp->curBehavior)
00164 (*it)->behaviorStopped();
00165 }
00166
00167 virtual void behaviorStopped() {}
00168
00169 BehaviorGroup * behgrp;
00170 BehaviorBase* mybeh;
00171
00172 private:
00173 BehaviorSwitchControlBase(const BehaviorSwitchControlBase&);
00174 BehaviorSwitchControlBase operator=(const BehaviorSwitchControlBase&);
00175 };
00176
00177
00178
00179
00180
00181 template < class B, class Al = typename Factory0Arg<B>::template Factory<B> >
00182 class BehaviorSwitchControl : public BehaviorSwitchControlBase {
00183 public:
00184
00185 BehaviorSwitchControl(const std::string& n, bool retain=false)
00186 : BehaviorSwitchControlBase(n,NULL,NULL), retained(retain), startref(NULL)
00187 {}
00188
00189 BehaviorSwitchControl(B* beh, BehaviorGroup* bg=NULL)
00190 : BehaviorSwitchControlBase(beh,bg), retained(true), startref(NULL)
00191 {}
00192
00193 BehaviorSwitchControl(const std::string& n, B* beh, BehaviorGroup* bg=NULL, bool retain=false)
00194 : BehaviorSwitchControlBase(n,beh,bg), retained(retain), startref(NULL)
00195 {
00196 if(!retained) {
00197
00198 if(!mybeh->isActive()) {
00199 startmine();
00200 }
00201 mybeh->RemoveReference();
00202 }
00203 }
00204
00205 BehaviorSwitchControl(const std::string& n, BehaviorGroup* bg, bool retain=false)
00206 : BehaviorSwitchControlBase(n,NULL,bg), retained(retain), startref(NULL)
00207 {}
00208
00209
00210 virtual ~BehaviorSwitchControl() {
00211 stop();
00212 if(behgrp!=NULL) {
00213 behgrp->members.erase(this);
00214 behgrp->RemoveReference();
00215 behgrp=NULL;
00216 }
00217 if(mybeh!=NULL && retained)
00218 mybeh->RemoveReference();
00219 mybeh=NULL;
00220 }
00221
00222 virtual std::string getName() const {
00223 if(!isValid())
00224 return ControlBase::getName();
00225 else
00226 return BehaviorSwitchControlBase::getName();
00227 }
00228 virtual std::string getDescription() const {
00229 if(!isValid() || mybeh->getDescription().size()==0)
00230 return B::getClassDescription();
00231 else
00232 return BehaviorSwitchControlBase::getDescription();
00233 }
00234
00235 protected:
00236
00237 virtual void startmine() {
00238 if(!retained) {
00239 Al allocator;
00240 mybeh=allocator();
00241 mybeh->setName(getName());
00242 if(behgrp!=NULL)
00243 behgrp->curBehavior=mybeh;
00244 } else {
00245 if(mybeh==NULL) {
00246 Al allocator;
00247 mybeh=allocator();
00248 mybeh->setName(getName());
00249 mybeh->AddReference();
00250 }
00251 if(behgrp!=NULL)
00252 behgrp->curBehavior=mybeh;
00253 }
00254 startref=mybeh;
00255 startref->AddReference();
00256 mybeh->DoStart();
00257 }
00258
00259
00260 virtual bool isRunning() const {
00261 if(BehaviorSwitchControlBase::isRunning())
00262 return true;
00263 else if(startref!=NULL)
00264 const_cast<BehaviorSwitchControl<B,Al>*>(this)->stopother();
00265 return false;
00266 }
00267
00268
00269 virtual bool isValid() const {
00270 if(isRunning())
00271 return true;
00272 return retained;
00273 }
00274
00275 virtual void behaviorStopped() {
00276 if(!retained)
00277 mybeh=NULL;
00278 if(startref!=NULL) {
00279 startref->RemoveReference();
00280 startref=NULL;
00281 }
00282 }
00283
00284 bool retained;
00285 BehaviorBase * startref;
00286
00287 private:
00288 BehaviorSwitchControl(const BehaviorSwitchControl&);
00289 BehaviorSwitchControl operator=(const BehaviorSwitchControl&);
00290 };
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303 #endif