Tiberian Technologies Scripts Reference Revision: 9000
Loading...
Searching...
No Matches
engine_vector.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__ENGINE_VECTOR_H
13#define SCRIPTS_INCLUDE__ENGINE_VECTOR_H
14#include "engine_threading.h"
15#include "engine_common.h"
16#include "Singleton.h"
17//forward declarations
18class FastCriticalSectionClass;
19
20template <typename T> class NoEqualsClass
21{
22public:
23 bool operator== (const T &src)
24 {
25 return false;
26 };
27 bool operator!= (const T &src)
28 {
29 return true;
30 };
31};
32
33class NoInitClass {
34 public:
35 void operator () (void) const {};
36};
37template <class T> class VectorClass {
38protected:
39 T *Vector; // 0004
40 int VectorMax; // 0008
41 bool IsValid; // 000C
42 bool IsAllocated; // 000D
43 bool VectorClassPad[2]; // 000E
44public:
45 VectorClass(NoInitClass const &)
46 {
47 }
48 explicit VectorClass(int size=0, T const * array=0) : Vector(0),VectorMax(size),IsValid(true),IsAllocated(false)
49 {
50 if (size)
51 {
52 if (array)
53 {
54 Vector = new((void*)array) T[size];
55 }
56 else
57 {
58 Vector = new T[size];
59 IsAllocated = true;
60 }
61 }
62 }
63 VectorClass(VectorClass<T> const & vector) : Vector(0),VectorMax(0),IsValid(true),IsAllocated(false)
64 {
65 *this = vector;
66 }
67 VectorClass<T> &operator= (VectorClass<T> const &vector)
68 {
69 if (this != &vector)
70 {
71 Clear();
72 VectorMax = vector.Length();
73 if (VectorMax)
74 {
75 Vector = new T[VectorMax];
76 if (Vector)
77 {
78 IsAllocated = true;
79 for (int index = 0; index < VectorMax; index++)
80 {
81 Vector[index] = vector[index];
82 }
83 }
84 }
85 else
86 {
87 Vector = 0;
88 IsAllocated = false;
89 }
90 }
91 return *this;
92 }
93
94#if _MSC_VER >= 1600
95 /* id theft and destruction of evidence */
96 VectorClass(VectorClass<T>&& vector): Vector(vector.Vector), VectorMax(vector.VectorMax), IsValid(vector.IsValid), IsAllocated(vector.IsAllocated)
97 {
98 vector.Vector = 0;
99 }
100
101 VectorClass<T>& operator=(VectorClass<T>&& vector)
102 {
103 if (this != &vector)
104 {
105 delete[] Vector;
106 Vector = vector.Vector;
107 VectorMax = vector.VectorMax;
108 IsValid = vector.IsValid;
109 IsAllocated = vector.IsAllocated;
110 vector.Vector = 0;
111 }
112 return *this;
113 }
114#endif
115
116 virtual ~VectorClass()
117 {
118 Clear();
119 }
120
121 T & operator[](int index)
122 {
123 return(Vector[index]);
124 }
125
126 T const & operator[](int index) const
127 {
128 return(Vector[index]);
129 }
130
131 virtual bool operator== (VectorClass<T> const &vector) const
132 {
133 if (VectorMax == vector.Length())
134 {
135 for (int index = 0; index < VectorMax; index++)
136 {
137 if (Vector[index] != vector[index])
138 {
139 return false;
140 }
141 }
142 return true;
143 }
144 return false;
145 }
146 virtual bool Resize(int newsize, T const * array=0)
147 {
148 if (newsize)
149 {
150 T *newptr;
151 IsValid = false;
152 if (!array)
153 {
154 newptr = new T[newsize];
155 }
156 else
157 {
158 newptr = new((void*)array) T[newsize];
159 }
160 IsValid = true;
161 if (!newptr)
162 {
163 return false;
164 }
165 if (Vector != NULL)
166 {
167 int copycount = (newsize < VectorMax) ? newsize : VectorMax;
168 for (int index = 0; index < copycount; index++)
169 {
170 newptr[index] = std::move(Vector[index]);
171 }
172 if (IsAllocated)
173 {
174 delete[] Vector;
175 Vector = 0;
176 }
177 }
178 Vector = newptr;
179 VectorMax = newsize;
180 IsAllocated = (Vector && !array);
181 }
182 else
183 {
184 Clear();
185 }
186 return true;
187 }
188 virtual void Clear(void)
189 {
190 if (Vector)
191 {
192 if (IsAllocated) delete[] Vector;
193 Vector = 0;
194 VectorMax = 0;
195 IsAllocated = false;
196 }
197 }
198 int Length(void) const
199 {
200 return VectorMax;
201 }
202 virtual int ID(T const *ptr)
203 {
204 if (!IsValid)
205 {
206 return 0;
207 }
208 return(((unsigned long)ptr - (unsigned long)&(*this)[0]) / sizeof(T));
209 }
210 virtual int ID(T const &object)
211 {
212 if (!IsValid)
213 {
214 return 0;
215 }
216 for (int index = 0; index < VectorMax; index++)
217 {
218 if ((*this)[index] == object)
219 {
220 return index;
221 }
222 }
223 return -1;
224 }
225
226 T* begin()
227 {
228 return Vector;
229 }
230
231 const T* begin() const
232 {
233 return Vector;
234 }
235}; // 0010
236
237template <class T> class DynamicVectorClass : public VectorClass<T> {
238protected:
239 int ActiveCount; // 0010
240 int GrowthStep; // 0014
241public:
242 explicit DynamicVectorClass(unsigned size=0, T const *array = 0) : VectorClass<T>(size, array)
243 {
244 GrowthStep = 10;
245 ActiveCount = 0;
246 }
247
248 DynamicVectorClass(const DynamicVectorClass<T>& vector): VectorClass<T>(vector), GrowthStep(vector.GrowthStep), ActiveCount(vector.ActiveCount)
249 {
250 /* nothing */
251 }
252
253 DynamicVectorClass<T> & operator =(DynamicVectorClass<T> const &rvalue)
254 {
255 VectorClass<T>::operator =(rvalue);
256 ActiveCount = rvalue.ActiveCount;
257 GrowthStep = rvalue.GrowthStep;
258 return *this;
259 }
260
261#if _MSC_VER >= 1600
262 /* stealing candy from babies */
263 DynamicVectorClass(DynamicVectorClass<T>&& vector): VectorClass<T>(std::move(vector)), GrowthStep(vector.GrowthStep), ActiveCount(vector.ActiveCount)
264 {
265 /* nothing */
266 }
267
268 DynamicVectorClass<T>& operator=(DynamicVectorClass<T>&& vector)
269 {
270 if (this != &vector)
271 {
272 VectorClass<T>::operator =(std::move(vector));
273 ActiveCount = vector.ActiveCount;
274 GrowthStep = vector.GrowthStep;
275 }
276 return *this;
277 }
278#endif
279
280 bool operator== (const DynamicVectorClass &src)
281 {
282 return false;
283 }
284 bool operator!= (const DynamicVectorClass &src)
285 {
286 return true;
287 }
288 bool Resize(int newsize, T const *array = 0)
289 {
290 if (VectorClass<T>::Resize(newsize, array))
291 {
292 if (Length() < ActiveCount)
293 {
294 ActiveCount = Length();
295 }
296 return true;
297 }
298 return false;
299 }
300 void Clear(void)
301 {
302 ActiveCount = 0;
303 VectorClass<T>::Clear();
304 }
305 void Reset_Active(void)
306 {
307 ActiveCount = 0;
308 }
309 void Set_Active(int count)
310 {
311 ActiveCount = count;
312 }
313 int Count(void) const
314 {
315 return(ActiveCount);
316 }
317 bool Add(T const &object)
318 {
319 if (ActiveCount >= Length())
320 {
321 if ((IsAllocated || !VectorMax) && GrowthStep > 0)
322 {
323 if (!Resize(Length() + GrowthStep))
324 {
325 return false;
326 }
327 }
328 else
329 {
330 return false;
331 }
332 }
333 (*this)[ActiveCount++] = object;
334 return true;
335 }
336 bool Add_Head(T const &object)
337 {
338 return Insert(0, object);
339 }
340 bool Insert(int index,T const &object)
341 {
342 if (index < 0)
343 {
344 return false;
345 }
346 if (index > ActiveCount)
347 {
348 return false;
349 }
350 if (ActiveCount >= Length())
351 {
352 if ((IsAllocated || !VectorMax) && GrowthStep > 0)
353 {
354 if (!Resize(Length() + GrowthStep))
355 {
356 return false;
357 }
358 }
359 else
360 {
361 return false;
362 }
363 }
364 for (int i = ActiveCount; i > index; --i)
365 {
366 Vector[i] = Vector[i-1];
367 }
368 (*this)[index] = object;
369 ActiveCount++;
370 return true;
371 }
372
373#if _MSC_VER >= 1600
374 /* these versions carry move semantics for capable objects */
375 bool Add(T&& object)
376 {
377 if (ActiveCount >= Length())
378 {
379 if ((IsAllocated || !VectorMax) && GrowthStep > 0)
380 {
381 if (!Resize(Length() + GrowthStep))
382 {
383 return false;
384 }
385 }
386 else
387 {
388 return false;
389 }
390 }
391 (*this)[ActiveCount++] = std::move(object);
392 return true;
393 }
394
395 bool Add_Head(T&& object)
396 {
397 return Insert(0, std::move(object));
398 }
399
400 bool Insert(int index, T&& object)
401 {
402 if (index < 0)
403 {
404 return false;
405 }
406 if (index > ActiveCount)
407 {
408 return false;
409 }
410 if (ActiveCount >= Length())
411 {
412 if ((IsAllocated || !VectorMax) && GrowthStep > 0)
413 {
414 if (!Resize(Length() + GrowthStep))
415 {
416 return false;
417 }
418 }
419 else
420 {
421 return false;
422 }
423 }
424 for (int i = ActiveCount; i > index; --i)
425 {
426 Vector[i] = std::move(Vector[i-1]);
427 }
428 (*this)[index] = std::move(object);
429 ActiveCount++;
430 return true;
431 }
432#endif
433
434 bool DeleteObj(T const &object)
435 {
436 int id = ID(object);
437 if (id != -1)
438 {
439 return Delete(id);
440 }
441 return false;
442 }
443 bool Delete(int index)
444 {
445 if (index < ActiveCount)
446 {
447 ActiveCount--;
448 for (int i = index; i < ActiveCount; i++)
449 {
450 (*this)[i] = std::move((*this)[i+1]);
451 }
452 return true;
453 }
454 return false;
455 }
456 void Delete_All(void)
457 {
458 int len = VectorMax;
459 Clear();
460 Resize(len);
461 }
462 int Set_Growth_Step(int step)
463 {
464 return(GrowthStep = step);
465 }
466 int Growth_Step(void)
467 {
468 return GrowthStep;
469 }
470 virtual int ID(T const *ptr)
471 {
472 return(VectorClass<T>::ID(ptr));
473 }
474 virtual int ID(T const &object)
475 {
476 for (int index = 0; index < Count(); index++)
477 {
478 if ((*this)[index] == object)
479 {
480 return(index);
481 }
482 }
483 return -1;
484 }
485 T *Uninitialized_Add(void)
486 {
487 if (ActiveCount >= Length())
488 {
489 if (GrowthStep > 0)
490 {
491 if (!Resize(Length() + GrowthStep))
492 {
493 return NULL;
494 }
495 }
496 else
497 {
498 return NULL;
499 }
500 }
501 return &((*this)[ActiveCount++]);
502 }
503 void Add_Multiple(const DynamicVectorClass<T>& elements)
504 {
505 Add_Multiple(elements.begin(), elements.Count());
506 }
507 void Add_Multiple(const T* elements, int count)
508 {
509 int newcount = ActiveCount + count;
510 Grow(newcount);
511
512 for (int i = 0; i < count; i++)
513 {
514 Vector[ActiveCount + i] = elements[i];
515 }
516 ActiveCount = newcount;
517 }
518 void Add_Multiple(int number_to_add)
519 {
520 int newcount = ActiveCount + number_to_add;
521 Grow(newcount);
522 ActiveCount = newcount;
523 }
524 // Grows by 1.5x if growth step is 0, otherwise grows according to step size.
525 // Returns false if the resize fails.
526 bool Grow()
527 {
528 if (GrowthStep == 0)
529 {
530 int len = VectorClass<T>::Length();
531 int newlen = len + (len >> 1); // 1.5x
532 if (newlen < 10) newlen = 10; // minimum length 10
533 return Grow(newlen);
534 }
535 else if (GrowthStep > 0)
536 {
537 return Grow(VectorClass<T>::Length() + GrowthStep);
538 }
539 TT_UNREACHABLE; // somebody set the growth step to negative
540 }
541 // Returns false if the resize fails or we don't need to grow (current length is greater than newlen).
542 bool Grow(int newlen)
543 {
544 if (newlen > Length() && (VectorClass<T>::IsAllocated || !VectorClass<T>::VectorMax))
545 {
546 return Resize(newlen);
547 }
548 return false;
549 }
550}; // 0018
551
552
553template <typename T> class PointerStack
554{
555public:
556 inline PointerStack(T* initial_item)
557 {
558 m_pStack[0] = initial_item;
559 m_iDepth = 1;
560 }
561
562 inline T* Pop()
563 {
564 TT_ASSERT(m_iDepth >= 0);
565 return m_pStack[--m_iDepth];
566 }
567
568 inline void Push(T* data)
569 {
570 TT_ASSERT(m_iDepth < 128);
571 if (m_iDepth >= 128) return;
572 m_pStack[m_iDepth++] = data;
573 }
574
575 int Depth()
576 {
577 return m_iDepth;
578 }
579
580private:
581 T* m_pStack[128];
582 int m_iDepth;
583};
584
585template <class T> class SimpleVecClass {
586protected:
587 T *Vector; // 0004
588 int VectorMax; // 0008
589public:
590 explicit SimpleVecClass(int size = 0)
591 {
592 Vector = 0;
593 VectorMax = 0;
594 if (size > 0)
595 {
596 Resize(size);
597 }
598 }
599 virtual ~SimpleVecClass()
600 {
601 if (Vector)
602 {
603 delete[] Vector;
604 Vector = 0;
605 VectorMax = 0;
606 }
607 }
608
609 SimpleVecClass(const SimpleVecClass<T>& vector)
610 {
611 Vector = (T*)(new char[vector.VectorMax * sizeof(T)]);
612 VectorMax = vector.VectorMax;
613 memcpy(Vector,vector.Vector, VectorMax * sizeof(T));
614 }
615
616 SimpleVecClass<T>& operator =(const SimpleVecClass<T>& vector)
617 {
618 if (this != &vector)
619 {
620 delete[] Vector;
621 Vector = (T*)(new char[vector.VectorMax * sizeof(T)]);
622 VectorMax = vector.VectorMax;
623 memcpy(Vector,vector.Vector, VectorMax * sizeof(T));
624 }
625 return *this;
626 }
627
628#if _MSC_VER >= 1600
629 /* more move semantics, yay! */
630 SimpleVecClass(SimpleVecClass<T>&& vector): Vector(vector.Vector), VectorMax(vector.VectorMax)
631 {
632 vector.Vector = 0;
633 }
634
635 SimpleVecClass<T>& operator =(SimpleVecClass<T>&& vector)
636 {
637 if (this != &vector)
638 {
639 delete[] Vector;
640 Vector = vector.Vector;
641 VectorMax = vector.VectorMax;
642 vector.Vector = 0;
643 }
644 return *this;
645 }
646#endif
647
648 virtual bool Resize(int newsize)
649 {
650 if (VectorMax == newsize)
651 {
652 return true;
653 }
654 if (newsize > 0)
655 {
656 T *vec = new T[newsize];
657 if (Vector)
658 {
659 int count = VectorMax;
660 if (newsize < count)
661 {
662 count = newsize;
663 }
664 memcpy(vec,Vector,count*sizeof(T));
665 delete[] Vector;
666 Vector = 0;
667 }
668 Vector = vec;
669 VectorMax = newsize;
670 }
671 else
672 {
673 VectorMax = 0;
674 if (Vector)
675 {
676 delete[] Vector;
677 Vector = 0;
678 }
679 }
680 return true;
681 }
682 virtual bool Uninitialised_Grow(int newsize)
683 {
684 if (newsize <= VectorMax)
685 {
686 return true;
687 }
688 if (newsize > 0)
689 {
690 if (Vector)
691 {
692 delete[] Vector;
693 }
694 Vector = new T[newsize];
695 VectorMax = newsize;
696 }
697 return true;
698 }
699
700 void Uninitialized_Resize(int newsize)
701 {
702 TT_ASSERT(newsize > 0);
703 delete[] Vector;
704 Vector = new T[newsize];
705 VectorMax = newsize;
706 }
707
708 int Length() const
709 {
710 return VectorMax;
711 }
712 T &operator[](int index)
713 {
714 return Vector[index];
715 }
716 T const &operator[](int index) const
717 {
718 return Vector[index];
719 }
720
721 T* Peek()
722 {
723 return Vector;
724 }
725
726 const T* Peek() const
727 {
728 return Vector;
729 }
730
731 void Zero_Memory()
732 {
733 if (Vector != NULL)
734 {
735 memset(Vector,0,VectorMax * sizeof(T));
736 }
737 }
738}; // 000C
739
740
741
742template <class T> class SimpleDynVecClass :
743 public SimpleVecClass<T>
744{
745
746protected:
747
748 int ActiveCount; // 000C
749
750 bool Grow(int new_size_hint)
751 {
752 int new_size = max(VectorMax + VectorMax/4,VectorMax + 4);
753 new_size = max(new_size,new_size_hint);
754 return Resize(new_size);
755 }
756 bool Shrink(void)
757 {
758 if (ActiveCount < VectorMax/4)
759 {
760 return Resize(ActiveCount);
761 }
762 return true;
763 }
764
765public:
766 virtual ~SimpleDynVecClass()
767 {
768 ActiveCount = 0;
769 }
770 explicit SimpleDynVecClass(int size = 0) : SimpleVecClass<T>(size)
771 {
772 ActiveCount = 0;
773 }
774
775 SimpleDynVecClass(const SimpleDynVecClass<T>& vector): SimpleVecClass(vector), ActiveCount(vector.ActiveCount)
776 {
777 /* nothing */
778 }
779
780 SimpleDynVecClass<T>& operator =(const SimpleDynVecClass<T>& vector)
781 {
782 if (this != &vector)
783 {
784 SimpleVecClass<T>::operator =(vector);
785 ActiveCount = vector.ActiveCount;
786 }
787 return *this;
788 }
789
790#if _MSC_VER >= 1600
791 /* move semantics ftw */
792 SimpleDynVecClass(SimpleDynVecClass<T>&& vector): SimpleVecClass(std::move(vector)), ActiveCount(vector.ActiveCount)
793 {
794 /* nothing */
795 };
796
797 SimpleDynVecClass<T>& operator =(SimpleDynVecClass<T>&& vector)
798 {
799 if (this != &vector)
800 {
801 SimpleVecClass::operator =(std::move(vector));
802 ActiveCount = vector.ActiveCount;
803 }
804 return *this;
805 }
806#endif
807
808 int Find_Index(T const & object)
809 {
810 for (int index = 0;index < Count();index++)
811 {
812 if (Vector[index] == object)
813 {
814 return index;
815 }
816 }
817 return -1;
818 }
819
820 int Count() const
821 {
822 return ActiveCount;
823 }
824 T &operator[](int index)
825 {
826 return Vector[index];
827 }
828 T const &operator[](int index) const
829 {
830 return Vector[index];
831 }
832 bool Resize(int newsize)
833 {
834 if (SimpleVecClass<T>::Resize(newsize))
835 {
836 if (VectorMax < ActiveCount)
837 {
838 ActiveCount = VectorMax;
839 }
840 return true;
841 }
842 return false;
843 }
844 bool Add(T const& data, int new_size_hint = 0)
845 {
846 if (ActiveCount >= VectorMax)
847 {
848 if (!Grow(new_size_hint))
849 {
850 return false;
851 }
852 }
853 Vector[ActiveCount++] = data;
854 return true;
855 }
856 T *Add_Multiple(int number_to_add)
857 {
858 int index = ActiveCount;
859 ActiveCount += number_to_add;
860 if (ActiveCount > VectorMax)
861 {
862 Grow(ActiveCount);
863 }
864 return &Vector[index];
865 }
866 void Add_Multiple(const SimpleDynVecClass<T>& elements)
867 {
868 Add_Multiple(elements.begin(), elements.Count());
869 }
870 void Add_Multiple(const T* elements, int count)
871 {
872 int newcount = ActiveCount + count;
873 if (newcount > VectorMax) Grow(newcount);
874 memcpy(Vector + ActiveCount, elements, count * sizeof(T));
875 ActiveCount = newcount;
876 }
877 bool Add_Head(const T& object)
878 {
879 return Insert(0, object);
880 }
881 bool Insert(int index, const T& object)
882 {
883 TT_ASSERT(index >= 0 && index <= ActiveCount);
884 if (ActiveCount >= VectorMax)
885 {
886 if (!Grow(0))
887 {
888 return false;
889 }
890 }
891 if (index < ActiveCount)
892 {
893 memmove(&Vector[index+1], &Vector[index], (ActiveCount-index) * sizeof(T));
894 }
895 Vector[index] = object;
896 ++ActiveCount;
897 return true;
898 }
899 bool Delete(int index,bool allow_shrink = true)
900 {
901 if (index < ActiveCount-1)
902 {
903 memmove(&(Vector[index]),&(Vector[index+1]),(ActiveCount - index - 1) * sizeof(T));
904 }
905 ActiveCount--;
906 if (allow_shrink)
907 {
908 Shrink();
909 }
910 return true;
911 }
912 bool Delete(T const & object,bool allow_shrink = true)
913 {
914 int id = Find_Index(object);
915 if (id != -1)
916 {
917 return Delete(id,allow_shrink);
918 }
919 return false;
920 }
921 bool Delete_Range(int start,int count,bool allow_shrink = true)
922 {
923 if (start < ActiveCount - count)
924 {
925 memmove(&(Vector[start]),&(Vector[start + count]),(ActiveCount - start - count) * sizeof(T));
926 }
927 ActiveCount -= count;
928 if (allow_shrink)
929 {
930 Shrink();
931 }
932 return true;
933 }
934 void Delete_All(bool allow_shrink = true)
935 {
936 ActiveCount = 0;
937 if (allow_shrink)
938 {
939 Shrink();
940 }
941 }
942
943 void qsort(int (*compareCallback)(const T&, const T&))
944 {
945 ::qsort(Vector, ActiveCount, sizeof(T), (int (*)(const void*, const void*))compareCallback);
946 }
947
948 bool isEmpty() const { return ActiveCount == 0; }
949
950}; // 0010
951
952
953class GenericList;
954class GenericNode {
955public:
956 GenericNode(void) : NextNode(0), PrevNode(0) {}
957 virtual ~GenericNode(void) {Unlink();}
958 GenericNode(GenericNode & node) {node.Link(this);}
959 GenericNode & operator = (GenericNode & node)
960 {
961 if (&node != this)
962 {
963 node.Link(this);
964 }
965 return(*this);
966 }
967 void Unlink(void)
968 {
969 if (Is_Valid())
970 {
971 PrevNode->NextNode = NextNode;
972 NextNode->PrevNode = PrevNode;
973 PrevNode = 0;
974 NextNode = 0;
975 }
976 }
977 GenericList * Main_List(void) const
978 {
979 GenericNode const * node = this;
980 while (node->PrevNode)
981 {
982 node = PrevNode;
983 }
984 return((GenericList *)this);
985 }
986 void Link(GenericNode * node)
987 {
988 TT_ASSERT(node != (GenericNode *)0);
989 node->Unlink();
990 node->NextNode = NextNode;
991 node->PrevNode = this;
992 if (NextNode) NextNode->PrevNode = node;
993 NextNode = node;
994 }
995 GenericNode * Next(void) const {return(NextNode);}
996 GenericNode * Next_Valid(void) const
997 {
998 return ((NextNode && NextNode->NextNode) ? NextNode : (GenericNode *)0);
999 }
1000 GenericNode * Prev(void) const {return(PrevNode);}
1001 GenericNode * Prev_Valid(void) const
1002 {
1003 return ((PrevNode && PrevNode->PrevNode) ? PrevNode : (GenericNode *)0);
1004 }
1005 bool Is_Valid(void) const {return(this != (GenericNode *)0 && NextNode != (GenericNode *)0 && PrevNode != (GenericNode *)0);}
1006protected:
1007 GenericNode * NextNode; // 0004
1008 GenericNode * PrevNode; // 0008
1009}; // 000C
1010class GenericList {
1011public:
1012 GenericList(void)
1013 {
1014 FirstNode.Link(&LastNode);
1015 }
1016 virtual ~GenericList(void)
1017 {
1018 while (FirstNode.Next()->Is_Valid())
1019 {
1020 FirstNode.Next()->Unlink();
1021 }
1022 }
1023 GenericNode * First(void) const {return(FirstNode.Next());}
1024 GenericNode * First_Valid(void) const
1025 {
1026 GenericNode *node = FirstNode.Next();
1027 return (node->Next() ? node : (GenericNode *)0);
1028 }
1029 GenericNode * Last(void) const {return(LastNode.Prev());}
1030 GenericNode * Last_Valid(void) const
1031 {
1032 GenericNode *node = LastNode.Prev();
1033 return (node->Prev() ? node : (GenericNode *)0);
1034 }
1035 bool Is_Empty(void) const {return(!FirstNode.Next()->Is_Valid());}
1036 void Add_Head(GenericNode * node) {FirstNode.Link(node);}
1037 void Add_Tail(GenericNode * node) {LastNode.Prev()->Link(node);}
1038 int Get_Valid_Count(void) const
1039 {
1040 GenericNode * node = First_Valid();
1041 int counter = 0;
1042 while(node)
1043 {
1044 counter++;
1045 node = node->Next_Valid();
1046 }
1047 return counter;
1048 }
1049protected:
1050 GenericNode FirstNode; // 0004
1051 GenericNode LastNode; // 0010
1052private:
1053 GenericList(GenericList & list);
1054 GenericList & operator = (GenericList const &);
1055}; // 001C
1056template<class T> class List;
1057template<class T>
1058class Node : public GenericNode
1059{
1060public:
1061 List<T> * Main_List(void) const {return((List<T> *)GenericNode::Main_List());}
1062 T Next(void) const {return((T)GenericNode::Next());}
1063 T Next_Valid(void) const {return((T)GenericNode::Next_Valid());}
1064 T Prev(void) const {return((T)GenericNode::Prev());}
1065 T Prev_Valid(void) const {return((T)GenericNode::Prev_Valid());}
1066 bool Is_Valid(void) const {return(GenericNode::Is_Valid());}
1067}; // 000C
1068template<class T>
1069class List : public GenericList
1070{
1071public:
1072 List(void) {};
1073 T First(void) const {return((T)GenericList::First());}
1074 T First_Valid(void) const {return((T)GenericList::First_Valid());}
1075 T Last(void) const {return((T)GenericList::Last());}
1076 T Last_Valid(void) const {return((T)GenericList::Last_Valid());}
1077 void Delete(void) {while (First()->Is_Valid()) delete First();}
1078private:
1079 List(List<T> const & rvalue);
1080 List<T> operator = (List<T> const & rvalue);
1081}; // 001C
1082template<class T>
1083class DataNode : public GenericNode
1084{
1085 T Value;
1086public:
1087 DataNode() {};
1088 DataNode(T value) { Set(value); };
1089 void Set(T value) { Value = value; };
1090 T Get() const { return Value; };
1091 DataNode<T> * Next(void) const { return (DataNode<T> *)GenericNode::Next(); }
1092 DataNode<T> * Next_Valid(void) const { return (DataNode<T> *)GenericNode::Next_Valid(); }
1093 DataNode<T> * Prev(void) const { return (DataNode<T> *)GenericNode::Prev(); }
1094 DataNode<T> * Prev_Valid(void) const { return (DataNode<T> *)GenericNode::Prev_Valid(); }
1095};
1096template<class C, class D>
1097class ContextDataNode : public DataNode<D>
1098{
1099 C Context;
1100public:
1101 ContextDataNode() {};
1102 ContextDataNode(C context, D data) { Set_Context(context); Set(data); }
1103 void Set_Context(C context) { Context = context; };
1104 C Get_Context() { return Context; };
1105};
1106template<class C, class D>
1107class SafeContextDataNode : public ContextDataNode<C,D>
1108{
1109public:
1110 SafeContextDataNode(C context, D data) : ContextDataNode<C,D>(context, data) { }
1111private:
1112 SafeContextDataNode();
1113};
1114template<class PRIMARY, class SECONDARY>
1115class DoubleNode
1116{
1117 void Initialize() { Primary.Set(this); Secondary.Set(this); };
1118 PRIMARY PrimaryValue;
1119 SECONDARY SecondaryValue;
1120public:
1121 typedef DoubleNode<PRIMARY, SECONDARY> Type;
1122 DataNode<Type *> Primary;
1123 DataNode<Type *> Secondary;
1124 DoubleNode() { Initialize(); };
1125 DoubleNode(PRIMARY primary, SECONDARY secondary) { Initialize(); Set_Primary(primary); Set_Secondary(secondary); };
1126 void Set_Primary(PRIMARY value) { PrimaryValue = value; };
1127 void Set_Secondary(SECONDARY value) { SecondaryValue = value; };
1128 PRIMARY Get_Primary() { return PrimaryValue; };
1129 SECONDARY Get_Secondary() { return SecondaryValue; };
1130 void Unlink() { Primary.Unlink(); Secondary.Unlink(); };
1131};
1132
1133template <typename T1,class T2> class IndexClass {
1134 struct NodeElement {
1135 T1 ID;
1136 T2 Data;
1137 NodeElement(T1 const &id, T2 const &data) : ID(id), Data(data)
1138 {
1139 }
1140 NodeElement() : ID(0), Data(0)
1141 {
1142 }
1143 bool operator==(NodeElement const &elem)
1144 {
1145 return ID == elem.ID;
1146 }
1147 bool operator<(NodeElement const &elem)
1148 {
1149 return ID < elem.ID;
1150 }
1151 };
1152 NodeElement* IndexTable;
1153 int IndexCount;
1154 int IndexSize;
1155 unsigned char IsSorted;
1156 const NodeElement* Archive;
1157public:
1158 IndexClass() : IndexTable(0), IndexCount(0), IndexSize(0), IsSorted(false), Archive(0)
1159 {
1160 Invalidate_Archive();
1161 }
1162 ~IndexClass()
1163 {
1164 Clear();
1165 }
1166 bool Remove_Index(const T1 &ID)
1167 {
1168 int pos = -1;
1169 for (int i = 0;i < IndexCount;i++)
1170 {
1171 if (IndexTable[i].ID == ID)
1172 {
1173 pos = i;
1174 break;
1175 }
1176 }
1177 if (pos == -1)
1178 {
1179 return false;
1180 }
1181 else
1182 {
1183 for (int i = pos;i < IndexCount;i++)
1184 {
1185 IndexTable[i] = IndexTable[i+1];
1186 }
1187 }
1188 IndexCount--;
1189 IndexTable[IndexCount].ID = 0;
1190 IndexTable[IndexCount].Data = 0;
1191 Invalidate_Archive();
1192 return true;
1193 }
1194 bool Is_Present(const T1 &ID)
1195 {
1196 if (IndexCount)
1197 {
1198 if (Is_Archive_Same(ID))
1199 {
1200 return true;
1201 }
1202 else
1203 {
1204 NodeElement *node = Search_For_Node(ID);
1205 if (node)
1206 {
1207 Set_Archive(node);
1208 return true;
1209 }
1210 else
1211 {
1212 return false;
1213 }
1214 }
1215 }
1216 return false;
1217 }
1218 bool Add_Index(const T1 &ID,const T2 &Data)
1219 {
1220 if (IndexCount + 1 <= IndexSize)
1221 {
1222 IndexTable[IndexCount].ID = ID;
1223 IndexTable[IndexCount++].Data = Data;
1224 IsSorted = false;
1225 return true;
1226 }
1227 int size = IndexSize;
1228 if (!size)
1229 {
1230 size = 10;
1231 }
1232 if (Increase_Table_Size(size))
1233 {
1234 IndexTable[IndexCount].ID = ID;
1235 IndexTable[IndexCount++].Data = Data;
1236 IsSorted = false;
1237 return true;
1238 }
1239 else
1240 {
1241 return false;
1242 }
1243 }
1244 int Count() const
1245 {
1246 return IndexCount;
1247 }
1248 const T2 &operator[](T1 const &ID)
1249 {
1250 static const T2 x;
1251 if (Is_Present(ID))
1252 {
1253 return Archive->Data;
1254 }
1255 return x;
1256 }
1257 void Invalidate_Archive()
1258 {
1259 Archive = 0;
1260 }
1261 void Clear()
1262 {
1263 if (IndexTable)
1264 {
1265 delete[] IndexTable;
1266 }
1267 IndexTable = 0;
1268 IndexCount = 0;
1269 IndexSize = 0;
1270 IsSorted = 0;
1271 Invalidate_Archive();
1272 }
1273 bool Is_Archive_Same(const T1 &ID)
1274 {
1275 return Archive && Archive->ID == ID;
1276 }
1277 NodeElement *Search_For_Node(const T1 &ID)
1278 {
1279 if (IndexCount)
1280 {
1281 if (!IsSorted)
1282 {
1283 qsort(IndexTable,IndexCount,sizeof(NodeElement),search_compfunc);
1284 Invalidate_Archive();
1285 IsSorted = true;
1286 }
1287 NodeElement elem(ID,0);
1288 return Binary_Search<NodeElement>(IndexTable,IndexCount,elem);
1289 }
1290 return false;
1291 }
1292 void Set_Archive(NodeElement const *archive)
1293 {
1294 Archive = archive;
1295 }
1296 bool Increase_Table_Size(int amount)
1297 {
1298 if (amount >= 0)
1299 {
1300 int newsize = IndexSize + amount;
1301 NodeElement *newindex = new NodeElement[newsize];
1302 if (newindex)
1303 {
1304 TT_ASSERT(IndexCount < newsize);
1305 for (int i = 0;i < this->IndexCount;i++)
1306 {
1307 newindex[i].ID = IndexTable[i].ID;
1308 newindex[i].Data = IndexTable[i].Data;
1309 }
1310 if (IndexTable)
1311 delete[] IndexTable;
1312 IndexTable = newindex;
1313 IndexSize += amount;
1314 Invalidate_Archive();
1315 return true;
1316 }
1317 }
1318 return false;
1319 }
1320 T1 Fetch_ID_By_Position(int position)
1321 {
1322 return IndexTable[position].ID;
1323 }
1324 T2 Fetch_By_Position(int position)
1325 {
1326 return IndexTable[position].Data;
1327 }
1328 static int search_compfunc(void const *ptr2, void const *ptr1)
1329 {
1330 if (*(NodeElement *)ptr2 == *(NodeElement *)ptr1)
1331 {
1332 return 0;
1333 }
1334 else
1335 {
1336 if (*(NodeElement *)ptr1 < *(NodeElement *)ptr2)
1337 {
1338 return 1;
1339 }
1340 else
1341 {
1342 return -1;
1343 }
1344 }
1345 }
1346}; // 0014
1347template <typename T> T *Binary_Search(T *list,int count,T &var)
1348{
1349 T *list2 = list;
1350 int pos = count;
1351 while (pos > 0)
1352 {
1353 T *list3 = &list2[pos / 2];
1354 if (var.ID >= list3->ID)
1355 {
1356 if (list3->ID == var.ID)
1357 {
1358 return &list2[pos / 2];
1359 }
1360 list2 = list3 + 1;
1361 pos = pos - pos / 2 - 1;
1362 }
1363 else
1364 {
1365 pos /= 2;
1366 }
1367 }
1368 return 0;
1369}
1370
1371template<typename T, int BLOCK_SIZE> class ObjectPoolClass
1372{
1373
1374private:
1375
1376 T* FreeListHead; // 0000
1377 void* BlockListHead; // 0004
1378 int FreeObjectCount; // 0008
1379 int TotalObjectCount; // 000C
1380 FastCriticalSectionClass ObjectPoolCS; // 0010
1381
1382public:
1383
1384 ObjectPoolClass()
1385 {
1386 FreeListHead = 0;
1387 BlockListHead = 0;
1388 FreeObjectCount = 0;
1389 TotalObjectCount = 0;
1390 }
1391
1392 ~ObjectPoolClass()
1393 {
1394 // If you hit the following assert, one or more objects were not freed.
1395 if (FreeObjectCount != TotalObjectCount)
1396 {
1397 char buffer[256];
1398 sprintf(buffer, "%d memory leaks found in " __FUNCTION__ "\n", TotalObjectCount - FreeObjectCount);
1399 OutputDebugStringA(buffer);
1400 // TODO: There are quite a few mem leaks of this kind. Fix them.
1401 }
1402
1403 void* block = BlockListHead;
1404 while (block)
1405 {
1406 void* nextBlock = *(void**)block;
1407 delete[] block;
1408 block = nextBlock;
1409 }
1410 }
1411
1412 T* Allocate_Object_Memory()
1413 {
1414 FastCriticalSectionClass::LockClass lock(ObjectPoolCS);
1415 if (!FreeListHead)
1416 {
1417 void* newBlockListHead = (void*)((void*)new char[sizeof(void*) + sizeof(T[BLOCK_SIZE])]);
1418 *(void**)newBlockListHead = BlockListHead;
1419 BlockListHead = newBlockListHead;
1420 FreeListHead = (T*)((intptr_t)BlockListHead + sizeof(void*));
1421 for (int i = 0; i < BLOCK_SIZE; i++)
1422 (T*&)FreeListHead[i] = &FreeListHead[i+1];
1423
1424 (T*&)FreeListHead[BLOCK_SIZE-1] = NULL;
1425 FreeObjectCount += BLOCK_SIZE;
1426 TotalObjectCount += BLOCK_SIZE;
1427 }
1428
1429 T* object = FreeListHead;
1430 FreeListHead = *(T**)(FreeListHead);
1431 FreeObjectCount--;
1432 return object;
1433 }
1434
1435 void Free_Object_Memory(T& object)
1436 {
1437 FastCriticalSectionClass::LockClass lock(ObjectPoolCS);
1438 writeDummyPattern(object, 0xEDE7E10D);
1439 (T*&)object = FreeListHead;
1440 FreeListHead = &object;
1441 FreeObjectCount++;
1442 }
1443
1444 void writeDummyPattern(T& object, DWORD pattern)
1445 {
1446#ifdef DEBUG
1447 static_assert(sizeof(T) % 4 == 0, "Expected type size to be a multiple of 4.");
1448 DWORD* dword = (DWORD*)&object;
1449 DWORD* endDword = (DWORD*)(&object+1);
1450 for (; dword < endDword; ++dword)
1451 *dword = pattern;
1452#endif
1453 }
1454
1455}; // 0014
1456
1457
1458#define objectPoolClass(T, nAlign) (Singleton<ObjectPoolClass<T, nAlign>>::getInstance())
1459
1460#pragma push_macro("new")
1461#pragma push_macro("delete")
1462#undef new
1463#undef delete
1464
1465
1466template<typename T, uint32 nAlign>
1467class AutoPoolClass
1468{
1469
1470private:
1471
1472 static void* operator new[](size_t size, const char* file = NULL, uint line = 0, const char* function = NULL);
1473 static void operator delete[](void* object);
1474 static void operator delete[](void* object, const char* file, uint line, const char* function);
1475
1476public:
1477
1478 static void* operator new(size_t size, const char* file = NULL, uint line = 0, const char* function = NULL)
1479 {
1480 TT_ASSERT(size == sizeof(T));
1481 return (void*)objectPoolClass(T, nAlign).Allocate_Object_Memory();
1482 }
1483
1484 static void operator delete(void* object)
1485 {
1486 if (object)
1487 objectPoolClass(T, nAlign).Free_Object_Memory(*(T*)object);
1488 }
1489
1490 static void operator delete(void* object, const char* file, uint line, const char* function)
1491 {
1492 if (object)
1493 objectPoolClass(T, nAlign).Free_Object_Memory(*(T*)object);
1494 }
1495
1496}; // 0000
1497
1498#pragma pop_macro("new")
1499#pragma pop_macro("delete")
1500
1501class RefCountClass {
1502private:
1503 long NumRefs; // 0004
1504public:
1505 RefCountClass() : NumRefs(1)
1506 {
1507 }
1508 RefCountClass(const RefCountClass &) : NumRefs(1)
1509 {
1510 }
1511 virtual void Delete_This()
1512 {
1513 delete this;
1514 }
1515 TT_INLINE void Release_Ref()
1516 {
1517 TT_ASSERT(NumRefs > 0);
1518 if (--NumRefs == 0)
1519 Delete_This();
1520 }
1521 TT_INLINE void Add_Ref()
1522 {
1523 ++NumRefs;
1524 }
1525 TT_INLINE void Release()
1526 {
1527 Release_Ref();
1528 }
1529 int Num_Refs()
1530 {
1531 return NumRefs;
1532 }
1533protected:
1534 virtual ~RefCountClass()
1535 {
1536 //If you reached this assert, you deleted a RefCountClass object. Don't do that.
1537 TT_ASSERT(NumRefs == 0);
1538 }
1539}; // 0008 0020
1540
1541template <class T> class ShareBufferClass : public RefCountClass {
1542public:
1543 ShareBufferClass(int count) : Count(count)
1544 {
1545 Array = new T[Count];
1546 }
1547 ShareBufferClass(const ShareBufferClass & that) : Count(that.Count)
1548 {
1549 Array = new T[Count];
1550 for (int i = 0;i < Count;i++)
1551 {
1552 Array[i] = that.Array[i];
1553 }
1554 }
1555 ~ShareBufferClass(void)
1556 {
1557 if (Array)
1558 {
1559 delete[] Array;
1560 Array = NULL;
1561 }
1562 }
1563 T *Get_Array(void)
1564 {
1565 return Array;
1566 }
1567 int Get_Count(void)
1568 {
1569 return Count;
1570 }
1571 void Set_Element(int index, const T & thing)
1572 {
1573 Array[index] = thing;
1574 }
1575 const T &Get_Element(int index) const
1576 {
1577 return Array[index];
1578 }
1579 T &Get_Element(int index)
1580 {
1581 return Array[index];
1582 }
1583 void Clear(void)
1584 {
1585 memset(Array,0,Count * sizeof(T));
1586 }
1587protected:
1588 T *Array;
1589 int Count;
1590 ShareBufferClass & operator = (const ShareBufferClass &);
1591};
1592
1593template <typename K, typename T> class PtrHashTable
1594{
1595
1596private:
1597
1598 template <typename K, typename T> struct Node
1599 {
1600
1601 private:
1602
1603 Node(const Node<K,T>& v){}; // The compiler likes complaining
1604
1605 public:
1606
1607 K Key;
1608 T Value;
1609 Node<K,T>* Next;
1610
1611 Node() :
1612 Next(NULL)
1613 {
1614 }
1615
1616 };
1617
1618
1619protected:
1620
1621 Node<K,T>* Vector[4096];
1622 Node<K,T>* Free;
1623 int AllocCount;
1624
1625
1626 Node<K,T>* GetLast(Node<K,T>* node) const
1627 {
1628 if (!node)
1629 return NULL;
1630
1631 while (node->Next != NULL)
1632 node = node->Next;
1633
1634 return node;
1635 }
1636
1637
1638 Node<K,T>* GetNodeWithNext(Node<K,T>* node, Node<K,T>* find) const
1639 {
1640 while (node)
1641 {
1642 if (node->Next == find)
1643 return node;
1644
1645 node = node->Next;
1646 };
1647
1648 return NULL;
1649 }
1650
1651
1652 Node<K,T>* GetFreeNode()
1653 {
1654 Node<K,T>* node = Free;
1655
1656 if (node)
1657 Free = node->Next;
1658
1659 else
1660 {
1661 node = new Node<K,T>;
1662 ++AllocCount;
1663 }
1664
1665 return node;
1666 }
1667
1668
1669 Node<K,T>* GetFreeNodeNoAlloc()
1670 {
1671 Node<K,T>* node = Free;
1672 if (node)
1673 Free = node->Next;
1674
1675 return node;
1676 }
1677
1678
1679 void AddFreeNode(Node<K,T>* node)
1680 {
1681 node->Next = Free;
1682 Free = node;
1683 }
1684
1685
1686 static unsigned int GetIndex(K key)
1687 {
1688 return (reinterpret_cast<unsigned int>(const_cast<K>(key)) >> 4) & (4096 - 1);
1689 }
1690
1691
1692public:
1693
1694 PtrHashTable()
1695 {
1696 memset(Vector, 0x00, sizeof(Node<K,T>*) * 4096);
1697 Free = NULL;
1698 AllocCount = 0;
1699 }
1700
1701
1702 ~PtrHashTable()
1703 {
1704 while (Node<K,T>* node = GetFreeNodeNoAlloc())
1705 delete node;
1706
1707 for (unsigned int i = 0; i < 4096; ++i)
1708 {
1709 Node<K,T>* node = Vector[i];
1710 while (node)
1711 {
1712 Node<K,T>* next = node->Next;
1713 delete node;
1714 node = next;
1715 }
1716 }
1717 }
1718
1719
1720 void Clear()
1721 {
1722 for (unsigned int i = 0; i < 4096; ++i)
1723 {
1724 Node<K,T>* node = Vector[i];
1725 while (node)
1726 {
1727 Node<K,T>* next = node->Next;
1728 AddFreeNode(node);
1729 node = next;
1730 }
1731
1732 Vector[i] = NULL;
1733 }
1734 }
1735
1736
1737 void Remove(K key)
1738 {
1739 unsigned int index = GetIndex(key);
1740 Node<K,T>* node = Vector[index];
1741 Node<K,T>** prevNextPtr = &Vector[index];
1742
1743 while (node)
1744 {
1745 if (node->Key == key)
1746 {
1747 *prevNextPtr = node->Next;
1748
1749 node->Key = NULL;
1750 AddFreeNode(node);
1751 break;
1752 }
1753
1754 prevNextPtr = &node->Next;
1755 node = node->Next;
1756 }
1757 }
1758
1759
1760 void Add(K key, T value)
1761 {
1762 unsigned int index = GetIndex(key);
1763
1764 Node<K,T>* free = GetFreeNode();
1765 free->Key = key;
1766 free->Value = value;
1767 free->Next = Vector[index];
1768 Vector[index] = free;
1769 }
1770
1771
1772 T operator[](K key)
1773 {
1774 for (Node<K,T>* node = Vector[GetIndex(key)]; node; node = node->Next)
1775 if (node->Key == key)
1776 return node->Value;
1777
1778 return NULL;
1779 }
1780
1781
1782 void assertValid()
1783 {
1784 for (uint i = 0; i < _countof(Vector); i++)
1785 {
1786 uint limit = 1000;
1787 for (Node<K,T>* node = Vector[i]; node; node = node->Next)
1788 {
1789 TT_ASSERT(node != node->Next);
1790 TT_ASSERT(limit-- != 0);
1791 }
1792 }
1793 }
1794
1795};
1796
1797
1798
1799#define DEFINE_AUTO_POOL(T, BLOCKSIZE) ObjectPoolClass<T, BLOCKSIZE> AutoPoolClass<T,BLOCKSIZE>::Allocator;
1800
1801
1802
1803#define REF_PTR_SET(dst,src) { if (src) (src)->Add_Ref(); if (dst) (dst)->Release_Ref(); (dst) = (src); }
1804#define REF_PTR_RELEASE(x) { if (x) x->Release_Ref(); x = NULL; }
1805#define REF_PTR_DTOR(x) { if (x) x->Release_Ref(); }
1806
1807template <typename T> inline T* REF_PTR_NEW(T* src)
1808{
1809 src->Add_Ref();
1810 return src;
1811};
1812
1813
1814#include "multilist.h"
1815
1816
1817
1818#endif // include guard