1 | /* |
---|
2 | * ORXONOX - the hottest 3D action shooter ever to exist |
---|
3 | * > www.orxonox.net < |
---|
4 | * |
---|
5 | * |
---|
6 | * License notice: |
---|
7 | * |
---|
8 | * This program is free software; you can redistribute it and/or |
---|
9 | * modify it under the terms of the GNU General Public License |
---|
10 | * as published by the Free Software Foundation; either version 2 |
---|
11 | * of the License, or (at your option) any later version. |
---|
12 | * |
---|
13 | * This program is distributed in the hope that it will be useful, |
---|
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
16 | * GNU General Public License for more details. |
---|
17 | * |
---|
18 | * You should have received a copy of the GNU General Public License |
---|
19 | * along with this program; if not, write to the Free Software |
---|
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
---|
21 | * |
---|
22 | * Author: |
---|
23 | * Fabian 'x3n' Landau |
---|
24 | * Co-authors: |
---|
25 | * ... |
---|
26 | * |
---|
27 | */ |
---|
28 | |
---|
29 | /** |
---|
30 | @file |
---|
31 | @brief Implementation of the ObjectListBase class. |
---|
32 | */ |
---|
33 | |
---|
34 | #include "ObjectListBase.h" |
---|
35 | |
---|
36 | #include <set> |
---|
37 | #include "Iterator.h" |
---|
38 | #include "Listable.h" |
---|
39 | #include "ObjectListIterator.h" |
---|
40 | |
---|
41 | namespace orxonox |
---|
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 | // ############################### |
---|
55 | /** |
---|
56 | @brief Constructor: Sets default values. |
---|
57 | */ |
---|
58 | ObjectListBase::ObjectListBase() |
---|
59 | { |
---|
60 | this->first_ = nullptr; |
---|
61 | this->last_ = nullptr; |
---|
62 | this->size_ = 0; |
---|
63 | } |
---|
64 | |
---|
65 | /** |
---|
66 | @brief Destructor: Detaches all list-elements, but doesn't delete them (nor the objects). |
---|
67 | */ |
---|
68 | ObjectListBase::~ObjectListBase() |
---|
69 | { |
---|
70 | ObjectListBaseElement* current = this->first_; |
---|
71 | while (current) |
---|
72 | { |
---|
73 | ObjectListBaseElement* next = current->next_; |
---|
74 | |
---|
75 | current->list_ = nullptr; |
---|
76 | current->next_ = nullptr; |
---|
77 | current->prev_ = nullptr; |
---|
78 | |
---|
79 | current = next; |
---|
80 | } |
---|
81 | |
---|
82 | if (!this->listeners_.empty()) |
---|
83 | orxout(internal_error) << "Deleting ObjectListBase but it still has " << this->listeners_.size() << " listeners. This will lead to a crash. " |
---|
84 | << "Ensure that all Iterators are destroyed before deleting object lists." << endl; |
---|
85 | } |
---|
86 | |
---|
87 | /** |
---|
88 | @brief Notifies all listeners that the given element is about to get removed. |
---|
89 | @param element The element that gets removed |
---|
90 | This is mainly used for iterators which point at the removed element |
---|
91 | */ |
---|
92 | void ObjectListBase::notifyRemovalListeners(ObjectListBaseElement* element) const |
---|
93 | { |
---|
94 | for (ObjectListElementRemovalListener* listener : this->listeners_) |
---|
95 | listener->removedElement(element); |
---|
96 | } |
---|
97 | |
---|
98 | /** |
---|
99 | @brief Adds a new object to the end of the list. |
---|
100 | @param element The element to add |
---|
101 | */ |
---|
102 | void ObjectListBase::addElement(ObjectListBaseElement* element) |
---|
103 | { |
---|
104 | if (element->list_) |
---|
105 | { |
---|
106 | orxout(internal_error) << "Element is already registered in another list" << endl; |
---|
107 | return; |
---|
108 | } |
---|
109 | |
---|
110 | if (element->objectBase_) |
---|
111 | orxout(verbose, context::object_list) << "Added object to " << element->objectBase_->getIdentifier()->getName() << "-list." << endl; |
---|
112 | |
---|
113 | if (!this->last_) |
---|
114 | { |
---|
115 | // If the list is empty |
---|
116 | this->last_ = element; |
---|
117 | this->first_ = element; // There's only one object in the list now |
---|
118 | } |
---|
119 | else |
---|
120 | { |
---|
121 | // If the list isn't empty |
---|
122 | ObjectListBaseElement* temp = this->last_; |
---|
123 | this->last_ = element; |
---|
124 | element->prev_ = temp; |
---|
125 | temp->next_ = element; |
---|
126 | } |
---|
127 | |
---|
128 | element->list_ = this; |
---|
129 | ++this->size_; |
---|
130 | } |
---|
131 | |
---|
132 | /** |
---|
133 | * @brief Removes the element from the list |
---|
134 | */ |
---|
135 | void ObjectListBase::removeElement(ObjectListBaseElement* element) |
---|
136 | { |
---|
137 | if (element->list_ != this) |
---|
138 | { |
---|
139 | orxout(internal_error) << "Element is not registered in this list" << endl; |
---|
140 | return; |
---|
141 | } |
---|
142 | |
---|
143 | if (element->objectBase_) |
---|
144 | orxout(verbose, context::object_list) << "Removing Object from " << element->objectBase_->getIdentifier()->getName() << "-list." << endl; |
---|
145 | this->notifyRemovalListeners(element); |
---|
146 | |
---|
147 | if (element->next_) |
---|
148 | element->next_->prev_ = element->prev_; |
---|
149 | else |
---|
150 | this->last_ = element->prev_; // If there is no next_, we deleted the last object and have to update the last_ pointer of the list |
---|
151 | |
---|
152 | if (element->prev_) |
---|
153 | element->prev_->next_ = element->next_; |
---|
154 | else |
---|
155 | this->first_ = element->next_; // If there is no prev_, we deleted the first object and have to update the first_ pointer of the list |
---|
156 | |
---|
157 | element->list_ = nullptr; |
---|
158 | element->next_ = nullptr; |
---|
159 | element->prev_ = nullptr; |
---|
160 | --this->size_; |
---|
161 | } |
---|
162 | } |
---|