Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
May 6, 2010, 4:01:25 PM (15 years ago)
Author:
dafrick
Message:

Resolved bug in DistanceMultiTrigger, that caused a segfault, when an object in range of the trigger was destroyed.

Location:
code/trunk/src/modules/objects/triggers
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • code/trunk/src/modules/objects/triggers/DistanceMultiTrigger.cc

    r6857 r6860  
    8686
    8787        // Check for objects that were in range but no longer are. Iterate through all objects, that are in range.
    88         for(std::set<WorldEntity*>::iterator it = this->range_.begin(); it != this->range_.end(); )
     88        for(std::map<WorldEntity*, WeakPtr<WorldEntity>* >::iterator it = this->range_.begin(); it != this->range_.end(); )
    8989        {
    90             Vector3 distanceVec = (*it)->getWorldPosition() - this->getWorldPosition();
     90            WorldEntity* entity = it->second->get();
     91            WorldEntity* key = it->first;
     92            if(entity == NULL)
     93            {
     94                it++;
     95                this->removeFromRange(key);
     96                continue;
     97            }
     98           
     99            Vector3 distanceVec = entity->getWorldPosition() - this->getWorldPosition();
    91100            // If the object is no longer in range.
    92101            if (distanceVec.length() > this->distance_)
    93102            {
    94                 WorldEntity* temp = *(it++);
    95                 if(!this->removeFromRange(temp))
     103                if(!this->removeFromRange(entity))
    96104                    continue;
    97105
     
    103111                MultiTriggerState* state = new MultiTriggerState;
    104112                state->bTriggered = false;
    105                 state->originator = temp;
     113                state->originator = entity;
    106114                queue->push(state);
    107115            }
     
    113121        for(ClassTreeMaskObjectIterator it = targetMask.begin(); it != targetMask.end(); ++it)
    114122        {
    115             WorldEntity* entity = orxonox_cast<WorldEntity*>(*it);
    116             if (entity == NULL || this->inRange(entity)) //If the object is no WorldEntity or is already in range.
     123            WorldEntity* entity = static_cast<WorldEntity*>(*it);
     124            if (entity == NULL) //If the object is no WorldEntity or is already in range.
    117125                continue;
    118126
  • code/trunk/src/modules/objects/triggers/DistanceMultiTrigger.h

    r6857 r6860  
    3838
    3939#include "worldentities/WorldEntity.h"
    40 #include <set>
     40#include "core/WeakPtr.h"
     41#include <map>
    4142
    4243#include "MultiTrigger.h"
     
    7980
    8081            /**
    81             @brief Check whether a given entity is currently (since the last update) in range of the DistanceMultiTrigger.
    82             @param entity A pointer to the entity.
    83             @return Returns true if the entity is in the range.
    84             */
    85             inline bool inRange(WorldEntity* entity)
    86                 { return this->range_.find(entity) != this->range_.end(); }
    87             /**
    8882            @brief Add a given entity to the entities, that currently are in range of the DistanceMultiTrigger.
    8983            @param entity A pointer to the entity.
     
    9185            */
    9286            inline bool addToRange(WorldEntity* entity)
    93                 { std::pair<std::set<WorldEntity*>::iterator, bool> pair = this->range_.insert(entity); return pair.second; }
     87                { 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; }
    9488            /**
    9589            @brief Remove a given entity from the set of entities, that currently are in range of the DistanceMultiTrigger.
     
    9892            */
    9993            inline bool removeFromRange(WorldEntity* entity)
    100                 { return this->range_.erase(entity) > 0; }
     94                { (*this->range_.find(entity)->second)->destroy(); bool erased = this->range_.erase(entity) > 0; return erased; }
    10195               
    10296        private:
    10397            float distance_; //!< The distance at which the DistanceMultiTrigger triggers.
    104             std::set<WorldEntity*> range_; //!< The set of entities that currently are in range of the DistanceMultiTrigger.
     98            std::map<WorldEntity*, WeakPtr<WorldEntity>* > range_; //!< The set of entities that currently are in range of the DistanceMultiTrigger.
    10599       
    106100    };
Note: See TracChangeset for help on using the changeset viewer.