Browse Source

Mod system improvement Part I : Fix content losing after deserialization

Dmitry Orlov 5 years ago
parent
commit
195fb8ff41
7 changed files with 36 additions and 13 deletions
  1. 1 1
      client/CMT.cpp
  2. 8 8
      lib/CModHandler.cpp
  3. 1 1
      lib/CModHandler.h
  4. 1 1
      lib/CTownHandler.cpp
  5. 10 0
      lib/VCMI_Lib.cpp
  6. 14 1
      lib/VCMI_Lib.h
  7. 1 1
      lib/spells/CSpellHandler.cpp

+ 1 - 1
client/CMT.cpp

@@ -698,7 +698,7 @@ void processCommand(const std::string &message)
 
 		for(auto contentName : contentNames)
 		{
-			auto & content = VLC->modh->content[contentName];
+			auto & content = (*VLC->modh->content)[contentName];
 
 			auto contentOutPath = outPath / contentName;
 			bfs::create_directories(contentOutPath);

+ 8 - 8
lib/CModHandler.cpp

@@ -610,7 +610,7 @@ void CModInfo::loadLocalData(const JsonNode & data)
 		validation = validated ? PASSED : FAILED;
 }
 
-CModHandler::CModHandler()
+CModHandler::CModHandler() : content(std::make_shared<CContentHandler>())
 {
     modules.COMMANDERS = false;
     modules.STACK_ARTIFACT = false;
@@ -955,7 +955,7 @@ void CModHandler::load()
 
 	logMod->info("\tInitializing content handler: %d ms", timer.getDiff());
 
-	content.init();
+	content->init();
 
 	for(const TModID & modName : activeMods)
 	{
@@ -965,16 +965,16 @@ void CModHandler::load()
 
 	// first - load virtual "core" mod that contains all data
 	// TODO? move all data into real mods? RoE, AB, SoD, WoG
-	content.preloadData(coreMod);
+	content->preloadData(coreMod);
 	for(const TModID & modName : activeMods)
-		content.preloadData(allMods[modName]);
+		content->preloadData(allMods[modName]);
 	logMod->info("\tParsing mod data: %d ms", timer.getDiff());
 
-	content.load(coreMod);
+	content->load(coreMod);
 	for(const TModID & modName : activeMods)
-		content.load(allMods[modName]);
+		content->load(allMods[modName]);
 
-	content.loadCustom();
+	content->loadCustom();
 
 	logMod->info("\tLoading mod data: %d ms", timer.getDiff());
 
@@ -984,7 +984,7 @@ void CModHandler::load()
 	identifiers.finalize();
 	logMod->info("\tResolving identifiers: %d ms", timer.getDiff());
 
-	content.afterLoadFinalization();
+	content->afterLoadFinalization();
 	logMod->info("\tHandlers post-load finalization: %d ms ", timer.getDiff());
 	logMod->info("\tAll game content loaded in %d ms", totalTime.getDiff());
 }

+ 1 - 1
lib/CModHandler.h

@@ -253,7 +253,7 @@ public:
 
 	CIdentifierStorage identifiers;
 
-	CContentHandler content; //(!)Do not serialize
+	std::shared_ptr<CContentHandler> content; //(!)Do not serialize
 
 	/// receives list of available mods and trying to load mod.json from all of them
 	void initializeConfig();

+ 1 - 1
lib/CTownHandler.cpp

@@ -107,7 +107,7 @@ void CBuilding::update792(const BuildingID & bid, BuildingSubID::EBuildingSubID
 		return;
 
 	const auto & faction = town->faction->identifier;
-	auto factionsContent = VLC->modh->content["factions"];
+	auto factionsContent = (*VLC->modh->content)["factions"];
 	auto & coreData = factionsContent.modData.at("core");
 	auto & coreFactions = coreData.modData;
 	auto & currentFaction = coreFactions[faction];

+ 10 - 0
lib/VCMI_Lib.cpp

@@ -186,3 +186,13 @@ LibClasses::~LibClasses()
 {
 	clear();
 }
+
+std::shared_ptr<CContentHandler> LibClasses::getContent() const
+{
+	return modh->content;
+}
+
+void LibClasses::setContent(std::shared_ptr<CContentHandler> content)
+{
+	modh->content = content;
+}

+ 14 - 1
lib/VCMI_Lib.h

@@ -21,6 +21,7 @@ class CObjectClassesHandler;
 class CTownHandler;
 class CGeneralTextHandler;
 class CModHandler;
+class CContentHandler;
 class IBonusTypeHandler;
 class CBonusTypeHandler;
 class CTerrainViewPatternConfig;
@@ -33,6 +34,9 @@ class DLL_LINKAGE LibClasses
 
 	void callWhenDeserializing(); //should be called only by serialize !!!
 	void makeNull(); //sets all handler pointers to null
+	std::shared_ptr<CContentHandler> getContent() const;
+	void setContent(std::shared_ptr<CContentHandler> content);
+
 public:
 	bool IS_AI_ENABLED; //unused?
 
@@ -73,7 +77,16 @@ public:
 		{
 			h & skillh;
 		}
-		h & modh;
+		if(!h.saving)
+		{
+			//modh will be changed and modh->content will be empty after deserialization
+			auto content = getContent();
+			h & modh;
+			setContent(content);
+		}
+		else
+			h & modh;
+
 		h & IS_AI_ENABLED;
 		h & bth;
 		if(!h.saving)

+ 1 - 1
lib/spells/CSpellHandler.cpp

@@ -1038,7 +1038,7 @@ void CSpellHandler::update780()
 {
 	static_assert(MINIMAL_SERIALIZATION_VERSION < 780, "No longer needed CSpellHandler::update780");
 
-	auto spellsContent = VLC->modh->content["spells"];
+	auto spellsContent = (*VLC->modh->content)["spells"];
 
 	const ContentTypeHandler::ModInfo & coreData = spellsContent.modData.at("core");