Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Jun 3, 2010, 4:43:42 AM (14 years ago)
Author:
landauf
Message:

fixed various cases where master/slave pointers weren't synchronized with the AI's state (and therefore not removed after destruction). I couldn't find all edge cases though, so there's still some work to do. Instead i implemented a cleanup function in the destructor which removes all dangling pointers.

Location:
code/branches/presentation3/src/orxonox/controllers
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • code/branches/presentation3/src/orxonox/controllers/ArtificialController.cc

    r7106 r7107  
    8888    ArtificialController::~ArtificialController()
    8989    {
     90        if (this->isInitialized())
     91        {
     92            this->removeFromFormation();
     93           
     94            for (ObjectList<ArtificialController>::iterator it = ObjectList<ArtificialController>::begin(); it; ++it)
     95            {
     96                if (*it != this)
     97                {
     98                    if (it->myMaster_ == this)
     99                    {
     100                        COUT(1) << "error: " << this << " is still master in " << (*it) << std::endl;
     101                        it->myMaster_ = 0;
     102                    }
     103                   
     104                    while (true)
     105                    {
     106                        std::vector<ArtificialController*>::iterator it2 = std::find(it->slaves_.begin(), it->slaves_.end(), this);
     107                        if (it2 != it->slaves_.end())
     108                        {
     109                            COUT(1) << "error: " << this << " is still slave in " << (*it) << std::endl;
     110                            it->slaves_.erase(it2);
     111                        }
     112                        else
     113                            break;
     114                    }
     115                }
     116            }
     117        }
    90118    }
    91119
     
    122150            ArtificialController *aiController = orxonox_cast<ArtificialController*>(controller);
    123151
    124             if(aiController)
     152            if (aiController)
    125153            {
    126154                aiController->formationFlight_ = form;
    127                 if(!form)
     155                if (!form)
    128156                {
    129                     if(aiController->state_ == MASTER) aiController->freeSlaves();
    130                     aiController->state_ = FREE;
     157                    aiController->removeFromFormation();
    131158                }
    132159            }
     
    276303    void ArtificialController::changedControllableEntity()
    277304    {
    278         if(!getControllableEntity())
    279         {
    280         if (this->state_ == SLAVE) unregisterSlave();
    281         if (this->state_ == MASTER) setNewMasterWithinFormation();
    282         this->slaves_.clear();
    283         this->state_ = FREE;
    284         this->specificMasterAction_ = NONE;
    285 
    286         }
    287     }
    288 
     305        if (!this->getControllableEntity())
     306            this->removeFromFormation();
     307    }
     308
     309    void ArtificialController::removeFromFormation()
     310    {
     311        if (this->state_ == SLAVE || this->myMaster_) // slaves can also be temporary free, so check if myMaster_ is set
     312            this->unregisterSlave();
     313        else if (this->state_ == MASTER)
     314            this->setNewMasterWithinFormation();
     315    }
    289316
    290317    void ArtificialController::moveToPosition(const Vector3& target)
     
    365392        @brief Unregisters a slave from its master. Initiated by a slave.
    366393    */
    367     void ArtificialController::unregisterSlave() {
    368         if(myMaster_)
    369         {
    370             std::vector<ArtificialController*>::iterator it = std::find(myMaster_->slaves_.begin(), myMaster_->slaves_.end(), this);
    371             if( it != myMaster_->slaves_.end() )
    372                 myMaster_->slaves_.erase(it);
    373         }
     394    void ArtificialController::unregisterSlave()
     395    {
     396        if (this->myMaster_)
     397        {
     398            std::vector<ArtificialController*>::iterator it = std::find(this->myMaster_->slaves_.begin(), this->myMaster_->slaves_.end(), this);
     399            if (it != this->myMaster_->slaves_.end())
     400                this->myMaster_->slaves_.erase(it);
     401        }
     402       
     403        this->myMaster_ = 0;
     404        this->state_ = FREE;
    374405    }
    375406
     
    386417        for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it)
    387418        {
    388 
    389419            //same team?
    390420            if (!ArtificialController::sameTeam(this->getControllableEntity(), static_cast<ControllableEntity*>(*it), this->getGametype()))
     
    436466        }
    437467
    438         if (state_ != SLAVE  && teamSize != 0) state_ = MASTER;
    439 
     468        if (this->state_ != SLAVE  && teamSize != 0)
     469        {
     470            this->state_ = MASTER;
     471            this->myMaster_ = 0;
     472        }
    440473    }
    441474
     
    489522        if(this->state_ != MASTER) return;
    490523
    491         if (this->slaves_.empty())
    492             return;
    493 
    494         ArtificialController *newMaster = this->slaves_.back();
    495         this->slaves_.pop_back();
    496 
    497         if(!newMaster) return;
    498         newMaster->state_ = MASTER;
    499         newMaster->slaves_ = this->slaves_;
     524        if (!this->slaves_.empty())
     525        {
     526            ArtificialController *newMaster = this->slaves_.back();
     527            this->slaves_.pop_back();
     528
     529            newMaster->state_ = MASTER;
     530            newMaster->slaves_ = this->slaves_;
     531            newMaster->myMaster_ = 0;
     532
     533            for(std::vector<ArtificialController*>::iterator it = newMaster->slaves_.begin(); it != newMaster->slaves_.end(); it++)
     534            {
     535                (*it)->myMaster_ = newMaster;
     536            }
     537        }
    500538
    501539        this->slaves_.clear();
    502540        this->specificMasterAction_ = NONE;
    503         this->state_ = SLAVE;
    504         this->myMaster_ = newMaster;
    505 
    506         for(std::vector<ArtificialController*>::iterator it = newMaster->slaves_.begin(); it != newMaster->slaves_.end(); it++)
    507         {
    508             (*it)->myMaster_ = newMaster;
    509         }
    510 
     541        this->state_ = FREE;
    511542    }
    512543
     
    521552        {
    522553            (*it)->state_ = FREE;
     554            (*it)->myMaster_ = 0;
    523555        }
    524556        this->slaves_.clear();
  • code/branches/presentation3/src/orxonox/controllers/ArtificialController.h

    r7097 r7107  
    9797            void moveToTargetPosition();
    9898
     99            void removeFromFormation();
    99100            void unregisterSlave();
    100101            void searchNewMaster();
Note: See TracChangeset for help on using the changeset viewer.