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/Factory.h"
00009 #include "Shared/debuget.h"
00010
00011
00012 class BehaviorSwitchControlBase : public ControlBase {
00013 public:
00014
00015
00016
00017
00018
00019
00020
00021 class BehaviorGroup : public ReferenceCounter {
00022 public:
00023 BehaviorGroup() : curBehavior(NULL) { }
00024 ~BehaviorGroup() { if(curBehavior!=NULL) curBehavior->DoStop(); }
00025 BehaviorBase * curBehavior;
00026 private:
00027 BehaviorGroup(const BehaviorGroup&);
00028 BehaviorGroup operator=(const BehaviorGroup&);
00029 };
00030
00031
00032 BehaviorSwitchControlBase(const std::string& n, BehaviorBase* beh, BehaviorGroup* bg=NULL)
00033 : ControlBase(n), behgrp(bg), mybeh(beh) {
00034 if(behgrp!=NULL)
00035 behgrp->AddReference();
00036 if(mybeh!=NULL)
00037 mybeh->AddReference();
00038 }
00039
00040 BehaviorSwitchControlBase(BehaviorBase* beh, BehaviorGroup* bg=NULL)
00041 : ControlBase(), behgrp(bg), mybeh(beh) {
00042 if(behgrp!=NULL)
00043 behgrp->AddReference();
00044 mybeh->AddReference();
00045 }
00046
00047
00048 virtual ~BehaviorSwitchControlBase() {
00049 if(mybeh!=NULL)
00050 stop();
00051 if(behgrp!=NULL) {
00052 behgrp->RemoveReference();
00053 behgrp=NULL;
00054 }
00055 if(mybeh!=NULL)
00056 mybeh->RemoveReference();
00057 }
00058
00059
00060
00061 virtual BehaviorSwitchControlBase* start() { if(!isRunning()) { stopother(); startmine(); } return this; }
00062
00063
00064 virtual BehaviorSwitchControlBase* stop() { if(isRunning()) stopother(); return this; }
00065
00066
00067 virtual BehaviorSwitchControlBase* toggle() { if(isRunning()) stopother(); else { stopother(); startmine(); } return this; }
00068
00069
00070
00071 virtual ControlBase * activate(MotionManager::MC_ID display, Socket * gui) {
00072 if(slotsSize()==0) {
00073 toggle();
00074 return NULL;
00075 } else
00076 return ControlBase::activate(display,gui);
00077 }
00078
00079
00080 virtual std::string getName() const {
00081 return (mybeh->isActive()?'#':'-')+mybeh->getName();
00082 }
00083 virtual std::string getDescription() const {
00084 return mybeh->getDescription();
00085 }
00086
00087 protected:
00088
00089 virtual void stopother() {
00090 if(behgrp==NULL) {
00091 if(mybeh->isActive())
00092 mybeh->DoStop();
00093 } else if(behgrp->curBehavior!=NULL) {
00094 behgrp->curBehavior->DoStop();
00095 behgrp->curBehavior=NULL;
00096 }
00097 }
00098
00099
00100 virtual void startmine() {
00101 if(behgrp!=NULL)
00102 behgrp->curBehavior=mybeh;
00103 mybeh->DoStart();
00104 }
00105
00106
00107 virtual bool isRunning() const {
00108 if(mybeh==NULL)
00109 return false;
00110
00111 if(behgrp==NULL)
00112 return mybeh->isActive();
00113
00114 return (behgrp->curBehavior==mybeh);
00115 }
00116
00117 BehaviorGroup * behgrp;
00118 BehaviorBase* mybeh;
00119
00120 private:
00121 BehaviorSwitchControlBase(const BehaviorSwitchControlBase&);
00122 BehaviorSwitchControlBase operator=(const BehaviorSwitchControlBase&);
00123 };
00124
00125
00126
00127
00128
00129 template < class B, class Al = Factory< B > >
00130 class BehaviorSwitchControl : public BehaviorSwitchControlBase {
00131 public:
00132
00133 BehaviorSwitchControl(const std::string& n, bool retain=false)
00134 : BehaviorSwitchControlBase(n,NULL,NULL), retained(retain)
00135 {}
00136
00137 BehaviorSwitchControl(B* beh, BehaviorGroup* bg=NULL)
00138 : BehaviorSwitchControlBase(beh,bg), retained(true)
00139 {}
00140
00141 BehaviorSwitchControl(const std::string& n, B* beh, BehaviorGroup* bg=NULL, bool retain=false)
00142 : BehaviorSwitchControlBase(n,beh,bg), retained(retain)
00143 {
00144 if(!retained) {
00145
00146 if(!mybeh->isActive()) {
00147
00148 mybeh->DoStart();
00149 bool stopped=!mybeh->isActive();
00150 mybeh->RemoveReference();
00151 if(stopped)
00152 mybeh=NULL;
00153 } else
00154 mybeh->RemoveReference();
00155 }
00156 if(behgrp!=NULL) {
00157 if(mybeh->isActive()) {
00158 if(behgrp->curBehavior!=NULL)
00159 behgrp->curBehavior->DoStop();
00160 behgrp->curBehavior=mybeh;
00161 } else if(!retained) {
00162 if(behgrp->curBehavior!=NULL)
00163 behgrp->curBehavior->DoStop();
00164 behgrp->curBehavior=NULL;
00165 }
00166 }
00167 }
00168
00169 BehaviorSwitchControl(const std::string& n, BehaviorGroup* bg, bool retain=false)
00170 : BehaviorSwitchControlBase(n,NULL,bg), retained(retain)
00171 {}
00172
00173
00174 virtual ~BehaviorSwitchControl() {
00175 stop();
00176 if(behgrp!=NULL) {
00177 behgrp->RemoveReference();
00178 behgrp=NULL;
00179 }
00180 if(mybeh!=NULL && retained)
00181 mybeh->RemoveReference();
00182 mybeh=NULL;
00183 }
00184
00185 virtual std::string getName() const {
00186 if(!isValid())
00187 return ControlBase::getName();
00188 else
00189 return BehaviorSwitchControlBase::getName();
00190 }
00191 virtual std::string getDescription() const {
00192 if(!isValid() || mybeh->getDescription().size()==0)
00193 return B::getClassDescription();
00194 else
00195 return BehaviorSwitchControlBase::getDescription();
00196 }
00197
00198
00199 protected:
00200
00201 virtual void stopother() {
00202 if(behgrp==NULL) {
00203 if(mybeh!=NULL) {
00204 if(mybeh->isActive()) {
00205 mybeh->DoStop();
00206 if(!retained)
00207 mybeh=NULL;
00208 } else
00209 ASSERT(retained,"null group, non-null not retained beh, not active, did you call inherited DoStart/DoStop in your Behavior?");
00210 }
00211 } else if(behgrp->curBehavior!=NULL) {
00212 behgrp->curBehavior->DoStop();
00213 if(behgrp->curBehavior==mybeh)
00214 mybeh=NULL;
00215 behgrp->curBehavior=NULL;
00216 }
00217 }
00218
00219 virtual void startmine() {
00220 if(!retained) {
00221 mybeh=Al::construct();
00222 if(behgrp!=NULL)
00223 behgrp->curBehavior=mybeh;
00224 } else {
00225 if(mybeh==NULL) {
00226 mybeh=Al::construct();
00227 mybeh->AddReference();
00228 }
00229 if(behgrp!=NULL)
00230 behgrp->curBehavior=mybeh;
00231 }
00232 mybeh->AddReference();
00233 mybeh->DoStart();
00234 bool stopped=(!mybeh->isActive() && !retained);
00235 mybeh->RemoveReference();
00236 if(stopped) {
00237 if(behgrp!=NULL && behgrp->curBehavior==mybeh)
00238 behgrp->curBehavior=NULL;
00239 mybeh=NULL;
00240 }
00241 }
00242
00243
00244 virtual bool isValid() const {
00245 if(isRunning())
00246 return true;
00247 return retained;
00248 }
00249
00250 private:
00251 bool retained;
00252 BehaviorSwitchControl(const BehaviorSwitchControl&);
00253 BehaviorSwitchControl operator=(const BehaviorSwitchControl&);
00254 };
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267 #endif