Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
multilist.h
Go to the documentation of this file.
1/*
2** Command & Conquer Generals Zero Hour(tm)
3** Copyright 2025 Electronic Arts Inc.
4**
5** This program is free software: you can redistribute it and/or modify
6** it under the terms of the GNU General Public License as published by
7** the Free Software Foundation, either version 3 of the License, or
8** (at your option) any later version.
9**
10** This program is distributed in the hope that it will be useful,
11** but WITHOUT ANY WARRANTY; without even the implied warranty of
12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13** GNU General Public License for more details.
14**
15** You should have received a copy of the GNU General Public License
16** along with this program. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19/***********************************************************************************************
20 *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
21 ***********************************************************************************************
22 * *
23 * Project Name : WWLib *
24 * *
25 * $Archive:: /Commando/Code/wwlib/multilist.h $*
26 * *
27 * Original Author:: Greg Hjelstrom *
28 * *
29 * $Author:: Jani_p $*
30 * *
31 * $Modtime:: 4/09/01 8:26p $*
32 * *
33 * $Revision:: 16 $*
34 * *
35 *---------------------------------------------------------------------------------------------*
36 * Functions: *
37 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
38
39
40#if defined(_MSC_VER)
41#pragma once
42#endif
43
44#ifndef MULTILIST_H
45#define MULTILIST_H
46
47#include "always.h"
48#include "mempool.h"
49#include <assert.h>
50
53
54
55/******************************************************************************
56
57 MultiLists
58
59 MultiLists solve the problem of needing to have objects that can be placed
60 into multiple lists at the same time. MultiListNodes are all allocated from
61 a pool which grows in chunks to avoid overhead from calling new and delete.
62 All operations such as insertion, removal, checking if a list contains an
63 object, are ether immediate or O(numlists) where numlists is the number of
64 different lists that the object in question currently occupies.
65
66******************************************************************************/
67
68
78{
79public:
80
81 MultiListObjectClass(void) : ListNode(NULL) { }
82 virtual ~MultiListObjectClass(void);
83
84 MultiListNodeClass * Get_List_Node() const { return ListNode; }
85 void Set_List_Node(MultiListNodeClass *node) { ListNode = node; }
86
87private:
89};
90
91
99class MultiListNodeClass : public AutoPoolClass<MultiListNodeClass, 256>
100{
101public:
102 MultiListNodeClass(void) { Prev = Next = NextList = 0; Object = 0; List = 0; }
103
104 MultiListNodeClass *Prev; // prev object in list
105 MultiListNodeClass *Next; // next object in list
106 MultiListNodeClass *NextList; // next list this object is in
107 MultiListObjectClass *Object; // pointer back to the object
108 GenericMultiListClass *List; // pointer to list for this node
109};
110
111
121{
122public:
123
124 GenericMultiListClass(void) { Head.Next = Head.Prev = &Head; Head.Object = 0; Head.NextList = 0; }
125 virtual ~GenericMultiListClass(void);
126
128 bool Contains(MultiListObjectClass * obj);
129 bool Is_Empty(void);
130 int Count(void);
131
132protected:
133
134 bool Internal_Add(MultiListObjectClass *obj,bool onlyonce = true);
135 bool Internal_Add_Tail(MultiListObjectClass * obj,bool onlyonce = true);
136 bool Internal_Add_After(MultiListObjectClass * obj,const MultiListObjectClass * existing_list_member,bool onlyonce = true);
138
141
142private:
143
147};
148
150{
151 return Contains(obj);
152}
153
155{
156 return (Head.Next == &Head);
157}
158
160{
161 if (Head.Next == &Head) {
162 return 0; // no more objects
163 } else {
164 assert(Head.Next->Object != 0);
165 return Head.Next->Object;
166 }
167}
168
169
170
178{
179public:
181
182 void First(GenericMultiListClass *list) { List = list; CurNode = List->Head.Next; }
183 void First(void) { CurNode = List->Head.Next; }
184 void Last(GenericMultiListClass *list) { List = list; CurNode = List->Head.Prev; }
185 void Last(void) { CurNode = List->Head.Prev; }
186
187 void Next(void) { CurNode = CurNode->Next; }
188 void Prev(void) { CurNode = CurNode->Prev; }
189 bool Is_Done(void) { return (CurNode == &(List->Head)); }
190
191protected:
192
193 MultiListObjectClass * Current_Object(void) { return CurNode->Object; }
194
195 GenericMultiListClass * List; // list we're working in
196 MultiListNodeClass * CurNode; // node we're currently at.
197
198};
199
200
201
202/**************************************************************************************
203
204 MultiListClass, MultiListIterator
205
206 These templates inherits from GenericMultiListClass and GenericMultiListIterator
207 and handle all typecasting to your object type. These classes require that
208 your 'ObjectType' be derived from MultiListObjectClass.
209
210**************************************************************************************/
211
220template <class ObjectType>
222{
223public:
224
226
227 virtual ~MultiListClass(void)
228 {
229 while (!Is_Empty()) {
230 Remove_Head();
231 }
232 }
233
234 bool Add(ObjectType * obj,bool onlyonce = true)
235 {
236 return Internal_Add(obj,onlyonce);
237 }
238
239 bool Add_Tail(ObjectType * obj,bool onlyonce = true)
240 {
241 return Internal_Add_Tail(obj,onlyonce);
242 }
243
244 bool Add_After(ObjectType * obj,const ObjectType * existing_list_member,bool onlyonce = true)
245 {
246 return Internal_Add_After(obj,existing_list_member,onlyonce);
247 }
248
249 bool Remove(ObjectType *obj)
250 {
251 return Internal_Remove(obj);
252 }
253
254 ObjectType * Get_Head()
255 {
256 return ((ObjectType*)Internal_Get_List_Head());
257 }
258
259 ObjectType * Peek_Head()
260 {
261 return ((ObjectType*)Internal_Get_List_Head());
262 }
263
264 ObjectType * Remove_Head()
265 {
266 return ((ObjectType*)Internal_Remove_List_Head());
267 }
268
270 {
271 while (Get_Head() != NULL) {
272 Remove_Head();
273 }
274 }
275
276private:
277
278 // not implemented
279 MultiListClass(const MultiListClass & that);
280 MultiListClass & operator = (const MultiListClass & that);
281
282};
283
294template <class ObjectType>
296{
297public:
298
300
301 ObjectType * Get_Obj(void)
302 {
303 return (ObjectType*)Current_Object();
304 }
305
306 ObjectType * Peek_Obj(void)
307 {
308 return (ObjectType*)Current_Object();
309 }
310
312 {
313 ObjectType * obj = Peek_Obj();
314 if (obj != NULL) {
315 Next();
316 ((MultiListClass<ObjectType> *)List)->Remove(obj);
317 }
318 }
319
320};
321
322
323/**************************************************************************************
324
325 RefMultiListClass, RefMultiListIterator
326
327 These templates inherits from GenericMultiListClass and GenericMultiListIterator
328 and handle all typecasting to your object type and also do proper reference tracking.
329 These classes require that your 'ObjectType' be derived from MultiListObjectClass and
330 RefCountClass.
331
332**************************************************************************************/
333
341template <class ObjectType>
343{
344public:
345
346 virtual ~RefMultiListClass(void)
347 {
348 while (!Is_Empty()) {
349 Release_Head();
350 }
351 }
352
353 bool Add(ObjectType * obj,bool onlyonce = true)
354 {
355 // if we add the object from our list, add a reference to it
356 bool result = Internal_Add(obj,onlyonce);
357 if (result == true) {
358 obj->Add_Ref();
359 }
360 return result;
361 }
362
363 bool Add_Tail(ObjectType * obj,bool onlyonce = true)
364 {
365 // if we add the object from our list, add a reference to it
366 bool result = Internal_Add_Tail(obj,onlyonce);
367 if (result == true) {
368 obj->Add_Ref();
369 }
370 return result;
371 }
372
373 bool Add_After(ObjectType * obj,const ObjectType * existing_list_member,bool onlyonce = true)
374 {
375 // if we add the object from our list, add a reference to it
376 bool result = Internal_Add_After(obj,existing_list_member,onlyonce);
377 if (result == true) {
378 obj->Add_Ref();
379 }
380 return result;
381 }
382
383 bool Remove(ObjectType *obj)
384 {
385 // if we remove the object from our list, release our reference to it
386 bool result = Internal_Remove(obj);
387 if (result) {
388 obj->Release_Ref();
389 }
390 return result;
391 }
392
393 bool Release_Head(void)
394 {
395 // remove the head from the list and release our reference to it
396 ObjectType * obj = ((ObjectType*)Internal_Remove_List_Head());
397 if (obj) {
398 obj->Release_Ref();
399 return true;
400 } else {
401 return false;
402 }
403 }
404
405 ObjectType * Get_Head()
406 {
407 // if we have a head, add a reference for the caller of this function
408 ObjectType * obj = ((ObjectType*)Internal_Get_List_Head());
409 if (obj) {
410 obj->Add_Ref();
411 }
412 return obj;
413 }
414
415 ObjectType * Peek_Head()
416 {
417 // no need to add-ref since the caller is 'peek'ing
418 return ((ObjectType*)Internal_Get_List_Head());
419 }
420
421 ObjectType * Remove_Head()
422 {
423 // our reference is transferred to the caller of this function
424 return ((ObjectType*)Internal_Remove_List_Head());
425 }
426
428 {
429 while (Peek_Head() != NULL) {
430 Release_Head();
431 }
432 }
433};
434
445template <class ObjectType>
447{
448public:
449
451
452 ObjectType * Get_Obj(void)
453 {
454 ObjectType * obj = (ObjectType*)Current_Object();
455 if (obj != NULL) {
456 obj->Add_Ref();
457 }
458 return obj;
459 }
460
461 ObjectType * Peek_Obj(void)
462 {
463 return ((ObjectType*)Current_Object());
464 }
465
467 {
468 ObjectType * obj = Peek_Obj();
469 if (obj != NULL) {
470 Next();
471 ((RefMultiListClass<ObjectType> *)List)->Remove(obj);
472 }
473 }
474};
475
476
477
478/**************************************************************************************
479
480 PriorityMultiListIterator
481
482 This template inherits from MultiListIterator and is used to implement a simple
483 priority queue where nodes are popped off the head of the list and added to the tail.
484
485**************************************************************************************/
486
487template <class ObjectType>
489{
490public:
494
495 bool
496 Process_Head (ObjectType **object)
497 {
498 bool retval = false;
499
500 // Check to ensure we don't wrap around the list (stop after iterating
501 // the list once).
502 if (CurNode != NULL && CurNode->Object != NULL && OriginalHead != CurNode) {
504 (*object) = (ObjectType *)CurNode->Object;
505
506
507 // Remove the node from the head of the list and
508 // add it to the tail of the list
511
512 retval = true;
513 }
514
515 return retval;
516 }
517
518protected:
519
521};
522
523
524#endif //LIST_CLASS_H
525
#define NULL
Definition BaseType.h:92
bool Is_In_List(MultiListObjectClass *obj)
Definition multilist.h:149
bool Contains(MultiListObjectClass *obj)
Definition multilist.cpp:75
friend class MultiListObjectClass
Definition multilist.h:146
bool Internal_Remove(MultiListObjectClass *obj)
bool Internal_Add(MultiListObjectClass *obj, bool onlyonce=true)
Definition multilist.cpp:97
MultiListObjectClass * Internal_Get_List_Head(void)
Definition multilist.h:159
bool Internal_Add_Tail(MultiListObjectClass *obj, bool onlyonce=true)
virtual ~GenericMultiListClass(void)
Definition multilist.cpp:70
MultiListObjectClass * Internal_Remove_List_Head(void)
bool Internal_Add_After(MultiListObjectClass *obj, const MultiListObjectClass *existing_list_member, bool onlyonce=true)
friend class GenericMultiListIterator
Definition multilist.h:145
void First(GenericMultiListClass *list)
Definition multilist.h:182
MultiListObjectClass * Current_Object(void)
Definition multilist.h:193
GenericMultiListIterator(GenericMultiListClass *list)
Definition multilist.h:180
void Last(GenericMultiListClass *list)
Definition multilist.h:184
GenericMultiListClass * List
Definition multilist.h:195
MultiListNodeClass * CurNode
Definition multilist.h:196
bool Add(ObjectType *obj, bool onlyonce=true)
Definition multilist.h:234
ObjectType * Remove_Head()
Definition multilist.h:264
bool Add_Tail(ObjectType *obj, bool onlyonce=true)
Definition multilist.h:239
void Reset_List()
Definition multilist.h:269
ObjectType * Peek_Head()
Definition multilist.h:259
ObjectType * Get_Head()
Definition multilist.h:254
bool Remove(ObjectType *obj)
Definition multilist.h:249
bool Add_After(ObjectType *obj, const ObjectType *existing_list_member, bool onlyonce=true)
Definition multilist.h:244
virtual ~MultiListClass(void)
Definition multilist.h:227
MultiListClass(void)
Definition multilist.h:225
void Remove_Current_Object(void)
Definition multilist.h:311
ObjectType * Get_Obj(void)
Definition multilist.h:301
MultiListIterator(MultiListClass< ObjectType > *list)
Definition multilist.h:299
ObjectType * Peek_Obj(void)
Definition multilist.h:306
MultiListObjectClass * Object
Definition multilist.h:107
MultiListNodeClass * Prev
Definition multilist.h:104
GenericMultiListClass * List
Definition multilist.h:108
MultiListNodeClass * NextList
Definition multilist.h:106
MultiListNodeClass * Next
Definition multilist.h:105
void Set_List_Node(MultiListNodeClass *node)
Definition multilist.h:85
virtual ~MultiListObjectClass(void)
Definition multilist.cpp:54
MultiListNodeClass * Get_List_Node() const
Definition multilist.h:84
bool Process_Head(ObjectType **object)
Definition multilist.h:496
PriorityMultiListIterator(MultiListClass< ObjectType > *list)
Definition multilist.h:491
MultiListNodeClass * OriginalHead
Definition multilist.h:520
virtual ~RefMultiListClass(void)
Definition multilist.h:346
ObjectType * Get_Head()
Definition multilist.h:405
bool Add(ObjectType *obj, bool onlyonce=true)
Definition multilist.h:353
ObjectType * Remove_Head()
Definition multilist.h:421
ObjectType * Peek_Head()
Definition multilist.h:415
bool Release_Head(void)
Definition multilist.h:393
bool Remove(ObjectType *obj)
Definition multilist.h:383
bool Add_After(ObjectType *obj, const ObjectType *existing_list_member, bool onlyonce=true)
Definition multilist.h:373
bool Add_Tail(ObjectType *obj, bool onlyonce=true)
Definition multilist.h:363
ObjectType * Get_Obj(void)
Definition multilist.h:452
void Remove_Current_Object(void)
Definition multilist.h:466
RefMultiListIterator(RefMultiListClass< ObjectType > *list)
Definition multilist.h:450
ObjectType * Peek_Obj(void)
Definition multilist.h:461