[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