[Orxonox-commit 2144] r6860 - code/trunk/src/modules/objects/triggers
dafrick at orxonox.net
dafrick at orxonox.net
Thu May 6 16:01:25 CEST 2010
Author: dafrick
Date: 2010-05-06 16:01:25 +0200 (Thu, 06 May 2010)
New Revision: 6860
Modified:
code/trunk/src/modules/objects/triggers/DistanceMultiTrigger.cc
code/trunk/src/modules/objects/triggers/DistanceMultiTrigger.h
Log:
Resolved bug in DistanceMultiTrigger, that caused a segfault, when an object in range of the trigger was destroyed.
Modified: code/trunk/src/modules/objects/triggers/DistanceMultiTrigger.cc
===================================================================
--- code/trunk/src/modules/objects/triggers/DistanceMultiTrigger.cc 2010-05-06 12:56:39 UTC (rev 6859)
+++ code/trunk/src/modules/objects/triggers/DistanceMultiTrigger.cc 2010-05-06 14:01:25 UTC (rev 6860)
@@ -85,14 +85,22 @@
std::queue<MultiTriggerState*>* queue = NULL;
// Check for objects that were in range but no longer are. Iterate through all objects, that are in range.
- for(std::set<WorldEntity*>::iterator it = this->range_.begin(); it != this->range_.end(); )
+ for(std::map<WorldEntity*, WeakPtr<WorldEntity>* >::iterator it = this->range_.begin(); it != this->range_.end(); )
{
- Vector3 distanceVec = (*it)->getWorldPosition() - this->getWorldPosition();
+ WorldEntity* entity = it->second->get();
+ WorldEntity* key = it->first;
+ if(entity == NULL)
+ {
+ it++;
+ this->removeFromRange(key);
+ continue;
+ }
+
+ Vector3 distanceVec = entity->getWorldPosition() - this->getWorldPosition();
// If the object is no longer in range.
if (distanceVec.length() > this->distance_)
{
- WorldEntity* temp = *(it++);
- if(!this->removeFromRange(temp))
+ if(!this->removeFromRange(entity))
continue;
// If no queue has been created, yet.
@@ -102,7 +110,7 @@
// Create a state and append it to the queue.
MultiTriggerState* state = new MultiTriggerState;
state->bTriggered = false;
- state->originator = temp;
+ state->originator = entity;
queue->push(state);
}
else
@@ -112,8 +120,8 @@
// Check for new objects that are in range
for(ClassTreeMaskObjectIterator it = targetMask.begin(); it != targetMask.end(); ++it)
{
- WorldEntity* entity = orxonox_cast<WorldEntity*>(*it);
- if (entity == NULL || this->inRange(entity)) //If the object is no WorldEntity or is already in range.
+ WorldEntity* entity = static_cast<WorldEntity*>(*it);
+ if (entity == NULL) //If the object is no WorldEntity or is already in range.
continue;
Vector3 distanceVec = entity->getWorldPosition() - this->getWorldPosition();
Modified: code/trunk/src/modules/objects/triggers/DistanceMultiTrigger.h
===================================================================
--- code/trunk/src/modules/objects/triggers/DistanceMultiTrigger.h 2010-05-06 12:56:39 UTC (rev 6859)
+++ code/trunk/src/modules/objects/triggers/DistanceMultiTrigger.h 2010-05-06 14:01:25 UTC (rev 6860)
@@ -37,7 +37,8 @@
#include "objects/ObjectsPrereqs.h"
#include "worldentities/WorldEntity.h"
-#include <set>
+#include "core/WeakPtr.h"
+#include <map>
#include "MultiTrigger.h"
@@ -78,30 +79,23 @@
virtual std::queue<MultiTriggerState*>* letTrigger(void); //!< This method is called by the MultiTrigger to get information about new trigger events that need to be looked at.
/**
- @brief Check whether a given entity is currently (since the last update) in range of the DistanceMultiTrigger.
- @param entity A pointer to the entity.
- @return Returns true if the entity is in the range.
- */
- inline bool inRange(WorldEntity* entity)
- { return this->range_.find(entity) != this->range_.end(); }
- /**
@brief Add a given entity to the entities, that currently are in range of the DistanceMultiTrigger.
@param entity A pointer to the entity.
@return Returns true if successful, false if not.
*/
inline bool addToRange(WorldEntity* entity)
- { std::pair<std::set<WorldEntity*>::iterator, bool> pair = this->range_.insert(entity); return pair.second; }
+ { std::pair<std::map<WorldEntity*, WeakPtr<WorldEntity>* >::iterator, bool> pair = this->range_.insert(std::pair<WorldEntity*, WeakPtr<WorldEntity>* >(entity, new WeakPtr<WorldEntity>(entity))); return pair.second; }
/**
@brief Remove a given entity from the set of entities, that currently are in range of the DistanceMultiTrigger.
@param entity A pointer ot the entity.
@return Returns true if successful.
*/
inline bool removeFromRange(WorldEntity* entity)
- { return this->range_.erase(entity) > 0; }
+ { (*this->range_.find(entity)->second)->destroy(); bool erased = this->range_.erase(entity) > 0; return erased; }
private:
float distance_; //!< The distance at which the DistanceMultiTrigger triggers.
- std::set<WorldEntity*> range_; //!< The set of entities that currently are in range of the DistanceMultiTrigger.
+ std::map<WorldEntity*, WeakPtr<WorldEntity>* > range_; //!< The set of entities that currently are in range of the DistanceMultiTrigger.
};
More information about the Orxonox-commit
mailing list