From c7676bde5353f84b199feaa007442ec28a89e32e Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Sat, 4 Nov 2023 18:22:27 +0200 Subject: [PATCH] Serialize Enitity classes by their ID --- include/vcmi/Entity.h | 2 ++ lib/constants/EntityIdentifiers.cpp | 22 ++++++++++++++++++++++ lib/constants/EntityIdentifiers.h | 20 +++++++++++++++----- lib/serializer/BinaryDeserializer.h | 20 +++++++++++++++++++- lib/serializer/BinarySerializer.h | 13 +++++++++++++ lib/serializer/CSerializer.h | 18 ------------------ 6 files changed, 71 insertions(+), 24 deletions(-) diff --git a/include/vcmi/Entity.h b/include/vcmi/Entity.h index 34ccc2757..eded843b7 100644 --- a/include/vcmi/Entity.h +++ b/include/vcmi/Entity.h @@ -50,6 +50,8 @@ template class DLL_LINKAGE EntityT : public Entity { public: + using IdentifierType = IdType; + virtual IdType getId() const = 0; }; diff --git a/lib/constants/EntityIdentifiers.cpp b/lib/constants/EntityIdentifiers.cpp index 6ad6f37a1..2d908b6b7 100644 --- a/lib/constants/EntityIdentifiers.cpp +++ b/lib/constants/EntityIdentifiers.cpp @@ -37,6 +37,8 @@ #include "constants/StringConstants.h" #include "CGeneralTextHandler.h" #include "TerrainHandler.h" //TODO: remove +#include "RiverHandler.h" +#include "RoadHandler.h" #include "BattleFieldHandler.h" #include "ObstacleHandler.h" #include "CTownHandler.h" @@ -404,6 +406,11 @@ std::string FactionID::entityType() return "faction"; } +const Faction * FactionID::toEntity(const Services * service) const +{ + return service->factions()->getByIndex(num); +} + si32 TerrainId::decode(const std::string & identifier) { auto rawId = VLC->identifiers()->getIdentifier(ModScope::scopeGame(), entityType(), identifier); @@ -423,6 +430,21 @@ std::string TerrainId::entityType() return "terrain"; } +const TerrainType * TerrainId::toEntity(const Services * service) const +{ + return VLC->terrainTypeHandler->getByIndex(num); +} + +const RoadType * RoadId::toEntity(const Services * service) const +{ + return VLC->roadTypeHandler->getByIndex(num); +} + +const RiverType * RiverId::toEntity(const Services * service) const +{ + return VLC->riverTypeHandler->getByIndex(num); +} + const BattleField BattleField::NONE; const BattleFieldInfo * BattleField::getInfo() const diff --git a/lib/constants/EntityIdentifiers.h b/lib/constants/EntityIdentifiers.h index edf4a36cb..9c842c1f4 100644 --- a/lib/constants/EntityIdentifiers.h +++ b/lib/constants/EntityIdentifiers.h @@ -22,6 +22,10 @@ class CreatureService; class HeroType; class CHero; class HeroTypeService; +class Faction; +class RoadType; +class RiverType; +class TerrainType; namespace spells { @@ -181,20 +185,20 @@ public: static std::string entityType(); }; -class HeroTypeID : public Identifier +class DLL_LINKAGE HeroTypeID : public Identifier { public: using Identifier::Identifier; ///json serialization helpers - DLL_LINKAGE static si32 decode(const std::string & identifier); - DLL_LINKAGE static std::string encode(const si32 index); + static si32 decode(const std::string & identifier); + static std::string encode(const si32 index); static std::string entityType(); const CHero * toHeroType() const; const HeroType * toEntity(const Services * services) const; - DLL_LINKAGE static const HeroTypeID NONE; - DLL_LINKAGE static const HeroTypeID RANDOM; + static const HeroTypeID NONE; + static const HeroTypeID RANDOM; bool isValid() const { @@ -349,6 +353,7 @@ public: static si32 decode(const std::string& identifier); static std::string encode(const si32 index); + const Faction * toEntity(const Services * service) const; static std::string entityType(); bool isValid() const @@ -596,6 +601,8 @@ public: static const RoadId DIRT_ROAD; static const RoadId GRAVEL_ROAD; static const RoadId COBBLESTONE_ROAD; + + const RoadType * toEntity(const Services * service) const; }; class DLL_LINKAGE RiverId : public Identifier @@ -608,6 +615,8 @@ public: static const RiverId ICY_RIVER; static const RiverId MUD_RIVER; static const RiverId LAVA_RIVER; + + const RiverType * toEntity(const Services * service) const; }; class DLL_LINKAGE EPathfindingLayerBase : public IdentifierBase @@ -912,6 +921,7 @@ public: DLL_LINKAGE static si32 decode(const std::string & identifier); DLL_LINKAGE static std::string encode(const si32 index); static std::string entityType(); + const TerrainType * toEntity(const Services * service) const; }; class ObstacleInfo; diff --git a/lib/serializer/BinaryDeserializer.h b/lib/serializer/BinaryDeserializer.h index caa36ee7d..124f89370 100644 --- a/lib/serializer/BinaryDeserializer.h +++ b/lib/serializer/BinaryDeserializer.h @@ -258,6 +258,25 @@ public: return; } + loadPointerImpl(data); + } + + template < typename T, typename std::enable_if < std::is_base_of_v>, int >::type = 0 > + void loadPointerImpl(T &data) + { + using DataType = std::remove_pointer_t; + + typename DataType::IdentifierType index; + load(index); + + auto * constEntity = index.toEntity(VLC); + auto * constData = dynamic_cast(constEntity); + data = const_cast(constData); + } + + template < typename T, typename std::enable_if < !std::is_base_of_v>, int >::type = 0 > + void loadPointerImpl(T &data) + { ui32 pid = 0xffffffff; //pointer id (or maybe rather pointee id) if(smartPointerSerialization) { @@ -273,7 +292,6 @@ public: return; } } - //get type id ui16 tid; load( tid ); diff --git a/lib/serializer/BinarySerializer.h b/lib/serializer/BinarySerializer.h index 0afcab95e..05db4a4ca 100644 --- a/lib/serializer/BinarySerializer.h +++ b/lib/serializer/BinarySerializer.h @@ -203,6 +203,19 @@ public: return; } + savePointerImpl(data); + } + + template < typename T, typename std::enable_if < std::is_base_of_v>, int >::type = 0 > + void savePointerImpl(const T &data) + { + auto index = data->getId(); + save(index); + } + + template < typename T, typename std::enable_if < !std::is_base_of_v>, int >::type = 0 > + void savePointerImpl(const T &data) + { if(smartPointerSerialization) { // We might have an object that has multiple inheritance and store it via the non-first base pointer. diff --git a/lib/serializer/CSerializer.h b/lib/serializer/CSerializer.h index 525caf2bc..9adc58e72 100644 --- a/lib/serializer/CSerializer.h +++ b/lib/serializer/CSerializer.h @@ -164,24 +164,6 @@ struct VectorizedIDType using type = std::conditional_t, ObjectInstanceID, int32_t>; }; -template <> -struct VectorizedIDType -{ - using type = ArtifactID; -}; - -template <> -struct VectorizedIDType -{ - using type = CreatureID; -}; - -template <> -struct VectorizedIDType -{ - using type = HeroTypeID; -}; - template <> struct VectorizedIDType {