Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Changeset 1063


Ignore:
Timestamp:
Apr 14, 2008, 6:23:52 PM (16 years ago)
Author:
landauf
Message:

fixed an interesting bug in ObjectList/MetaObjectList/Iterator: it's now possible to delete multiple objects in one function-call while iterating through the objects. (and it would have crashed with std::list as well, so no stupid comments please :D)

added a feature in Timer.cc, allowing timers to tick faster than orxonox. this is from core2-branch but got lost while merging.

Location:
code/trunk/src
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • code/trunk/src/core/Identifier.h

    r1062 r1063  
    303303            void setName(const std::string& name);
    304304            /** @brief Returns the list of all existing objects of this class. @return The list */
    305             inline const ObjectList<T>* getObjects() const { return this->objects_; }
     305            inline ObjectList<T>* getObjects() const { return this->objects_; }
    306306            /** @brief Returns a list of all existing objects of this class. @return The list */
    307             inline const ObjectList<BaseObject>* getObjectList() const { return (ObjectList<BaseObject>*)this->objects_; }
     307            inline ObjectList<BaseObject>* getObjectList() const { return (ObjectList<BaseObject>*)this->objects_; }
    308308
    309309            void updateConfigValues() const;
  • code/trunk/src/core/Iterator.h

    r1056 r1063  
    6565            {
    6666                this->element_ = 0;
     67                ClassManager<T>::getIdentifier()->getObjects()->registerIterator(this);
    6768            }
    6869
     
    7475            {
    7576                this->element_ = element;
     77                ClassManager<T>::getIdentifier()->getObjects()->registerIterator(this);
     78            }
     79
     80            /**
     81                @brief Unregisters the Iterator from the ObjectList.
     82            */
     83            ~Iterator()
     84            {
     85                ClassManager<T>::getIdentifier()->getObjects()->unregisterIterator(this);
    7686            }
    7787
     
    91101            Iterator<T> operator++()
    92102            {
    93                 this->element_ = this->element_->next_;
     103                if (this->element_)
     104                    this->element_ = this->element_->next_;
    94105                return *this;
    95106            }
     
    102113            {
    103114                Iterator<T> copy = *this;
    104                 this->element_ = this->element_->next_;
     115                if (this->element_)
     116                    this->element_ = this->element_->next_;
    105117                return copy;
    106118            }
     
    112124            Iterator<T> operator--()
    113125            {
    114                 this->element_ = this->element_->prev_;
     126                if (this->element_)
     127                    this->element_ = this->element_->prev_;
    115128                return *this;
    116129            }
     
    123136            {
    124137                Iterator<T> copy = *this;
    125                 this->element_ = this->element_->prev_;
     138                if (this->element_)
     139                    this->element_ = this->element_->prev_;
    126140                return copy;
    127141            }
     
    133147            T* operator*()
    134148            {
    135                 return this->element_->object_;
     149                if (this->element_)
     150                    return this->element_->object_;
     151                else
     152                    return 0;
    136153            }
    137154
     
    142159            T* operator->() const
    143160            {
    144                 return this->element_->object_;
     161                if (this->element_)
     162                    return this->element_->object_;
     163                else
     164                    return 0;
    145165
    146166            }
  • code/trunk/src/core/MetaObjectList.h

    r1056 r1063  
    8989    MetaObjectListElement<T>::~MetaObjectListElement()
    9090    {
     91        COUT(5) << "*** MetaObjectList: Removing Object from " << ClassManager<T>::getIdentifier()->getName() << "-list." << std::endl;
     92        this->list_->notifyIterators(this->element_);
     93
    9194        if (this->element_->next_)
    9295            this->element_->next_->prev_ = this->element_->prev_;
     
    99102            this->list_->first_ = this->element_->next_; // If there is no prev_, we deleted the first object and have to update the first_ pointer of the list
    100103
    101 
    102         COUT(5) << "*** MetaObjectList: Removing Object from " << ClassManager<T>::getIdentifier()->getName() << "-list." << std::endl;
    103104        delete this->element_;
    104105    }
     
    106107
    107108    // ###############################
    108     // ###       ObjectList        ###
     109    // ###     MetaObjectList      ###
    109110    // ###############################
    110111    //!  The MetaObjectList contains ObjectListElements and their ObjectLists.
  • code/trunk/src/core/ObjectList.h

    r1062 r1063  
    3838#ifndef _ObjectList_H__
    3939#define _ObjectList_H__
     40
     41#include <set>
    4042
    4143#include "CorePrereqs.h"
     
    9092
    9193            ObjectListElement<T>* add(T* object);
    92 //            void remove(OrxonoxClass* object, bool bIterateForwards = true);
    9394
    9495            /** @brief Returns the first element in the list. @return The first element */
     
    104105                { return Iterator<T>(ClassManager<T>::getIdentifier()->getObjects()->last_); }
    105106
     107            inline void registerIterator(Iterator<T>* iterator)
     108                { this->iterators_.insert(this->iterators_.end(), (void*)iterator); }
     109            inline void unregisterIterator(Iterator<T>* iterator)
     110                { this->iterators_.erase((void*)iterator); }
     111            void notifyIterators(ObjectListElement<T>* element);
     112
    106113            ObjectListElement<T>* first_;       //!< The first element in the list
    107114            ObjectListElement<T>* last_;        //!< The last element in the list
     115
     116        private:
     117            std::set<void*> iterators_;  //!< A list of iterators pointing on an element in this list
    108118    };
    109119
     
    134144
    135145    /**
     146        @brief Increases all Iterators that currently point on the given element (because it gets removed).
     147        @param element The element that gets removed
     148    */
     149    template <class T>
     150    void ObjectList<T>::notifyIterators(ObjectListElement<T>* element)
     151    {
     152        for (std::set<void*>::iterator it = this->iterators_.begin(); it != this->iterators_.end(); ++it)
     153            if ((*(*((Iterator<T>*)(*it)))) == element->object_)
     154                ++(*((Iterator<T>*)(*it)));
     155    }
     156
     157    /**
    136158        @brief Adds a new object to the end of the list.
    137159        @param object The object to add
     
    158180        return this->last_;
    159181    }
    160 
    161 
    162 //    /**
    163 //        @brief Removes an object from the list.
    164 //        @param object The object to remove
    165 //        @param bIterateForwards If true: Start searching the object at the beginning of the list
    166 //    */
    167     /*
    168     template <class T>
    169     void ObjectList<T>::remove(OrxonoxClass* object, bool bIterateForwards)
    170     {
    171         if (!object || !this->first_ || !this->last_)
    172             return;
    173 
    174         // If there's only one object in the list, we have to set first_ and last_ to zero
    175         if (this->first_ == this->last_)
    176         {
    177             if (this->first_->object_ == object)
    178             {
    179                 delete this->first_;
    180                 this->first_ = 0;
    181                 this->last_ = 0;
    182             }
    183 
    184             return;
    185         }
    186 
    187         // Now we are sure we have more than one element in the list
    188         if (bIterateForwards)
    189         {
    190             // Start at the beginning of the list
    191 
    192             // Check if it's the first object
    193             if (this->first_->object_ == object)
    194             {
    195                 ObjectListElement<T>* temp = this->first_->next_;
    196                 delete this->first_;
    197                 this->first_ = temp;
    198                 this->first_->prev_ = 0;
    199 
    200                 return;
    201             }
    202 
    203             // Iterate through the whole list
    204             ObjectListElement<T>* temp = this->first_;
    205             while (temp->next_)
    206             {
    207                 if (temp->next_->object_ == object)
    208                 {
    209                     ObjectListElement<T>* temp2 = temp->next_->next_;
    210                     delete temp->next_;
    211                     temp->next_ = temp2;
    212                     if (temp2)
    213                         temp2->prev_ = temp;
    214                     else
    215                         this->last_ = temp; // If there is no next_, we deleted the last element and have to update the last_ pointer.
    216 
    217                     return;
    218                 }
    219 
    220                 temp = temp->next_;
    221             }
    222         }
    223         else
    224         {
    225             // Start at the end of the list
    226 
    227             // Check if it's the last object
    228             if (this->last_->object_ == object)
    229             {
    230                 ObjectListElement<T>* temp = this->last_->prev_;
    231                 delete this->last_;
    232                 this->last_ = temp;
    233                 this->last_->next_ = 0;
    234 
    235                 return;
    236             }
    237 
    238             // Iterate through the whole list
    239             ObjectListElement<T>* temp = this->last_;
    240             while (temp->prev_)
    241             {
    242                 if (temp->prev_->object_ == object)
    243                 {
    244                     ObjectListElement<T>* temp2 = temp->prev_->prev_;
    245                     delete temp->prev_;
    246                     temp->prev_ = temp2;
    247                     if (temp2)
    248                         temp2->next_ = temp;
    249                     else
    250                         this->first_ = temp; // If there is no prev_, we deleted the first element and have to update the first_ pointer.
    251 
    252                     return;
    253                 }
    254 
    255                 temp = temp->prev_;
    256             }
    257         }
    258     }
    259     */
    260182}
    261183
  • code/trunk/src/orxonox/tools/Timer.cc

    r1062 r1063  
    108108                // It's time to call the function
    109109                if (this->bLoop_)
    110                     // Q: Why '+=' and not '='? A: Think about it. It's more accurate like that. Seriously.
    111                     this->time_ += this->interval_;
     110                {
     111                    this->time_ += this->interval_; // Q: Why '+=' and not '='? A: Think about it. It's more accurate like that. Seriously.
     112                    while (this->time_ <= 0)
     113                    {
     114                        // The interval was shorter than one tick, so execute the function more than once
     115                        this->run();
     116                        this->time_ += this->interval_;
     117                    }
     118                }
    112119                else
    113120                    this->stopTimer(); // Stop the timer if we don't want to loop
     
    117124        }
    118125    }
    119 
    120126}
Note: See TracChangeset for help on using the changeset viewer.