Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Feb 18, 2011, 12:07:04 AM (14 years ago)
Author:
landauf
Message:

Ok, here comes a tricky one: we knew the destructor of WorldEntity is dangerous because it deletes its children - this works only if no child deletes the subsequent child in the set because then the iterator would become invalid. However this is never the case, right?

Wrong! If you define a CameraPosition with "absolute" flag, it will not be attached to a ControllableEntity but to its parent! The CE however still deletes the CameraPosition. This led to very rare and random crashes while destroying the Pong level (the only level where an absolute camera is used).

  • fixed this issue by using a safe destruction loop
  • fixed another issue in the same loop if a child has a smart pointer pointing to it, thus not being destroyed, hence it has to be detached
  • performance improvement in detach()

Thanks to Jo for sending me the crash log!

Location:
code/trunk/src/orxonox/worldentities
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • code/trunk/src/orxonox/worldentities/WorldEntity.cc

    r7905 r7910  
    120120                this->detachFromParent();
    121121
    122             for (std::set<WorldEntity*>::const_iterator it = this->children_.begin(); it != this->children_.end(); )
    123             {
     122            std::set<WorldEntity*>::iterator it;
     123            while ((it = this->children_.begin()) != this->children_.end())
     124            {
     125                // do this for all children, because even if getDeleteWithParent() returns true a child might still stay active due to smart pointers pointing to it
     126                (*it)->setPosition((*it)->getWorldPosition());
     127                this->detach(*it); // detach also erases the element from the children set
     128
    124129                if ((*it)->getDeleteWithParent())
    125                     (*(it++))->destroy();
    126                 else
    127                 {
    128                     (*it)->setPosition((*it)->getWorldPosition());
    129                     this->detach(*(it++));
    130                 }
     130                    (*it)->destroy();
    131131            }
    132132
     
    450450    void WorldEntity::detach(WorldEntity* object)
    451451    {
    452         if (this->children_.find(object) == this->children_.end())
     452        std::set<WorldEntity*>::iterator it = this->children_.find(object);
     453        if (it == this->children_.end())
    453454        {
    454455            CCOUT(2) << "Warning: Cannot detach an object that is not a child." << std::endl;
     
    467468
    468469        this->detachNode(object->node_);
    469         this->children_.erase(object);
     470        this->children_.erase(it);
    470471
    471472        object->notifyDetached();
  • code/trunk/src/orxonox/worldentities/WorldEntity.h

    r7401 r7910  
    214214        private:
    215215            void registerVariables();
    216            
     216
    217217            inline void lookAt_xmlport(const Vector3& target)
    218218                { this->lookAt(target); }
Note: See TracChangeset for help on using the changeset viewer.