listnode.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. /*
  2. ** Command & Conquer Renegade(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. *** 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 ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : Command & Conquer *
  23. * *
  24. * $Archive:: /Commando/Code/wwlib/listnode.h $*
  25. * *
  26. * $Author:: Ian_l $*
  27. * *
  28. * $Modtime:: 9/20/01 9:46p $*
  29. * *
  30. * $Revision:: 4 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. #if _MSC_VER >= 1000
  36. #pragma once
  37. #endif // _MSC_VER >= 1000
  38. #ifndef LISTNODE_H
  39. #define LISTNODE_H
  40. /*
  41. ** Includes
  42. */
  43. #include "assert.h"
  44. #ifdef __BORLANDC__
  45. #pragma warn -inl
  46. #endif
  47. /*
  48. ** This is a doubly linked list node. Typical use of this node is to derive
  49. ** objects from this node. The interface class for this node can be used for
  50. ** added convenience.
  51. */
  52. class GenericList;
  53. class GenericNode {
  54. public:
  55. GenericNode(void) : NextNode(0), PrevNode(0) {}
  56. virtual ~GenericNode(void) {Unlink();}
  57. GenericNode(GenericNode & node) {node.Link(this);}
  58. GenericNode & operator = (GenericNode & node) {
  59. if (&node != this) {
  60. node.Link(this);
  61. }
  62. return(*this);
  63. }
  64. void Unlink(void) {
  65. // note that this means that the special generic node at the head
  66. // and tail of the list can not be unlinked. This is done because
  67. // the user should never unlink them -- it will destroy the list in
  68. // an evil way.
  69. if (Is_Valid()) {
  70. PrevNode->NextNode = NextNode;
  71. NextNode->PrevNode = PrevNode;
  72. PrevNode = 0;
  73. NextNode = 0;
  74. }
  75. }
  76. GenericList * Main_List(void) const {
  77. GenericNode const * node = this;
  78. while (node->PrevNode) {
  79. node = PrevNode;
  80. }
  81. return((GenericList *)this);
  82. }
  83. void Link(GenericNode * node) {
  84. assert(node != (GenericNode *)0);
  85. node->Unlink();
  86. node->NextNode = NextNode;
  87. node->PrevNode = this;
  88. if (NextNode) NextNode->PrevNode = node;
  89. NextNode = node;
  90. }
  91. GenericNode * Next(void) const {return(NextNode);}
  92. GenericNode * Next_Valid(void) const {
  93. return ((NextNode && NextNode->NextNode) ? NextNode : (GenericNode *)0);
  94. }
  95. GenericNode * Prev(void) const {return(PrevNode);}
  96. GenericNode * Prev_Valid(void) const {
  97. return ((PrevNode && PrevNode->PrevNode) ? PrevNode : (GenericNode *)0);
  98. }
  99. bool Is_Valid(void) const {return(this != (GenericNode *)0 && NextNode != (GenericNode *)0 && PrevNode != (GenericNode *)0);}
  100. protected:
  101. GenericNode * NextNode;
  102. GenericNode * PrevNode;
  103. };
  104. /*
  105. ** This is a generic list handler. It manages N generic nodes. Use the interface class
  106. ** to the generic list for added convenience.
  107. */
  108. class GenericList {
  109. public:
  110. GenericList(void) {
  111. FirstNode.Link(&LastNode);
  112. }
  113. virtual ~GenericList(void) {
  114. while (FirstNode.Next()->Is_Valid()) {
  115. FirstNode.Next()->Unlink();
  116. }
  117. }
  118. GenericNode * First(void) const {return(FirstNode.Next());}
  119. GenericNode * First_Valid(void) const
  120. {
  121. GenericNode *node = FirstNode.Next();
  122. return (node->Next() ? node : (GenericNode *)0);
  123. }
  124. GenericNode * Last(void) const {return(LastNode.Prev());}
  125. GenericNode * Last_Valid(void) const
  126. {
  127. GenericNode *node = LastNode.Prev();
  128. return (node->Prev() ? node : (GenericNode *)0);
  129. }
  130. bool Is_Empty(void) const {return(!FirstNode.Next()->Is_Valid());}
  131. void Add_Head(GenericNode * node) {FirstNode.Link(node);}
  132. void Add_Tail(GenericNode * node) {LastNode.Prev()->Link(node);}
  133. // void Delete(void) {while (FirstNode.Next()->Is_Valid()) delete FirstNode.Next();}
  134. int Get_Valid_Count(void) const
  135. {
  136. GenericNode * node = First_Valid();
  137. int counter = 0;
  138. while(node) {
  139. counter++;
  140. node = node->Next_Valid();
  141. }
  142. return counter;
  143. }
  144. protected:
  145. GenericNode FirstNode;
  146. GenericNode LastNode;
  147. private:
  148. GenericList(GenericList & list);
  149. GenericList & operator = (GenericList const &);
  150. };
  151. /*
  152. ** This node class serves only as an "interface class" for the normal node
  153. ** object. In order to use this interface class you absolutely must be sure
  154. ** that the node is the root base object of the "class T". If it is true that the
  155. ** address of the node is the same as the address of the "class T", then this
  156. ** interface class will work. You can usually ensure this by deriving the
  157. ** class T object from this node.
  158. */
  159. template<class T> class List;
  160. template<class T>
  161. class Node : public GenericNode {
  162. public:
  163. List<T> * Main_List(void) const {return((List<T> *)GenericNode::Main_List());}
  164. T Next(void) const {return((T)GenericNode::Next());}
  165. T Next_Valid(void) const {return((T)GenericNode::Next_Valid());}
  166. T Prev(void) const {return((T)GenericNode::Prev());}
  167. T Prev_Valid(void) const {return((T)GenericNode::Prev_Valid());}
  168. bool Is_Valid(void) const {return(GenericNode::Is_Valid());}
  169. };
  170. /*
  171. ** This is an "interface class" for a list of nodes. The rules for the class T object
  172. ** are the same as the requirements required of the node class.
  173. */
  174. template<class T>
  175. class List : public GenericList {
  176. public:
  177. List(void) {};
  178. T First(void) const {return((T)GenericList::First());}
  179. T First_Valid(void) const {return((T)GenericList::First_Valid());}
  180. T Last(void) const {return((T)GenericList::Last());}
  181. T Last_Valid(void) const {return((T)GenericList::Last_Valid());}
  182. void Delete(void) {while (First()->Is_Valid()) delete First();}
  183. private:
  184. List(List<T> const & rvalue);
  185. List<T> operator = (List<T> const & rvalue);
  186. };
  187. /*
  188. The DataNode template class allows you to have a node with a peice of data associated with it.
  189. Commonly used to maintain a list of objects which are not derived from GenericNode.
  190. - EHC
  191. */
  192. template<class T>
  193. class DataNode : public GenericNode {
  194. T Value;
  195. public:
  196. DataNode() {};
  197. DataNode(T value) { Set(value); };
  198. void Set(T value) { Value = value; };
  199. T Get() const { return Value; };
  200. DataNode<T> * Next(void) const { return (DataNode<T> *)GenericNode::Next(); }
  201. DataNode<T> * Next_Valid(void) const { return (DataNode<T> *)GenericNode::Next_Valid(); }
  202. DataNode<T> * Prev(void) const { return (DataNode<T> *)GenericNode::Prev(); }
  203. DataNode<T> * Prev_Valid(void) const { return (DataNode<T> *)GenericNode::Prev_Valid(); }
  204. };
  205. /*
  206. The ContextDataNode template class is an extension of the DataNode class and has an additional
  207. data value associated with it. Commonly used for tracking the owner of a DataNode.
  208. - EHC
  209. */
  210. template<class C, class D>
  211. class ContextDataNode : public DataNode<D> {
  212. C Context;
  213. public:
  214. ContextDataNode() {};
  215. ContextDataNode(C context, D data) { Set_Context(context); Set(data); }
  216. void Set_Context(C context) { Context = context; };
  217. C Get_Context() { return Context; };
  218. };
  219. /*
  220. ** A SafeContextDataNode requires the user to supply context and
  221. ** Data values to the constructor. This eliminates the problem of
  222. ** uninitialized ContextDataNodes. -DRM
  223. */
  224. template<class C, class D>
  225. class SafeContextDataNode : public ContextDataNode<C,D>
  226. {
  227. public:
  228. SafeContextDataNode(C context, D data) : ContextDataNode<C,D>(context, data) { }
  229. private:
  230. // if the compiler complains that it can't access this constructor,
  231. // you are trying to construct a SafeContextDataNode without providing
  232. // context and data values. Perhaps you've included a SafeContextDataNode
  233. // as a member variable, but forgotten to add it to the initializer list
  234. // in your class constructor.
  235. // DO NOT change the void constructor to public. That would defeat
  236. // the purpose of the SafeContextDataNode. -DRM
  237. SafeContextDataNode();
  238. };
  239. /*
  240. The DoubleNode class has double everything a DataNode has!
  241. Each DataNode's data member points to the DoubleNode object
  242. that owns it. This type of object can therefore be in two distinct
  243. lists, and when it is destroyed it is removed from both of them
  244. automatically.
  245. usage example:
  246. typedef a symbol for the usage of the DoubleNode class as such:
  247. typedef DoubleNode<int, bool> DOUBLENODE;
  248. declare the head of the list as a DataNode with type DOUBLENODE
  249. List<DOUBLENODE *> PrimaryList; // member of object1
  250. List<DOUBLENODE *> SecondaryList; // member of object2
  251. Iterate through the list starting at PrimaryList or SecondaryList.
  252. These two lists are intended to be located in different
  253. objects, such as an Active list and an Association list as used in G
  254. Planet mode.
  255. */
  256. template<class PRIMARY, class SECONDARY>
  257. class DoubleNode {
  258. void Initialize() { Primary.Set(this); Secondary.Set(this); };
  259. PRIMARY PrimaryValue;
  260. SECONDARY SecondaryValue;
  261. public:
  262. typedef DoubleNode<PRIMARY, SECONDARY> Type;
  263. DataNode<Type *> Primary;
  264. DataNode<Type *> Secondary;
  265. DoubleNode() { Initialize(); };
  266. DoubleNode(PRIMARY primary, SECONDARY secondary) { Initialize(); Set_Primary(primary); Set_Secondary(secondary); };
  267. void Set_Primary(PRIMARY value) { PrimaryValue = value; };
  268. void Set_Secondary(SECONDARY value) { SecondaryValue = value; };
  269. PRIMARY Get_Primary() { return PrimaryValue; };
  270. SECONDARY Get_Secondary() { return SecondaryValue; };
  271. void Unlink() { Primary.Unlink(); Secondary.Unlink(); };
  272. };
  273. #endif