Panda3D
 All Classes Functions Variables Enumerations
internalNameCollection.cxx
1 // Filename: internalNameCollection.cxx
2 // Created by: drose (16Mar02)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "internalNameCollection.h"
16 
17 #include "indent.h"
18 
19 ////////////////////////////////////////////////////////////////////
20 // Function: InternalNameCollection::Constructor
21 // Access: Published
22 // Description:
23 ////////////////////////////////////////////////////////////////////
24 InternalNameCollection::
25 InternalNameCollection() {
26 }
27 
28 ////////////////////////////////////////////////////////////////////
29 // Function: InternalNameCollection::Copy Constructor
30 // Access: Published
31 // Description:
32 ////////////////////////////////////////////////////////////////////
33 InternalNameCollection::
34 InternalNameCollection(const InternalNameCollection &copy) :
35  _names(copy._names)
36 {
37 }
38 
39 ////////////////////////////////////////////////////////////////////
40 // Function: InternalNameCollection::Copy Assignment Operator
41 // Access: Published
42 // Description:
43 ////////////////////////////////////////////////////////////////////
44 void InternalNameCollection::
45 operator = (const InternalNameCollection &copy) {
46  _names = copy._names;
47 }
48 
49 ////////////////////////////////////////////////////////////////////
50 // Function: InternalNameCollection::add_name
51 // Access: Published
52 // Description: Adds a new InternalName to the collection.
53 ////////////////////////////////////////////////////////////////////
55 add_name(const InternalName *name) {
56  // If the pointer to our internal array is shared by any other
57  // InternalNameCollections, we have to copy the array now so we won't
58  // inadvertently modify any of our brethren InternalNameCollection
59  // objects.
60 
61  if (_names.get_ref_count() > 1) {
62  InternalNames old_names = _names;
63  _names = InternalNames::empty_array(0);
64  _names.v() = old_names.v();
65  }
66 
67  _names.push_back(name);
68 }
69 
70 ////////////////////////////////////////////////////////////////////
71 // Function: InternalNameCollection::remove_name
72 // Access: Published
73 // Description: Removes the indicated InternalName from the collection.
74 // Returns true if the name was removed, false if it was
75 // not a member of the collection.
76 ////////////////////////////////////////////////////////////////////
78 remove_name(const InternalName *name) {
79  int name_index = -1;
80  for (int i = 0; name_index == -1 && i < (int)_names.size(); i++) {
81  if (_names[i] == name) {
82  name_index = i;
83  }
84  }
85 
86  if (name_index == -1) {
87  // The indicated name was not a member of the collection.
88  return false;
89  }
90 
91  // If the pointer to our internal array is shared by any other
92  // InternalNameCollections, we have to copy the array now so we won't
93  // inadvertently modify any of our brethren InternalNameCollection
94  // objects.
95 
96  if (_names.get_ref_count() > 1) {
97  InternalNames old_names = _names;
98  _names = InternalNames::empty_array(0);
99  _names.v() = old_names.v();
100  }
101 
102  _names.erase(_names.begin() + name_index);
103  return true;
104 }
105 
106 ////////////////////////////////////////////////////////////////////
107 // Function: InternalNameCollection::add_names_from
108 // Access: Published
109 // Description: Adds all the InternalNames indicated in the other
110 // collection to this name. The other names are simply
111 // appended to the end of the names in this list;
112 // duplicates are not automatically removed.
113 ////////////////////////////////////////////////////////////////////
116  int other_num_names = other.get_num_names();
117  for (int i = 0; i < other_num_names; i++) {
118  add_name(other.get_name(i));
119  }
120 }
121 
122 
123 ////////////////////////////////////////////////////////////////////
124 // Function: InternalNameCollection::remove_names_from
125 // Access: Published
126 // Description: Removes from this collection all of the InternalNames
127 // listed in the other collection.
128 ////////////////////////////////////////////////////////////////////
131  InternalNames new_names;
132  int num_names = get_num_names();
133  for (int i = 0; i < num_names; i++) {
134  const InternalName *name = get_name(i);
135  if (!other.has_name(name)) {
136  new_names.push_back(name);
137  }
138  }
139  _names = new_names;
140 }
141 
142 ////////////////////////////////////////////////////////////////////
143 // Function: InternalNameCollection::remove_duplicate_names
144 // Access: Published
145 // Description: Removes any duplicate entries of the same InternalNames
146 // on this collection. If a InternalName appears multiple
147 // times, the first appearance is retained; subsequent
148 // appearances are removed.
149 ////////////////////////////////////////////////////////////////////
152  InternalNames new_names;
153 
154  int num_names = get_num_names();
155  for (int i = 0; i < num_names; i++) {
156  const InternalName *name = get_name(i);
157  bool duplicated = false;
158 
159  for (int j = 0; j < i && !duplicated; j++) {
160  duplicated = (name == get_name(j));
161  }
162 
163  if (!duplicated) {
164  new_names.push_back(name);
165  }
166  }
167 
168  _names = new_names;
169 }
170 
171 ////////////////////////////////////////////////////////////////////
172 // Function: InternalNameCollection::has_name
173 // Access: Published
174 // Description: Returns true if the indicated InternalName appears in
175 // this collection, false otherwise.
176 ////////////////////////////////////////////////////////////////////
178 has_name(const InternalName *name) const {
179  for (int i = 0; i < get_num_names(); i++) {
180  if (name == get_name(i)) {
181  return true;
182  }
183  }
184  return false;
185 }
186 
187 ////////////////////////////////////////////////////////////////////
188 // Function: InternalNameCollection::clear
189 // Access: Published
190 // Description: Removes all InternalNames from the collection.
191 ////////////////////////////////////////////////////////////////////
193 clear() {
194  _names.clear();
195 }
196 
197 ////////////////////////////////////////////////////////////////////
198 // Function: InternalNameCollection::get_num_names
199 // Access: Published
200 // Description: Returns the number of InternalNames in the collection.
201 ////////////////////////////////////////////////////////////////////
203 get_num_names() const {
204  return _names.size();
205 }
206 
207 ////////////////////////////////////////////////////////////////////
208 // Function: InternalNameCollection::get_name
209 // Access: Published
210 // Description: Returns the nth InternalName in the collection.
211 ////////////////////////////////////////////////////////////////////
212 const InternalName *InternalNameCollection::
213 get_name(int index) const {
214  nassertr(index >= 0 && index < (int)_names.size(), NULL);
215 
216  return _names[index];
217 }
218 
219 ////////////////////////////////////////////////////////////////////
220 // Function: InternalNameCollection::operator []
221 // Access: Published
222 // Description: Returns the nth InternalName in the collection. This is
223 // the same as get_name(), but it may be a more
224 // convenient way to access it.
225 ////////////////////////////////////////////////////////////////////
226 const InternalName *InternalNameCollection::
227 operator [] (int index) const {
228  nassertr(index >= 0 && index < (int)_names.size(), NULL);
229 
230  return _names[index];
231 }
232 
233 ////////////////////////////////////////////////////////////////////
234 // Function: InternalNameCollection::size
235 // Access: Published
236 // Description: Returns the number of names in the collection. This
237 // is the same thing as get_num_names().
238 ////////////////////////////////////////////////////////////////////
240 size() const {
241  return _names.size();
242 }
243 
244 ////////////////////////////////////////////////////////////////////
245 // Function: InternalNameCollection::output
246 // Access: Published
247 // Description: Writes a brief one-line description of the
248 // InternalNameCollection to the indicated output stream.
249 ////////////////////////////////////////////////////////////////////
251 output(ostream &out) const {
252  if (get_num_names() == 1) {
253  out << "1 InternalName";
254  } else {
255  out << get_num_names() << " InternalNames";
256  }
257 }
258 
259 ////////////////////////////////////////////////////////////////////
260 // Function: InternalNameCollection::write
261 // Access: Published
262 // Description: Writes a complete multi-line description of the
263 // InternalNameCollection to the indicated output stream.
264 ////////////////////////////////////////////////////////////////////
266 write(ostream &out, int indent_level) const {
267  for (int i = 0; i < get_num_names(); i++) {
268  indent(out, indent_level) << *get_name(i) << "\n";
269  }
270 }
int size() const
Returns the number of names in the collection.
void write(ostream &out, int indent_level=0) const
Writes a complete multi-line description of the InternalNameCollection to the indicated output stream...
const InternalName * operator[](int index) const
Returns the nth InternalName in the collection.
void clear()
Removes all InternalNames from the collection.
void add_names_from(const InternalNameCollection &other)
Adds all the InternalNames indicated in the other collection to this name.
bool remove_name(const InternalName *name)
Removes the indicated InternalName from the collection.
bool has_name(const InternalName *name) const
Returns true if the indicated InternalName appears in this collection, false otherwise.
void remove_names_from(const InternalNameCollection &other)
Removes from this collection all of the InternalNames listed in the other collection.
void add_name(const InternalName *name)
Adds a new InternalName to the collection.
void output(ostream &out) const
Writes a brief one-line description of the InternalNameCollection to the indicated output stream...
const InternalName * get_name(int index) const
Returns the nth InternalName in the collection.
void remove_duplicate_names()
Removes any duplicate entries of the same InternalNames on this collection.
int get_num_names() const
Returns the number of InternalNames in the collection.