nodelist.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  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. /* $Header: /Commando/Code/Tools/pluglib/nodelist.cpp 9 3/14/02 4:22p Greg_h $ */
  19. /***********************************************************************************************
  20. *** Confidential - Westwood Studios ***
  21. ***********************************************************************************************
  22. * *
  23. * Project Name : Commando / G *
  24. * *
  25. * File Name : NODELIST.CPP *
  26. * *
  27. * Programmer : Greg Hjelstrom *
  28. * *
  29. * Start Date : 06/09/97 *
  30. * *
  31. * Last Update : June 9, 1997 [GH] *
  32. * *
  33. *---------------------------------------------------------------------------------------------*
  34. * Functions: *
  35. * INodeListClass::INodeListClass -- Create an INodeList *
  36. * INodeListClass::~INodeListClass -- Delete the INode List *
  37. * INode * INodeListClass::operator[] -- Array-like access to the list members *
  38. * INodeListClass::callback -- callback function for MAX *
  39. * INodeListClass::INodeListClass -- A "copy" contstructor with filtering... *
  40. * INodeListClass::INodeListClass -- constructor *
  41. * INodeListClass::INodeListClass -- Constructor *
  42. * INodeListClass::Insert -- insert a list of nodes into this list *
  43. * INodeListClass::Insert -- Inserts an INode into the list *
  44. * INodeListClass::Add_Tree -- Add a tree of INodes to the list *
  45. * INodeListClass::Remove -- Remove the i'th element of the list *
  46. * INodeListClass::Contains -- test whether the given node is in this list *
  47. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  48. #include "nodelist.h"
  49. static AnyINodeFilter _AnyFilter;
  50. /*******************************************************************************
  51. * ListEntryClass
  52. *
  53. * Used to implement a linked list of INodes.
  54. *
  55. *******************************************************************************/
  56. class INodeListEntryClass
  57. {
  58. public:
  59. INodeListEntryClass(INode * n,TimeValue /*time*/) { Node = n; }
  60. ~INodeListEntryClass(void) {}
  61. INode * Node;
  62. INodeListEntryClass * Next;
  63. };
  64. /***********************************************************************************************
  65. * INodeListClass::INodeListClass -- Constructor *
  66. * *
  67. * INPUT: *
  68. * *
  69. * OUTPUT: *
  70. * *
  71. * WARNINGS: *
  72. * *
  73. * HISTORY: *
  74. * 07/02/1997 GH : Created. *
  75. *=============================================================================================*/
  76. INodeListClass::INodeListClass(TimeValue time,INodeFilterClass * inodefilter) :
  77. NumNodes(0),
  78. Time(time),
  79. ListHead(NULL),
  80. INodeFilter(inodefilter)
  81. {
  82. if (INodeFilter == NULL) {
  83. INodeFilter = &_AnyFilter;
  84. }
  85. }
  86. /***********************************************************************************************
  87. * INodeListClass::INodeListClass -- Create an INodeList *
  88. * *
  89. * INPUT: *
  90. * scene - 3dsMAX scene to enumerate *
  91. * time - time at which to create the list of INodes *
  92. * inodefilter - object which will accept or reject each INode in the scene *
  93. * *
  94. * OUTPUT: *
  95. * *
  96. * WARNINGS: *
  97. * *
  98. * HISTORY: *
  99. * 06/09/1997 GH : Created. *
  100. *=============================================================================================*/
  101. INodeListClass::INodeListClass(IScene * scene,TimeValue time,INodeFilterClass * inodefilter) :
  102. NumNodes(0),
  103. Time(time),
  104. ListHead(NULL),
  105. INodeFilter(inodefilter)
  106. {
  107. if (INodeFilter == NULL) {
  108. INodeFilter = &_AnyFilter;
  109. }
  110. scene->EnumTree(this);
  111. }
  112. /***********************************************************************************************
  113. * INodeListClass::INodeListClass -- Constructor *
  114. * *
  115. * INPUT: *
  116. * *
  117. * OUTPUT: *
  118. * *
  119. * WARNINGS: *
  120. * *
  121. * HISTORY: *
  122. * 1/13/98 GTH : Created. *
  123. *=============================================================================================*/
  124. INodeListClass::INodeListClass(INode * root,TimeValue time,INodeFilterClass * nodefilter) :
  125. NumNodes(0),
  126. Time(time),
  127. ListHead(NULL),
  128. INodeFilter(nodefilter)
  129. {
  130. if (INodeFilter == NULL) {
  131. INodeFilter = &_AnyFilter;
  132. }
  133. Add_Tree(root);
  134. }
  135. /***********************************************************************************************
  136. * INodeListClass::INodeListClass -- A "copy" contstructor with filtering... *
  137. * *
  138. * INPUT: *
  139. * *
  140. * OUTPUT: *
  141. * *
  142. * WARNINGS: *
  143. * *
  144. * HISTORY: *
  145. * 07/02/1997 GH : Created. *
  146. *=============================================================================================*/
  147. INodeListClass::INodeListClass(INodeListClass & copyfrom,TimeValue time,INodeFilterClass * inodefilter) :
  148. NumNodes(0),
  149. Time(time),
  150. ListHead(NULL),
  151. INodeFilter(inodefilter)
  152. {
  153. if (INodeFilter == NULL) {
  154. INodeFilter = &_AnyFilter;
  155. }
  156. for (unsigned i=0; i<copyfrom.Num_Nodes(); i++) {
  157. Insert(copyfrom[i]);
  158. }
  159. }
  160. /***********************************************************************************************
  161. * INodeListClass::~INodeListClass -- Delete the INode List *
  162. * *
  163. * INPUT: *
  164. * *
  165. * OUTPUT: *
  166. * *
  167. * WARNINGS: *
  168. * *
  169. * HISTORY: *
  170. * 06/09/1997 GH : Created. *
  171. *=============================================================================================*/
  172. INodeListClass::~INodeListClass(void)
  173. {
  174. while (ListHead)
  175. {
  176. INodeListEntryClass * next = ListHead->Next;
  177. delete ListHead;
  178. ListHead = next;
  179. }
  180. NumNodes = 0;
  181. ListHead = NULL;
  182. }
  183. /***********************************************************************************************
  184. * INode * INodeListClass::operator[] -- Array-like access to the list members *
  185. * *
  186. * INPUT: *
  187. * index - index of the list entry *
  188. * *
  189. * OUTPUT: *
  190. * pointer to an INode *
  191. * *
  192. * WARNINGS: *
  193. * *
  194. * HISTORY: *
  195. * 06/09/1997 GH : Created. *
  196. *=============================================================================================*/
  197. INode * INodeListClass::operator[] ( int index ) const
  198. {
  199. INodeListEntryClass * entry = ListHead;
  200. while (index > 0 && entry != NULL )
  201. {
  202. entry = entry->Next;
  203. index--;
  204. }
  205. return entry->Node;
  206. }
  207. /***********************************************************************************************
  208. * INodeListClass::Insert -- insert a list of nodes into this list *
  209. * *
  210. * INPUT: *
  211. * *
  212. * OUTPUT: *
  213. * *
  214. * WARNINGS: *
  215. * *
  216. * HISTORY: *
  217. * 1/14/98 GTH : Created. *
  218. *=============================================================================================*/
  219. void INodeListClass::Insert(INodeListClass & insertlist)
  220. {
  221. for (unsigned int i=0; i<insertlist.Num_Nodes(); i++) {
  222. Insert(insertlist[i]);
  223. }
  224. }
  225. /***********************************************************************************************
  226. * INodeListClass::Insert -- Inserts an INode into the list *
  227. * *
  228. * INPUT: *
  229. * *
  230. * OUTPUT: *
  231. * *
  232. * WARNINGS: *
  233. * *
  234. * HISTORY: *
  235. * 07/02/1997 GH : Created. *
  236. *=============================================================================================*/
  237. void INodeListClass::Insert(INode * node)
  238. {
  239. if (INodeFilter->Accept_Node(node,Time))
  240. {
  241. INodeListEntryClass * newentry = new INodeListEntryClass(node, Time);
  242. newentry->Next = ListHead;
  243. ListHead = newentry;
  244. NumNodes++;
  245. }
  246. }
  247. /***********************************************************************************************
  248. * INodeListClass::Remove -- Remove the i'th element of the list *
  249. * *
  250. * INPUT: *
  251. * *
  252. * OUTPUT: *
  253. * *
  254. * WARNINGS: *
  255. * *
  256. * HISTORY: *
  257. * 10/27/2000 gth : Created. *
  258. *=============================================================================================*/
  259. void INodeListClass::Remove(int i)
  260. {
  261. if ((i < 0) || (i > Num_Nodes())) {
  262. return;
  263. }
  264. INodeListEntryClass * prev = ListHead;
  265. while (i > 1) {
  266. prev = prev->Next;
  267. }
  268. INodeListEntryClass * deleteme = prev->Next;
  269. if (deleteme != NULL) {
  270. prev->Next = prev->Next->Next;
  271. delete deleteme;
  272. }
  273. }
  274. /***********************************************************************************************
  275. * INodeListClass::Add_Tree -- Add a tree of INodes to the list *
  276. * *
  277. * INPUT: *
  278. * *
  279. * OUTPUT: *
  280. * *
  281. * WARNINGS: *
  282. * *
  283. * HISTORY: *
  284. * 1/13/98 GTH : Created. *
  285. *=============================================================================================*/
  286. void INodeListClass::Add_Tree(INode * root)
  287. {
  288. if (root == NULL) return;
  289. Insert(root);
  290. for (int i=0; i<root->NumberOfChildren(); i++) {
  291. Add_Tree(root->GetChildNode(i));
  292. }
  293. }
  294. /***********************************************************************************************
  295. * INodeListClass::Contains -- test whether the given node is in this list *
  296. * *
  297. * INPUT: *
  298. * *
  299. * OUTPUT: *
  300. * *
  301. * WARNINGS: *
  302. * *
  303. * HISTORY: *
  304. * 1/30/2002 gth : Created. *
  305. *=============================================================================================*/
  306. bool INodeListClass::Contains(INode * node)
  307. {
  308. INodeListIterator it(this);
  309. while (!it.Is_Done()) {
  310. if (it.Get_INode() == node) {
  311. return true;
  312. }
  313. }
  314. return false;
  315. }
  316. /***********************************************************************************************
  317. * INodeListClass::callback -- callback function for MAX *
  318. * *
  319. * 3dsMAX calls this function with a pointer to each INode in the scene. We keep a pointer *
  320. * to the ones we like. *
  321. * *
  322. * INPUT: *
  323. * *
  324. * OUTPUT: *
  325. * *
  326. * WARNINGS: *
  327. * *
  328. * HISTORY: *
  329. * 06/09/1997 GH : Created. *
  330. *=============================================================================================*/
  331. int INodeListClass::callback(INode * node)
  332. {
  333. Insert(node);
  334. return TREE_CONTINUE; // Keep on enumerating....
  335. }
  336. void INodeListClass::Sort(const INodeCompareClass & node_compare)
  337. {
  338. for (unsigned int i=0; i<Num_Nodes(); i++) {
  339. for (unsigned int j=0; j<Num_Nodes(); j++) {
  340. INodeListEntryClass * ni = get_nth_item(i);
  341. INodeListEntryClass * nj = get_nth_item(j);
  342. if (node_compare(ni->Node,nj->Node) > 0) {
  343. INode * tmp = ni->Node;
  344. ni->Node = nj->Node;
  345. nj->Node = tmp;
  346. }
  347. }
  348. }
  349. }
  350. INodeListEntryClass * INodeListClass::get_nth_item(int index)
  351. {
  352. INodeListEntryClass * entry = ListHead;
  353. while (index > 0 && entry != NULL )
  354. {
  355. entry = entry->Next;
  356. index--;
  357. }
  358. return entry;
  359. }
  360. /*******************************************************************************
  361. * INodeListIterator
  362. *
  363. * Iterator for INodeLists
  364. *
  365. *******************************************************************************/
  366. INodeListIterator::INodeListIterator(INodeListClass * list) :
  367. List(list)
  368. {
  369. assert(list != NULL);
  370. First();
  371. }
  372. INodeListIterator::~INodeListIterator(void)
  373. {
  374. }
  375. void INodeListIterator::First(INodeListClass * list)
  376. {
  377. if (list != NULL) {
  378. List = list;
  379. }
  380. assert(List != NULL);
  381. Node = List->ListHead;
  382. }
  383. void INodeListIterator::Next(void)
  384. {
  385. if (Node != NULL) {
  386. Node = Node->Next;
  387. }
  388. }
  389. bool INodeListIterator::Is_Done(void)
  390. {
  391. return (Node == NULL);
  392. }
  393. INode * INodeListIterator::Get_INode(void)
  394. {
  395. if (Node != NULL) {
  396. return Node->Node;
  397. }
  398. return NULL;
  399. }