浏览代码

Add mechanism to provide save compatibility if class is removed or
addded

Ivan Savenko 1 年之前
父节点
当前提交
ac271c09b9
共有 3 个文件被更改,包括 27 次插入19 次删除
  1. 0 14
      lib/mapObjects/TownBuildingInstance.h
  2. 0 2
      lib/serializer/RegisterTypes.h
  3. 27 3
      lib/serializer/SerializerReflection.cpp

+ 0 - 14
lib/mapObjects/TownBuildingInstance.h

@@ -92,18 +92,4 @@ public:
 	}
 };
 
-/// Compatibility for old code
-class DLL_LINKAGE CTownCompatBuilding1 : public TownRewardableBuildingInstance
-{
-public:
-	using TownRewardableBuildingInstance::TownRewardableBuildingInstance;
-};
-
-/// Compatibility for old code
-class DLL_LINKAGE CTownCompatBuilding2 : public TownRewardableBuildingInstance
-{
-public:
-	using TownRewardableBuildingInstance::TownRewardableBuildingInstance;
-};
-
 VCMI_LIB_NAMESPACE_END

+ 0 - 2
lib/serializer/RegisterTypes.h

@@ -114,8 +114,6 @@ void registerTypes(Serializer &s)
 	s.template registerType<OppositeSideLimiter>(51);
 	s.template registerType<TownBuildingInstance>(52);
 	s.template registerType<TownRewardableBuildingInstance>(53);
-	s.template registerType<CTownCompatBuilding1>(54);
-	s.template registerType<CTownCompatBuilding2>(55);
 	s.template registerType<CRewardableObject>(56);
 	s.template registerType<CTeamVisited>(57);
 	s.template registerType<CGObelisk>(58);

+ 27 - 3
lib/serializer/SerializerReflection.cpp

@@ -12,7 +12,6 @@
 
 #include "BinaryDeserializer.h"
 #include "BinarySerializer.h"
-#include "CTypeList.h"
 
 #include "RegisterTypes.h"
 
@@ -36,12 +35,34 @@ public:
 	void savePtr(BinarySerializer &s, const Serializeable *data) const override
 	{
 		const Type *ptr = dynamic_cast<const Type*>(data);
-
-		//T is most derived known type, it's time to call actual serialize
 		const_cast<Type*>(ptr)->serialize(s);
 	}
 };
 
+template<typename Type, ESerializationVersion maxVersion>
+class SerializerCompatibility : public ISerializerReflection
+{
+public:
+	Serializeable * createPtr(BinaryDeserializer &ar, IGameCallback * cb) const override
+	{
+		return ClassObjectCreator<Type>::invoke(cb);
+	}
+
+	void savePtr(BinarySerializer &s, const Serializeable *data) const override
+	{
+		throw std::runtime_error("Illegal call to savePtr - this type should not be used for serialization!");
+	}
+};
+
+class SerializerCompatibilityBonusingBuilding final : public SerializerCompatibility<TownRewardableBuildingInstance, ESerializationVersion::NEW_TOWN_BUILDINGS>
+{
+	void loadPtr(BinaryDeserializer &ar, IGameCallback * cb, Serializeable * data) const override
+	{
+		auto * realPtr = dynamic_cast<TownRewardableBuildingInstance *>(data);
+		realPtr->serialize(ar);
+	}
+};
+
 template<typename Type>
 void CSerializationApplier::registerType(uint16_t ID)
 {
@@ -52,6 +73,9 @@ void CSerializationApplier::registerType(uint16_t ID)
 CSerializationApplier::CSerializationApplier()
 {
 	registerTypes(*this);
+
+	apps[54].reset(new SerializerCompatibilityBonusingBuilding);
+	apps[55].reset(new SerializerCompatibilityBonusingBuilding);
 }
 
 CSerializationApplier & CSerializationApplier::getInstance()