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.h
Go to the documentation of this file.
1 /* unitCollection.h
2  *
3  *****/
4 
5 #ifndef _UNITCOLLECTION_H_
6 #define _UNITCOLLECTION_H_
7 
8 //Collection type:
9 //#define USE_OLD_COLLECTION
10 #define USE_STL_COLLECTION
11 
12 #if defined (USE_OLD_COLLECTION)
13 #include "oldcollection.h"
14 #elif defined (USE_STL_COLLECTION)
15 
16 #include <cstddef>
17 #include <list>
18 #include <vector>
19 
20 class Unit;
21 
22 /*
23  * UnitCollection is the list container for units.
24  * It's used to contain subunits, units in a system, etc.
25  * Currently, you dont assign one collection to another.
26  * You're not supposed to hold references to the list across physics frames
27  * UnitCollection is designed to be robust to at least 20,000 units.
28  */
30 {
31 public:
32  /*
33  * UnitIterator is the "node" class for UnitCollection.
34  * It's meant to mimic std::iterator's for the most part, but
35  * Python code doesn't use them that way so we had to keep some
36  * functions for backwards compatibility.
37  * Operators supported : ++(), ()++, =, *
38  */
40  {
41  public:
42  UnitIterator() : col( NULL ) {}
43  UnitIterator( const UnitIterator& );
45  virtual ~UnitIterator();
46 
47  inline bool isDone()
48  {
49  if ( col && it != col->u.end() )
50  return false;
51  return true;
52  }
53  inline bool notDone()
54  {
55  return !isDone();
56  }
57 
58  /* Request the current unit to be removed */
59  void remove();
60 
61  /* Move argument list to the beginning of current list */
62  void moveBefore( UnitCollection& );
63 
64  /* Insert unit before current unit */
65  void preinsert( class Unit* );
66 
67  /* Insert unit after current unit */
68  void postinsert( class Unit*unit );
69 
70  /* increment to next valid unit (may iterate many times) */
71  void advance();
72 
73  /* same as advance, only it returns the unit at the same time */
74  Unit * next();
75 
77  inline const UnitIterator operator++( int )
78  {
79  UnitCollection::UnitIterator tmp( *this );
80  advance();
81  return tmp;
82  }
83  inline const UnitIterator& operator++()
84  {
85  advance();
86  return *this;
87  }
88  inline Unit* operator*()
89  {
90  if ( col && it != col->u.end() )
91  return *it;
92  return NULL;
93  }
94 
95  protected:
96  friend class UnitCollection;
97  //Pointer back to the collection we were spawned from
99 
100  //Current position in the list
101  std::list< class Unit* >::iterator it;
102  };
103 
104  /* This class is to be used when no changes to the list are made
105  * and the iterator doesn't persist across physics frames.
106  * that is to say, these should only be used as temporary iterators
107  * in loops where the list is not modified.
108  */
110  {
111  public:
112  ConstIterator() : col( NULL ) {}
113  ConstIterator( const ConstIterator& );
114  ConstIterator( const UnitCollection* );
115  ~ConstIterator();
116  ConstIterator& operator=( const ConstIterator &orig );
117  Unit * next();
118  inline bool isDone()
119  {
120  if ( col && it != col->u.end() )
121  return false;
122  return true;
123  }
124  inline bool notDone()
125  {
126  return !isDone();
127  }
128  void advance();
129  const ConstIterator& operator++();
130  const ConstIterator operator++( int );
131  inline Unit* operator*() const
132  {
133  if ( it != col->u.end() && !col->empty() ) return *it;
134  return NULL;
135  }
136  protected:
137  friend class UnitCollection;
139  std::list< class Unit* >::const_iterator it;
140  };
141 
142  /* backwards compatibility only. Typedefs suck. dont use them. */
145 
146  UnitCollection();
147  UnitCollection( const UnitCollection& );
149  {
150  destr();
151  }
152 
153  /* Iterator creation functions. We use this to set the col pointer */
155  {
156  return UnitIterator( this );
157  }
159  {
160  return FastIterator( this );
161  }
163  {
164  return ConstIterator( this );
165  }
167  {
168  return ConstFastIterator( this );
169  }
170 
171  /* Traverses entire list and only inserts if no matches are found
172  * Do not use in any fast-code paths */
173  void insert_unique( Unit* );
174  inline bool empty() const
175  {
176  if (u.size()-removedIters.size() > 0) return false;
177  return true;
178  }
179 
180  /* Add a unit or iterator to the front of the list. */
181  void prepend( Unit* );
182  void prepend( UnitIterator* );
183 
184  /* Add a unit or iterator to the back of the list. */
185  void append( class Unit* );
186  void append( UnitIterator* );
187 
188  /* This is how iterators insert units. Always inserts before iterator */
189  void insert( std::list< Unit* >::iterator&, Unit* );
190 
191  /* Whipes out entire list only if no iterators are being held.
192  * No code uses this function as of 0.5 release */
193  void clear();
194 
195  bool contains( const class Unit* ) const;
196 
197  /* We only erase the unit from the list under the following conditions:
198  * 1. if we have less than 4 iterators being held
199  * 2. if none of those iterators are referencing the requested unit
200  * Otherwise the Unit pointer is removed from the list and set to NULL,
201  * and the iterator is referenced on another list to be deleted
202  * the delete list is processed when the number of iterators hits 1 or 0.
203  * The reason for this is so we can be scalable to 20,000+ units and
204  * modifications to the list by multiple held iterators dont bog us down
205  */
206  void erase( std::list< class Unit* >::iterator& );
207 
208  /* traverse list and remove all matching Units.
209  * Do not use in fast-path code */
210  bool remove( const class Unit* );
211 
212  /* Returns number of non-null units in list */
213  inline const int size() const
214  {
215  return u.size()-removedIters.size();
216  }
217 
218  /* Returns last non-null unit in list. May be Killed() */
219  inline Unit * back()
220  {
221  for (std::list< Unit* >::reverse_iterator it = u.rbegin(); it != u.rend(); ++it)
222  if (*it)
223  return *it;
224  return NULL;
225  }
226 
227  /* Returns first non-null unit in list. May be Killed() */
228  inline Unit * front()
229  {
230  for (std::list< Unit* >::iterator it = u.begin(); it != u.end(); ++it)
231  if (*it)
232  return *it;
233  return NULL;
234  }
235 
236 private:
237  friend class UnitIterator;
238  friend class ConstIterator;
239 
240  /* Does not clear list. It sets all the Unit pointers to null
241  * And sets all the current iterator's collection pointers to NULL.
242  * Effectively shutting the list down so it can be destroyed safely. */
243  void destr();
244 
245  /* Nothing uses this operator as of 0.5, but maybe someday */
246  const UnitCollection& operator=( const UnitCollection& );
247 
248  /* An iterator "registers" with a collection when it is created
249  * This is how a collection tracks how many iterators are being held
250  * and what position they are all holding
251  */
252  void reg( UnitCollection::UnitIterator* );
253 
254  /* Unregistering has the added function of clearing the list of
255  * Null unit pointers to be removed from the collection when
256  * we are down to our last active iterator */
257  void unreg( UnitCollection::UnitIterator* );
258 
259  /* This is a list of the current iterators being held */
260  std::vector< class UnitCollection::UnitIterator* >activeIters;
261 
262  /* This is a list of positions in the collection that are pointing to
263  * NULL units, positions that should be removed from the collection
264  * but couldn't because another iterator was referencing it. */
265  std::vector< std::list< class Unit* >::iterator >removedIters;
266 
267  /* Main collection */
268  std::list< class Unit* >u;
269 };
270 
271 /* Typedefs. We really should not use them but we're lazy */
276 
277 #else
278 #error "No collection type chosen in collection.h:10"
279 #endif //USE_STL_COLLECTION
280 
281 #endif
282