reflist.h 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  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. *** Confidential - Westwood Studios ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : Commando / G *
  23. * *
  24. * $Archive:: /Commando/Code/Combat/reflist.h $*
  25. * *
  26. * $Author:: Patrick $*
  27. * *
  28. * $Modtime:: 2/06/01 2:33p $*
  29. * *
  30. * $Revision:: 13 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. #ifndef REFLIST_H
  36. #define REFLIST_H
  37. #ifndef ALWAYS_H
  38. #include "always.h"
  39. #endif
  40. #ifndef WWDEBUG_H
  41. #include "wwdebug.h"
  42. #endif
  43. #ifndef CHUNKIO_H
  44. #include "chunkio.h"
  45. #endif
  46. #ifndef SAVELOAD_H
  47. #include "saveload.h"
  48. #endif
  49. #ifndef PERSIST_H
  50. #include "persist.h"
  51. #endif
  52. /*
  53. ** Forward declarations
  54. */
  55. class ScriptableGameObj;
  56. class ReferencerClass;
  57. /*
  58. ** Advance notice of referencer
  59. */
  60. //template <class T> class ReferencerClass;
  61. /*
  62. ** A object class that can be referenced
  63. */
  64. template <class T>
  65. class ReferenceableClass {
  66. public:
  67. friend class ReferencerClass;
  68. ReferenceableClass( T *reference_data ) : ReferenceData( reference_data ), ReferencerListHead( NULL ) {}
  69. ~ReferenceableClass( void );
  70. bool Save( ChunkSaveClass & csave );
  71. bool Load( ChunkLoadClass & cload );
  72. protected:
  73. ReferencerClass *ReferencerListHead;
  74. T * Get_Data( void ) const { return ReferenceData; }
  75. private:
  76. T *ReferenceData;
  77. };
  78. /*
  79. ** An object class that can reference an ReferencableClass
  80. */
  81. class ReferencerClass : public PostLoadableClass {
  82. public:
  83. friend class ReferenceableClass<ScriptableGameObj>;
  84. ReferencerClass( void ) : ReferenceTarget( NULL ), TargetReferencerListNext( NULL ) {}
  85. ReferencerClass( const ScriptableGameObj * target ) : ReferenceTarget( NULL ), TargetReferencerListNext( NULL ) { *this = target; }
  86. virtual ~ReferencerClass( void ) { operator = ((const ScriptableGameObj*)NULL); }
  87. virtual void On_Post_Load(void);
  88. bool Save( ChunkSaveClass & csave );
  89. bool Load( ChunkLoadClass & cload );
  90. const ReferencerClass & operator = ( const ReferencerClass & src ) { operator = (src.Get_Ptr()); return *this; }
  91. const ReferencerClass & operator = ( const ScriptableGameObj * reference_target );
  92. void Set_Ptr (const ScriptableGameObj * reference_target) { *this = reference_target; }
  93. ScriptableGameObj * Get_Ptr (void) const { return ReferenceTarget ? ReferenceTarget->Get_Data() : NULL; }
  94. operator ScriptableGameObj * (void) const { return Get_Ptr(); }
  95. protected:
  96. ReferenceableClass<ScriptableGameObj> *ReferenceTarget;
  97. ReferencerClass *TargetReferencerListNext;
  98. };
  99. /*
  100. ** Clears all references in objects referencing me
  101. */
  102. template<class T>
  103. ReferenceableClass<T>::~ReferenceableClass( void )
  104. {
  105. while ( ReferencerListHead != NULL ) { // clear each reference to me
  106. ReferencerClass *referencer = ReferencerListHead;
  107. WWASSERT( referencer->ReferenceTarget == this );
  108. ReferencerListHead = referencer->TargetReferencerListNext;
  109. referencer->ReferenceTarget = NULL;
  110. referencer->TargetReferencerListNext = NULL;
  111. }
  112. }
  113. /*
  114. ** Save & Load
  115. */
  116. enum {
  117. CHUNKID_REF_VARIABLES = 913991844,
  118. XXXX_MICROCHUNKID_LIST_HEAD = 1,
  119. MICROCHUNKID_XXXXXXXXX,
  120. MICROCHUNKID_PTR,
  121. MICROCHUNKID_TARGET,
  122. XXXX_MICROCHUNKID_NEXT,
  123. };
  124. template<class T>
  125. bool ReferenceableClass<T>::Save( ChunkSaveClass & csave )
  126. {
  127. csave.Begin_Chunk( CHUNKID_REF_VARIABLES );
  128. void * ptr = this;
  129. WRITE_MICRO_CHUNK( csave, MICROCHUNKID_PTR, ptr );
  130. csave.End_Chunk();
  131. return true;
  132. }
  133. template<class T>
  134. bool ReferenceableClass<T>::Load( ChunkLoadClass & cload )
  135. {
  136. void * old_ptr;
  137. cload.Open_Chunk();
  138. WWASSERT( cload.Cur_Chunk_ID() == CHUNKID_REF_VARIABLES );
  139. WWASSERT( ReferencerListHead == NULL );
  140. while (cload.Open_Micro_Chunk()) {
  141. switch(cload.Cur_Micro_Chunk_ID()) {
  142. case MICROCHUNKID_PTR:
  143. cload.Read(&old_ptr,sizeof(void*));
  144. SaveLoadSystemClass::Register_Pointer(old_ptr, this);
  145. break;
  146. default:
  147. // Debug_Say(( "Unrecognized REFLIST Variable chunkID\n" ));
  148. break;
  149. }
  150. cload.Close_Micro_Chunk();
  151. }
  152. cload.Close_Chunk();
  153. return true;
  154. }
  155. /*
  156. ** A refcounted version of the ReferencerClass
  157. */
  158. class RefCountedReferencerClass : public ReferencerClass, public RefCountClass {
  159. public:
  160. friend class ReferenceableClass<ScriptableGameObj>;
  161. RefCountedReferencerClass( void ) :
  162. ReferencerClass ()
  163. {
  164. }
  165. RefCountedReferencerClass( const ReferencerClass &src ) :
  166. ReferencerClass ()
  167. {
  168. ReferencerClass::operator=( src );
  169. }
  170. };
  171. #endif