00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <Windows.h>
00023 #include <Assert.h>
00024
00025 #include "Entities.h"
00026 #include "BaseType.h"
00027 #include "Errorlog.h"
00028 #include "Vec3d.h"
00029 #include "Ram.h"
00030
00031
00032 #include "World.h"
00033 #include "GBSPFile.h"
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 static geWorld *GWorld;
00044
00045
00046
00047 static geBoolean InsertEntityInClassList(geWorld *World, geEntity *Entity)
00048 {
00049 const char *EntClassName;
00050 geWorld_EntClassSet *WSet;
00051 int32 i;
00052
00053 if (!Entity->Class)
00054 return GE_TRUE;
00055
00056 assert(Entity->Class->Name);
00057
00058 EntClassName = Entity->Class->Name;
00059
00060 WSet = World->EntClassSets;
00061
00062 for (i=0; i< World->NumEntClassSets; i++)
00063 {
00064 if (!WSet[i].ClassName)
00065 continue;
00066
00067 if (!stricmp(WSet[i].ClassName, EntClassName))
00068 {
00069
00070 if (!geEntity_EntitySetAddEntity(WSet[i].Set, Entity))
00071 return GE_FALSE;
00072
00073 return GE_TRUE;
00074 }
00075 }
00076
00077 if (i >= MAX_WORLD_ENT_CLASS_SETS)
00078 return GE_FALSE;
00079
00080
00081 WSet[i].Set = geEntity_EntitySetCreate();
00082
00083
00084 WSet[i].ClassName = EntClassName;
00085 geEntity_EntitySetAddEntity(WSet[i].Set, Entity);
00086
00087 World->NumEntClassSets++;
00088
00089 return GE_TRUE;
00090 }
00091
00092
00093
00094
00095
00096 geBoolean Ent_WorldInit(geWorld *World)
00097 {
00098 GBSP_BSPData *BSP;
00099 geEntity_EntitySet *EntitySet;
00100 geEntity *Entity;
00101
00102 assert(World != NULL);
00103
00104 GWorld = World;
00105
00106 World->NumEntClassSets = 0;
00107
00108 if ( ! World->CurrentBSP )
00109 return GE_TRUE;
00110
00111 BSP = &(World->CurrentBSP->BSPData);
00112
00113 if (BSP->NumGFXEntData == 0)
00114 return GE_TRUE;
00115
00116 EntitySet = LoadEntitySet(BSP->GFXEntData, BSP->NumGFXEntData);
00117
00118 if (!EntitySet)
00119 return GE_FALSE;
00120
00121
00122 World->EntClassSets[0].ClassName = NULL;
00123 World->EntClassSets[0].Set = EntitySet;
00124 World->NumEntClassSets++;
00125
00126
00127 Entity = NULL;
00128 while (1)
00129 {
00130 Entity = geEntity_EntitySetGetNextEntity(EntitySet, Entity);
00131
00132 if (!Entity)
00133 break;
00134
00135 InsertEntityInClassList(World, Entity);
00136 }
00137
00138 return GE_TRUE;
00139 }
00140
00141
00142
00143
00144
00145 void Ent_WorldShutdown(geWorld *World)
00146 {
00147 int32 i;
00148
00149 assert(World);
00150
00151 for (i=0; i< World->NumEntClassSets; i++)
00152 geEntity_EntitySetDestroy(World->EntClassSets[i].Set);
00153 }
00154
00155
00156
00157
00158 static char *CopyString(const char *String)
00159 {
00160 char *NewString;
00161
00162 NewString = geRam_Allocate(strlen(String)+1);
00163
00164 if (!NewString)
00165 return NULL;
00166
00167 strcpy(NewString, String);
00168
00169 return NewString;
00170 }
00171
00172
00173
00174
00175 geEntity *geEntity_Create(void)
00176 {
00177 geEntity *Entity;
00178
00179 Entity = geRam_Allocate(sizeof(geEntity));
00180
00181 if (!Entity)
00182 return NULL;
00183
00184 memset(Entity, 0, sizeof(geEntity));
00185
00186 return Entity;
00187 }
00188
00189
00190
00191
00192
00193 void geEntity_Destroy(geEntity *Entity)
00194 {
00195 geEntity_Epair *Epair, *Next;
00196
00197 assert(Entity);
00198
00199 for (Epair = Entity->Epairs; Epair; Epair = Next)
00200 {
00201 Next = Epair->Next;
00202
00203 geEntity_EpairDestroy(Epair);
00204 }
00205
00206 if (Entity->UserData)
00207 geRam_Free(Entity->UserData);
00208
00209 geRam_Free(Entity);
00210 }
00211
00212
00213
00214
00215 GENESISAPI void *geEntity_GetUserData(geEntity *Entity)
00216 {
00217 assert(Entity);
00218
00219 return Entity->UserData;
00220 }
00221
00222
00223
00224
00225 geBoolean geEntity_GetModelNumForKey(geEntity *Entity, const char *Key, int32 *ModelNum)
00226 {
00227 geEntity_Epair *Epair;
00228 int32 Value;
00229
00230 for (Epair = Entity->Epairs; Epair; Epair = Epair->Next)
00231 {
00232 if (!stricmp(Epair->Key, Key))
00233 {
00234 if (Epair->Value[0] == '*')
00235 sscanf(Epair->Value+1, "%d", &Value);
00236 else
00237 sscanf(Epair->Value, "%d", &Value);
00238
00239 *ModelNum = (int32)Value;
00240 return GE_TRUE;
00241 }
00242 }
00243 return GE_FALSE;
00244
00245 }
00246
00247
00248
00249
00250 geBoolean geEntity_AddEpair(geEntity *Entity, geEntity_Epair *Epair)
00251 {
00252 geEntity_Epair *Ep;
00253
00254 assert(Entity);
00255 assert(Epair);
00256
00257 assert(Epair->Next == NULL);
00258
00259 if (!Entity->Epairs)
00260 {
00261 Entity->Epairs = Epair;
00262 return GE_TRUE;
00263 }
00264
00265
00266 for (Ep = Entity->Epairs; Ep->Next; Ep = Ep->Next);
00267
00268 Ep->Next = Epair;
00269
00270 return GE_TRUE;
00271 }
00272
00273
00274
00275
00276 const char *geEntity_GetStringForKey(const geEntity *Entity, const char *Key)
00277 {
00278 geEntity_Epair *Epair;
00279
00280 for (Epair = Entity->Epairs; Epair; Epair = Epair->Next)
00281 {
00282 if (!stricmp(Epair->Key, Key))
00283 {
00284 return Epair->Value;
00285 }
00286 }
00287 return NULL;
00288 }
00289
00290
00291
00292
00293 geEntity_Epair *geEntity_EpairCreate(void)
00294 {
00295 geEntity_Epair *Epair;
00296
00297 Epair = geRam_Allocate(sizeof(geEntity_Epair));
00298
00299 if (!Epair)
00300 return NULL;
00301
00302 memset(Epair, 0, sizeof(geEntity_Epair));
00303
00304 return Epair;
00305 }
00306
00307
00308
00309
00310 void geEntity_EpairDestroy(geEntity_Epair *Epair)
00311 {
00312 assert(Epair);
00313
00314 if (Epair->Key)
00315 geRam_Free(Epair->Key);
00316
00317 if (Epair->Value)
00318 geRam_Free(Epair->Value);
00319
00320 geRam_Free(Epair);
00321 }
00322
00323
00324
00325
00326 geEntity_Field *geEntity_FieldCreate(const char *Name, int32 Offset, geEntity_Class *TypeClass)
00327 {
00328 geEntity_Field *Field;
00329
00330 Field = GE_RAM_ALLOCATE_STRUCT(geEntity_Field);
00331
00332 if (!Field)
00333 return NULL;
00334
00335 memset(Field, 0, sizeof(geEntity_Field));
00336
00337 if (Name)
00338 Field->Name = CopyString(Name);
00339
00340 Field->Offset = Offset;
00341 Field->TypeClass = TypeClass;
00342
00343 return Field;
00344 }
00345
00346
00347
00348
00349 void geEntity_FieldDestroy(geEntity_Field *Field)
00350 {
00351 assert(Field);
00352
00353 if (Field->Name)
00354 geRam_Free(Field->Name);
00355
00356 geRam_Free(Field);
00357 }
00358
00359
00360
00361
00362 geEntity_Class *geEntity_ClassCreate(geEntity_ClassType Type, const char *Name, int32 TypeSize)
00363 {
00364 geEntity_Class *Class;
00365
00366 Class = GE_RAM_ALLOCATE_STRUCT(geEntity_Class);
00367
00368 if (!Class)
00369 return NULL;
00370
00371 memset(Class, 0, sizeof(geEntity_Class));
00372
00373 Class->Type = Type;
00374
00375 if (Name)
00376 Class->Name = CopyString(Name);
00377
00378 Class->TypeSize = TypeSize;
00379
00380 return Class;
00381 }
00382
00383
00384
00385
00386 void geEntity_ClassDestroy(geEntity_Class *Class)
00387 {
00388 geEntity_Field *Field, *NextField;
00389 assert(Class);
00390
00391 for (Field = Class->Fields; Field; Field = NextField )
00392 {
00393 NextField = Field->Next;
00394 geEntity_FieldDestroy(Field);
00395 }
00396 if (Class->Name)
00397 geRam_Free(Class->Name);
00398
00399 geRam_Free(Class);
00400 }
00401
00402
00403
00404
00405 geBoolean geEntity_ClassAddField(geEntity_Class *Class, geEntity_Field *Field)
00406 {
00407 assert(Class);
00408 assert(Field);
00409
00410
00411 Field->Next = Class->Fields;
00412 Class->Fields = Field;
00413
00414
00415 Class->FieldSize += Field->TypeClass->TypeSize;
00416
00417 return GE_TRUE;
00418 }
00419
00420
00421
00422
00423 geEntity_Field *geEntity_ClassFindFieldByName(geEntity_Class *Class, const char *Name)
00424 {
00425 geEntity_Field *Field;
00426
00427 assert(Class);
00428
00429 for (Field = Class->Fields; Field; Field = Field->Next)
00430 {
00431 if (!stricmp(Field->Name, Name))
00432 return Field;
00433
00434 }
00435
00436 return NULL;
00437 }
00438
00439
00440
00441
00442 geEntity_EntitySet *geEntity_EntitySetCreate(void)
00443 {
00444 geEntity_EntitySet *EntitySet;
00445
00446 EntitySet = geRam_Allocate(sizeof(geEntity_EntitySet));
00447
00448 if (!EntitySet)
00449 return NULL;
00450
00451 memset(EntitySet, 0, sizeof(geEntity_EntitySet));
00452
00453 return EntitySet;
00454 }
00455
00456
00457
00458
00459
00460 void geEntity_EntitySetDestroy(geEntity_EntitySet *EntitySet)
00461 {
00462 geEntity_EntitySet *Set, *Next;
00463 geEntity_Class *Class, *NextClass;
00464
00465 assert(EntitySet);
00466
00467 if (EntitySet->OwnsEntities)
00468 {
00469 for (Class = EntitySet->Classes; Class; Class = NextClass)
00470 {
00471 NextClass = Class->Next;
00472
00473 geEntity_ClassDestroy(Class);
00474 }
00475
00476 for (Set = EntitySet; Set; Set = Next)
00477 {
00478 Next = Set->Next;
00479 if (Set->Entity)
00480 geEntity_Destroy(Set->Entity);
00481 }
00482 }
00483
00484
00485 for (Set = EntitySet; Set; Set = Next)
00486 {
00487 Next = Set->Next;
00488
00489 geRam_Free(Set);
00490 }
00491 }
00492
00493
00494
00495
00496 geEntity_Class *geEntity_EntitySetFindClassByName(geEntity_EntitySet *Set, const char *Name)
00497 {
00498 geEntity_Class *Class;
00499
00500 assert(Set);
00501
00502 for (Class = Set->Classes; Class; Class = Class->Next)
00503 {
00504 if (!stricmp(Class->Name, Name))
00505 return Class;
00506 }
00507
00508 return NULL;
00509 }
00510
00511 GENESISAPI void geEntity_GetName(const geEntity *Entity, char *Buff, int MaxLen)
00512 {
00513 const char * EntName;
00514 int Length;
00515
00516 assert(Entity);
00517 assert(Buff);
00518
00519 EntName = geEntity_GetStringForKey(Entity, "%Name%");
00520 assert(EntName);
00521 Length = strlen(EntName) + 1;
00522 memcpy(Buff, EntName, min(Length, MaxLen));
00523 }
00524
00525
00526
00527
00528 geEntity *geEntity_EntitySetFindEntityByName(geEntity_EntitySet *EntitySet, const char *Name)
00529 {
00530 const char *EntName;
00531 geEntity_EntitySet *Set;
00532
00533 assert(EntitySet);
00534 assert(Name);
00535
00536 for (Set = EntitySet; Set; Set = Set->Next)
00537 {
00538 EntName = geEntity_GetStringForKey(Set->Entity, "%Name%");
00539
00540 if (!EntName)
00541 continue;
00542
00543 if (!stricmp(Name, EntName))
00544 return Set->Entity;
00545 }
00546
00547 return NULL;
00548 }
00549
00550
00551
00552
00553 geBoolean geEntity_EntitySetAddEntity(geEntity_EntitySet *EntitySet, geEntity *Entity)
00554 {
00555 geEntity_EntitySet *NewSet, *Set;
00556
00557 assert(EntitySet);
00558 assert(Entity);
00559
00560
00561 if (!EntitySet->Entity)
00562 {
00563 assert(EntitySet->Next == NULL);
00564 assert(EntitySet->Current == NULL);
00565
00566 EntitySet->Entity = Entity;
00567 return GE_TRUE;
00568 }
00569
00570 NewSet = geEntity_EntitySetCreate();
00571
00572 if (!NewSet)
00573 return GE_FALSE;
00574
00575
00576 NewSet->Entity = Entity;
00577
00578
00579 for (Set = EntitySet; Set->Next; Set = Set->Next);
00580
00581
00582 Set->Next = NewSet;
00583 return GE_TRUE;
00584 }
00585
00586
00587
00588
00589 GENESISAPI geEntity *geEntity_EntitySetGetNextEntity(geEntity_EntitySet *EntitySet, geEntity *Entity)
00590 {
00591 geEntity_EntitySet *Set, *NextSet;
00592
00593 assert(EntitySet);
00594
00595 if (!Entity)
00596 {
00597 EntitySet->Current = EntitySet;
00598 return EntitySet->Entity;
00599 }
00600
00601 assert(EntitySet->Current);
00602
00603
00604 if (EntitySet->Current->Entity == Entity)
00605 {
00606 NextSet = EntitySet->Current->Next;
00607
00608 if (!NextSet)
00609 return NULL;
00610
00611 EntitySet->Current = NextSet;
00612 return NextSet->Entity;
00613 }
00614
00615
00616 for (Set = EntitySet; Set; Set = Set->Next)
00617 {
00618 assert(Set->Entity);
00619
00620 if (Set->Entity == Entity)
00621 {
00622 NextSet = Set->Next;
00623
00624 EntitySet->Current = NextSet;
00625 return NextSet->Entity;
00626 }
00627 }
00628
00629 return NULL;
00630 }
00631
00632
00633
00634
00635 geBoolean geEntity_EntitySetAddClass(geEntity_EntitySet *EntitySet, geEntity_Class *Class)
00636 {
00637 assert(EntitySet);
00638 assert(Class);
00639
00640 assert(Class->Next == NULL);
00641
00642
00643 Class->Next = EntitySet->Classes;
00644 EntitySet->Classes = Class;
00645
00646 return GE_TRUE;
00647 }
00648
00649
00650
00651
00652 static geBoolean BuildClassTypes(geEntity_EntitySet *EntitySet)
00653 {
00654 const char *Name;
00655 geEntity_Class *Class;
00656 geEntity_EntitySet *Set;
00657
00658
00659 Class = geEntity_ClassCreate(TYPE_INT, "int", sizeof(int32));
00660 geEntity_EntitySetAddClass(EntitySet, Class);
00661
00662
00663
00664
00665 Class = geEntity_ClassCreate(TYPE_FLOAT, "geFloat", sizeof(geFloat));
00666 geEntity_EntitySetAddClass(EntitySet, Class);
00667
00668 Class = geEntity_ClassCreate(TYPE_COLOR, "color", sizeof(GE_RGBA));
00669 geEntity_EntitySetAddClass(EntitySet, Class);
00670
00671 Class = geEntity_ClassCreate(TYPE_POINT, "point", sizeof(geVec3d));
00672 geEntity_EntitySetAddClass(EntitySet, Class);
00673
00674 Class = geEntity_ClassCreate(TYPE_STRING, "string", sizeof(char *));
00675 geEntity_EntitySetAddClass(EntitySet, Class);
00676
00677 Class = geEntity_ClassCreate(TYPE_PTR, "ptr", sizeof(void *));
00678 geEntity_EntitySetAddClass(EntitySet, Class);
00679
00680 Class = geEntity_ClassCreate(TYPE_MODEL, "model", sizeof(void*));
00681 geEntity_EntitySetAddClass(EntitySet, Class);
00682
00683
00684 for (Set = EntitySet; Set; Set = Set->Next)
00685 {
00686 geEntity *Entity;
00687
00688 Entity = Set->Entity;
00689
00690 Name = geEntity_GetStringForKey(Entity, "classname");
00691
00692 if (!Name)
00693 continue;
00694
00695 if (stricmp(Name, "%typedef%"))
00696 continue;
00697
00698 Name = geEntity_GetStringForKey(Entity, "%typename%");
00699
00700 if (!Name)
00701 return GE_FALSE;
00702
00703 Class = geEntity_ClassCreate(TYPE_STRUCT, Name, sizeof(void*));
00704
00705 if (!Class)
00706 goto ExitWithError;
00707
00708 if (!geEntity_EntitySetAddClass(EntitySet, Class))
00709 goto ExitWithError;
00710 }
00711
00712 for (Set = EntitySet; Set; Set = Set->Next)
00713 {
00714 geEntity *Entity;
00715 geEntity_Epair *Epair;
00716
00717 Entity = Set->Entity;
00718
00719 Name = geEntity_GetStringForKey(Entity, "classname");
00720
00721 if (!Name)
00722 continue;
00723
00724 if (stricmp(Name, "%typedef%"))
00725 continue;
00726
00727 Name = geEntity_GetStringForKey(Entity, "%typename%");
00728
00729 if (!Name)
00730 return GE_FALSE;
00731
00732 Class = geEntity_EntitySetFindClassByName(EntitySet, Name);
00733
00734 if (!Class)
00735 continue;
00736
00737 for (Epair = Entity->Epairs; Epair; Epair = Epair->Next)
00738 {
00739 geEntity_Class *TypeClass;
00740 geEntity_Field *Field;
00741
00742
00743 if (!stricmp(Epair->Key, "classname"))
00744 continue;
00745 if (!stricmp(Epair->Key, "%typename%"))
00746 continue;
00747
00748 assert(stricmp(Epair->Key, "%defaultvalue%"));
00749
00750
00751
00752
00753 if(!stricmp(Epair->Value, "float"))
00754 TypeClass = geEntity_EntitySetFindClassByName(EntitySet, "geFloat");
00755 else
00756 TypeClass = geEntity_EntitySetFindClassByName(EntitySet, Epair->Value);
00757
00758 if (!TypeClass)
00759 goto ExitWithError;
00760
00761 Field = geEntity_FieldCreate(Epair->Key, Class->FieldSize, TypeClass);
00762
00763 if (!Field)
00764 goto ExitWithError;
00765
00766 if (!geEntity_ClassAddField(Class, Field))
00767 goto ExitWithError;
00768
00769 Epair = Epair->Next;
00770 assert(Epair);
00771 assert(!stricmp(Epair->Key, "%defaultvalue%"));
00772
00773 }
00774 }
00775
00776 return GE_TRUE;
00777
00778
00779 ExitWithError:
00780 {
00781 if (Class)
00782 geEntity_ClassDestroy(Class);
00783
00784 return GE_FALSE;
00785 }
00786 }
00787
00788
00789
00790
00791 static geBoolean ParseClassUserData(geEntity_EntitySet *EntitySet, geEntity *Entity)
00792 {
00793 geEntity_Epair *Epair;
00794
00795 if (!Entity->Class)
00796 return GE_TRUE;
00797
00798 for (Epair = Entity->Epairs; Epair; Epair = Epair->Next)
00799 {
00800 char *UData;
00801 geEntity_Field *Field;
00802
00803
00804 if (!stricmp(Epair->Key, "classname"))
00805 continue;
00806
00807 if (Epair->Key[0] == '%')
00808 continue;
00809
00810
00811 Field = geEntity_ClassFindFieldByName(Entity->Class, Epair->Key);
00812
00813 if (!Field)
00814 return GE_FALSE;
00815
00816
00817 UData = Entity->UserData;
00818
00819 switch (Field->TypeClass->Type)
00820 {
00821 double f;
00822 double X, Y, Z;
00823 int32 M;
00824 geEntity *Ent;
00825
00826 case TYPE_INT:
00827 sscanf(Epair->Value, "%d", UData + Field->Offset);
00828 break;
00829
00830 case TYPE_FLOAT:
00831 sscanf(Epair->Value, "%lf", &f);
00832 *(geFloat *)(UData + Field->Offset) = (geFloat)f;
00833 break;
00834
00835 case TYPE_POINT:
00836 sscanf(Epair->Value, "%lf %lf %lf", &X, &Y, &Z);
00837 ((geVec3d *)(UData + Field->Offset))->X = (geFloat)X;
00838 ((geVec3d *)(UData + Field->Offset))->Y = (geFloat)Y;
00839 ((geVec3d *)(UData + Field->Offset))->Z = (geFloat)Z;
00840 break;
00841
00842 case TYPE_COLOR:
00843 sscanf(Epair->Value, "%lf %lf %lf", &X, &Y, &Z);
00844 ((GE_RGBA *)(UData + Field->Offset))->r = (geFloat)X;
00845 ((GE_RGBA *)(UData + Field->Offset))->g = (geFloat)Y;
00846 ((GE_RGBA *)(UData + Field->Offset))->b = (geFloat)Z;
00847 ((GE_RGBA *)(UData + Field->Offset))->a = 0.0f;
00848 break;
00849
00850 case TYPE_STRING:
00851
00852 *(char **)(UData + Field->Offset) = Epair->Value;
00853 break;
00854
00855 case TYPE_PTR:
00856
00857
00858 *(void **)(UData + Field->Offset) = NULL;
00859 break;
00860
00861 case TYPE_MODEL:
00862
00863 Ent = geEntity_EntitySetFindEntityByName(EntitySet, Epair->Value);
00864
00865 if (!Ent)
00866 {
00867 geErrorLog_Add(GE_ERR_MODEL_NOT_FOUND, NULL);
00868 return GE_FALSE;
00869 }
00870
00871 if (!geEntity_GetModelNumForKey(Ent, "Model", &M))
00872 {
00873 geErrorLog_Add(GE_ERR_MODEL_NOT_IN_ENTITY, NULL);
00874 return GE_FALSE;
00875 }
00876
00877
00878 *(geWorld_Model**)(UData + Field->Offset) = &GWorld->CurrentBSP->Models[M];
00879
00880 break;
00881
00882 case TYPE_STRUCT:
00883 Ent = geEntity_EntitySetFindEntityByName(EntitySet, Epair->Value);
00884
00885 if (!Ent)
00886 return GE_FALSE;
00887
00888
00889 *(void **)(UData + Field->Offset) = Ent->UserData;
00890
00891 assert(*(void **)(UData + Field->Offset) != NULL);
00892 break;
00893
00894 default:
00895
00896 geErrorLog_Add(GE_ERR_INVALID_ENTITY_FIELD_TYPE, NULL);
00897 return GE_FALSE;
00898 }
00899 }
00900
00901 return GE_TRUE;
00902 }
00903
00904
00905
00906
00907 static geBoolean ParseClassData(geEntity_EntitySet *EntitySet)
00908 {
00909 geEntity_EntitySet *Set;
00910 const char *Name;
00911
00912
00913
00914
00915
00916
00917
00918
00919 for (Set = EntitySet; Set; Set = Set->Next)
00920 {
00921 geEntity *Entity;
00922 geEntity_Class *Class;
00923
00924 Entity = Set->Entity;
00925
00926 Name = geEntity_GetStringForKey(Entity, "classname");
00927
00928 if (!Name)
00929 continue;
00930
00931 Class = geEntity_EntitySetFindClassByName(EntitySet, Name);
00932
00933 Entity->Class = NULL;
00934 Entity->UserData = NULL;
00935
00936 if (!Class)
00937 continue;
00938
00939
00940 Entity->Class = Class;
00941
00942 Entity->UserData = GE_RAM_ALLOCATE_ARRAY(char, Class->FieldSize);
00943
00944 if (!Entity->UserData)
00945 {
00946 geErrorLog_Add(GE_ERR_GET_ENTITY_DATA_ERROR, NULL);
00947 return GE_FALSE;
00948 }
00949
00950
00951 memset(Entity->UserData, 0, Class->FieldSize);
00952 }
00953
00954 for (Set = EntitySet; Set; Set = Set->Next)
00955 {
00956 geEntity *Entity;
00957
00958 Entity = Set->Entity;
00959
00960 Name = geEntity_GetStringForKey(Entity, "classname");
00961
00962 if (!Name)
00963 continue;
00964
00965 if (!ParseClassUserData(EntitySet, Entity))
00966 {
00967 geErrorLog_Add(GE_ERR_GET_ENTITY_DATA_ERROR, NULL);
00968 return GE_FALSE;
00969 }
00970 }
00971
00972 return GE_TRUE;
00973 }
00974
00975
00976
00977
00978 geBoolean geEntity_EntitySetBuildClasses(geEntity_EntitySet *Set)
00979 {
00980 if (!BuildClassTypes(Set))
00981 return GE_FALSE;
00982
00983 if (!ParseClassData(Set))
00984 return GE_FALSE;
00985
00986 return GE_TRUE;
00987 }
00988
00989
00990
00991
00992 geBoolean geEntity_EntitySetLoadEntities(geEntity_EntitySet *EntitySet, geVFile *VFile)
00993 {
00994 int32 i, NumEntities;
00995
00996 if (!geVFile_Read(VFile, &NumEntities, sizeof(int32)))
00997 return GE_FALSE;
00998
00999 for (i=0; i< NumEntities; i++)
01000 {
01001 geEntity *Entity;
01002 int32 e, NumEpairs;
01003
01004
01005 Entity = geEntity_Create();
01006
01007 if (!Entity)
01008 return GE_FALSE;
01009
01010
01011 if (!geEntity_EntitySetAddEntity(EntitySet, Entity))
01012 return GE_FALSE;
01013
01014
01015 if (!geVFile_Read(VFile, &NumEpairs, sizeof(int32)))
01016 return GE_FALSE;
01017
01018 for (e=0; e<NumEpairs; e++)
01019 {
01020 geEntity_Epair *Epair;
01021 int32 Size;
01022
01023 Epair = geEntity_EpairCreate();
01024
01025 if (!Epair)
01026 return GE_FALSE;
01027
01028
01029 if (!geVFile_Read(VFile, &Size, sizeof(int32)))
01030 return GE_FALSE;
01031
01032 Epair->Key = GE_RAM_ALLOCATE_ARRAY(char, Size);
01033
01034 if (!Epair->Key)
01035 return GE_FALSE;
01036
01037
01038 if (!geVFile_Read(VFile, Epair->Key, sizeof(char)*Size))
01039 return GE_FALSE;
01040
01041
01042 if (!geVFile_Read(VFile, &Size, sizeof(int32)))
01043 return GE_FALSE;
01044
01045 Epair->Value = GE_RAM_ALLOCATE_ARRAY(char, Size);
01046
01047 if (!Epair->Value)
01048 return GE_FALSE;
01049
01050
01051 if (!geVFile_Read(VFile, Epair->Value, sizeof(char)*Size))
01052 return GE_FALSE;
01053
01054
01055 if (!geEntity_AddEpair(Entity, Epair))
01056 return GE_FALSE;
01057 }
01058
01059 }
01060
01061 return GE_TRUE;
01062
01063 }
01064
01065
01066
01067
01068 geEntity_EntitySet *LoadEntitySet(const char *EntityData, int32 EntityDataSize)
01069 {
01070 geEntity_EntitySet *EntitySet;
01071 geVFile_MemoryContext Context;
01072 geVFile *MemFile;
01073
01074
01075 EntitySet = NULL;
01076 MemFile = NULL;
01077
01078
01079 Context.Data = (void*)EntityData;
01080 Context.DataLength = EntityDataSize;
01081
01082 MemFile = geVFile_OpenNewSystem(NULL, GE_VFILE_TYPE_MEMORY, NULL, &Context, GE_VFILE_OPEN_READONLY);
01083
01084 if (!MemFile)
01085 return FALSE;
01086
01087
01088 EntitySet = geEntity_EntitySetCreate();
01089
01090 if (!EntitySet)
01091 goto ExitWithError;
01092
01093 EntitySet->OwnsEntities = GE_TRUE;
01094
01095 if (!geEntity_EntitySetLoadEntities(EntitySet, MemFile))
01096 goto ExitWithError;
01097
01098 geVFile_Close(MemFile);
01099 MemFile = NULL;
01100
01101 if (!geEntity_EntitySetBuildClasses(EntitySet))
01102 goto ExitWithError;
01103
01104 return EntitySet;
01105
01106
01107 ExitWithError:
01108 {
01109 if (EntitySet)
01110 geEntity_EntitySetDestroy(EntitySet);
01111
01112 if (MemFile)
01113 geVFile_Close(MemFile);
01114
01115 return NULL;
01116 }
01117 }