Tiberian Technologies Scripts Reference Revision: 9000
Loading...
Searching...
No Matches
multilist.h
1/* Renegade Scripts.dll
2 Copyright 2013 Tiberian Technologies
3
4 This file is part of the Renegade scripts.dll
5 The Renegade scripts.dll is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License as published by the Free
7 Software Foundation; either version 2, or (at your option) any later
8 version. See the file COPYING for more details.
9 In addition, an exemption is given to allow Run Time Dynamic Linking of this code with any closed source module that does not contain code covered by this licence.
10 Only the source code to the module(s) containing the licenced code has to be released.
11*/
12#ifndef SCRIPTS_INCLUDE__MULTILIST_H_
13#define SCRIPTS_INCLUDE__MULTILIST_H_
14
15#include "engine_vector.h"
16
17class GenericMultiListClass;
18class MultiListObjectClass;
19class GenericMultiListIterator;
20
21class MultiListNodeClass : public AutoPoolClass<MultiListNodeClass, 256>
22{
23public:
24 MultiListNodeClass()
25 {
26 Prev = Next = NextList = 0;
27 Object = 0;
28 List = 0;
29 };
30
31 MultiListNodeClass* Prev; // Previous object in list 0000
32 MultiListNodeClass* Next; // Next object in list 0004
33 MultiListNodeClass* NextList; // Next list for object 0008
34 MultiListObjectClass* Object; // Pointer to object 000C
35 GenericMultiListClass* List; // List for this node 0010
36}; // 0014
37
38class MultiListObjectClass
39{
40private:
41 MultiListNodeClass* ListNode; // 0004
42
43public:
44 MultiListObjectClass(): ListNode(NULL) {};
45 virtual ~MultiListObjectClass();
46
47 MultiListNodeClass* Get_List_Node() const
48 {
49 return ListNode;
50 };
51
52 void Set_List_Node(MultiListNodeClass *node)
53 {
54 ListNode = node;
55 };
56
57}; // 0008
58
59class GenericMultiListClass
60{
61private:
62 MultiListNodeClass Head; // 0004
63
64 // not implemented
65 GenericMultiListClass(const GenericMultiListClass&);
66 GenericMultiListClass& operator = (const GenericMultiListClass&);
67
68protected:
69 friend class GenericMultiListIterator;
70 friend class MultiListObjectClass;
71 SHARED_API bool Internal_Add(MultiListObjectClass *obj, bool onlyonce = true);
72 SHARED_API bool Internal_Add_Tail(MultiListObjectClass *obj, bool onlyonce = true);
73 SHARED_API bool Internal_Add_After(MultiListObjectClass *obj, const MultiListObjectClass* existing_list_member, bool onlyonce = true);
74 SHARED_API bool Internal_Remove(MultiListObjectClass *obj);
75 SHARED_API MultiListObjectClass* Internal_Remove_List_Head();
76
77 inline MultiListObjectClass* Internal_Get_List_Head() const
78 {
79 if (Is_Empty()) return 0;
80 TT_ASSERT(Head.Next->Object != NULL);
81 return Head.Next->Object;
82 };
83
84public:
85 GenericMultiListClass()
86 {
87 Head.Next = Head.Prev = &Head;
88 Head.Object = 0;
89 Head.NextList = 0;
90 };
91
92 virtual ~GenericMultiListClass()
93 {
94 TT_ASSERT(Is_Empty());
95 };
96
97 inline bool Is_In_List(MultiListObjectClass *obj) const
98 {
99 return Contains(obj);
100 };
101
102 inline bool Is_Empty() const
103 {
104 return (Head.Next == &Head);
105 };
106
107 bool Contains(MultiListObjectClass * obj) const
108 {
109 TT_ASSERT(obj);
110 for (MultiListNodeClass* node = obj->Get_List_Node(); node; node = node->NextList)
111 {
112 if (node->List == this)
113 {
114 return true;
115 };
116 };
117 return false;
118 }
119
120 int Count() const;
121}; // 0018
122
123class GenericMultiListIterator
124{
125public:
126 GenericMultiListIterator(const GenericMultiListClass *list)
127 {
128 TT_ASSERT(list);
129 First(list);
130 };
131
132 void First(const GenericMultiListClass *list)
133 {
134 List = list;
135 CurNode = List->Head.Next;
136 };
137
138 void First()
139 {
140 CurNode = List->Head.Next;
141 };
142
143 void Next()
144 {
145 CurNode = CurNode->Next;
146 };
147
148 void Prev()
149 {
150 CurNode = CurNode->Prev;
151 };
152
153 bool Is_Done() const
154 {
155 return (CurNode == &(List->Head));
156 };
157
158protected:
159 MultiListObjectClass* Current_Object() const
160 {
161 return CurNode->Object;
162 };
163
164 const GenericMultiListClass* List; // list we're working in
165 const MultiListNodeClass* CurNode; // node we're currently at.
166};
167
168template <typename T> class MultiListIterator;
169template <typename T> class MultiListClass : public GenericMultiListClass
170{
171private:
172 // not implemented
173 MultiListClass(const MultiListClass & that);
174 MultiListClass & operator = (const MultiListClass & that);
175
176public:
177 MultiListClass(): GenericMultiListClass() {};
178
179 virtual ~MultiListClass()
180 {
181 while (!Is_Empty())
182 {
183 Remove_Head();
184 }
185 };
186
187 bool Add(T* obj, bool onlyonce = true)
188 {
189 return Internal_Add(obj, onlyonce);
190 };
191
192 bool Add_Tail(T* obj, bool onlyonce = true)
193 {
194 return Internal_Add_Tail(obj, onlyonce);
195 };
196
197 bool Add_After(T* obj, const T* existing_list_member, bool onlyonce = true)
198 {
199 return Internal_Add_After(obj, existing_list_member, onlyonce);
200 };
201
202 bool Remove(T* obj)
203 {
204 return Internal_Remove(obj);
205 };
206
207 T* Get_Head() const
208 {
209 return (T*) Internal_Get_List_Head();
210 };
211
212 T* Peek_Head() const
213 {
214 return (T*) Internal_Get_List_Head();
215 };
216
217 T* Remove_Head()
218 {
219 return (T*) Internal_Remove_List_Head();
220 };
221
222 void Reset_List()
223 {
224 while (Peek_Head() != NULL)
225 {
226 Remove_Head();
227 };
228 };
229
230 MultiListIterator<T> Iterator() const;
231}; // 0018
232
233template <typename T> class MultiListIterator : public GenericMultiListIterator
234{
235public:
236 MultiListIterator(const MultiListClass<T> *list) : GenericMultiListIterator(list) {};
237
238 T* Get_Obj(void) const
239 {
240 return (T*)Current_Object();
241 };
242
243 T* Peek_Obj(void) const
244 {
245 return (T*)Current_Object();
246 };
247
248 void Remove_Current_Object()
249 {
250 T* obj = Peek_Obj();
251 if (obj != NULL) {
252 Next();
253 ((MultiListClass<T>*)List)->Remove(obj);
254 }
255 };
256
257
258 void operator++() { Next(); }
259 operator bool() const { return !Is_Done(); }
260 T* operator->() { return Get_Obj(); }
261 T* operator*() { return Get_Obj(); }
262
263};
264
265template <typename T> MultiListIterator<T> MultiListClass<T>::Iterator() const
266{
267 return MultiListIterator<T>(this);
268};
269
270template <typename T> class RefMultiListIterator;
271template <typename T> class RefMultiListClass: public GenericMultiListClass
272{
273private:
274 // not implemented
275 RefMultiListClass(const RefMultiListClass&);
276 RefMultiListClass& operator = (const RefMultiListClass&);
277
278public:
279 RefMultiListClass(): GenericMultiListClass() {};
280
281 virtual ~RefMultiListClass()
282 {
283 while (!Is_Empty())
284 {
285 Release_Head();
286 }
287 };
288
289 bool Add(T* obj, bool onlyonce = true)
290 {
291 bool res = Internal_Add(obj, onlyonce);
292 if (res == true) obj->Add_Ref();
293 return res;
294 };
295
296 bool Add_Tail(T* obj, bool onlyonce = true)
297 {
298 bool res = Internal_Add_Tail(obj, onlyonce);
299 if (res == true) obj->Add_Ref();
300 return res;
301 };
302
303 bool Add_After(T* obj, const T* existing_list_member, bool onlyonce = true)
304 {
305 bool res = Internal_Add_After(obj, existing_list_member, onlyonce);
306 if (res == true) obj->Add_Ref();
307 return res;
308 };
309
310 bool Remove(T* obj)
311 {
312 bool res = Internal_Remove(obj);
313 if (res == true) obj->Release_Ref();
314 return res;
315 };
316
317 bool Release_Head()
318 {
319 T* obj = (T*) Internal_Remove_List_Head();
320 if (obj)
321 {
322 obj->Release_Ref();
323 return true;
324 }
325 return false;
326 };
327
328 T* Get_Head() const
329 {
330 T* obj = (T*) Internal_Get_List_Head();
331 if (obj) obj->Add_Ref();
332 return obj;
333 };
334
335 T* Peek_Head() const
336 {
337 return (T*) Internal_Get_List_Head();
338 };
339
340 T* Remove_Head()
341 {
342 return (T*) Internal_Remove_List_Head();
343 };
344
345 void Reset_List()
346 {
347 while (Peek_Head() != NULL)
348 {
349 Release_Head();
350 };
351 };
352
353 RefMultiListIterator<T> Iterator() const;
354}; // 0018 0018 001C 0018
355
356template <typename T> class RefMultiListIterator : public GenericMultiListIterator
357{
358public:
359 RefMultiListIterator(const RefMultiListClass<T> *list): GenericMultiListIterator(list) {};
360
361 T* Get_Obj() const
362 {
363 T* obj = (T*)Current_Object();
364 if (obj != NULL) obj->Add_Ref();
365 return obj;
366 };
367
368 T* Peek_Obj() const
369 {
370 return (T*)Current_Object();
371 };
372
373 void Remove_Current_Object()
374 {
375 T* obj = Peek_Obj();
376 if (obj != NULL) {
377 Next();
378 ((RefMultiListClass<T> *)List)->Remove(obj);
379 };
380 };
381
382 void operator++() { Next(); }
383 operator bool() const { return !Is_Done(); }
384 T* operator->() const { return Peek_Obj(); }
385
386};
387
388template <typename T> RefMultiListIterator<T> RefMultiListClass<T>::Iterator() const
389{
390 return RefMultiListIterator<T>(this);
391};
392
393TT_INLINE MultiListObjectClass::~MultiListObjectClass()
394{
395 while (ListNode)
396 {
397 ListNode->List->Internal_Remove(this);
398 };
399}
400
401TT_INLINE int GenericMultiListClass::Count() const
402{
403 int counter = 0;
404 GenericMultiListIterator it(this);
405 for (it.First(); !it.Is_Done(); it.Next())
406 {
407 ++counter;
408 }
409 return counter;
410}
411
412
413template<class ObjectType> class PriorityMultiListIterator :
414 public MultiListIterator<ObjectType>
415{
416public:
417 PriorityMultiListIterator(MultiListClass<ObjectType>* list)
418 : OriginalHead (NULL),
419 MultiListIterator<ObjectType>(list)
420 {
421 First();
422 }
423
424 bool Process_Head(ObjectType** object)
425 {
426 bool result = false;
427
428 // Check to ensure we don't wrap around the list (stop after iterating
429 // the list once).
430 if (CurNode != NULL && CurNode->Object != NULL && OriginalHead != CurNode) {
431 if (!OriginalHead)
432 OriginalHead = CurNode;
433 *object = (ObjectType*)CurNode->Object;
434
435 // Remove the node from the head of the list and
436 // add it to the tail of the list
437 Remove_Current_Object();
438 ((MultiListClass<ObjectType> *)PriorityMultiListIterator::List)->Add_Tail ((*object));
439
440 result = true;
441 }
442
443 return result;
444 }
445
446protected:
447
448 const MultiListNodeClass* OriginalHead;
449};
450
451
452#endif