HEAP.CPP 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663
  1. //
  2. // Copyright 2020 Electronic Arts Inc.
  3. //
  4. // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free
  5. // software: you can redistribute it and/or modify it under the terms of
  6. // the GNU General Public License as published by the Free Software Foundation,
  7. // either version 3 of the License, or (at your option) any later version.
  8. // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed
  9. // in the hope that it will be useful, but with permitted additional restrictions
  10. // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
  11. // distributed with this program. You should have received a copy of the
  12. // GNU General Public License along with permitted additional restrictions
  13. // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
  14. /* $Header: /CounterStrike/HEAP.CPP 1 3/03/97 10:24a Joe_bostic $ */
  15. /***********************************************************************************************
  16. *** 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 ***
  17. ***********************************************************************************************
  18. * *
  19. * Project Name : Command & Conquer *
  20. * *
  21. * File Name : HEAP.CPP *
  22. * *
  23. * Programmer : Joe L. Bostic *
  24. * *
  25. * Start Date : 02/18/95 *
  26. * *
  27. * Last Update : May 6, 1996 [JLB] *
  28. * *
  29. *---------------------------------------------------------------------------------------------*
  30. * Functions: *
  31. * FixedHeapClass::Allocate -- Allocate a sub-block from the heap. *
  32. * FixedHeapClass::Clear -- Clears (and frees) the heap manager memory. *
  33. * FixedHeapClass::FixedHeapClass -- Normal constructor for heap management class. *
  34. * FixedHeapClass::Free -- Frees a sub-block in the heap. *
  35. * FixedHeapClass::Free_All -- Frees all objects in the fixed heap. *
  36. * FixedHeapClass::ID -- Converts a pointer to a sub-block index number. *
  37. * FixedHeapClass::Set_Heap -- Assigns a memory block for this heap manager. *
  38. * FixedHeapClass::~FixedHeapClass -- Destructor for the heap manager class. *
  39. * FixedIHeapClass::Allocate -- Allocate an object from the heap. *
  40. * FixedIHeapClass::Clear -- Clears the fixed heap of all entries. *
  41. * FixedIHeapClass::Free -- Frees an object in the heap. *
  42. * FixedIHeapClass::Free_All -- Frees all objects out of the indexed heap. *
  43. * FixedIHeapClass::Logical_ID -- Fetches the logical ID number. *
  44. * FixedIHeapClass::Set_Heap -- Set the heap to the buffer provided. *
  45. * TFixedIHeapClass::Code_Pointers -- codes pointers for every object, to prepare for save *
  46. * TFixedIHeapClass::Decode_Pointers -- Decodes all object pointers, for after loading *
  47. * TFixedIHeapClass::Load -- Loads all active objects *
  48. * TFixedIHeapClass::Save -- Saves all active objects *
  49. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  50. #include "function.h"
  51. #include "heap.h"
  52. //#include <mem.h>
  53. #include <stdio.h>
  54. #include <stddef.h>
  55. #include <conio.h>
  56. #include <string.h>
  57. template class TFixedIHeapClass<AircraftClass>;
  58. template class TFixedIHeapClass<AircraftTypeClass>;
  59. template class TFixedIHeapClass<AnimClass>;
  60. template class TFixedIHeapClass<AnimTypeClass>;
  61. template class TFixedIHeapClass<BuildingClass>;
  62. template class TFixedIHeapClass<BuildingTypeClass>;
  63. template class TFixedIHeapClass<BulletClass>;
  64. template class TFixedIHeapClass<BulletTypeClass>;
  65. template class TFixedIHeapClass<FactoryClass>;
  66. template class TFixedIHeapClass<HouseClass>;
  67. template class TFixedIHeapClass<HouseTypeClass>;
  68. template class TFixedIHeapClass<InfantryClass>;
  69. template class TFixedIHeapClass<InfantryTypeClass>;
  70. template class TFixedIHeapClass<OverlayClass>;
  71. template class TFixedIHeapClass<OverlayTypeClass>;
  72. template class TFixedIHeapClass<SmudgeClass>;
  73. template class TFixedIHeapClass<SmudgeTypeClass>;
  74. template class TFixedIHeapClass<TeamClass>;
  75. template class TFixedIHeapClass<TeamClass>;
  76. template class TFixedIHeapClass<TeamTypeClass>;
  77. template class TFixedIHeapClass<TemplateClass>;
  78. template class TFixedIHeapClass<TemplateTypeClass>;
  79. template class TFixedIHeapClass<TerrainClass>;
  80. template class TFixedIHeapClass<TerrainTypeClass>;
  81. template class TFixedIHeapClass<TriggerClass>;
  82. template class TFixedIHeapClass<TriggerTypeClass>;
  83. template class TFixedIHeapClass<UnitClass>;
  84. template class TFixedIHeapClass<UnitTypeClass>;
  85. template class TFixedIHeapClass<VesselClass>;
  86. template class TFixedIHeapClass<VesselTypeClass>;
  87. template class TFixedIHeapClass<WarheadTypeClass>;
  88. template class TFixedIHeapClass<WeaponTypeClass>;
  89. /***********************************************************************************************
  90. * FixedHeapClass::FixedHeapClass -- Normal constructor for heap management class. *
  91. * *
  92. * This is the normal constructor used for the heap manager class. This initializes *
  93. * the class but doesn't yet assign actual heap memory to this manager. That is handled *
  94. * by the Set_Heap() function. *
  95. * *
  96. * INPUT: size -- The size of the individual sub-blocks in this heap. This value is *
  97. * typically the size of some class or structure. *
  98. * *
  99. * OUTPUT: none *
  100. * *
  101. * WARNINGS: The heap must first be assigned a block of memory to manage before it can *
  102. * be used. *
  103. * *
  104. * HISTORY: *
  105. * 02/21/1995 JLB : Created. *
  106. *=============================================================================================*/
  107. FixedHeapClass::FixedHeapClass(int size) :
  108. IsAllocated(false),
  109. Size(size),
  110. TotalCount(0),
  111. ActiveCount(0),
  112. Buffer(0)
  113. {
  114. }
  115. /***********************************************************************************************
  116. * FixedHeapClass::~FixedHeapClass -- Destructor for the heap manager class. *
  117. * *
  118. * This is the default constructor for the heap manager class. It handles freeing the *
  119. * memory assigned to this heap. *
  120. * *
  121. * INPUT: none *
  122. * *
  123. * OUTPUT: none *
  124. * *
  125. * WARNINGS: none *
  126. * *
  127. * HISTORY: *
  128. * 02/21/1995 JLB : Created. *
  129. *=============================================================================================*/
  130. FixedHeapClass::~FixedHeapClass(void)
  131. {
  132. FixedHeapClass::Clear();
  133. }
  134. /***********************************************************************************************
  135. * FixedHeapClass::Set_Heap -- Assigns a memory block for this heap manager. *
  136. * *
  137. * This routine is used to assign a memory heap to this object. A memory heap so assigned *
  138. * will start with all sub-blocks unallocated. After this routine is called, normal *
  139. * allocation and freeing may occur. This routine will allocate necessary memory if the *
  140. * buffer parameter is NULL. *
  141. * *
  142. * INPUT: count -- The number of objects that this heap should manage. *
  143. * *
  144. * buffer -- Pointer to pre-allocated buffer that this manager will use. If this *
  145. * parameter is NULL, then memory will be automatically allocated. *
  146. * *
  147. * OUTPUT: bool; Was the heap successfully initialized? *
  148. * *
  149. * WARNINGS: none *
  150. * *
  151. * HISTORY: *
  152. * 02/21/1995 JLB : Created. *
  153. *=============================================================================================*/
  154. int FixedHeapClass::Set_Heap(int count, void * buffer)
  155. {
  156. /*
  157. ** Clear out the old heap data.
  158. */
  159. Clear();
  160. /*
  161. ** If there is no size to the objects in the heap, then this block memory
  162. ** handler can NEVER function. Return with a failure condition.
  163. */
  164. if (!Size) return(false);
  165. /*
  166. ** If there is no count specified, then this indicates that the heap should
  167. ** be disabled.
  168. */
  169. if (!count) return(true);
  170. /*
  171. ** Initialize the free boolean vector and the buffer for the actual
  172. ** allocation objects.
  173. */
  174. if (FreeFlag.Resize(count)) {
  175. if (!buffer) {
  176. buffer = new char[count * Size];
  177. if (!buffer) {
  178. FreeFlag.Clear();
  179. return(false);
  180. }
  181. IsAllocated = true;
  182. }
  183. Buffer = buffer;
  184. TotalCount = count;
  185. return(true);
  186. }
  187. return(false);
  188. }
  189. /***********************************************************************************************
  190. * FixedHeapClass::Allocate -- Allocate a sub-block from the heap. *
  191. * *
  192. * Finds the first available sub-block in the heap and returns a pointer to it. The sub- *
  193. * block is marked as allocated by this routine. If there are no more sub-blocks *
  194. * available, then this routine will return NULL. *
  195. * *
  196. * INPUT: none *
  197. * *
  198. * OUTPUT: Returns with a pointer to the newly allocated sub-block. *
  199. * *
  200. * WARNINGS: none *
  201. * *
  202. * HISTORY: *
  203. * 02/21/1995 JLB : Created. *
  204. *=============================================================================================*/
  205. void * FixedHeapClass::Allocate(void)
  206. {
  207. if (ActiveCount < TotalCount) {
  208. int index = FreeFlag.First_False();
  209. if (index != -1) {
  210. ActiveCount++;
  211. FreeFlag[index] = true;
  212. return((*this)[index]);
  213. }
  214. }
  215. return(0);
  216. }
  217. /***********************************************************************************************
  218. * FixedHeapClass::Free -- Frees a sub-block in the heap. *
  219. * *
  220. * Use this routine to free a previously allocated sub-block in the heap. *
  221. * *
  222. * INPUT: pointer -- A pointer to the sub-block to free. This is the same pointer that *
  223. * was returned from the Allocate() function. *
  224. * *
  225. * OUTPUT: bool; Was the deallocation successful? Failure could indicate a pointer that *
  226. * doesn't refer to this heap or a null pointer. *
  227. * *
  228. * WARNINGS: none *
  229. * *
  230. * HISTORY: *
  231. * 02/21/1995 JLB : Created. *
  232. *=============================================================================================*/
  233. int FixedHeapClass::Free(void * pointer)
  234. {
  235. if (pointer && ActiveCount) {
  236. int index = ID(pointer);
  237. if (index < TotalCount) {
  238. if (FreeFlag[index]) {
  239. ActiveCount--;
  240. FreeFlag[index] = false;
  241. return(true);
  242. }
  243. }
  244. }
  245. return(false);
  246. }
  247. /***********************************************************************************************
  248. * FixedHeapClass::ID -- Converts a pointer to a sub-block index number. *
  249. * *
  250. * Use this routine to convert a pointer (returned by Allocate) into the sub-block *
  251. * index number. This index number can be used as a form of identifier for the block. *
  252. * *
  253. * INPUT: pointer -- A pointer to the sub-block to convert into an ID number. *
  254. * *
  255. * OUTPUT: Returns with the index (ID) number for the sub-block specified. This number will *
  256. * range between 0 and the sub-block max -1. If -1 is returned, then the pointer *
  257. * was invalid. *
  258. * *
  259. * WARNINGS: none *
  260. * *
  261. * HISTORY: *
  262. * 02/21/1995 JLB : Created. *
  263. *=============================================================================================*/
  264. int FixedHeapClass::ID(void const * pointer) const
  265. {
  266. if (pointer && Size) {
  267. return((int)(((char *)pointer - (char *)Buffer) / Size));
  268. }
  269. return(-1);
  270. }
  271. /***********************************************************************************************
  272. * FixedHeapClass::Clear -- Clears (and frees) the heap manager memory. *
  273. * *
  274. * This routine is used to bring the heap manager back into a non-functioning state. All *
  275. * memory allocated by this manager is freed. Any previous pointers to allocated blocks *
  276. * from this heap are now invalid. *
  277. * *
  278. * INPUT: none *
  279. * *
  280. * OUTPUT: none *
  281. * *
  282. * WARNINGS: none *
  283. * *
  284. * HISTORY: *
  285. * 02/21/1995 JLB : Created. *
  286. *=============================================================================================*/
  287. void FixedHeapClass::Clear(void)
  288. {
  289. /*
  290. ** Free the old buffer (if present).
  291. */
  292. if (Buffer && IsAllocated) {
  293. delete[] Buffer;
  294. }
  295. Buffer = 0;
  296. IsAllocated = false;
  297. ActiveCount = 0;
  298. TotalCount = 0;
  299. FreeFlag.Clear();
  300. }
  301. /***********************************************************************************************
  302. * FixedHeapClass::Free_All -- Frees all objects in the fixed heap. *
  303. * *
  304. * This routine will free all previously allocated objects out of the heap. Use this *
  305. * routine to ensure that the heap is empty. *
  306. * *
  307. * INPUT: none *
  308. * *
  309. * OUTPUT: Was the heap successfully cleared of all objects? *
  310. * *
  311. * WARNINGS: none *
  312. * *
  313. * HISTORY: *
  314. * 05/22/1995 JLB : Created. *
  315. *=============================================================================================*/
  316. int FixedHeapClass::Free_All(void)
  317. {
  318. ActiveCount = 0;
  319. FreeFlag.Reset();
  320. return(true);
  321. }
  322. /////////////////////////////////////////////////////////////////////
  323. /***********************************************************************************************
  324. * FixedIHeapClass::Free_All -- Frees all objects out of the indexed heap. *
  325. * *
  326. * Use this routine to free all previously allocated objects in the heap. This routine will *
  327. * also clear out the allocated object vector as well. *
  328. * *
  329. * INPUT: none *
  330. * *
  331. * OUTPUT: Was the heap successfully cleared of objects? *
  332. * *
  333. * WARNINGS: none *
  334. * *
  335. * HISTORY: *
  336. * 05/22/1995 JLB : Created. *
  337. *=============================================================================================*/
  338. int FixedIHeapClass::Free_All(void)
  339. {
  340. ActivePointers.Delete_All();
  341. return(FixedHeapClass::Free_All());
  342. }
  343. /***********************************************************************************************
  344. * FixedIHeapClass::Clear -- Clears the fixed heap of all entries. *
  345. * *
  346. * This routine will clear the entire heap. All memory that was allocation, will be freed *
  347. * by this routine. After calling this routine, the heap must either be resized or *
  348. * a new heap memory block specifically attached, before it can be used again. *
  349. * *
  350. * INPUT: none *
  351. * *
  352. * OUTPUT: none *
  353. * *
  354. * WARNINGS: none *
  355. * *
  356. * HISTORY: *
  357. * 09/21/1995 JLB : Created. *
  358. *=============================================================================================*/
  359. void FixedIHeapClass::Clear(void)
  360. {
  361. FixedHeapClass::Clear();
  362. ActivePointers.Clear();
  363. }
  364. /***********************************************************************************************
  365. * FixedIHeapClass::Set_Heap -- Set the heap to the buffer provided. *
  366. * *
  367. * This routine will set the heap to use the buffer specified. Use this routine when a *
  368. * pre-allocated buffer is to be used for the heap. A heap that is assigned in this *
  369. * manner cannot be resized. *
  370. * *
  371. * INPUT: count -- The number of objects that the buffer pointer can be used to track. *
  372. * *
  373. * buffer -- Pointer to the buffer to use when keeping track of the objects. *
  374. * *
  375. * OUTPUT: Was the heap assigned successfully? *
  376. * *
  377. * WARNINGS: none *
  378. * *
  379. * HISTORY: *
  380. * 09/21/1995 JLB : Created. *
  381. *=============================================================================================*/
  382. int FixedIHeapClass::Set_Heap(int count, void * buffer)
  383. {
  384. Clear();
  385. if (FixedHeapClass::Set_Heap(count, buffer)) {
  386. ActivePointers.Resize(count);
  387. return(true);
  388. }
  389. return(false);
  390. }
  391. /***********************************************************************************************
  392. * FixedIHeapClass::Allocate -- Allocate an object from the heap. *
  393. * *
  394. * This routine will allocate an object located in the heap. If no free object space *
  395. * could be found, then NULL is returned. *
  396. * *
  397. * INPUT: none *
  398. * *
  399. * OUTPUT: Returns with a pointer to the allocated object memory block. *
  400. * *
  401. * WARNINGS: none *
  402. * *
  403. * HISTORY: *
  404. * 09/21/1995 JLB : Created. *
  405. *=============================================================================================*/
  406. void * FixedIHeapClass::Allocate(void)
  407. {
  408. void * ptr = FixedHeapClass::Allocate();
  409. if (ptr) {
  410. ActivePointers.Add(ptr);
  411. memset (ptr, 0, Size);
  412. }
  413. return(ptr);
  414. }
  415. /***********************************************************************************************
  416. * FixedIHeapClass::Free -- Frees an object in the heap. *
  417. * *
  418. * This routine is used to free an object in the heap. Freeing is accomplished by marking *
  419. * the object's memory as free to be reallocated. The object is also removed from the *
  420. * allocated object pointer vector. *
  421. * *
  422. * INPUT: pointer -- Pointer to the object that is to be removed from the heap. *
  423. * *
  424. * OUTPUT: none *
  425. * *
  426. * WARNINGS: none *
  427. * *
  428. * HISTORY: *
  429. * 02/21/1995 JLB : Created. *
  430. *=============================================================================================*/
  431. int FixedIHeapClass::Free(void * pointer)
  432. {
  433. if (FixedHeapClass::Free(pointer)) {
  434. ActivePointers.Delete(pointer);
  435. }
  436. return(false);
  437. }
  438. /***********************************************************************************************
  439. * FixedIHeapClass::Logical_ID -- Fetches the logical ID number. *
  440. * *
  441. * Ths logical ID number of a memory block is the index number of the block as if the *
  442. * heap consisted only of valid allocated blocks. This knowledge comes in handy when *
  443. * the real index number must be anticipated before a memory block packing process. *
  444. * *
  445. * INPUT: pointer -- Pointer to an allocated block in the heap. *
  446. * *
  447. * OUTPUT: Returns with the logical index number of this block. The number returned must not *
  448. * be used as a regular index into the heap until such time as the heap has been *
  449. * compacted (by some means or another) without modifying the block order. *
  450. * *
  451. * WARNINGS: Runs in linear time. *
  452. * *
  453. * HISTORY: *
  454. * 05/06/1996 JLB : Created. *
  455. *=============================================================================================*/
  456. int FixedIHeapClass::Logical_ID(void const * pointer) const
  457. {
  458. if (pointer != NULL) {
  459. for (int index = 0; index < Count(); index++) {
  460. if (Active_Ptr(index) == pointer) {
  461. return(index);
  462. }
  463. }
  464. }
  465. return(-1);
  466. }
  467. /***********************************************************************************************
  468. * TFixedIHeapClass::Save -- Saves all active objects *
  469. * *
  470. * INPUT: file file to write to *
  471. * *
  472. * OUTPUT: true = OK, false = error *
  473. * *
  474. * WARNINGS: none *
  475. * *
  476. * HISTORY: *
  477. * 03/15/1995 BRR : Created. *
  478. * 03/12/1996 JLB : Uses in-place new operator for virtual table control. *
  479. *=============================================================================================*/
  480. template<class T>
  481. int TFixedIHeapClass<T>::Save(Pipe & file) const
  482. {
  483. /*
  484. ** Save the number of instances of this class
  485. */
  486. file.Put(&ActiveCount, sizeof(ActiveCount));
  487. /*
  488. ** Save each instance of this class
  489. */
  490. for (int i = 0; i < ActiveCount; i++) {
  491. /*
  492. ** Save the array index of the object, so it can be loaded back into the
  493. ** same array location (so TARGET translations will work)
  494. */
  495. int idx = ID(Ptr(i));
  496. file.Put(&idx, sizeof(idx));
  497. /*
  498. ** Save the object itself
  499. */
  500. file.Put(Ptr(i), sizeof(T));
  501. }
  502. return(true);
  503. }
  504. /***********************************************************************************************
  505. * TFixedIHeapClass::Load -- Loads all active objects *
  506. * *
  507. * INPUT: file file to read from *
  508. * *
  509. * OUTPUT: true = OK, false = error *
  510. * *
  511. * WARNINGS: none *
  512. * *
  513. * HISTORY: *
  514. * 03/15/1995 BRR : Created. *
  515. *=============================================================================================*/
  516. template<class T>
  517. int TFixedIHeapClass<T>::Load(Straw & file)
  518. {
  519. int i; // loop counter
  520. int idx; // object index
  521. T * ptr; // object pointer
  522. int a_count;
  523. /*
  524. ** Read the number of instances of this class
  525. */
  526. if (file.Get(&a_count, sizeof(a_count)) != sizeof(a_count)) {
  527. return(false);
  528. }
  529. /*
  530. ** Error if more objects than we can hold
  531. */
  532. if (a_count > TotalCount) {
  533. return(false);
  534. }
  535. /*
  536. ** Read each class instance
  537. */
  538. for (i = 0; i < a_count; i++) {
  539. /*
  540. ** Read the object's array index
  541. */
  542. if (file.Get(&idx, sizeof(idx)) != sizeof(idx)) {
  543. return(false);
  544. }
  545. /*
  546. ** Get a pointer to the object, activate that object
  547. */
  548. ptr = (T *)(*this)[idx];
  549. FreeFlag[idx] = true;
  550. ActiveCount++;
  551. ActivePointers.Add(ptr);
  552. /*
  553. ** Load the object
  554. */
  555. file.Get(ptr, sizeof(T));
  556. new(ptr) T(NoInitClass());
  557. // if (!ptr->Load(file)) {
  558. // return(false);
  559. // }
  560. }
  561. return(true);
  562. }
  563. /***********************************************************************************************
  564. * TFixedIHeapClass::Code_Pointers -- codes pointers for every object, to prepare for save *
  565. * *
  566. * INPUT: file file to read from *
  567. * *
  568. * OUTPUT: true = OK, false = error *
  569. * *
  570. * WARNINGS: none *
  571. * *
  572. * HISTORY: *
  573. * 03/15/1995 BRR : Created. *
  574. *=============================================================================================*/
  575. template<class T>
  576. void TFixedIHeapClass<T>::Code_Pointers(void)
  577. {
  578. int i;
  579. for (i = 0; i < ActiveCount; i++) {
  580. Ptr(i)->Code_Pointers();
  581. }
  582. }
  583. /***********************************************************************************************
  584. * TFixedIHeapClass::Decode_Pointers -- Decodes all object pointers, for after loading *
  585. * *
  586. * INPUT: file file to read from *
  587. * *
  588. * OUTPUT: true = OK, false = error *
  589. * *
  590. * WARNINGS: none *
  591. * *
  592. * HISTORY: *
  593. * 03/15/1995 BRR : Created. *
  594. *=============================================================================================*/
  595. template<class T>
  596. void TFixedIHeapClass<T>::Decode_Pointers(void)
  597. {
  598. int i;
  599. for (i = 0; i < ActiveCount; i++) {
  600. Ptr(i)->Decode_Pointers();
  601. }
  602. }