Changeset 5935 for code/branches/pickup/src/libraries/core/BaseObject.cc
- Timestamp:
- Oct 13, 2009, 5:05:17 PM (15 years ago)
- Location:
- code/branches/pickup
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/pickup
- Property svn:mergeinfo changed
-
code/branches/pickup/src/libraries/core/BaseObject.cc
r5781 r5935 63 63 this->bVisible_ = true; 64 64 this->oldGametype_ = 0; 65 this->bRegisteredEventStates_ = false; 65 66 66 67 this->lastLoadedXMLElement_ = 0; 67 68 68 this->functorSetMainState_ = 0; 69 this->functorGetMainState_ = 0; 69 this->mainStateFunctor_ = 0; 70 70 71 71 this->setCreator(creator); … … 74 74 this->setFile(this->creator_->getFile()); 75 75 this->setNamespace(this->creator_->getNamespace()); 76 this->setScene(this->creator_->getScene() );76 this->setScene(this->creator_->getScene(), this->creator_->getSceneID()); 77 77 this->setGametype(this->creator_->getGametype()); 78 78 } … … 82 82 this->namespace_ = 0; 83 83 this->scene_ = 0; 84 this->sceneID_ = OBJECTID_UNKNOWN; 84 85 this->gametype_ = 0; 85 86 } … … 93 94 if (this->isInitialized()) 94 95 { 95 for (std::list<BaseObject*>::const_iterator it = this->events_.begin(); it != this->events_.end(); ++it) 96 (*it)->unregisterEventListener(this); 97 98 for (std::map<BaseObject*, std::string>::const_iterator it = this->eventListeners_.begin(); it != this->eventListeners_.end(); ++it) 99 it->first->removeEvent(this); 100 101 if (this->functorSetMainState_) 102 delete this->functorSetMainState_; 103 if (this->functorGetMainState_) 104 delete this->functorGetMainState_; 96 for (std::map<BaseObject*, std::string>::const_iterator it = this->eventSources_.begin(); it != this->eventSources_.end(); ) 97 this->removeEventSource((it++)->first); 98 99 for (std::set<BaseObject*>::const_iterator it = this->eventListeners_.begin(); it != this->eventListeners_.end(); ) 100 (*(it++))->removeEventSource(this); 101 102 for (std::map<std::string, EventState*>::const_iterator it = this->eventStates_.begin(); it != this->eventStates_.end(); ++it) 103 delete it->second; 105 104 } 106 105 } … … 110 109 @param xmlelement The XML-element 111 110 @param loading Loading (true) or saving (false) 112 @return The XML-element113 111 */ 114 112 void BaseObject::XMLPort(Element& xmlelement, XMLPort::Mode mode) … … 120 118 121 119 XMLPortObjectTemplate(BaseObject, Template, "templates", addTemplate, getTemplate, xmlelement, mode, Template*); 122 123 Element* events = xmlelement.FirstChildElement("events", false); 124 120 XMLPortObject(BaseObject, BaseObject, "eventlisteners", addEventListener, getEventListener, xmlelement, mode); 121 122 Element* events = 0; 123 if (mode == XMLPort::LoadObject || mode == XMLPort::ExpandObject) 124 events = xmlelement.FirstChildElement("events", false); 125 else if (mode == XMLPort::SaveObject) 126 {} 125 127 if (events) 126 { 127 std::list<std::string> eventnames; 128 129 if (mode == XMLPort::LoadObject || mode == XMLPort::ExpandObject) 130 { 131 for (ticpp::Iterator<ticpp::Element> child = events->FirstChildElement(false); child != child.end(); child++) 132 eventnames.push_back(child->Value()); 133 } 134 else if (mode == XMLPort::SaveObject) 135 { 136 for (std::map<std::string, XMLPortObjectContainer*>::const_iterator it = this->getIdentifier()->getXMLPortEventMapBegin(); it != this->getIdentifier()->getXMLPortEventMapEnd(); ++it) 137 eventnames.push_back(it->first); 138 } 139 140 for (std::list<std::string>::iterator it = eventnames.begin(); it != eventnames.end(); ++it) 141 { 142 std::string sectionname = (*it); 143 ExecutorMember<BaseObject>* loadexecutor = createExecutor(createFunctor(&BaseObject::addEvent), std::string( "BaseObject" ) + "::" + "addEvent"); 144 ExecutorMember<BaseObject>* saveexecutor = createExecutor(createFunctor(&BaseObject::getEvent), std::string( "BaseObject" ) + "::" + "getEvent"); 145 loadexecutor->setDefaultValue(1, sectionname); 146 147 XMLPortClassObjectContainer<BaseObject, BaseObject>* container = 0; 148 container = (XMLPortClassObjectContainer<BaseObject, BaseObject>*)(this->getIdentifier()->getXMLPortEventContainer(sectionname)); 149 if (!container) 150 { 151 container = new XMLPortClassObjectContainer<BaseObject, BaseObject>(sectionname, this->getIdentifier(), loadexecutor, saveexecutor, false, true); 152 this->getIdentifier()->addXMLPortEventContainer(sectionname, container); 153 } 154 container->port(this, *events, mode); 155 } 156 } 128 this->XMLEventPort(*events, mode); 129 } 130 131 /** 132 @brief Defines the possible event states of this object and parses eventsources from an XML file. 133 @param xmlelement The XML-element 134 @param loading Loading (true) or saving (false) 135 */ 136 void BaseObject::XMLEventPort(Element& xmlelement, XMLPort::Mode mode) 137 { 138 XMLPortEventState(BaseObject, BaseObject, "activity", setActive, xmlelement, mode); 139 XMLPortEventState(BaseObject, BaseObject, "visibility", setVisible, xmlelement, mode); 140 XMLPortEventState(BaseObject, BaseObject, "mainstate", setMainState, xmlelement, mode); 141 142 this->bRegisteredEventStates_ = true; 157 143 } 158 144 … … 220 206 } 221 207 222 void BaseObject::addEvent(BaseObject* event, const std::string& sectionname) 223 { 224 event->registerEventListener(this, sectionname); 225 this->events_.push_back(event); 226 } 227 228 void BaseObject::removeEvent(BaseObject* event) 229 { 230 this->events_.remove(event); 231 } 232 233 BaseObject* BaseObject::getEvent(unsigned int index) const 208 /** 209 @brief Adds a new event source for a specific state. 210 @param source The object which sends events to this object 211 @param state The state of this object which will be affected by the events 212 */ 213 void BaseObject::addEventSource(BaseObject* source, const std::string& state) 214 { 215 this->eventSources_[source] = state; 216 source->registerEventListener(this); 217 } 218 219 /** 220 @brief Removes an eventsource (but doesn't unregister itself at the source). 221 */ 222 void BaseObject::removeEventSource(BaseObject* source) 223 { 224 this->eventSources_.erase(source); 225 source->unregisterEventListener(this); 226 } 227 228 /** 229 @brief Returns an eventsource with a given index. 230 */ 231 BaseObject* BaseObject::getEventSource(unsigned int index, const std::string& state) const 234 232 { 235 233 unsigned int i = 0; 236 for (std::list<BaseObject*>::const_iterator it = this->events_.begin(); it != this->events_.end(); ++it) 237 { 234 for (std::map<BaseObject*, std::string>::const_iterator it = this->eventSources_.begin(); it != this->eventSources_.end(); ++it) 235 { 236 if (it->second != state) 237 continue; 238 238 239 if (i == index) 239 return (*it);240 return it->first; 240 241 ++i; 241 242 } … … 243 244 } 244 245 245 void BaseObject::addEventContainer(const std::string& sectionname, EventContainer* container) 246 { 247 std::map<std::string, EventContainer*>::const_iterator it = this->eventContainers_.find(sectionname); 248 if (it != this->eventContainers_.end()) 249 { 250 COUT(2) << "Warning: Overwriting EventContainer in class " << this->getIdentifier()->getName() << "." << std::endl; 246 /** 247 @brief Adds an object which listens to the events of this object. The events are sent to the other objects mainstate. 248 */ 249 void BaseObject::addEventListener(BaseObject* listener) 250 { 251 this->eventListenersXML_.insert(listener); 252 listener->addEventSource(this, "mainstate"); 253 } 254 255 /** 256 @brief Returns an event listener with a given index. 257 */ 258 BaseObject* BaseObject::getEventListener(unsigned int index) const 259 { 260 unsigned int i = 0; 261 for (std::set<BaseObject*>::const_iterator it = this->eventListenersXML_.begin(); it != this->eventListenersXML_.end(); ++it) 262 { 263 if (i == index) 264 return *it; 265 ++i; 266 } 267 return 0; 268 } 269 270 /** 271 @brief Adds a new event-state to the object. Event-states are states which can be changed by events. 272 @param name The name of the event 273 @param state The object containing information about the event-state 274 */ 275 void BaseObject::addEventState(const std::string& name, EventState* state) 276 { 277 std::map<std::string, EventState*>::const_iterator it = this->eventStates_.find(name); 278 if (it != this->eventStates_.end()) 279 { 280 COUT(2) << "Warning: Overwriting EventState in class " << this->getIdentifier()->getName() << "." << std::endl; 251 281 delete (it->second); 252 282 } 253 283 254 this->eventContainers_[sectionname] = container; 255 } 256 257 EventContainer* BaseObject::getEventContainer(const std::string& sectionname) const 258 { 259 std::map<std::string, EventContainer*>::const_iterator it = this->eventContainers_.find(sectionname); 260 if (it != this->eventContainers_.end()) 284 this->eventStates_[name] = state; 285 } 286 287 /** 288 @brief Returns the event-state with the given name. 289 */ 290 EventState* BaseObject::getEventState(const std::string& name) const 291 { 292 std::map<std::string, EventState*>::const_iterator it = this->eventStates_.find(name); 293 if (it != this->eventStates_.end()) 261 294 return ((*it).second); 262 295 else … … 264 297 } 265 298 266 void BaseObject::fireEvent() 267 { 268 this->fireEvent(true); 269 this->fireEvent(false); 270 } 271 272 void BaseObject::fireEvent(bool activate) 273 { 274 this->fireEvent(activate, this); 275 } 276 277 void BaseObject::fireEvent(bool activate, BaseObject* originator) 278 { 279 Event event(activate, originator); 280 281 for (std::map<BaseObject*, std::string>::iterator it = this->eventListeners_.begin(); it != this->eventListeners_.end(); ++it) 282 { 283 event.sectionname_ = it->second; 284 it->first->processEvent(event); 285 } 286 } 287 299 /** 300 @brief Fires an event (without a state). 301 */ 302 void BaseObject::fireEvent(const std::string& name) 303 { 304 this->fireEvent(true, name); 305 this->fireEvent(false, name); 306 } 307 308 /** 309 @brief Fires an event which activates or deactivates a state. 310 */ 311 void BaseObject::fireEvent(bool activate, const std::string& name) 312 { 313 this->fireEvent(activate, this, name); 314 } 315 316 /** 317 @brief Fires an event which activates or deactivates a state with agiven originator (the object which triggered the event). 318 */ 319 void BaseObject::fireEvent(bool activate, BaseObject* originator, const std::string& name) 320 { 321 Event event(activate, originator, name); 322 323 for (std::set<BaseObject*>::iterator it = this->eventListeners_.begin(); it != this->eventListeners_.end(); ++it) 324 { 325 event.statename_ = (*it)->eventSources_[this]; 326 (*it)->processEvent(event); 327 } 328 } 329 330 /** 331 @brief Fires an event, using the Event struct. 332 */ 288 333 void BaseObject::fireEvent(Event& event) 289 334 { 290 for (std::map<BaseObject*, std::string>::iterator it = this->eventListeners_.begin(); it != this->eventListeners_.end(); ++it) 291 it->first->processEvent(event); 292 } 293 335 for (std::set<BaseObject*>::iterator it = this->eventListeners_.begin(); it != this->eventListeners_.end(); ++it) 336 (*it)->processEvent(event); 337 } 338 339 /** 340 @brief Processing an event by calling the right main state. 341 @param event The event struct which contains the information about the event 342 */ 294 343 void BaseObject::processEvent(Event& event) 295 344 { 296 ORXONOX_SET_EVENT(BaseObject, "activity", setActive, event); 297 ORXONOX_SET_EVENT(BaseObject, "visibility", setVisible, event); 298 } 299 300 void BaseObject::setMainStateName(const std::string& name) 301 { 302 if (this->mainStateName_ != name) 303 { 304 this->mainStateName_ = name; 305 if (this->functorSetMainState_) 306 delete this->functorSetMainState_; 307 if (this->functorGetMainState_) 308 delete this->functorGetMainState_; 309 this->changedMainState(); 310 if (!this->functorSetMainState_) 311 COUT(2) << "Warning: \"" << name << "\" is not a valid MainState." << std::endl; 312 } 313 } 314 345 this->registerEventStates(); 346 347 std::map<std::string, EventState*>::const_iterator it = this->eventStates_.find(event.statename_); 348 if (it != this->eventStates_.end()) 349 it->second->process(event, this); 350 else if (event.statename_ != "") 351 COUT(2) << "Warning: \"" << event.statename_ << "\" is not a valid state in object \"" << this->getName() << "\" of class " << this->getIdentifier()->getName() << "." << std::endl; 352 else 353 COUT(2) << "Warning: Event with invalid source sent to object \"" << this->getName() << "\" of class " << this->getIdentifier()->getName() << "." << std::endl; 354 } 355 356 /** 357 @brief Sets the main state of the object to a given boolean value. 358 359 Note: The main state of an object can be set with the @ref setMainStateName function. 360 It's part of the eventsystem and used for event forwarding (when the target object can't specify a specific state, 361 the main state is used by default). 362 */ 315 363 void BaseObject::setMainState(bool state) 316 364 { 317 if (this->functorSetMainState_) 318 (*this->functorSetMainState_)(state); 365 if (this->mainStateFunctor_) 366 { 367 if (this->mainStateFunctor_->getParamCount() == 0) 368 { 369 if (state) 370 (*this->mainStateFunctor_)(); 371 } 372 else 373 { 374 (*this->mainStateFunctor_)(state); 375 } 376 } 319 377 else 320 378 COUT(2) << "Warning: No MainState defined in object \"" << this->getName() << "\" (" << this->getIdentifier()->getName() << ")" << std::endl; 321 379 } 322 380 323 bool BaseObject::getMainState() const 324 { 325 if (this->functorGetMainState_) 326 { 327 (*this->functorGetMainState_)(); 328 return this->functorGetMainState_->getReturnvalue(); 329 } 330 else 331 { 332 COUT(2) << "Warning: No MainState defined in object \"" << this->getName() << "\" (" << this->getIdentifier()->getName() << ")" << std::endl; 333 return false; 334 } 335 } 336 337 void BaseObject::changedMainState() 338 { 339 SetMainState(BaseObject, "activity", setActive, isActive); 340 SetMainState(BaseObject, "visibility", setVisible, isVisible); 381 /** 382 @brief This function gets called if the main state name of the object changes. 383 */ 384 void BaseObject::changedMainStateName() 385 { 386 this->mainStateFunctor_ = 0; 387 388 if (this->mainStateName_ != "") 389 { 390 this->registerEventStates(); 391 392 std::map<std::string, EventState*>::const_iterator it = this->eventStates_.find(this->mainStateName_); 393 if (it != this->eventStates_.end() && it->second->getFunctor()) 394 { 395 if (it->second->getFunctor()->getParamCount() <= 1) 396 this->mainStateFunctor_ = it->second->getFunctor(); 397 else 398 COUT(2) << "Warning: Can't use \"" << this->mainStateName_ << "\" as MainState because it needs a second argument." << std::endl; 399 } 400 else 401 COUT(2) << "Warning: \"" << this->mainStateName_ << "\" is not a valid MainState." << std::endl; 402 } 403 } 404 405 /** 406 @brief Calls XMLEventPort with an empty XML-element to register the event states if necessary. 407 */ 408 void BaseObject::registerEventStates() 409 { 410 if (!this->bRegisteredEventStates_) 411 { 412 Element xmlelement; 413 this->XMLEventPort(xmlelement, XMLPort::NOP); 414 } 415 } 416 417 /** 418 @brief Manually loads all event states, even if the class doesn't officially support them. This is needed by some classes like @ref EventDispatcher or @ref EventTarget. 419 */ 420 void BaseObject::loadAllEventStates(Element& xmlelement, XMLPort::Mode mode, BaseObject* object, Identifier* identifier) 421 { 422 Element* events = xmlelement.FirstChildElement("events", false); 423 if (events) 424 { 425 // get the list of all states present 426 std::list<std::string> eventnames; 427 if (mode == XMLPort::LoadObject || mode == XMLPort::ExpandObject) 428 { 429 for (ticpp::Iterator<ticpp::Element> child = events->FirstChildElement(false); child != child.end(); child++) 430 eventnames.push_back(child->Value()); 431 } 432 else if (mode == XMLPort::SaveObject) 433 { 434 } 435 436 // iterate through all states and get the event sources 437 for (std::list<std::string>::iterator it = eventnames.begin(); it != eventnames.end(); ++it) 438 { 439 std::string statename = (*it); 440 441 // if the event state is already known, continue with the next state 442 orxonox::EventState* eventstate = object->getEventState(statename); 443 if (eventstate) 444 continue; 445 446 XMLPortClassObjectContainer<BaseObject, BaseObject>* container = (XMLPortClassObjectContainer<BaseObject, BaseObject>*)(identifier->getXMLPortObjectContainer(statename)); 447 if (!container) 448 { 449 ExecutorMember<BaseObject>* setfunctor = createExecutor(createFunctor(&BaseObject::addEventSource), std::string( "BaseObject" ) + "::" + "addEventSource" + "(" + statename + ")"); 450 ExecutorMember<BaseObject>* getfunctor = createExecutor(createFunctor(&BaseObject::getEventSource), std::string( "BaseObject" ) + "::" + "getEventSource" + "(" + statename + ")"); 451 setfunctor->setDefaultValue(1, statename); 452 getfunctor->setDefaultValue(1, statename); 453 454 container = new XMLPortClassObjectContainer<BaseObject, BaseObject>(statename, identifier, setfunctor, getfunctor, false, true); 455 identifier->addXMLPortObjectContainer(statename, container); 456 } 457 container->port(object, *events, mode); 458 } 459 } 341 460 } 342 461 }
Note: See TracChangeset
for help on using the changeset viewer.