1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-08-13 19:54:17 +02:00

Serialize Enitity classes by their ID

This commit is contained in:
Ivan Savenko
2023-11-04 18:22:27 +02:00
parent f8a7f6e5a7
commit c7676bde53
6 changed files with 71 additions and 24 deletions

View File

@@ -50,6 +50,8 @@ template <typename IdType>
class DLL_LINKAGE EntityT : public Entity
{
public:
using IdentifierType = IdType;
virtual IdType getId() const = 0;
};

View File

@@ -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

View File

@@ -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<HeroTypeID>
class DLL_LINKAGE HeroTypeID : public Identifier<HeroTypeID>
{
public:
using Identifier<HeroTypeID>::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<RiverId>
@@ -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;

View File

@@ -258,6 +258,25 @@ public:
return;
}
loadPointerImpl(data);
}
template < typename T, typename std::enable_if < std::is_base_of_v<Entity, std::remove_pointer_t<T>>, int >::type = 0 >
void loadPointerImpl(T &data)
{
using DataType = std::remove_pointer_t<T>;
typename DataType::IdentifierType index;
load(index);
auto * constEntity = index.toEntity(VLC);
auto * constData = dynamic_cast<const DataType *>(constEntity);
data = const_cast<DataType *>(constData);
}
template < typename T, typename std::enable_if < !std::is_base_of_v<Entity, std::remove_pointer_t<T>>, 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 );

View File

@@ -203,6 +203,19 @@ public:
return;
}
savePointerImpl(data);
}
template < typename T, typename std::enable_if < std::is_base_of_v<Entity, std::remove_pointer_t<T>>, 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<Entity, std::remove_pointer_t<T>>, 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.

View File

@@ -164,24 +164,6 @@ struct VectorizedIDType
using type = std::conditional_t<std::is_base_of_v<CGObjectInstance, T>, ObjectInstanceID, int32_t>;
};
template <>
struct VectorizedIDType<CArtifact>
{
using type = ArtifactID;
};
template <>
struct VectorizedIDType<CCreature>
{
using type = CreatureID;
};
template <>
struct VectorizedIDType<CHero>
{
using type = HeroTypeID;
};
template <>
struct VectorizedIDType<CArtifactInstance>
{