Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
definitionmgr.cpp
Go to the documentation of this file.
1/*
2** Command & Conquer Generals Zero Hour(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/***********************************************************************************************
20 *** 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 ***
21 ***********************************************************************************************
22 * *
23 * Project Name : WWSaveLoad *
24 * *
25 * $Archive:: /Commando/Code/wwsaveload/definitionmgr.cpp $*
26 * *
27 * Author:: Patrick Smith *
28 * *
29 * $Modtime:: 12/10/01 2:37p $*
30 * *
31 * $Revision:: 35 $*
32 * *
33 *---------------------------------------------------------------------------------------------*
34 * Functions: *
35 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
36
37#include "definitionmgr.h"
38#include "definition.h"
39#include "definitionfactory.h"
41#include "definitionclassids.h"
42#include "chunkio.h"
43#include "persistfactory.h"
44#include "wwdebug.h"
45#include "wwmemlog.h"
46#include "twiddler.h"
47#include <string.h>
48#include "wwprofile.h"
49
50
52// Global instance
55
57// Constants
59static const int DEFINTION_LIST_GROW_SIZE = 1000;
60static const uint32 IDRANGE_PER_CLASS = 10000;
61
62enum
63{
64 CHUNKID_VARIABLES = 0x00000100,
67};
68
69enum
70{
72};
73
75// Static member initialization
77DefinitionClass ** DefinitionMgrClass::_SortedDefinitionArray = NULL;
78int DefinitionMgrClass::_DefinitionCount = 0;
79int DefinitionMgrClass::_MaxDefinitionCount = 0;
81
83//
84// DefinitionMgrClass
85//
91
92
94//
95// ~DefinitionMgrClass
96//
103
105//
106// Find_Definition
107//
111{
112 DefinitionClass *definition = NULL;
113
114 int lower_index = 0;
115 int upper_index = _DefinitionCount - 1;
116 int index = upper_index / 2;
117 bool keep_going = (_DefinitionCount > 0);
118
119 //
120 // Binary search the list until we've found the definition
121 //
122 while (keep_going) {
123
124 DefinitionClass *curr_def = _SortedDefinitionArray[index];
125 WWASSERT (curr_def != NULL);
126
127 //
128 // Is this the definition we are looking for?
129 //
130 if (curr_def->Get_ID () == id) {
131 definition = _SortedDefinitionArray[index];
132 keep_going = false;
133 } else if (upper_index <= lower_index + 1) {
134
135 //
136 // When the window get's too small, our divide by two won't catch
137 // both entries, so just go ahead and do them both now.
138 //
139 keep_going = false;
140 if (_SortedDefinitionArray[lower_index]->Get_ID () == id) {
141 definition = _SortedDefinitionArray[lower_index];
142 } else if (_SortedDefinitionArray[upper_index]->Get_ID () == id) {
143 definition = _SortedDefinitionArray[upper_index];
144 }
145
146 } else {
147
148 //
149 // Cut our 'window' in half
150 //
151 if (id > curr_def->Get_ID ()) {
152 lower_index = index;
153 index += (upper_index - index) / 2;
154 } else {
155 upper_index = index;
156 index -= (index - lower_index) / 2;
157 }
158 }
159 }
160
161 //
162 // Should we twiddle this definition? (Twiddling refers to our randomizing
163 // framework for definitions)
164 //
165 if ( twiddle &&
166 definition != NULL &&
167 definition->Get_Class_ID () == CLASSID_TWIDDLERS)
168 {
169 definition = ((TwiddlerClass *)definition)->Twiddle ();
170 }
171
172 return definition;
173}
174
175
177//
178// Find_Named_Definition
179//
182DefinitionMgrClass::Find_Named_Definition (const char *name, bool twiddle)
183{
184 DefinitionClass *definition = NULL;
185
186 //
187 // Loop through all the definitions and see if we can
188 // find the one with the requested name
189 //
190 for (int index = 0; index < _DefinitionCount; index ++) {
191 DefinitionClass *curr_def = _SortedDefinitionArray[index];
192
193 //
194 // Is this the definition we were looking for?
195 //
196 if (curr_def != NULL && ::stricmp (curr_def->Get_Name (), name) == 0) {
197 definition = curr_def;
198 break;
199 }
200 }
201
202 //
203 // Should we twiddle this definition? (Twiddling refers to our randomizing
204 // framework for definitions)
205 //
206 if ( twiddle &&
207 definition != NULL &&
208 definition->Get_Class_ID () == CLASSID_TWIDDLERS)
209 {
210 definition = ((TwiddlerClass *)definition)->Twiddle ();
211 }
212
213 return definition;
214}
215
216
218//
219// Find_Typed_Definition
220//
222
224DefinitionMgrClass::Find_Typed_Definition (const char *name, uint32 class_id, bool twiddle)
225{
226 //
227 // Sanity check
228 //
229 if (DefinitionHash == NULL) {
230 WWDEBUG_SAY (("DefinitionMgrClass::Find_Typed_Definition () failed due to a NULL DefinitionHash.\n"));
231 return NULL;
232 }
233
234 DefinitionClass *definition = NULL;
235
236 // Check the hash table first. The hash table is built as we need the definitions, so if definition is not
237 // in the table, it will be added there.
238
239 //
240 // TSS null deref on this sucker 08/03/01
241 //
242 WWASSERT(DefinitionHash != NULL);
243
244 StringClass lower_case_name(name,true);
245 _strlwr(lower_case_name.Peek_Buffer());
246 DynamicVectorClass<DefinitionClass*>* defs = DefinitionHash->Get(lower_case_name);
247
248 if (defs) {
249 for (int i=0;i<defs->Length();++i) {
250 DefinitionClass* curr_def=(*defs)[i];
251 WWASSERT(curr_def);
252 uint32 curr_class_id = curr_def->Get_Class_ID ();
253 if ( (curr_class_id == class_id) ||
254 (::SuperClassID_From_ClassID (curr_class_id) == class_id) ||
255 (twiddle && (curr_def->Get_Class_ID () == CLASSID_TWIDDLERS)))
256 {
257 definition = curr_def;
258 break;
259 }
260 }
261 }
262
263 //
264 // Loop through all the definitions and see if we can
265 // find the one with the requested name
266 //
267 if (!definition) {
268 for (int index = 0; index < _DefinitionCount; index ++) {
269 DefinitionClass *curr_def = _SortedDefinitionArray[index];
270 if (curr_def != NULL) {
271
272 //
273 // Is this the correct class of definition?
274 //
275 uint32 curr_class_id = curr_def->Get_Class_ID ();
276 if ( (curr_class_id == class_id) ||
277 (::SuperClassID_From_ClassID (curr_class_id) == class_id) ||
278 (twiddle && (curr_def->Get_Class_ID () == CLASSID_TWIDDLERS)))
279 {
280 //
281 // Is this the definition we were looking for?
282 //
283 if (::stricmp (curr_def->Get_Name (), name) == 0) {
284 definition = curr_def;
285 // Add the definition to the hash table, so that it can be quickly accessed the next time it is needed.
286 if (!defs) {
288 DefinitionHash->Insert(lower_case_name,defs);
289 }
290 defs->Add(definition);
291 break;
292 }
293 }
294 }
295 }
296 }
297
298 //
299 // Should we twiddle this definition? (Twiddling refers to our randomizing
300 // framework for definitions)
301 //
302 if ( twiddle &&
303 definition != NULL &&
304 definition->Get_Class_ID () == CLASSID_TWIDDLERS)
305 {
306 definition = ((TwiddlerClass *)definition)->Twiddle ();
307 }
308
309 return definition;
310}
311
312
314//
315// List_Available_Definitions
316//
318void
320{
321 //
322 // Loop through all the definitions and print the definition name
323 //
324 WWDEBUG_SAY(("Available definitions:\n"));
325 for (int index = 0; index < _DefinitionCount; index ++) {
326 DefinitionClass *curr_def = _SortedDefinitionArray[index];
327 if (curr_def != NULL) {
328 WWDEBUG_SAY((" >%s<\n", curr_def->Get_Name ()));
329 }
330 }
331
332 return ;
333}
334
335
337//
338// List_Available_Definitions
339//
341void
343{
344 //
345 // Loop through all the definitions and print the definition name
346 //
347 WWDEBUG_SAY(("Available superclass definitions for 0x%8X:\n", superclass_id));
348 DefinitionClass *definition = NULL;
349 for ( definition = Get_First (superclass_id, DefinitionMgrClass::ID_SUPERCLASS);
350 definition != NULL;
351 definition = Get_Next (definition, superclass_id, DefinitionMgrClass::ID_SUPERCLASS))
352 {
353 WWDEBUG_SAY((" >%s<\n", definition->Get_Name ()));
354 }
355
356 return ;
357}
358
359
361//
362// Get_First
363//
367{
368 DefinitionClass *definition = NULL;
369
370 //
371 // Loop through all the definitions and find the first
372 // one that belongs to the requested class
373 //
374 for ( int index = 0;
375 (definition == NULL) && (index < _DefinitionCount);
376 index ++)
377 {
378 DefinitionClass *curr_def = _SortedDefinitionArray[index];
379 if (curr_def != NULL) {
380
381 //
382 // Is this the definition we were looking for?
383 //
384 if ( (type == ID_SUPERCLASS) &&
385 (::SuperClassID_From_ClassID (curr_def->Get_Class_ID ()) == id)) {
386 definition = curr_def;
387 } else if ( (type == ID_CLASS) &&
388 (curr_def->Get_Class_ID () == id)) {
389 definition = curr_def;
390 }
391 }
392 }
393
394 return definition;
395}
396
397
399//
400// Get_Next
401//
405(
406 DefinitionClass * curr_def,
407 uint32 id,
408 ID_TYPE type
409)
410{
411 DefinitionClass *definition = NULL;
412
413 //
414 // Loop through all the definitions and find the first
415 // one that belongs to the requested class
416 //
417 for ( int index = curr_def->m_DefinitionMgrLink + 1;
418 (definition == NULL) && (index < _DefinitionCount);
419 index ++)
420 {
421 DefinitionClass *curr_def = _SortedDefinitionArray[index];
422 if (curr_def != NULL) {
423
424 //
425 // Is this the definition we were looking for?
426 //
427 if ( (type == ID_SUPERCLASS) &&
428 (::SuperClassID_From_ClassID (curr_def->Get_Class_ID ()) == id)) {
429 definition = curr_def;
430 } else if ( (type == ID_CLASS) &&
431 (curr_def->Get_Class_ID () == id)) {
432 definition = curr_def;
433 }
434 }
435 }
436
437 return definition;
438}
439
440
442//
443// Get_Next
444//
448{
449 WWASSERT (curr_def != NULL);
450 DefinitionClass *definition = NULL;
451
452 int index = curr_def->m_DefinitionMgrLink + 1;
453 if (index < _DefinitionCount) {
454 definition = _SortedDefinitionArray[index];
455 }
456
457 return definition;
458}
459
460
462//
463// Free_Definitions
464//
466void
468{
469 // Clear the hash table
470 if (DefinitionHash) {
472 for (ite.First();!ite.Is_Done();ite.Next()) {
474// delete ite.Peek_Value();
475 delete defs;
476 }
477 DefinitionHash->Remove_All();
478 delete DefinitionHash;
479 DefinitionHash=NULL;
480 }
481
482 //
483 // Free each of the definition objects
484 //
485 for (int index = 0; index < _DefinitionCount; index ++) {
486 DefinitionClass *definition = _SortedDefinitionArray[index];
487 if (definition != NULL) {
488 delete definition;
489 }
490 }
491
492 //
493 // Free the definition array
494 //
495 if (_SortedDefinitionArray != NULL) {
496 delete [] _SortedDefinitionArray;
497 }
498
499 _SortedDefinitionArray = NULL;
500 _MaxDefinitionCount = 0;
501 _DefinitionCount = 0;
502 return ;
503}
504
505
507//
508// Prepare_Definition_Array
509//
511void
512DefinitionMgrClass::Prepare_Definition_Array (void)
513{
514 if (_DefinitionCount + 1 > _MaxDefinitionCount) {
515
516 //
517 // Allocate a new, bigger array
518 //
519 int new_size = _MaxDefinitionCount + DEFINTION_LIST_GROW_SIZE;
520 DefinitionClass **new_array = W3DNEWARRAY DefinitionClass *[new_size];
521
522 //
523 // Copy the entries from the old array to the new array
524 //
525 ::memcpy (new_array, _SortedDefinitionArray, _DefinitionCount * sizeof (DefinitionClass *));
526
527 //
528 // Free the old array and start using the new array
529 //
530 if (_SortedDefinitionArray != NULL) {
531 delete [] _SortedDefinitionArray;
532 }
533 _SortedDefinitionArray = new_array;
534 _MaxDefinitionCount = new_size;
535 }
536 if (!DefinitionHash) DefinitionHash=W3DNEW HashTemplateClass<StringClass, DynamicVectorClass<DefinitionClass*>*>;
537
538 return ;
539}
540
541
543//
544// Register_Definition
545//
547void
549{
550 WWASSERT (definition != NULL);
551 if (definition != NULL && definition->m_DefinitionMgrLink == -1 && definition->Get_ID () != 0) {
552 //
553 // Make sure the definition array is large enough
554 //
555 Prepare_Definition_Array ();
556
557 //
558 // Calculate where in the list we should insert this definition
559 //
560 uint32 id = definition->Get_ID ();
561 int lower_index = 0;
562 int upper_index = _DefinitionCount - 1;
563 int index = upper_index / 2;
564 int insert_index = _DefinitionCount;
565 bool keep_going = (_DefinitionCount > 0);
566 bool is_valid = true;
567
568 while (keep_going) {
569
570 DefinitionClass *curr_def = _SortedDefinitionArray[index];
571 WWASSERT (curr_def != NULL);
572
573 //
574 // Check to make sure we aren't trying to register a definition
575 // that has the same ID as a definition that is already in the list.
576 //
577 if (curr_def->Get_ID () == id) {
578 insert_index = index;
579 keep_going = false;
580 is_valid = false;
581 } else {
582
583 //
584 // Cut our 'window' in half
585 //
586 if (id > curr_def->Get_ID ()) {
587 lower_index = index;
588 index += (upper_index - index) / 2;
589 } else {
590 upper_index = index;
591 index -= (index - lower_index) / 2;
592 }
593
594 //
595 // If we've narrowed down the window to 2 entries, then quick check
596 // the different possibilities.
597 //
598 if (upper_index <= lower_index + 1) {
599 if (_SortedDefinitionArray[upper_index]->Get_ID () <= id) {
600 insert_index = upper_index + 1;
601 } else if (_SortedDefinitionArray[lower_index]->Get_ID () <= id) {
602 insert_index = upper_index;
603 } else {
604 insert_index = lower_index;
605 }
606 keep_going = false;
607 }
608 }
609 }
610
611 //WWASSERT (is_valid);
612 if (is_valid) {
613
614 //
615 // Re-index all the definitions that got bumped one cell due to this insertion.
616 //
617 for (index = _DefinitionCount - 1; index >= insert_index; index --) {
618 _SortedDefinitionArray[index + 1] = _SortedDefinitionArray[index];
619 _SortedDefinitionArray[index + 1]->m_DefinitionMgrLink = index + 1;
620 }
621
622 //
623 // Insert this definition into the list
624 //
625 definition->m_DefinitionMgrLink = insert_index;
626 _SortedDefinitionArray[insert_index] = definition;
627 _DefinitionCount ++;
628 }
629 }
630
631 return ;
632}
633
634
636//
637// Unregister_Definition
638//
640void
642{
643 WWASSERT (definition != 0);
644 //WWASSERT (definition->m_DefinitionMgrLink >= 0 && definition->m_DefinitionMgrLink < _DefinitionCount);
645
646 if (definition != NULL && definition->m_DefinitionMgrLink != -1) {
647
648 //
649 // Re-index the definitions that come after this definition in the list
650 //
651 for (int index = definition->m_DefinitionMgrLink; index < _DefinitionCount - 1; index ++) {
652 _SortedDefinitionArray[index] = _SortedDefinitionArray[index + 1];
653 _SortedDefinitionArray[index]->m_DefinitionMgrLink = index;
654 }
655
656 _SortedDefinitionArray[_DefinitionCount - 1] = NULL;
657 definition->m_DefinitionMgrLink = -1;
658 _DefinitionCount --;
659 }
660
661 return ;
662}
663
664
666//
667// Save
668//
670bool
672(
673 ChunkSaveClass & csave
674)
675{
677
678 bool retval = true;
679
680 //
681 // Create a chunk to contain the class variables we need to serialize.
682 //
684 Save_Variables (csave);
685 csave.End_Chunk ();
686
687 //
688 // Have the base class write the objects to their own chunk.
689 //
691 retval &= Save_Objects (csave);
692 csave.End_Chunk ();
693
694 return retval;
695}
696
697
699//
700// Load
701//
703bool
705{
707 bool retval = true;
708
709 while (cload.Open_Chunk ()) {
710 switch (cload.Cur_Chunk_ID ()) {
711
712 //
713 // If this is the chunk that contains the class variables, then
714 // loop through and read each microchunk
715 //
717 retval &= Load_Variables (cload);
718 break;
719
720 //
721 // Load all the definition objects from this chunk
722 //
723 case CHUNKID_OBJECTS:
724 retval &= Load_Objects (cload);
725 break;
726 }
727
728 cload.Close_Chunk ();
729 }
730
731 return retval;
732}
733
734
736//
737// Save_Objects
738//
740bool
742(
743 ChunkSaveClass & csave
744)
745{
746 bool retval = true;
747
748 //
749 // Loop through all the definition objects
750 //
751 for (int index = 0; index < _DefinitionCount; index ++) {
752 DefinitionClass *definition = _SortedDefinitionArray[index];
753 if (definition != NULL && definition->Is_Save_Enabled ()) {
754
755 //
756 // Save this definition object
757 //
758 csave.Begin_Chunk (definition->Get_Factory ().Chunk_ID ());
759 definition->Get_Factory ().Save (csave, definition);
760 csave.End_Chunk ();
761 }
762 }
763
764 return retval;
765}
766
767
769//
770// Save_Variables
771//
773bool
775{
776 bool retval = true;
777 return retval;
778}
779
783
784
786//
787// Load_Objects
788//
790bool
792{
793 bool retval = true;
794
795 while (cload.Open_Chunk ()) {
796
797 //
798 // Load this definition from the chunk (if possible)
799 //
801 if (factory != NULL) {
802
803 DefinitionClass *definition = (DefinitionClass *)factory->Load (cload);
804 if (definition != NULL) {
805
806 //
807 // Add this definition to our array
808 //
809 Prepare_Definition_Array ();
810 _SortedDefinitionArray[_DefinitionCount ++] = definition;
811 }
812 }
813
814 cload.Close_Chunk ();
815 }
816
817 //
818 // Sort the definitions
819 //
820 if (_DefinitionCount > 0) {
821 ::qsort (_SortedDefinitionArray, _DefinitionCount, sizeof (DefinitionClass *), fnCompareDefinitionsCallback);
822 }
823
824 //
825 // Assign a mgr link to each definition
826 //
827 for (int index = 0; index < _DefinitionCount; index ++) {
828 _SortedDefinitionArray[index]->m_DefinitionMgrLink = index;
829 }
830
831 return retval;
832}
833
834
836//
837// Load_Variables
838//
840bool
842{
843 bool retval = true;
844
845 //
846 // Loop through all the microchunks that define the variables
847 //
848 while (cload.Open_Micro_Chunk ()) {
849 switch (cload.Cur_Micro_Chunk_ID ()) {
850
851 case VARID_NEXTDEFID:
852 break;
853 }
854
855 cload.Close_Micro_Chunk ();
856 }
857
858 return retval;
859}
860
861
863//
864// Get_New_ID
865//
867uint32
869{
870 uint32 idrange_start = (class_id - DEF_CLASSID_START) * IDRANGE_PER_CLASS;
871 uint32 idrange_end = (idrange_start + IDRANGE_PER_CLASS);
872
873 uint32 new_id = idrange_start + 1;
874
875 //
876 // Try to find the first empty slot in this ID range
877 //
878 for (int index = 0; index < _DefinitionCount; index ++) {
879 DefinitionClass *definition = _SortedDefinitionArray[index];
880 if (definition != NULL) {
881
882 //
883 // Get this definition's ID
884 //
885 uint32 curr_id = definition->Get_ID ();
886
887 //
888 // Is this id in the range we are looking for?
889 //
890 if (curr_id >= idrange_start && curr_id < idrange_end) {
891
892 bool is_ok = false;
893 if (index < _DefinitionCount - 1) {
894
895 //
896 // Check to see if the next definition in our array leaves a hole in the
897 // ID range.
898 //
899 DefinitionClass *next_definition = _SortedDefinitionArray[index + 1];
900 if (next_definition != NULL && next_definition->Get_ID () > (curr_id + 1)) {
901 is_ok = true;
902 }
903
904 } else {
905 is_ok = true;
906 }
907
908 //
909 // Return the new ID
910 //
911 if (is_ok) {
912 new_id = curr_id + 1;
913 break;
914 }
915 }
916 }
917 }
918
919 return new_id;
920}
921
922
924//
925// fnCompareDefinitionsCallback
926//
928int __cdecl
929DefinitionMgrClass::fnCompareDefinitionsCallback
930(
931 const void *elem1,
932 const void *elem2
933)
934{
935 WWASSERT (elem1 != NULL);
936 WWASSERT (elem2 != NULL);
937 DefinitionClass *definition1 = *((DefinitionClass **)elem1);
938 DefinitionClass *definition2 = *((DefinitionClass **)elem2);
939
940 //
941 // Sort the definitions based on ID
942 //
943 int result = 0;
944 if (definition1->Get_ID () > definition2->Get_ID ()) {
945 result = 1;
946 } else if (definition1->Get_ID () < definition2->Get_ID ()) {
947 result = -1;
948 } else {
949 result = 0;
950 }
951
952 return result;
953}
#define NULL
Definition BaseType.h:92
#define WWASSERT
#define __cdecl
Definition IFF.H:44
#define W3DNEWARRAY
Definition always.h:110
#define W3DNEW
Definition always.h:109
unsigned long uint32
Definition bittype.h:46
@ CHUNKID_VARIABLES
bool Close_Micro_Chunk()
Definition chunkio.cpp:585
bool Close_Chunk()
Definition chunkio.cpp:448
uint32 Cur_Chunk_ID()
Definition chunkio.cpp:484
uint32 Cur_Micro_Chunk_ID()
Definition chunkio.cpp:622
bool Open_Chunk()
Definition chunkio.cpp:412
bool Open_Micro_Chunk()
Definition chunkio.cpp:557
bool Begin_Chunk(uint32 id)
Definition chunkio.cpp:108
bool End_Chunk()
Definition chunkio.cpp:148
virtual uint32 Get_ID(void) const
Definition definition.h:179
virtual const char * Get_Name(void) const
Definition definition.h:160
virtual uint32 Get_Class_ID(void) const =0
bool Is_Save_Enabled(void) const
Definition definition.h:102
virtual bool Save(ChunkSaveClass &csave)
static DefinitionClass * Find_Typed_Definition(const char *name, uint32 class_id, bool twiddle=true)
bool Load_Objects(ChunkLoadClass &cload)
static DefinitionClass * Find_Named_Definition(const char *name, bool twiddle=true)
static DefinitionClass * Get_Next(DefinitionClass *curr_def)
bool Save_Variables(ChunkSaveClass &csave)
static void Unregister_Definition(DefinitionClass *definition)
static uint32 Get_New_ID(uint32 class_id)
bool Save_Objects(ChunkSaveClass &csave)
static DefinitionClass * Get_First(void)
bool Load_Variables(ChunkLoadClass &cload)
static void Register_Definition(DefinitionClass *definition)
static DefinitionClass * Find_Definition(uint32 id, bool twiddle=true)
friend class DefinitionClass
static void List_Available_Definitions(void)
virtual bool Load(ChunkLoadClass &cload)
static void Free_Definitions(void)
bool Insert(int index, T const &object)
Definition Vector.H:766
bool Add(T const &object)
Definition Vector.H:671
ValueType & Peek_Value()
virtual const PersistFactoryClass & Get_Factory(void) const =0
virtual uint32 Chunk_ID(void) const =0
virtual PersistClass * Load(ChunkLoadClass &cload) const =0
virtual void Save(ChunkSaveClass &csave, PersistClass *obj) const =0
static PersistFactoryClass * Find_Persist_Factory(uint32 chunk_id)
Definition saveload.cpp:173
TCHAR * Peek_Buffer(void)
Definition wwstring.h:560
WWINLINE int Length(void) const
Definition Vector.H:105
@ CLASSID_TWIDDLERS
const int DEF_CLASSID_START
uint32 SuperClassID_From_ClassID(uint32 class_id)
float _reg_time
@ VARID_NEXTDEFID
@ CHUNKID_OBJECT
@ CHUNKID_OBJECTS
float _load_time
DefinitionMgrClass _TheDefinitionMgr
float _alloc_time
else return(RetVal)
#define WWDEBUG_SAY(x)
Definition wwdebug.h:114
@ MEM_GAMEDATA
Definition wwmemlog.h:67
#define WWMEMLOG(category)
Definition wwmemlog.h:183