void C4MeshDenumerator::CompileFunc(StdCompiler* pComp, StdMeshInstance::AttachedMesh* attach) { if(pComp->isDeserializer()) { int32_t def; pComp->Value(mkNamingCountAdapt(def, "ChildInstance")); if(def) { C4DefGraphics* pGfx = nullptr; pComp->Value(mkNamingAdapt(C4DefGraphicsAdapt(pGfx), "ChildMesh")); Def = pGfx->pDef; if(pGfx->Type != C4DefGraphics::TYPE_Mesh) pComp->excCorrupt("ChildMesh points to non-mesh graphics"); assert(!attach->Child); pComp->Value(mkParAdapt(mkNamingContextPtrAdapt(attach->Child, *pGfx->Mesh, "ChildInstance"), C4MeshDenumeratorFactory)); assert(attach->Child != nullptr); attach->OwnChild = true; // Delete the newly allocated child instance when the parent instance is gone // TODO: Do we leak pGfx? } else { pComp->Value(mkNamingAdapt(Object, "ChildObject")); attach->OwnChild = false; // Keep child instance when parent instance is gone since it belongs to a different object } } else { int32_t def = 0; if(Def) ++def; pComp->Value(mkNamingCountAdapt(def, "ChildInstance")); if(Def) { assert(attach->OwnChild); C4DefGraphics* pGfx = &Def->Graphics; assert(pGfx->Type == C4DefGraphics::TYPE_Mesh); pComp->Value(mkNamingAdapt(C4DefGraphicsAdapt(pGfx), "ChildMesh")); pComp->Value(mkParAdapt(mkNamingContextPtrAdapt(attach->Child, *pGfx->Mesh, "ChildInstance"), C4MeshDenumeratorFactory)); } else { assert(!attach->OwnChild); pComp->Value(mkNamingAdapt(Object, "ChildObject")); } } }
void C4TeamList::CompileFunc(StdCompiler *pComp) { // if (pComp->isCompiler()) Clear(); - do not clear, because this would corrupt the fCustom-flag pComp->Value(mkNamingAdapt(fActive, "Active", true)); pComp->Value(mkNamingAdapt(fCustom, "Custom", true)); pComp->Value(mkNamingAdapt(fAllowHostilityChange, "AllowHostilityChange", false)); pComp->Value(mkNamingAdapt(fAllowTeamSwitch, "AllowTeamSwitch", false)); pComp->Value(mkNamingAdapt(fAutoGenerateTeams, "AutoGenerateTeams", false)); pComp->Value(mkNamingAdapt(iLastTeamID, "LastTeamID", 0)); StdEnumEntry<TeamDist> TeamDistEntries[] = { { "Free", TEAMDIST_Free }, { "Host", TEAMDIST_Host }, { "None", TEAMDIST_None }, { "Random", TEAMDIST_Random }, { "RandomInv", TEAMDIST_RandomInv }, }; pComp->Value(mkNamingAdapt(mkEnumAdaptT<uint8_t>(eTeamDist, TeamDistEntries), "TeamDistribution", TEAMDIST_Free)); pComp->Value(mkNamingAdapt(fTeamColors, "TeamColors", false)); pComp->Value(mkNamingAdapt(iMaxScriptPlayers, "MaxScriptPlayers", 0)); pComp->Value(mkNamingAdapt(mkParAdapt(sScriptPlayerNames, StdCompiler::RCT_All), "ScriptPlayerNames", StdStrBuf())); int32_t iOldTeamCount = iTeamCount; pComp->Value(mkNamingCountAdapt(iTeamCount, "Team")); if (pComp->isCompiler()) { while (iOldTeamCount--) delete ppList[iOldTeamCount]; delete [] ppList; if ((iTeamCapacity = iTeamCount)) { ppList = new C4Team *[iTeamCapacity]; memset(ppList, 0, sizeof(C4Team *)*iTeamCapacity); } else ppList = NULL; } if (iTeamCount) { // Force compiler to spezialize mkPtrAdaptNoNull(*ppList); // Save team list, using map-function. pComp->Value(mkNamingAdapt( mkArrayAdaptMap(ppList, iTeamCount, mkPtrAdaptNoNull<C4Team>), "Team")); } if (pComp->isCompiler()) { // adjust last team ID, which may not be set properly for player-generated team files iLastTeamID = std::max(GetLargestTeamID(), iLastTeamID); // force automatic generation of teams if none are defined if (!iTeamCount) fAutoGenerateTeams = true; } }
void C4Network2ResCore::CompileFunc(StdCompiler *pComp) { pComp->Value(mkNamingAdapt(mkEnumAdaptT<uint8_t>(eType, C4Network2ResType_EnumMap), "Type", NRT_Null)); pComp->Value(mkNamingAdapt(iID, "ID", -1)); pComp->Value(mkNamingAdapt(iDerID, "DerID", -1)); pComp->Value(mkNamingAdapt(fLoadable, "Loadable", true)); if (fLoadable) { pComp->Value(mkNamingAdapt(iFileSize, "FileSize", 0U)); pComp->Value(mkNamingAdapt(iFileCRC, "FileCRC", 0U)); pComp->Value(mkNamingAdapt(iChunkSize, "ChunkSize", C4NetResChunkSize)); if (!iChunkSize) pComp->excCorrupt("zero chunk size"); } pComp->Value(mkNamingAdapt(iContentsCRC, "ContentsCRC", 0U)); pComp->Value(mkNamingCountAdapt(fHasFileSHA, "FileSHA")); if (fHasFileSHA) pComp->Value(mkNamingAdapt(mkHexAdapt(FileSHA), "FileSHA")); pComp->Value(mkNamingAdapt(mkNetFilenameAdapt(FileName), "Filename", "")); }
void C4ObjectList::CompileFunc(StdCompiler *pComp, bool fSkipPlayerObjects, C4ValueNumbers * numbers) { // "Object" section count int32_t iObjCnt = ObjectCount(); pComp->Value(mkNamingCountAdapt(iObjCnt, "Object")); if (pComp->isDecompiler()) { // skipping player objects would screw object counting in non-naming compilers assert(!fSkipPlayerObjects || pComp->hasNaming()); // Decompile all objects in reverse order for (C4ObjectLink *pPos = Last; pPos; pPos = pPos->Prev) if (pPos->Obj->Status) if (!fSkipPlayerObjects || !pPos->Obj->IsUserPlayerObject()) pComp->Value(mkNamingAdapt(mkParAdapt(*pPos->Obj, numbers), "Object")); } else { // FIXME: Check that no PlayerObjects are loaded when fSkipPlayerObjects is true // i.e. that loading and saving was done with the same flag. // Remove previous data Clear(); // Load objects, add them to the list. for (int i = 0; i < iObjCnt; i++) { C4Object *pObj = NULL; try { pComp->Value(mkNamingAdapt(mkParAdapt(mkPtrAdaptNoNull(pObj), numbers), "Object")); Add(pObj, stReverse); } catch (StdCompiler::Exception *pExc) { // Failsafe object loading: If an error occurs during object loading, just skip that object and load the next one if (!pExc->Pos.getLength()) LogF("ERROR: Object loading: %s", pExc->Msg.getData()); else LogF("ERROR: Object loading(%s): %s", pExc->Pos.getData(), pExc->Msg.getData()); delete pExc; } } } }
void C4ClientList::CompileFunc(StdCompiler *pComp) { // Clear existing data bool fCompiler = pComp->isCompiler(); if (fCompiler) Clear(); // Client count uint32_t iClientCnt = getClientCnt(); pComp->Value(mkNamingCountAdapt(iClientCnt, "Client")); // Compile all clients if (pComp->isCompiler()) for (uint32_t i = 0; i < iClientCnt; i++) { C4Client *pClient = new C4Client(); pComp->Value(mkNamingAdapt(*pClient, "Client")); Add(pClient); } else for (C4Client *pClient = pFirst; pClient; pClient = pClient->pNext) pComp->Value(mkNamingAdapt(*pClient, "Client")); }