Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Aug 25, 2013, 9:08:42 PM (11 years ago)
Author:
landauf
Message:

merged core6 back to trunk

Location:
code/trunk
Files:
2 deleted
12 edited
2 copied

Legend:

Unmodified
Added
Removed
  • code/trunk

  • code/trunk/src/libraries/core/object/CMakeLists.txt

    r9591 r9667  
    33  Destroyable.cc
    44  Listable.cc
    5   MetaObjectList.cc
    65  ObjectListBase.cc
    76)
  • code/trunk/src/libraries/core/object/ClassFactory.h

    r9563 r9667  
    4343
    4444#include "util/Output.h"
    45 #include "core/class/Identifier.h"
    4645
    4746namespace orxonox
     
    5049    // ###       Factory       ###
    5150    // ###########################
    52     /// Base-class of ClassFactory.
     51    /// Base-class of all factories.
    5352    class _CoreExport Factory
    5453    {
    5554        public:
    56             virtual ~Factory() {};
    57             virtual OrxonoxClass* fabricate(BaseObject* creator) = 0;
     55            virtual ~Factory() {}
     56            virtual Identifiable* fabricate(Context* context) = 0;
    5857    };
    5958
     
    6160    // ###      ClassFactory       ###
    6261    // ###############################
    63     /// The ClassFactory is able to create new objects of a specific class.
     62    /// The ClassFactory is the base-class of all class-spezific factories
    6463    template <class T>
    6564    class ClassFactory : public Factory
    6665    {
     66    };
     67
     68    // ###############################
     69    // ###   ClassFactoryNoArgs    ###
     70    // ###############################
     71    /// The ClassFactoryNoArgs is able to create new objects of a specific class that require no constructor arguments.
     72    template <class T>
     73    class ClassFactoryNoArgs : public ClassFactory<T>
     74    {
    6775        public:
    68             /**
    69                 @brief Constructor: Adds the ClassFactory to the Identifier of the same type.
    70                 @param name The name of the class
    71                 @param bLoadable True if the class can be loaded through XML
    72             */
    73             ClassFactory(const std::string& name, bool bLoadable = true)
    74             {
    75                 orxout(verbose, context::misc::factory) << "Create entry for " << name << " in Factory." << endl;
    76                 ClassIdentifier<T>::getIdentifier(name)->addFactory(this);
    77                 ClassIdentifier<T>::getIdentifier()->setLoadable(bLoadable);
    78             }
    79 
    8076            /**
    8177                @brief Creates and returns a new object of class T.
    8278                @return The new object
    8379            */
    84             inline OrxonoxClass* fabricate(BaseObject* creator)
     80            inline Identifiable* fabricate(Context* context)
    8581            {
    86                 return static_cast<OrxonoxClass*>(new T(creator));
     82                return static_cast<Identifiable*>(new T());
     83            }
     84    };
     85
     86    // ###############################
     87    // ### ClassFactoryWithContext ###
     88    // ###############################
     89    /// The ClassFactoryWithContext is able to create new objects of a specific class that require a context as constructor argument
     90    template <class T>
     91    class ClassFactoryWithContext : public ClassFactory<T>
     92    {
     93        public:
     94            /**
     95                @brief Creates and returns a new object of class T.
     96                @return The new object
     97            */
     98            inline Identifiable* fabricate(Context* context)
     99            {
     100                return static_cast<Identifiable*>(new T(context));
    87101            }
    88102    };
  • code/trunk/src/libraries/core/object/Context.cc

    r9591 r9667  
    3333
    3434#include "Context.h"
     35#include "core/class/Identifier.h"
     36#include "core/CoreIncludes.h"
    3537
    3638namespace orxonox
    3739{
    38     Context::Context(Context* context) : parentContext_(context)
     40    RegisterClass(Context);
     41
     42    Context* Context::rootContext_s = 0;
     43
     44    Context* getContextForInitializationOfOtherContexts()
    3945    {
     46        static size_t count = 0;
     47        // the first time this is called, ++count returns 1 and the context is created
     48        // the second time this is called, ++count returns 2 and NULL is returned because we're in the constructor of the context itself
     49        // for each future call the context (now completely created) is returned
     50        if (++count == 2)
     51            return NULL;
     52        else
     53        {
     54            static Context context(NULL);
     55            return &context;
     56        }
     57    }
     58
     59    // Initialize Listable(*) with a special context, only used to initialize other contexts. Later in the constructor we change the context
     60    Context::Context(Context* context) : Listable(getContextForInitializationOfOtherContexts()), parentContext_(context)
     61    {
     62        RegisterObject(Context);
     63
     64        // the context is its own context
     65        this->setContext(this);
    4066    }
    4167
    4268    Context::~Context()
    4369    {
     70        // unregister context from object lists before object lists are destroyed
     71        this->unregisterObject();
     72        for (size_t i = 0; i < this->objectLists_.size(); ++i)
     73            delete this->objectLists_[i];
     74    }
     75
     76    /*static*/ void Context::setRootContext(Context* context)
     77    {
     78        if (Context::rootContext_s)
     79            delete Context::rootContext_s;
     80        Context::rootContext_s = context;
    4481    }
    4582
    4683    /*static*/ Context* Context::getRootContext()
    4784    {
    48         static Context rootContext(NULL);
    49         return &rootContext;
     85        if (!Context::rootContext_s)
     86            Context::rootContext_s = new Context(NULL);
     87        return Context::rootContext_s;
     88    }
     89
     90    ObjectListBase* Context::getObjectList(const Identifier* identifier)
     91    {
     92        unsigned int classID = identifier->getClassID();
     93        if (classID >= this->objectLists_.size())
     94            this->objectLists_.resize(classID + 1);
     95        if (!this->objectLists_[classID])
     96            this->objectLists_[classID] = new ObjectListBase();
     97        return this->objectLists_[classID];
    5098    }
    5199}
  • code/trunk/src/libraries/core/object/Context.h

    r9591 r9667  
    3737#include "core/CorePrereqs.h"
    3838
     39#include <vector>
     40
     41#include "Listable.h"
     42
    3943namespace orxonox
    4044{
    41     class _CoreExport Context
     45    class _CoreExport Context : virtual public Listable
    4246    {
    4347        public:
     48            static void setRootContext(Context* context);
     49            static Context* getRootContext();
     50
    4451            Context(Context* context);
    4552            virtual ~Context();
     
    4855                { return this->parentContext_; }
    4956
    50             static Context* getRootContext();
     57            ObjectListBase* getObjectList(const Identifier* identifier);
     58
     59            template <class T>
     60            inline ObjectListBase* getObjectList()
     61                { return this->getObjectList(ClassIdentifier<T>::getIdentifier()); }
     62
     63            template <class T>
     64            inline void addObject(T* object)
     65            {
     66                ObjectListBaseElement* element = Listable::createObjectListElement(object);
     67                this->getObjectList<T>()->addElement(element);
     68                object->elements_.push_back(element);
     69                if (this->getParentContext())
     70                    this->getParentContext()->addObject(object);
     71            }
    5172
    5273        private:
    5374            Context* parentContext_;
     75            std::vector<ObjectListBase*> objectLists_;
     76
     77            static Context* rootContext_s;
    5478    };
    5579}
  • code/trunk/src/libraries/core/object/Iterator.h

    r9573 r9667  
    5656#include "core/CorePrereqs.h"
    5757
    58 #include "core/class/Identifier.h"
    5958#include "ObjectListBase.h"
     59#include "IteratorBase.h"
    6060
    6161namespace orxonox
     
    7070    */
    7171    template <class T>
    72     class Iterator
     72    class Iterator : public IteratorBase<T, Iterator<T> >
    7373    {
    7474        public:
     
    7676                @brief Constructor: Sets the element, whereon the iterator points, to zero.
    7777            */
    78             inline Iterator()
    79             {
    80                 this->element_ = 0;
    81                 this->list_ = 0;
    82             }
     78            inline Iterator() : IteratorBase<T, Iterator<T> >(NULL) {}
    8379
    8480            /**
    85                 @brief Constructor: Sets this element to the exported element.
    86                 @param exp The exported element
     81                @brief Constructor: Sets this element to a given element
     82                @param element The element
    8783            */
    88             inline Iterator(const ObjectListBase::Export& exp)
    89             {
    90                 this->element_ = exp.element_;
    91                 this->list_ = exp.list_;
    92                 this->list_->registerIterator(this);
    93             }
     84            inline Iterator(ObjectListBaseElement* element) : IteratorBase<T, Iterator<T> >(element) {}
    9485
    9586            /**
     
    9788                @param other The other Iterator
    9889            */
    99             inline Iterator(const Iterator<T>& other)
    100             {
    101                 this->element_ = other.element_;
    102                 this->list_ = other.list_;
    103                 this->list_->registerIterator(this);
    104             }
    105 
    106             /**
    107                 @brief Constructor: Sets this element to a given element
    108                 @param element The element
    109             */
    110             template <class O>
    111             inline Iterator(ObjectListElement<O>* element)
    112             {
    113                 this->element_ = element;
    114                 this->list_ = ClassIdentifier<O>::getIdentifier()->getObjects();
    115                 this->list_->registerIterator(this);
    116             }
    117 
    118             /**
    119                 @brief Constructor: Sets this element to the element an ObjectListIterator.
    120                 @param other The ObjectListIterator
    121             */
    122             template <class O>
    123             inline Iterator(const ObjectListIterator<O>& other)
    124             {
    125                 this->element_ = other.element_;
    126                 this->list_ = ClassIdentifier<O>::getIdentifier()->getObjects();
    127                 this->list_->registerIterator(this);
    128             }
    129 
    130             /**
    131                 @brief Unregisters the Iterator from the ObjectList.
    132             */
    133             inline ~Iterator()
    134             {
    135                 this->list_->unregisterIterator(this);
    136             }
    137 
    138             /**
    139                 @brief Assigns an exported element.
    140                 @param exp The exported element
    141             */
    142             inline Iterator<T>& operator=(const ObjectListBase::Export& exp)
    143             {
    144                 if (this->list_)
    145                     this->list_->unregisterIterator(this);
    146 
    147                 this->element_ = exp.element_;
    148                 this->list_ = exp.list_;
    149                 this->list_->registerIterator(this);
    150 
    151                 return (*this);
    152             }
    153 
    154             /**
    155                 @brief Assigns the element of another Iterator.
    156                 @param other The other Iterator
    157             */
    158             inline Iterator<T>& operator=(const Iterator<T>& other)
    159             {
    160                 if (this->list_)
    161                     this->list_->unregisterIterator(this);
    162 
    163                 this->element_ = other.element_;
    164                 this->list_ = other.list_;
    165                 this->list_->registerIterator(this);
    166 
    167                 return (*this);
    168             }
     90            inline Iterator(const Iterator<T>& other) : IteratorBase<T, Iterator<T> >(other) {}
    16991
    17092            /**
     
    17294                @param element The element
    17395            */
    174             template <class O>
    175             inline Iterator<T>& operator=(ObjectListElement<O>* element)
     96            inline Iterator<T>& operator=(ObjectListBaseElement* element)
    17697            {
    177                 if (this->list_)
    178                     this->list_->unregisterIterator(this);
    179 
    180                 this->element_ = element;
    181                 this->list_ = ClassIdentifier<O>::getIdentifier()->getObjects();
    182                 this->list_->registerIterator(this);
    183 
     98                this->setElement(element);
    18499                return (*this);
    185             }
    186 
    187             /**
    188                 @brief Assigns the element of an ObjectListIterator.
    189                 @param other The ObjectListIterator
    190             */
    191             template <class O>
    192             inline Iterator<T>& operator=(const ObjectListIterator<O>& other)
    193             {
    194                 if (this->list_)
    195                     this->list_->unregisterIterator(this);
    196 
    197                 this->element_ = other.element_;
    198                 this->list_ = ClassIdentifier<O>::getIdentifier()->getObjects();
    199                 this->list_->registerIterator(this);
    200 
    201                 return (*this);
    202             }
    203 
    204             /**
    205                 @brief Overloading of the ++it operator: Iterator points to the next object in the list.
    206                 @return The Iterator itself
    207             */
    208             inline const Iterator<T>& operator++()
    209             {
    210                 this->element_ = this->element_->next_;
    211                 return *this;
    212             }
    213 
    214             /**
    215                 @brief Overloading of the it++ operator: Iterator points to the next object in the list.
    216                 @return The Iterator itself
    217             */
    218             inline Iterator<T> operator++(int)
    219             {
    220                 Iterator<T> copy = *this;
    221                 this->element_ = this->element_->next_;
    222                 return copy;
    223             }
    224 
    225             /**
    226                 @brief Overloading of the --it operator: Iterator points to the previous object in the list.
    227                 @return The Iterator itself
    228             */
    229             inline const Iterator<T>& operator--()
    230             {
    231                 this->element_ = this->element_->prev_;
    232                 return *this;
    233             }
    234 
    235             /**
    236                 @brief Overloading of the it-- operator: Iterator points to the previous object in the list.
    237                 @return The Iterator itself
    238             */
    239             inline Iterator<T> operator--(int i)
    240             {
    241                 Iterator<T> copy = *this;
    242                 this->element_ = this->element_->prev_;
    243                 return copy;
    244100            }
    245101
     
    261117                return orxonox_cast<T*>(this->element_->objectBase_);
    262118            }
    263 
    264             /**
    265                 @brief Overloading of the typecast-operator to bool: returns true if the iterator points to an existing object.
    266                 @return True if the Iterator points to an existing object.
    267             */
    268             inline operator bool() const
    269             {
    270                 return (this->element_ != 0);
    271             }
    272 
    273             /**
    274                 @brief Overloading of the == operator to compare with another Iterator.
    275                 @param compare The other Iterator
    276                 @return True if the iterators point to the same element
    277             */
    278             inline bool operator==(const Iterator<T>& compare) const
    279             {
    280                 return (this->element_ == compare.element_);
    281             }
    282 
    283             /**
    284                 @brief Overloading of the != operator to compare with another Iterator.
    285                 @param compare The other Iterator
    286                 @return True if the iterators point to different elements
    287             */
    288             inline bool operator!=(const Iterator<T>& compare) const
    289             {
    290                 return (this->element_ != compare.element_);
    291             }
    292 
    293             /**
    294                 @brief Increments the Iterator if it points at the given object.
    295                 @param object The object to compare with
    296             */
    297             inline void incrementIfEqual(Listable* object)
    298             {
    299                 if (this->element_ && this->element_->objectBase_ == object)
    300                     this->operator++();
    301             }
    302 
    303         protected:
    304             ObjectListBaseElement* element_;       //!< The element the Iterator points at
    305             ObjectListBase* list_;                 //!< The list wherein the element is
    306119    };
    307120}
  • code/trunk/src/libraries/core/object/Listable.cc

    r9572 r9667  
    3333
    3434#include "Listable.h"
    35 
    36 #include "core/object/MetaObjectList.h"
     35#include "core/CoreIncludes.h"
     36#include "ObjectListBase.h"
     37#include "Context.h"
    3738
    3839namespace orxonox
    3940{
     41    RegisterClass(Listable);
     42
    4043    /**
    41         @brief Constructor: creates the meta-object-list.
     44        @brief Constructor: Allocates space in the element list.
    4245    */
    4346    Listable::Listable()
    4447    {
    45         this->metaList_ = new MetaObjectList();
     48        this->context_ = Context::getRootContext();
     49        this->elements_.reserve(6);
     50
     51        RegisterObject(Listable);
     52    }
     53
     54    /**
     55        @brief Constructor: Allocates space in the element list and assigns the context
     56    */
     57    Listable::Listable(Context* context)
     58    {
     59        this->context_ = context;
     60        this->elements_.reserve(6);
     61
     62        RegisterObject(Listable);
    4663    }
    4764
     
    5976    void Listable::unregisterObject()
    6077    {
    61         if (this->metaList_)
    62             delete this->metaList_;
    63         this->metaList_ = 0;
     78        for (size_t i = 0; i < this->elements_.size(); ++i)
     79            Listable::deleteObjectListElement(this->elements_[i]);
     80        this->elements_.clear();
     81    }
     82
     83    /**
     84     * @brief Changes the context.
     85     * The object is removed from the current context and added to the new one. This also applies to all object lists the object is registered in.
     86     */
     87    void Listable::setContext(Context* context)
     88    {
     89        assert(context);
     90        std::vector<ObjectListBaseElement*> copy = this->elements_;
     91        this->elements_.clear();
     92
     93        for (size_t i = 0; i < copy.size(); ++i)
     94        {
     95            copy[i]->changeContext(this->context_, context);
     96            Listable::deleteObjectListElement(copy[i]);
     97        }
     98
     99        this->context_ = context;
     100    }
     101
     102    /* static */ SmallObjectAllocator& Listable::getObjectListElementAllocator()
     103    {
     104        static SmallObjectAllocator allocator(sizeof(ObjectListElement<Listable>), 1024);
     105        return allocator;
     106    }
     107
     108    /* static */ void Listable::deleteObjectListElement(ObjectListBaseElement* element)
     109    {
     110        element->~ObjectListBaseElement();
     111        Listable::getObjectListElementAllocator().free(element);
    64112    }
    65113}
  • code/trunk/src/libraries/core/object/Listable.h

    r9572 r9667  
    3737
    3838#include "core/CorePrereqs.h"
     39
     40#include <vector>
     41
    3942#include "core/class/Identifiable.h"
    4043
     
    4245{
    4346    /**
    44         @brief Listable stores the MetaObjectList which is used when storing instances in object lists.
     47        @brief Listable stores the entries of all object lists pointing to this instance.
    4548    */
    4649    class _CoreExport Listable : virtual public Identifiable
    4750    {
    48         template <class T>
    49         friend class ClassIdentifier;
     51        friend class Context;
    5052
    5153        public:
    5254            Listable();
     55            Listable(Context* context);
    5356            virtual ~Listable();
    5457
    5558            void unregisterObject();
    5659
     60            void setContext(Context* context);
     61            inline Context* getContext() const
     62                { return this->context_; }
     63
    5764        private:
    58             MetaObjectList* metaList_; //!< MetaObjectList, containing all ObjectLists and ObjectListElements the object is registered in
     65            static SmallObjectAllocator& getObjectListElementAllocator();
     66
     67            template <class T>
     68            static ObjectListElement<T>* createObjectListElement(T* object)
     69            {
     70                void* chunk = Listable::getObjectListElementAllocator().alloc();
     71                return new (chunk) ObjectListElement<T>(object);
     72            }
     73
     74            static void deleteObjectListElement(ObjectListBaseElement* element);
     75
     76            Context* context_;                             //!< The object will register itself in the object lists of this context
     77            std::vector<ObjectListBaseElement*> elements_; //!< The corresponding ObjectListElements in all object lists the object is registered in
    5978    };
    6079}
  • code/trunk/src/libraries/core/object/ObjectList.h

    r9557 r9667  
    4949#include "ObjectListBase.h"
    5050#include "ObjectListIterator.h"
     51#include "Context.h"
    5152
    5253namespace orxonox
     
    6869            typedef ObjectListIterator<T> iterator;
    6970
     71            /// Returns the size of the list
     72            inline static size_t size()
     73            {
     74                return Context::getRootContext()->getObjectList<T>()->size();
     75            }
     76
    7077            /// Returns an Iterator to the first element in the list.
    7178            inline static ObjectListElement<T>* begin()
    7279            {
    73                 ObjectListBase* list = ClassIdentifier<T>::getIdentifier()->getObjects();
    74                 return static_cast<ObjectListElement<T>*>(list->begin().element_);
     80                ObjectListBase* list = Context::getRootContext()->getObjectList<T>();
     81                return static_cast<ObjectListElement<T>*>(list->begin());
    7582            }
    7683
     
    7885            inline static ObjectListElement<T>* end()
    7986            {
    80                 ObjectListBase* list = ClassIdentifier<T>::getIdentifier()->getObjects();
    81                 return static_cast<ObjectListElement<T>*>(list->end().element_);
     87                ObjectListBase* list = Context::getRootContext()->getObjectList<T>();
     88                return static_cast<ObjectListElement<T>*>(list->end());
    8289            }
    8390
     
    8592            inline static ObjectListElement<T>* rbegin()
    8693            {
    87                 ObjectListBase* list = ClassIdentifier<T>::getIdentifier()->getObjects();
    88                 return static_cast<ObjectListElement<T>*>(list->rbegin().element_);
     94                ObjectListBase* list = Context::getRootContext()->getObjectList<T>();
     95                return static_cast<ObjectListElement<T>*>(list->rbegin());
    8996            }
    9097
     
    9299            inline static ObjectListElement<T>* rend()
    93100            {
    94                 ObjectListBase* list = ClassIdentifier<T>::getIdentifier()->getObjects();
    95                 return static_cast<ObjectListElement<T>*>(list->rend().element_);
     101                ObjectListBase* list = Context::getRootContext()->getObjectList<T>();
     102                return static_cast<ObjectListElement<T>*>(list->rend());
    96103            }
    97104    };
  • code/trunk/src/libraries/core/object/ObjectListBase.cc

    r9593 r9667  
    4141namespace orxonox
    4242{
     43    // ###############################
     44    // ###  ObjectListBaseElement  ###
     45    // ###############################
     46    void ObjectListBaseElement::removeFromList()
     47    {
     48        if (this->list_)
     49            this->list_->removeElement(this);
     50    }
     51
     52    // ###############################
     53    // ###     ObjectListBase      ###
     54    // ###############################
    4355    /**
    4456        @brief Constructor: Sets default values.
     
    4860        this->first_ = 0;
    4961        this->last_ = 0;
     62        this->size_ = 0;
    5063    }
    5164
     
    5568    ObjectListBase::~ObjectListBase()
    5669    {
    57         ObjectListBaseElement* temp;
    58         while (this->first_)
     70        ObjectListBaseElement* current = this->first_;
     71        while (current)
    5972        {
    60             temp = this->first_->next_;
    61             delete this->first_;
    62             this->first_ = temp;
     73            ObjectListBaseElement* next = current->next_;
     74
     75            current->list_ = 0;
     76            current->next_ = 0;
     77            current->prev_ = 0;
     78
     79            current = next;
    6380        }
    6481    }
    6582
    6683    /**
    67         @brief Increases all Iterators that currently point on the given element (because it gets removed).
    68         @param object The object that gets removed
     84        @brief Notifies all listeners that the given element is about to get removed.
     85        @param element The element that gets removed
     86        This is mainly used for iterators which point at the removed element
    6987    */
    70     void ObjectListBase::notifyIterators(Listable* object) const
     88    void ObjectListBase::notifyRemovalListeners(ObjectListBaseElement* element) const
    7189    {
    72         for (std::vector<void*>::const_iterator it = this->iterators_.begin(); it != this->iterators_.end(); ++it)
    73             ((Iterator<Listable>*)(*it))->incrementIfEqual(object);
    74         for (std::vector<void*>::const_iterator it = this->objectListIterators_.begin(); it != this->objectListIterators_.end(); ++it)
    75             ((ObjectListIterator<Listable>*)(*it))->incrementIfEqual(object);
     90        for (std::vector<ObjectListElementRemovalListener*>::const_iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
     91            (*it)->removedElement(element);
    7692    }
    7793
     
    7995        @brief Adds a new object to the end of the list.
    8096        @param element The element to add
    81         @return The pointer to the new ObjectListBaseElement, needed by the MetaObjectList of the added object
    8297    */
    83     ObjectListBaseElement* ObjectListBase::addElement(ObjectListBaseElement* element)
     98    void ObjectListBase::addElement(ObjectListBaseElement* element)
    8499    {
     100        if (element->list_)
     101        {
     102            orxout(internal_error) << "Element is already registered in another list" << endl;
     103            return;
     104        }
     105
     106        if (element->objectBase_)
     107            orxout(verbose, context::object_list) << "Added object to " << element->objectBase_->getIdentifier()->getName() << "-list." << endl;
     108
    85109        if (!this->last_)
    86110        {
    87111            // If the list is empty
    88112            this->last_ = element;
    89             this->first_ = this->last_; // There's only one object in the list now
     113            this->first_ = element; // There's only one object in the list now
    90114        }
    91115        else
     
    94118            ObjectListBaseElement* temp = this->last_;
    95119            this->last_ = element;
    96             this->last_->prev_ = temp;
    97             temp->next_ = this->last_;
     120            element->prev_ = temp;
     121            temp->next_ = element;
    98122        }
    99123
    100         return this->last_;
     124        element->list_ = this;
     125        ++this->size_;
    101126    }
    102127
     128    /**
     129     * @brief Removes the element from the list
     130     */
    103131    void ObjectListBase::removeElement(ObjectListBaseElement* element)
    104132    {
    105         orxout(verbose, context::object_list) << "Removing Object from " << element->objectBase_->getIdentifier()->getName() << "-list." << endl;
    106         this->notifyIterators(element->objectBase_);
     133        if (element->list_ != this)
     134        {
     135            orxout(internal_error) << "Element is not registered in this list" << endl;
     136            return;
     137        }
     138
     139        if (element->objectBase_)
     140            orxout(verbose, context::object_list) << "Removing Object from " << element->objectBase_->getIdentifier()->getName() << "-list." << endl;
     141        this->notifyRemovalListeners(element);
    107142
    108143        if (element->next_)
     
    115150        else
    116151            this->first_ = element->next_; // If there is no prev_, we deleted the first object and have to update the first_ pointer of the list
     152
     153        element->list_ = 0;
     154        element->next_ = 0;
     155        element->prev_ = 0;
     156        --this->size_;
    117157    }
    118158}
  • code/trunk/src/libraries/core/object/ObjectListBase.h

    r9593 r9667  
    4242#include "core/CorePrereqs.h"
    4343#include <vector>
     44#include "Context.h"
    4445
    4546namespace orxonox
     
    5657                @param objectBase The object to store
    5758            */
    58             ObjectListBaseElement(Listable* objectBase) : next_(0), prev_(0), objectBase_(objectBase) {}
     59            ObjectListBaseElement(Listable* object) : next_(0), prev_(0), objectBase_(object), list_(0) {}
     60            virtual ~ObjectListBaseElement() { this->removeFromList(); }
     61
     62            virtual void changeContext(Context* oldContext, Context* newContext) = 0;
    5963
    6064            ObjectListBaseElement* next_;       //!< The next element in the list
    6165            ObjectListBaseElement* prev_;       //!< The previous element in the list
    62             Listable* objectBase_;
     66            Listable* objectBase_;              //!< The object
     67            ObjectListBase* list_;              //!< The list
     68
     69        protected:
     70            void removeFromList();
    6371    };
    6472
     
    7381        public:
    7482            ObjectListElement(T* object) : ObjectListBaseElement(static_cast<Listable*>(object)), object_(object) {}
     83
     84            virtual void changeContext(Context* oldContext, Context* newContext)
     85            {
     86                // add object to new context, but only if this element belongs exactly to the old context (and not to a sub-context to avoid re-adding objects
     87                // multiple times if they are in multiple contexts)
     88                if (oldContext->getObjectList<T>() == this->list_)
     89                    newContext->addObject(this->object_);
     90
     91                // remove from old list
     92                this->removeFromList();
     93            }
     94
    7595            T* object_;              //!< The object
    7696    };
    7797
     98
     99    // ########################################
     100    // ### ObjectListElementRemovalListener ###
     101    // ########################################
     102    /// Gets called by the object list if an element is removed
     103    class _CoreExport ObjectListElementRemovalListener
     104    {
     105        public:
     106            virtual ~ObjectListElementRemovalListener() {}
     107            virtual void removedElement(ObjectListBaseElement* element) = 0;
     108    };
    78109
    79110    // ###############################
     
    97128            ~ObjectListBase();
    98129
    99             template <class T>
    100             inline ObjectListBaseElement* add(T* object)
    101                 { return this->addElement(new ObjectListElement<T>(object)); }
    102 
    103             ObjectListBaseElement* addElement(ObjectListBaseElement* element);
     130            void addElement(ObjectListBaseElement* element);
    104131            void removeElement(ObjectListBaseElement* element);
    105132
    106             /// Helper struct, used to export an element and the list to an instance of Iterator.
    107             struct Export
    108             {
    109                 Export(ObjectListBase* list, ObjectListBaseElement* element) : list_(list), element_(element) {}
    110                 ObjectListBase* list_;
    111                 ObjectListBaseElement* element_;
    112             };
     133            size_t size() const { return this->size_; }
    113134
    114135            /// Returns a pointer to the first element in the list. Works only with Iterator.
    115             inline Export begin() { return ObjectListBase::Export(this, this->first_); }
     136            inline ObjectListBaseElement* begin() const { return this->first_; }
    116137            /// Returns a pointer to the element after the last element in the list. Works only with Iterator.
    117             inline Export end() { return ObjectListBase::Export(this, 0); }
     138            inline ObjectListBaseElement* end() const { return 0; }
    118139            /// Returns a pointer to the last element in the list. Works only with Iterator.
    119             inline Export rbegin() { return ObjectListBase::Export(this, this->last_); }
     140            inline ObjectListBaseElement* rbegin() const { return this->last_; }
    120141            /// Returns a pointer to the element in front of the first element in the list. Works only with Iterator.
    121             inline Export rend() { return ObjectListBase::Export(this, 0); }
     142            inline ObjectListBaseElement* rend() const { return 0; }
    122143
    123             inline void registerIterator(void* iterator) { this->iterators_.push_back(iterator); }
    124             inline void unregisterIterator(void* iterator)
     144            inline void registerRemovalListener(ObjectListElementRemovalListener* listener) { this->listeners_.push_back(listener); }
     145            inline void unregisterRemovalListener(ObjectListElementRemovalListener* listener)
    125146            {
    126                 for (unsigned int i = 0; i < this->iterators_.size(); ++i)
     147                for (unsigned int i = 0; i < this->listeners_.size(); ++i)
    127148                {
    128                     if (iterators_[i] == iterator)
     149                    if (listeners_[i] == listener)
    129150                    {
    130                         iterators_.erase(iterators_.begin() + i);
     151                        listeners_.erase(listeners_.begin() + i);
    131152                        break;
    132153                    }
    133154                }
    134155            }
    135             inline void registerObjectListIterator(void* iterator) { this->objectListIterators_.push_back(iterator); }
    136             inline void unregisterObjectListIterator(void* iterator)
    137             {
    138                 for (unsigned int i = 0; i < this->objectListIterators_.size(); ++i)
    139                 {
    140                     if (objectListIterators_[i] == iterator)
    141                     {
    142                         objectListIterators_.erase(objectListIterators_.begin() + i);
    143                         break;
    144                     }
    145                 }
    146             }
    147             void notifyIterators(Listable* object) const;
    148156
    149157        private:
    150             ObjectListBaseElement* first_;           //!< The first element in the list
    151             ObjectListBaseElement* last_;            //!< The last element in the list
    152             std::vector<void*> iterators_;           //!< A list of Iterators pointing on an element in this list
    153             std::vector<void*> objectListIterators_; //!< A list of ObjectListIterators pointing on an element in this list
     158            void notifyRemovalListeners(ObjectListBaseElement* element) const;
     159
     160            ObjectListBaseElement* first_;                              //!< The first element in the list
     161            ObjectListBaseElement* last_;                               //!< The last element in the list
     162            size_t size_;                                               //!< The number of elements in the list
     163            std::vector<ObjectListElementRemovalListener*> listeners_;  //!< A list of Iterators pointing on an element in this list
    154164    };
    155165}
  • code/trunk/src/libraries/core/object/ObjectListIterator.h

    r9573 r9667  
    5858#include "core/class/Identifier.h"
    5959#include "ObjectList.h"
     60#include "IteratorBase.h"
    6061
    6162namespace orxonox
     
    6768    */
    6869    template <class T>
    69     class ObjectListIterator
     70    class ObjectListIterator : public IteratorBase<T, ObjectListIterator<T> >
    7071    {
    71         template <class I>
    72         friend class Iterator;
    73 
    7472        public:
    7573            /**
    7674                @brief Constructor: Sets the element, whereon the ObjectListIterator points, to zero.
    7775            */
    78             inline ObjectListIterator()
    79             {
    80                 this->element_ = 0;
    81                 ClassIdentifier<T>::getIdentifier()->getObjects()->registerObjectListIterator(this);
    82             }
     76            inline ObjectListIterator() : IteratorBase<T, ObjectListIterator<T> >(NULL) {}
    8377
    8478            /**
     
    8680                @param element The element to start with
    8781            */
    88             inline ObjectListIterator(ObjectListElement<T>* element)
    89             {
    90                 this->element_ = element;
    91                 ClassIdentifier<T>::getIdentifier()->getObjects()->registerObjectListIterator(this);
    92             }
     82            inline ObjectListIterator(ObjectListElement<T>* element) : IteratorBase<T, ObjectListIterator<T> >(element) {}
    9383
    9484            /**
     
    9686                @param other The other ObjectListIterator
    9787            */
    98             inline ObjectListIterator(const ObjectListIterator<T>& other)
    99             {
    100                 this->element_ = other.element_;
    101                 ClassIdentifier<T>::getIdentifier()->getObjects()->registerObjectListIterator(this);
    102             }
    103 
    104             /**
    105                 @brief Unregisters the ObjectListIterator from the ObjectList.
    106             */
    107             inline ~ObjectListIterator()
    108             {
    109                 ClassIdentifier<T>::getIdentifier()->getObjects()->unregisterObjectListIterator(this);
    110             }
    111 
    112             /**
    113                 @brief Assigns an ObjectListElement.
    114                 @param element The ObjectListElement
    115             */
    116             inline ObjectListIterator<T>& operator=(ObjectListElement<T>* element)
    117             {
    118                 this->element_ = element;
    119                 return (*this);
    120             }
    121 
    122             /**
    123                 @brief Assigns the element of another ObjectListIterator.
    124                 @param other The other ObjectListIterator
    125             */
    126             inline ObjectListIterator<T>& operator=(const ObjectListIterator<T>& other)
    127             {
    128                 this->element_ = other.element_;
    129                 return (*this);
    130             }
    131 
    132             /**
    133                 @brief Overloading of the ++it operator: ObjectListIterator points to the next object in the list.
    134                 @return The ObjectListIterator itself
    135             */
    136             inline const ObjectListIterator<T>& operator++()
    137             {
    138                 this->element_ = static_cast<ObjectListElement<T>*>(this->element_->next_);
    139                 return *this;
    140             }
    141 
    142             /**
    143                 @brief Overloading of the it++ operator: ObjectListIterator points to the next object in the list.
    144                 @return The ObjectListIterator itself
    145             */
    146             inline ObjectListIterator<T> operator++(int)
    147             {
    148                 ObjectListIterator<T> copy = *this;
    149                 this->element_ = static_cast<ObjectListElement<T>*>(this->element_->next_);
    150                 return copy;
    151             }
    152 
    153             /**
    154                 @brief Overloading of the --it operator: ObjectListIterator points to the previous object in the list.
    155                 @return The ObjectListIterator itself
    156             */
    157             inline const ObjectListIterator<T>& operator--()
    158             {
    159                 this->element_ = static_cast<ObjectListElement<T>*>(this->element_->prev_);
    160                 return *this;
    161             }
    162 
    163             /**
    164                 @brief Overloading of the it-- operator: ObjectListIterator points to the previous object in the list.
    165                 @return The ObjectListIterator itself
    166             */
    167             inline ObjectListIterator<T> operator--(int i)
    168             {
    169                 ObjectListIterator<T> copy = *this;
    170                 this->element_ = static_cast<ObjectListElement<T>*>(this->element_->prev_);
    171                 return copy;
    172             }
     88            inline ObjectListIterator(const IteratorBase<T, ObjectListIterator<T> >& other) : IteratorBase<T, ObjectListIterator<T> >(other) {}
    17389
    17490            /**
     
    17894            inline T* operator*() const
    17995            {
    180                 return this->element_->object_;
     96                return static_cast<ObjectListElement<T>*>(this->element_)->object_;
    18197            }
    18298
     
    187103            inline T* operator->() const
    188104            {
    189                 return this->element_->object_;
     105                return static_cast<ObjectListElement<T>*>(this->element_)->object_;
    190106            }
    191 
    192             /**
    193                 @brief Overloading of the typecast-operator to bool: returns true if the ObjectListIterator points to an existing object.
    194                 @return True if the ObjectListIterator points to an existing object.
    195             */
    196             inline operator bool() const
    197             {
    198                 return (this->element_ != 0);
    199             }
    200 
    201             /**
    202                 @brief Overloading of the == operator to compare with another ObjectListIterator.
    203                 @param compare The other ObjectListIterator
    204                 @return True if the ObjectListIterator point to the same element
    205             */
    206             inline bool operator==(const ObjectListIterator<T>& compare) const
    207             {
    208                 return (this->element_ == compare.element_);
    209             }
    210 
    211             /**
    212                 @brief Overloading of the != operator to compare with another ObjectListIterator.
    213                 @param compare The other ObjectListIterator
    214                 @return True if the ObjectListIterator point to different elements
    215             */
    216             inline bool operator!=(const ObjectListIterator<T>& compare) const
    217             {
    218                 return (this->element_ != compare.element_);
    219             }
    220 
    221             /**
    222                 @brief Increments the ObjectListIterator if it points at the given object.
    223                 @param object The object to compare with
    224             */
    225             inline void incrementIfEqual(Listable* object)
    226             {
    227                 if (this->element_ && this->element_->objectBase_ == object)
    228                     this->operator++();
    229             }
    230 
    231         private:
    232             ObjectListElement<T>* element_;        //!< The element the iterator points at
    233107    };
    234108}
Note: See TracChangeset for help on using the changeset viewer.