Changeset 9667 for code/trunk/src/libraries/core/object
- Timestamp:
- Aug 25, 2013, 9:08:42 PM (11 years ago)
- Location:
- code/trunk
- Files:
-
- 2 deleted
- 12 edited
- 2 copied
Legend:
- Unmodified
- Added
- Removed
-
code/trunk
- Property svn:mergeinfo changed
/code/branches/core6 merged: 9552-9554,9556-9574,9577-9579,9585-9593,9596-9612,9626-9662
- Property svn:mergeinfo changed
-
code/trunk/src/libraries/core/object/CMakeLists.txt
r9591 r9667 3 3 Destroyable.cc 4 4 Listable.cc 5 MetaObjectList.cc6 5 ObjectListBase.cc 7 6 ) -
code/trunk/src/libraries/core/object/ClassFactory.h
r9563 r9667 43 43 44 44 #include "util/Output.h" 45 #include "core/class/Identifier.h"46 45 47 46 namespace orxonox … … 50 49 // ### Factory ### 51 50 // ########################### 52 /// Base-class of ClassFactory.51 /// Base-class of all factories. 53 52 class _CoreExport Factory 54 53 { 55 54 public: 56 virtual ~Factory() {} ;57 virtual OrxonoxClass* fabricate(BaseObject* creator) = 0;55 virtual ~Factory() {} 56 virtual Identifiable* fabricate(Context* context) = 0; 58 57 }; 59 58 … … 61 60 // ### ClassFactory ### 62 61 // ############################### 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 64 63 template <class T> 65 64 class ClassFactory : public Factory 66 65 { 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 { 67 75 public: 68 /**69 @brief Constructor: Adds the ClassFactory to the Identifier of the same type.70 @param name The name of the class71 @param bLoadable True if the class can be loaded through XML72 */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 80 76 /** 81 77 @brief Creates and returns a new object of class T. 82 78 @return The new object 83 79 */ 84 inline OrxonoxClass* fabricate(BaseObject* creator)80 inline Identifiable* fabricate(Context* context) 85 81 { 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)); 87 101 } 88 102 }; -
code/trunk/src/libraries/core/object/Context.cc
r9591 r9667 33 33 34 34 #include "Context.h" 35 #include "core/class/Identifier.h" 36 #include "core/CoreIncludes.h" 35 37 36 38 namespace orxonox 37 39 { 38 Context::Context(Context* context) : parentContext_(context) 40 RegisterClass(Context); 41 42 Context* Context::rootContext_s = 0; 43 44 Context* getContextForInitializationOfOtherContexts() 39 45 { 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); 40 66 } 41 67 42 68 Context::~Context() 43 69 { 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; 44 81 } 45 82 46 83 /*static*/ Context* Context::getRootContext() 47 84 { 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]; 50 98 } 51 99 } -
code/trunk/src/libraries/core/object/Context.h
r9591 r9667 37 37 #include "core/CorePrereqs.h" 38 38 39 #include <vector> 40 41 #include "Listable.h" 42 39 43 namespace orxonox 40 44 { 41 class _CoreExport Context 45 class _CoreExport Context : virtual public Listable 42 46 { 43 47 public: 48 static void setRootContext(Context* context); 49 static Context* getRootContext(); 50 44 51 Context(Context* context); 45 52 virtual ~Context(); … … 48 55 { return this->parentContext_; } 49 56 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 } 51 72 52 73 private: 53 74 Context* parentContext_; 75 std::vector<ObjectListBase*> objectLists_; 76 77 static Context* rootContext_s; 54 78 }; 55 79 } -
code/trunk/src/libraries/core/object/Iterator.h
r9573 r9667 56 56 #include "core/CorePrereqs.h" 57 57 58 #include "core/class/Identifier.h"59 58 #include "ObjectListBase.h" 59 #include "IteratorBase.h" 60 60 61 61 namespace orxonox … … 70 70 */ 71 71 template <class T> 72 class Iterator 72 class Iterator : public IteratorBase<T, Iterator<T> > 73 73 { 74 74 public: … … 76 76 @brief Constructor: Sets the element, whereon the iterator points, to zero. 77 77 */ 78 inline Iterator() 79 { 80 this->element_ = 0; 81 this->list_ = 0; 82 } 78 inline Iterator() : IteratorBase<T, Iterator<T> >(NULL) {} 83 79 84 80 /** 85 @brief Constructor: Sets this element to the exported element.86 @param e xp The exportedelement81 @brief Constructor: Sets this element to a given element 82 @param element The element 87 83 */ 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) {} 94 85 95 86 /** … … 97 88 @param other The other Iterator 98 89 */ 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) {} 169 91 170 92 /** … … 172 94 @param element The element 173 95 */ 174 template <class O> 175 inline Iterator<T>& operator=(ObjectListElement<O>* element) 96 inline Iterator<T>& operator=(ObjectListBaseElement* element) 176 97 { 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); 184 99 return (*this); 185 }186 187 /**188 @brief Assigns the element of an ObjectListIterator.189 @param other The ObjectListIterator190 */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 itself207 */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 itself217 */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 itself228 */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 itself238 */239 inline Iterator<T> operator--(int i)240 {241 Iterator<T> copy = *this;242 this->element_ = this->element_->prev_;243 return copy;244 100 } 245 101 … … 261 117 return orxonox_cast<T*>(this->element_->objectBase_); 262 118 } 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() const269 {270 return (this->element_ != 0);271 }272 273 /**274 @brief Overloading of the == operator to compare with another Iterator.275 @param compare The other Iterator276 @return True if the iterators point to the same element277 */278 inline bool operator==(const Iterator<T>& compare) const279 {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 Iterator286 @return True if the iterators point to different elements287 */288 inline bool operator!=(const Iterator<T>& compare) const289 {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 with296 */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 at305 ObjectListBase* list_; //!< The list wherein the element is306 119 }; 307 120 } -
code/trunk/src/libraries/core/object/Listable.cc
r9572 r9667 33 33 34 34 #include "Listable.h" 35 36 #include "core/object/MetaObjectList.h" 35 #include "core/CoreIncludes.h" 36 #include "ObjectListBase.h" 37 #include "Context.h" 37 38 38 39 namespace orxonox 39 40 { 41 RegisterClass(Listable); 42 40 43 /** 41 @brief Constructor: creates the meta-object-list.44 @brief Constructor: Allocates space in the element list. 42 45 */ 43 46 Listable::Listable() 44 47 { 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); 46 63 } 47 64 … … 59 76 void Listable::unregisterObject() 60 77 { 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); 64 112 } 65 113 } -
code/trunk/src/libraries/core/object/Listable.h
r9572 r9667 37 37 38 38 #include "core/CorePrereqs.h" 39 40 #include <vector> 41 39 42 #include "core/class/Identifiable.h" 40 43 … … 42 45 { 43 46 /** 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. 45 48 */ 46 49 class _CoreExport Listable : virtual public Identifiable 47 50 { 48 template <class T> 49 friend class ClassIdentifier; 51 friend class Context; 50 52 51 53 public: 52 54 Listable(); 55 Listable(Context* context); 53 56 virtual ~Listable(); 54 57 55 58 void unregisterObject(); 56 59 60 void setContext(Context* context); 61 inline Context* getContext() const 62 { return this->context_; } 63 57 64 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 59 78 }; 60 79 } -
code/trunk/src/libraries/core/object/ObjectList.h
r9557 r9667 49 49 #include "ObjectListBase.h" 50 50 #include "ObjectListIterator.h" 51 #include "Context.h" 51 52 52 53 namespace orxonox … … 68 69 typedef ObjectListIterator<T> iterator; 69 70 71 /// Returns the size of the list 72 inline static size_t size() 73 { 74 return Context::getRootContext()->getObjectList<T>()->size(); 75 } 76 70 77 /// Returns an Iterator to the first element in the list. 71 78 inline static ObjectListElement<T>* begin() 72 79 { 73 ObjectListBase* list = C lassIdentifier<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()); 75 82 } 76 83 … … 78 85 inline static ObjectListElement<T>* end() 79 86 { 80 ObjectListBase* list = C lassIdentifier<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()); 82 89 } 83 90 … … 85 92 inline static ObjectListElement<T>* rbegin() 86 93 { 87 ObjectListBase* list = C lassIdentifier<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()); 89 96 } 90 97 … … 92 99 inline static ObjectListElement<T>* rend() 93 100 { 94 ObjectListBase* list = C lassIdentifier<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()); 96 103 } 97 104 }; -
code/trunk/src/libraries/core/object/ObjectListBase.cc
r9593 r9667 41 41 namespace orxonox 42 42 { 43 // ############################### 44 // ### ObjectListBaseElement ### 45 // ############################### 46 void ObjectListBaseElement::removeFromList() 47 { 48 if (this->list_) 49 this->list_->removeElement(this); 50 } 51 52 // ############################### 53 // ### ObjectListBase ### 54 // ############################### 43 55 /** 44 56 @brief Constructor: Sets default values. … … 48 60 this->first_ = 0; 49 61 this->last_ = 0; 62 this->size_ = 0; 50 63 } 51 64 … … 55 68 ObjectListBase::~ObjectListBase() 56 69 { 57 ObjectListBaseElement* temp;58 while ( this->first_)70 ObjectListBaseElement* current = this->first_; 71 while (current) 59 72 { 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; 63 80 } 64 81 } 65 82 66 83 /** 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 69 87 */ 70 void ObjectListBase::notify Iterators(Listable* object) const88 void ObjectListBase::notifyRemovalListeners(ObjectListBaseElement* element) const 71 89 { 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); 76 92 } 77 93 … … 79 95 @brief Adds a new object to the end of the list. 80 96 @param element The element to add 81 @return The pointer to the new ObjectListBaseElement, needed by the MetaObjectList of the added object82 97 */ 83 ObjectListBaseElement*ObjectListBase::addElement(ObjectListBaseElement* element)98 void ObjectListBase::addElement(ObjectListBaseElement* element) 84 99 { 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 85 109 if (!this->last_) 86 110 { 87 111 // If the list is empty 88 112 this->last_ = element; 89 this->first_ = this->last_; // There's only one object in the list now113 this->first_ = element; // There's only one object in the list now 90 114 } 91 115 else … … 94 118 ObjectListBaseElement* temp = this->last_; 95 119 this->last_ = element; 96 this->last_->prev_ = temp;97 temp->next_ = this->last_;120 element->prev_ = temp; 121 temp->next_ = element; 98 122 } 99 123 100 return this->last_; 124 element->list_ = this; 125 ++this->size_; 101 126 } 102 127 128 /** 129 * @brief Removes the element from the list 130 */ 103 131 void ObjectListBase::removeElement(ObjectListBaseElement* element) 104 132 { 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); 107 142 108 143 if (element->next_) … … 115 150 else 116 151 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_; 117 157 } 118 158 } -
code/trunk/src/libraries/core/object/ObjectListBase.h
r9593 r9667 42 42 #include "core/CorePrereqs.h" 43 43 #include <vector> 44 #include "Context.h" 44 45 45 46 namespace orxonox … … 56 57 @param objectBase The object to store 57 58 */ 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; 59 63 60 64 ObjectListBaseElement* next_; //!< The next element in the list 61 65 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(); 63 71 }; 64 72 … … 73 81 public: 74 82 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 75 95 T* object_; //!< The object 76 96 }; 77 97 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 }; 78 109 79 110 // ############################### … … 97 128 ~ObjectListBase(); 98 129 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); 104 131 void removeElement(ObjectListBaseElement* element); 105 132 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_; } 113 134 114 135 /// 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_; } 116 137 /// 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; } 118 139 /// 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_; } 120 141 /// 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; } 122 143 123 inline void register Iterator(void* iterator) { this->iterators_.push_back(iterator); }124 inline void unregister Iterator(void* iterator)144 inline void registerRemovalListener(ObjectListElementRemovalListener* listener) { this->listeners_.push_back(listener); } 145 inline void unregisterRemovalListener(ObjectListElementRemovalListener* listener) 125 146 { 126 for (unsigned int i = 0; i < this-> iterators_.size(); ++i)147 for (unsigned int i = 0; i < this->listeners_.size(); ++i) 127 148 { 128 if ( iterators_[i] == iterator)149 if (listeners_[i] == listener) 129 150 { 130 iterators_.erase(iterators_.begin() + i);151 listeners_.erase(listeners_.begin() + i); 131 152 break; 132 153 } 133 154 } 134 155 } 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;148 156 149 157 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 154 164 }; 155 165 } -
code/trunk/src/libraries/core/object/ObjectListIterator.h
r9573 r9667 58 58 #include "core/class/Identifier.h" 59 59 #include "ObjectList.h" 60 #include "IteratorBase.h" 60 61 61 62 namespace orxonox … … 67 68 */ 68 69 template <class T> 69 class ObjectListIterator 70 class ObjectListIterator : public IteratorBase<T, ObjectListIterator<T> > 70 71 { 71 template <class I>72 friend class Iterator;73 74 72 public: 75 73 /** 76 74 @brief Constructor: Sets the element, whereon the ObjectListIterator points, to zero. 77 75 */ 78 inline ObjectListIterator() 79 { 80 this->element_ = 0; 81 ClassIdentifier<T>::getIdentifier()->getObjects()->registerObjectListIterator(this); 82 } 76 inline ObjectListIterator() : IteratorBase<T, ObjectListIterator<T> >(NULL) {} 83 77 84 78 /** … … 86 80 @param element The element to start with 87 81 */ 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) {} 93 83 94 84 /** … … 96 86 @param other The other ObjectListIterator 97 87 */ 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) {} 173 89 174 90 /** … … 178 94 inline T* operator*() const 179 95 { 180 return this->element_->object_;96 return static_cast<ObjectListElement<T>*>(this->element_)->object_; 181 97 } 182 98 … … 187 103 inline T* operator->() const 188 104 { 189 return this->element_->object_;105 return static_cast<ObjectListElement<T>*>(this->element_)->object_; 190 106 } 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() const197 {198 return (this->element_ != 0);199 }200 201 /**202 @brief Overloading of the == operator to compare with another ObjectListIterator.203 @param compare The other ObjectListIterator204 @return True if the ObjectListIterator point to the same element205 */206 inline bool operator==(const ObjectListIterator<T>& compare) const207 {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 ObjectListIterator214 @return True if the ObjectListIterator point to different elements215 */216 inline bool operator!=(const ObjectListIterator<T>& compare) const217 {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 with224 */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 at233 107 }; 234 108 }
Note: See TracChangeset
for help on using the changeset viewer.