Changeset 7601 for code/trunk/src/modules/objects/triggers/MultiTrigger.cc
- Timestamp:
- Oct 30, 2010, 1:54:49 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
code/trunk/src/modules/objects/triggers/MultiTrigger.cc
r7301 r7601 30 30 @file MultiTrigger.cc 31 31 @brief Implementation of the MultiTrigger class. 32 @ingroup MultiTrigger 32 33 */ 33 34 … … 41 42 namespace orxonox 42 43 { 43 44 // Initialization of some static (magic) variables.45 /*static*/ const int MultiTrigger::INF_s = -1;46 /*static*/ const std::string MultiTrigger::and_s = "and";47 /*static*/ const std::string MultiTrigger::or_s = "or";48 /*static*/ const std::string MultiTrigger::xor_s = "xor";49 44 50 45 CreateFactory(MultiTrigger); … … 56 51 The creator. 57 52 */ 58 MultiTrigger::MultiTrigger(BaseObject* creator) : StaticEntity(creator)53 MultiTrigger::MultiTrigger(BaseObject* creator) : TriggerBase(creator) 59 54 { 60 55 RegisterObject(MultiTrigger); 61 56 62 this->bFirstTick_ = true;63 64 this->delay_ = 0.0f;65 this->bSwitch_ = false;66 this->bStayActive_ = false;67 68 this->remainingActivations_ = INF_s;69 57 this->maxNumSimultaneousTriggerers_ = INF_s; 70 58 71 this->bInvertMode_ = false;72 this->mode_ = MultiTriggerMode::EventTriggerAND;73 74 59 this->bBroadcast_ = false; 75 60 76 this->parentTrigger_ = NULL;77 78 61 this->targetMask_.exclude(Class(BaseObject)); 62 63 this->bMultiTrigger_ = true; 79 64 80 65 this->setSyncMode(0x0); … … 105 90 SUPER(MultiTrigger, XMLPort, xmlelement, mode); 106 91 107 XMLPortParam(MultiTrigger, "delay", setDelay, getDelay, xmlelement, mode);108 XMLPortParam(MultiTrigger, "switch", setSwitch, getSwitch, xmlelement, mode);109 XMLPortParam(MultiTrigger, "stayactive", setStayActive, getStayActive, xmlelement, mode);110 XMLPortParam(MultiTrigger, "activations", setActivations, getActivations, xmlelement, mode);111 92 XMLPortParam(MultiTrigger, "simultaneousTriggerers", setSimultaneousTriggerers, getSimultaneousTriggerers, xmlelement, mode); 112 XMLPortParam(MultiTrigger, "invert", setInvert, getInvert, xmlelement, mode);113 XMLPortParamTemplate(MultiTrigger, "mode", setMode, getModeString, xmlelement, mode, const std::string&);114 93 XMLPortParam(MultiTrigger, "broadcast", setBroadcast, getBroadcast, xmlelement, mode); 115 94 XMLPortParamLoadOnly(MultiTrigger, "target", addTargets, xmlelement, mode).defaultValues("Pawn"); //TODO: Remove load only 116 95 117 XMLPortObject(MultiTrigger, MultiTrigger, "", addTrigger, getTrigger, xmlelement, mode);118 119 96 COUT(4) << "MultiTrigger '" << this->getName() << "' (&" << this << ") created." << std::endl; 120 97 } … … 124 101 @brief 125 102 A method that is executed each tick. 103 Most of the magic of MultiTriggers happens here. 126 104 @param dt 127 105 The duration of the last tick. 128 106 */ 107 //TODO: Segment into some helper methods? 129 108 void MultiTrigger::tick(float dt) 130 109 { … … 159 138 160 139 // The new triggered state dependent on the requested state, the mode and the invert-mode. 161 bool bTriggered = (state->bTriggered & this->isModeTriggered(state->originator)) ^ this-> bInvertMode_;140 bool bTriggered = (state->bTriggered & this->isModeTriggered(state->originator)) ^ this->getInvert(); 162 141 163 142 // If the 'triggered' state has changed or the MultiTrigger has delay and thus we don't know whether this state will actually change the 'triggered' state, a new state is added to the state queue. 164 if(this-> delay_> 0.0f || bTriggered ^ this->isTriggered(state->originator))143 if(this->getDelay() > 0.0f || bTriggered ^ this->isTriggered(state->originator)) 165 144 { 166 145 state->bTriggered = bTriggered; … … 192 171 { 193 172 // If the maximum number of objects simultaneously triggering this MultiTrigger is not exceeded. 194 if(this-> maxNumSimultaneousTriggerers_ == INF_s || this->triggered_.size() < (unsigned int)this->maxNumSimultaneousTriggerers_)173 if(this->getSimultaneousTriggerers() == TriggerBase::INF_s || this->triggered_.size() < (unsigned int)this->getSimultaneousTriggerers()) 195 174 { 196 175 bool bStateChanged = false; … … 211 190 bool bActive; 212 191 // If the MultiTrigger is in switch mode the 'active'-state only changes of the state changed to triggered. 213 if(this-> bSwitch_&& !state->bTriggered)192 if(this->getSwitch() && !state->bTriggered) 214 193 bActive = this->isActive(state->originator); 215 194 else … … 239 218 { 240 219 // If the MultiTrigger doesn't stay active or hasn't' exceeded its remaining activations. 241 if(!this-> bStayActive_|| this->remainingActivations_ > 0)220 if(!this->getStayActive() || this->remainingActivations_ > 0) 242 221 this->active_.erase(state->originator); 243 222 else … … 249 228 { 250 229 // If the MultiTrigger is set to broadcast and has no originator a boradcast is fired. 251 if(this-> bBroadcast_&& state->originator == NULL)230 if(this->getBroadcast() && state->originator == NULL) 252 231 this->broadcast(bActive); 253 232 // Else a normal event is fired. … … 267 246 COUT(4) << "MultiTrigger '" << this->getName() << "' (&" << this << ") changed state. originator: NULL, active: " << bActive << ", triggered: " << state->bTriggered << "." << std::endl; 268 247 269 // If the MultiTrigger has a parent trigger it needs to call a method to notify him, that its activity has changed.270 if(this->parent Trigger_ != NULL)271 this->parentTrigger_->subTriggerActivityChanged(state->originator);248 // If the MultiTrigger has a parent trigger, that is itself a MultiTrigger, it needs to call a method to notify him, that its activity has changed. 249 if(this->parent_ != NULL && this->parent_->isMultiTrigger()) 250 static_cast<MultiTrigger*>(this->parent_)->childActivityChanged(state->originator); 272 251 } 273 252 … … 302 281 Returns true if the MultiTrigger is active, false if not. 303 282 */ 304 bool MultiTrigger::isActive(BaseObject* triggerer) 305 { 306 std::set<BaseObject*>:: iterator it = this->active_.find(triggerer);283 bool MultiTrigger::isActive(BaseObject* triggerer) const 284 { 285 std::set<BaseObject*>::const_iterator it = this->active_.find(triggerer); 307 286 if(it == this->active_.end()) 308 287 return false; 309 288 return true; 310 }311 312 /**313 @brief314 Set the mode of the MultiTrigger.315 @param modeName316 The name of the mode as a string.317 */318 void MultiTrigger::setMode(const std::string& modeName)319 {320 if (modeName == MultiTrigger::and_s)321 this->setMode(MultiTriggerMode::EventTriggerAND);322 else if (modeName == MultiTrigger::or_s)323 this->setMode(MultiTriggerMode::EventTriggerOR);324 else if (modeName == MultiTrigger::xor_s)325 this->setMode(MultiTriggerMode::EventTriggerXOR);326 else327 COUT(2) << "Invalid mode '" << modeName << "' in MultiTrigger " << this->getName() << " &(" << this << "). Leaving mode at '" << this->getModeString() << "'." << std::endl;328 }329 330 /**331 @brief332 Get the mode of the MultiTrigger.333 @return334 Returns the mode as a string.335 */336 const std::string& MultiTrigger::getModeString() const337 {338 if (this->mode_ == MultiTriggerMode::EventTriggerAND)339 return MultiTrigger::and_s;340 else if (this->mode_ == MultiTriggerMode::EventTriggerOR)341 return MultiTrigger::or_s;342 else if (this->mode_ == MultiTriggerMode::EventTriggerXOR)343 return MultiTrigger::xor_s;344 else // This can never happen, but the compiler needs it to feel secure.345 return MultiTrigger::and_s;346 289 } 347 290 … … 397 340 /** 398 341 @brief 399 Adds a MultiTrigger as a sub-trigger to the trigger.400 Beware: Loops are not prevented and potentially very bad, so just don't create any loops.401 @param trigger402 The MultiTrigger to be added.403 */404 void MultiTrigger::addTrigger(MultiTrigger* trigger)405 {406 if (this != trigger && trigger != NULL)407 this->subTriggers_.insert(trigger);408 trigger->addParentTrigger(this);409 }410 411 /**412 @brief413 Get the sub-trigger of this MultiTrigger at the given index.414 @param index415 The index.416 @return417 Returns a pointer ot the MultiTrigger. NULL if no such trigger exists.418 */419 const MultiTrigger* MultiTrigger::getTrigger(unsigned int index) const420 {421 // If the index is greater than the number of sub-triggers.422 if (this->subTriggers_.size() <= index)423 return NULL;424 425 std::set<MultiTrigger*>::const_iterator it;426 it = this->subTriggers_.begin();427 428 for (unsigned int i = 0; i != index; ++i)429 ++it;430 431 return (*it);432 }433 434 /**435 @brief436 342 This method is called by the MultiTrigger to get information about new trigger events that need to be looked at. 437 343 This method is the device for the behavior (the conditions under which the MultiTrigger triggers) of any derived class of MultiTrigger. … … 456 362 { 457 363 MultiTriggerState* state = new MultiTriggerState; 458 state->bTriggered = (!this->isTriggered(originator) & this->isModeTriggered(originator)) ^ this-> bInvertMode_;364 state->bTriggered = (!this->isTriggered(originator) & this->isModeTriggered(originator)) ^ this->getInvert(); 459 365 state->originator = originator; 460 366 this->addState(state); … … 463 369 /** 464 370 @brief 465 This method is called by any sub-trigger to advertise changes in its state to its parent-trigger.371 This method is called by any child to advertise changes in its state to its parent. 466 372 @param originator 467 373 The object that caused the change in activity. 468 374 */ 469 void MultiTrigger:: subTriggerActivityChanged(BaseObject* originator)375 void MultiTrigger::childActivityChanged(BaseObject* originator) 470 376 { 471 377 MultiTriggerState* state = new MultiTriggerState; 472 state->bTriggered = (this->isTriggered(originator) & this->isModeTriggered(originator)) ^ this-> bInvertMode_;378 state->bTriggered = (this->isTriggered(originator) & this->isModeTriggered(originator)) ^ this->getInvert(); 473 379 state->originator = originator; 474 380 this->addState(state); … … 477 383 /** 478 384 @brief 479 Checks whether the sub-triggers are in such a way that, according to the mode of the MultiTrigger, the MultiTrigger is triggered (only considering the sub-triggers, not the state of MultiTrigger itself), for a given object.480 To make an example: When the mode is 'and', then this would be true or a given object if all the sub-triggerswere triggered for the given object.385 Checks whether the children are in such a way that, according to the mode of the MultiTrigger, the MultiTrigger is triggered (only considering the children, not the state of MultiTrigger itself), for a given object. 386 To make an example: When the mode is <em>and</em>, then this would be true or a given object if all the children were triggered for the given object. 481 387 @param triggerer 482 388 The object. 483 389 @return 484 Returns true if the MultiTrigger is triggered concerning it's sub-triggers.390 Returns true if the MultiTrigger is triggered concerning it's children. 485 391 */ 486 392 bool MultiTrigger::isModeTriggered(BaseObject* triggerer) 487 393 { 488 if(this-> subTriggers_.size() != 0)489 { 490 bool returnVal= false;394 if(this->children_.size() != 0) 395 { 396 bool triggered = false; 491 397 492 398 switch(this->mode_) 493 399 { 494 case MultiTriggerMode::EventTriggerAND:495 returnVal= checkAnd(triggerer);400 case TriggerMode::EventTriggerAND: 401 triggered = checkAnd(triggerer); 496 402 break; 497 case MultiTriggerMode::EventTriggerOR:498 returnVal= checkOr(triggerer);403 case TriggerMode::EventTriggerOR: 404 triggered = checkOr(triggerer); 499 405 break; 500 case MultiTriggerMode::EventTriggerXOR:501 returnVal= checkXor(triggerer);406 case TriggerMode::EventTriggerXOR: 407 triggered = checkXor(triggerer); 502 408 break; 503 409 default: // This will never happen. 504 returnVal= false;410 triggered = false; 505 411 break; 506 412 } 507 413 508 return returnVal;414 return triggered; 509 415 } 510 416 … … 585 491 586 492 // Add it ot the state queue with the delay specified for the MultiTrigger. 587 this->stateQueue_.push_back(std::pair<float, MultiTriggerState*>(this-> delay_, state));493 this->stateQueue_.push_back(std::pair<float, MultiTriggerState*>(this->getDelay(), state)); 588 494 589 495 return true; … … 592 498 /** 593 499 @brief 594 Checks whether the sub-triggers amount to true for the 'and'mode for a given object.500 Checks whether the children amount to true for the <em>and</em> mode for a given object. 595 501 @param triggerer 596 502 The object. … … 600 506 bool MultiTrigger::checkAnd(BaseObject* triggerer) 601 507 { 602 for(std::set<MultiTrigger*>::iterator it = this->subTriggers_.begin(); it != this->subTriggers_.end(); ++it) 603 { 604 if(!(*it)->isActive(triggerer)) 605 return false; 508 for(std::set<TriggerBase*>::iterator it = this->children_.begin(); it != this->children_.end(); ++it) 509 { 510 TriggerBase* trigger = *it; 511 if(trigger->isMultiTrigger()) 512 { 513 if(!static_cast<MultiTrigger*>(trigger)->isActive(triggerer)) 514 return false; 515 } 516 else 517 { 518 if(!trigger->isActive()) 519 return false; 520 } 606 521 } 607 522 return true; … … 610 525 /** 611 526 @brief 612 Checks whether the sub-triggers amount to true for the 'or'mode for a given object.527 Checks whether the children amount to true for the <em>or</em> mode for a given object. 613 528 @param triggerer 614 529 The object. … … 618 533 bool MultiTrigger::checkOr(BaseObject* triggerer) 619 534 { 620 for(std::set<MultiTrigger*>::iterator it = this->subTriggers_.begin(); it != this->subTriggers_.end(); ++it) 621 { 622 if((*it)->isActive(triggerer)) 623 return true; 535 for(std::set<TriggerBase*>::iterator it = this->children_.begin(); it != this->children_.end(); ++it) 536 { 537 TriggerBase* trigger = *it; 538 if(trigger->isMultiTrigger()) 539 { 540 if(static_cast<MultiTrigger*>(trigger)->isActive(triggerer)) 541 return true; 542 } 543 else 544 { 545 if(trigger->isActive()) 546 return true; 547 } 624 548 } 625 549 return false; … … 628 552 /** 629 553 @brief 630 Checks whether the sub-triggers amount to true for the 'xor'mode for a given object.554 Checks whether the children amount to true for the <em>xor</em> mode for a given object. 631 555 @param triggerer 632 556 The object. … … 636 560 bool MultiTrigger::checkXor(BaseObject* triggerer) 637 561 { 638 bool test = false; 639 for(std::set<MultiTrigger*>::iterator it = this->subTriggers_.begin(); it != this->subTriggers_.end(); ++it) 640 { 641 if(test && (*it)->isActive(triggerer)) 642 return false; 643 644 if((*it)->isActive(triggerer)) 645 test = true; 646 } 647 return test; 562 bool triggered = false; 563 for(std::set<TriggerBase*>::iterator it = this->children_.begin(); it != this->children_.end(); ++it) 564 { 565 TriggerBase* trigger = *it; 566 if(triggered) 567 { 568 if(trigger->isMultiTrigger()) 569 { 570 if(static_cast<MultiTrigger*>(trigger)->isActive(triggerer)) 571 return false; 572 } 573 else 574 { 575 if(trigger->isActive()) 576 return false; 577 } 578 } 579 580 if(trigger->isMultiTrigger()) 581 { 582 if(static_cast<MultiTrigger*>(trigger)->isActive(triggerer)) 583 triggered = true; 584 } 585 else 586 { 587 if(trigger->isActive()) 588 triggered = true; 589 } 590 } 591 return triggered; 648 592 } 649 593
Note: See TracChangeset
for help on using the changeset viewer.