Vegastrike 0.5.1 rc1  1.0
Original sources for Vegastrike Evolved
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
collection.cpp
Go to the documentation of this file.
1 #include "collection.h"
2 
3 #if defined (USE_OLD_COLLECTION)
4 #include "oldcollection.cpp"
5 #elif defined (USE_STL_COLLECTION)
6 
7 #include <list>
8 #include <vector>
9 #ifndef LIST_TESTING
10 #include "unit_generic.h"
11 #else
12 #include "testcollection/unit.h"
13 #endif
14 
15 using std::list;
16 using std::vector;
17 //UnitIterator BEGIN:
18 
20 {
21  if (col != orig.col) {
22  if (col)
23  col->unreg( this );
24  col = orig.col;
25  if (col)
26  col->reg( this );
27  }
28  it = orig.it;
29  return *this;
30 }
31 
33 {
34  col = orig.col;
35  it = orig.it;
36  if (col)
37  col->reg( this );
38 }
39 
41 {
42  col = orig;
43  for (it = orig->u.begin(); it != col->u.end(); ++it)
44  if (*it)
45  break;
46  col->reg( this );
47 }
48 
50 {
51  if (col)
52  col->unreg( this );
53 }
54 
56 {
57  if ( col && it != col->u.end() )
58  col->erase( it );
59 }
60 
62 {
63  if ( col && it != col->u.end() ) {
64  otherlist.prepend( *it );
65  col->erase( it );
66  }
67 }
68 
70 {
71  if (col && unit)
72  col->insert( it, unit );
73 }
74 
76 {
77  list< Unit* >::iterator tmp = it;
78  if ( col && unit && it != col->u.end() ) {
79  ++tmp;
80  col->insert( tmp, unit );
81  }
82 }
83 
85 {
86  if ( !col || it == col->u.end() ) return;
87  if ( (*it) != NULL && (*it)->Killed() )
88  col->erase( it );
89  else
90  ++it;
91  while ( it != col->u.end() ) {
92  if ( (*it) == NULL )
93  ++it;
94  else if ( (*it)->Killed() )
95  col->erase( it );
96  else
97  break;
98  }
99 }
100 
102 {
103  advance();
104  if ( !col || it == col->u.end() )
105  return NULL;
106  return *it;
107 }
108 
109 //UnitIterator END:
110 
111 //ConstIterator Begin:
112 
114 {
115  col = orig.col;
116  it = orig.it;
117  return *this;
118 }
119 
121 {
122  col = orig.col;
123  it = orig.it;
124 }
125 
127 {
128  col = orig;
129  for (it = orig->u.begin(); it != col->u.end(); ++it)
130  if (*it)
131  break;
132 }
133 
135 {}
136 
138 {
139  advance();
140  if ( col && it != col->u.end() )
141  return *it;
142  return NULL;
143 }
144 
146 {
147  if ( !col || it == col->u.end() ) return;
148  ++it;
149  while ( it != col->u.end() ) {
150  if ( (*it) == NULL )
151  ++it;
152  else if ( (*it)->Killed() )
153  ++it;
154  else
155  break;
156  }
157 }
158 
160 {
161  advance();
162  return *this;
163 }
164 
166 {
167  UnitCollection::ConstIterator tmp( *this );
168  advance();
169  return tmp;
170 }
171 
172 //ConstIterator END:
173 
174 //UnitCollection BEGIN:
175 
177 {
178  activeIters.reserve( 20 );
179 }
180 
182 {
183  list< Unit* >::const_iterator in = uc.u.begin();
184  while ( in != uc.u.end() ) {
185  append( *in );
186  ++in;
187  }
188 }
189 
191 {
192  if (unit) {
193  for (list< Unit* >::iterator it = u.begin(); it != u.end(); ++it)
194  if (*it == unit)
195  return;
196  unit->Ref();
197  u.push_front( unit );
198  }
199 }
200 
202 {
203  if (unit) {
204  unit->Ref();
205  u.push_front( unit );
206  }
207 }
208 
210 {
211  Unit *tmp = NULL;
212  if (!it) return;
213  list< Unit* >::iterator tmpI = u.begin();
214  while ( (tmp = **it) ) {
215  tmp->Ref();
216  u.insert( tmpI, tmp );
217  ++tmpI;
218  it->advance();
219  }
220 }
221 
223 {
224  if (un) {
225  un->Ref();
226  u.push_back( un );
227  }
228 }
229 
231 {
232  if (!it) return;
233  Unit *tmp = NULL;
234  while ( (tmp = **it) ) {
235  tmp->Ref();
236  u.push_back( tmp );
237  it->advance();
238  }
239 }
240 
241 void UnitCollection::insert( list< Unit* >::iterator &temp, Unit *unit )
242 {
243  if (unit) {
244  unit->Ref();
245  temp = u.insert( temp, unit );
246  }
247  temp = u.end();
248 }
249 
251 {
252  if ( !activeIters.empty() ) {
253  fprintf(stderr, "WARNING! Attempting to clear a collection with active iterators!\n" );
254  return;
255  }
256 
257  for (list< Unit* >::iterator it = u.begin(); it != u.end(); ++it) {
258  (*it)->UnRef();
259  (*it) = NULL;
260  }
261  u.clear();
262 }
263 
264 void UnitCollection::destr()
265 {
266  for (list< Unit* >::iterator it = u.begin(); it != u.end(); ++it)
267  if (*it) {
268  (*it)->UnRef();
269  (*it) = NULL;
270  }
271  for (vector< un_iter* >::iterator t = activeIters.begin(); t != activeIters.end(); ++t)
272  (*t)->col = NULL;
273 }
274 
275 bool UnitCollection::contains( const Unit *unit ) const
276 {
277  if (u.empty() || !unit)
278  return false;
279  for (list< Unit* >::const_iterator it = u.begin(); it != u.end(); ++it)
280  if ( (*it) == unit && !(*it)->Killed() )
281  return true;
282  return false;
283 }
284 
285 inline void UnitCollection::erase( list< Unit* >::iterator &it2 )
286 {
287  if ( !(*it2) ) {
288  ++it2;
289  return;
290  }
291  //If we have more than 4 iterators, just push node onto vector.
292  if (activeIters.size() > 3) {
293  removedIters.push_back( it2 );
294  (*it2)->UnRef();
295  (*it2) = NULL;
296  ++it2;
297  return;
298  }
299  //If we have between 2 and 4 iterators, see if any are actually
300  //on the node we want to remove, if so, just push onto vector.
301  //Purpose : This special case is to reduce the size of the list in the
302  //situation where removedIters isn't being processed.
303  if (activeIters.size() > 1)
304  for (vector<UnitCollection::UnitIterator*>::size_type i = 0; i < activeIters.size(); ++i)
305  if (activeIters[i]->it == it2) {
306  removedIters.push_back( it2 );
307  (*it2)->UnRef();
308  (*it2) = NULL;
309  ++it2;
310  return;
311  }
312  //If we have 1 iterator, or none of the iterators are currently on the
313  //requested node to be removed, then remove it right away.
314  (*it2)->UnRef();
315  (*it2) = NULL;
316  it2 = u.erase( it2 );
317 }
318 
319 bool UnitCollection::remove( const Unit *unit )
320 {
321  bool res = false;
322  if (u.empty() || !unit)
323  return false;
324  for (list< Unit* >::iterator it = u.begin(); it != u.end();) {
325  if ( (*it) == unit ) {
326  erase( it );
327  res = true;
328  } else {
329  ++it;
330  }
331  }
332  return res;
333 }
334 
335 const UnitCollection& UnitCollection::operator=( const UnitCollection &uc )
336 {
337  destr();
338  list< Unit* >::const_iterator in = uc.u.begin();
339  while ( in != uc.u.end() ) {
340  append( *in );
341  ++in;
342  }
343  return *this;
344 }
345 
346 inline void UnitCollection::reg( un_iter *iter )
347 {
348  activeIters.push_back( iter );
349 }
350 
351 inline void UnitCollection::unreg( un_iter *iter )
352 {
353  for (vector< un_iter* >::iterator t = activeIters.begin(); t != activeIters.end(); ++t)
354  if ( (*t) == iter ) {
355  activeIters.erase( t );
356  break;
357  }
358  if ( activeIters.empty() || ( activeIters.size() == 1 && ( activeIters[0]->it == u.end() || ( *(activeIters[0]->it) ) ) ) )
359  while ( !removedIters.empty() ) {
360  u.erase( removedIters.back() );
361  removedIters.pop_back();
362  }
363 }
364 
365 //UnitCollection END:
366 
367 #endif //USE_STL_COLLECTION
368