mirror of
https://github.com/vcmi/vcmi.git
synced 2025-08-13 19:54:17 +02:00
Improve serialization of IDs from mods, so they are resolved correctly after all mods are loaded.
This commit is contained in:
@@ -33,6 +33,7 @@
|
|||||||
#include "StringConstants.h"
|
#include "StringConstants.h"
|
||||||
#include "CGeneralTextHandler.h"
|
#include "CGeneralTextHandler.h"
|
||||||
#include "CModHandler.h"//todo: remove
|
#include "CModHandler.h"//todo: remove
|
||||||
|
#include "TerrainHandler.h" //TODO: remove
|
||||||
#include "BattleFieldHandler.h"
|
#include "BattleFieldHandler.h"
|
||||||
#include "ObstacleHandler.h"
|
#include "ObstacleHandler.h"
|
||||||
|
|
||||||
@@ -203,7 +204,7 @@ const FactionID FactionID::NEUTRAL = FactionID(9);
|
|||||||
|
|
||||||
si32 FactionID::decode(const std::string & identifier)
|
si32 FactionID::decode(const std::string & identifier)
|
||||||
{
|
{
|
||||||
auto rawId = VLC->modh->identifiers.getIdentifier(CModHandler::scopeGame(), "faction", identifier);
|
auto rawId = VLC->modh->identifiers.getIdentifier(CModHandler::scopeGame(), scope(), identifier);
|
||||||
if(rawId)
|
if(rawId)
|
||||||
return rawId.value();
|
return rawId.value();
|
||||||
else
|
else
|
||||||
@@ -215,6 +216,31 @@ std::string FactionID::encode(const si32 index)
|
|||||||
return VLC->factions()->getByIndex(index)->getJsonKey();
|
return VLC->factions()->getByIndex(index)->getJsonKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string FactionID::scope()
|
||||||
|
{
|
||||||
|
return "faction";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
si32 TerrainID::decode(const std::string & identifier)
|
||||||
|
{
|
||||||
|
auto rawId = VLC->modh->identifiers.getIdentifier(CModHandler::scopeGame(), scope(), identifier);
|
||||||
|
if(rawId)
|
||||||
|
return rawId.value();
|
||||||
|
else
|
||||||
|
return static_cast<si32>(ETerrainId::NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string TerrainID::encode(const si32 index)
|
||||||
|
{
|
||||||
|
return VLC->terrainTypeHandler->getByIndex(index)->getJsonKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string TerrainID::scope()
|
||||||
|
{
|
||||||
|
return "terrain";
|
||||||
|
}
|
||||||
|
|
||||||
std::ostream & operator<<(std::ostream & os, const EActionType actionType)
|
std::ostream & operator<<(std::ostream & os, const EActionType actionType)
|
||||||
{
|
{
|
||||||
static const std::map<EActionType, std::string> actionTypeToString =
|
static const std::map<EActionType, std::string> actionTypeToString =
|
||||||
|
@@ -459,11 +459,19 @@ class FactionID : public BaseForID<FactionID, int32_t>
|
|||||||
DLL_LINKAGE static const FactionID CONFLUX;
|
DLL_LINKAGE static const FactionID CONFLUX;
|
||||||
DLL_LINKAGE static const FactionID NEUTRAL;
|
DLL_LINKAGE static const FactionID NEUTRAL;
|
||||||
|
|
||||||
///json serialization helpers
|
static si32 decode(const std::string& identifier);
|
||||||
static si32 decode(const std::string & identifier);
|
|
||||||
static std::string encode(const si32 index);
|
static std::string encode(const si32 index);
|
||||||
|
static std::string scope();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TerrainID
|
||||||
|
{
|
||||||
|
//Dummy class used only for serialization
|
||||||
|
public:
|
||||||
|
static si32 decode(const std::string & identifier);
|
||||||
|
static std::string encode(const si32 index);
|
||||||
|
static std::string scope();
|
||||||
|
};
|
||||||
|
|
||||||
class BuildingID
|
class BuildingID
|
||||||
{
|
{
|
||||||
|
@@ -353,38 +353,13 @@ void ZoneOptions::serializeJson(JsonSerializeFormat & handler)
|
|||||||
|
|
||||||
if(terrainTypeLikeZone == NO_ZONE)
|
if(terrainTypeLikeZone == NO_ZONE)
|
||||||
{
|
{
|
||||||
JsonNode node;
|
handler.serializeIdArray<TerrainId, TerrainID>("terrainTypes", terrainTypes, std::set<TerrainId>());
|
||||||
if(handler.saving)
|
|
||||||
{
|
|
||||||
node.setType(JsonNode::JsonType::DATA_VECTOR);
|
|
||||||
for(const auto & ttype : terrainTypes)
|
|
||||||
{
|
|
||||||
JsonNode n;
|
|
||||||
n.String() = VLC->terrainTypeHandler->getById(ttype)->getJsonKey();
|
|
||||||
node.Vector().push_back(n);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
handler.serializeRaw("terrainTypes", node, std::nullopt);
|
|
||||||
if(!handler.saving)
|
|
||||||
{
|
|
||||||
if(!node.Vector().empty())
|
|
||||||
{
|
|
||||||
terrainTypes.clear();
|
|
||||||
for(const auto & ttype : node.Vector())
|
|
||||||
{
|
|
||||||
VLC->modh->identifiers.requestIdentifier("terrain", ttype, [this](int32_t identifier)
|
|
||||||
{
|
|
||||||
terrainTypes.emplace(identifier);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
handler.serializeBool("townsAreSameType", townsAreSameType, false);
|
handler.serializeBool("townsAreSameType", townsAreSameType, false);
|
||||||
handler.serializeIdArray<FactionID, FactionID>("allowedMonsters", monsterTypes, std::set<FactionID>());
|
handler.serializeIdArray<FactionID>("allowedMonsters", monsterTypes, std::set<FactionID>());
|
||||||
handler.serializeIdArray<FactionID, FactionID>("allowedTowns", townTypes, std::set<FactionID>());
|
handler.serializeIdArray<FactionID>("allowedTowns", townTypes, std::set<FactionID>());
|
||||||
handler.serializeIdArray<FactionID, FactionID>("bannedTowns", bannedTownTypes, std::set<FactionID>());
|
handler.serializeIdArray<FactionID>("bannedTowns", bannedTownTypes, std::set<FactionID>());
|
||||||
|
|
||||||
{
|
{
|
||||||
//TODO: add support for std::map to serializeEnum
|
//TODO: add support for std::map to serializeEnum
|
||||||
|
@@ -82,7 +82,7 @@ void TerrainPainter::initTerrainType()
|
|||||||
if ((terrain->isSurface() && !zone.isUnderground()) ||
|
if ((terrain->isSurface() && !zone.isUnderground()) ||
|
||||||
(terrain->isUnderground() && zone.isUnderground()))
|
(terrain->isUnderground() && zone.isUnderground()))
|
||||||
{
|
{
|
||||||
terrainTypes.insert(terrain->getId());
|
terrainTypes.insert(TerrainId(terrain->getId()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -334,6 +334,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
///si32-convertible identifier set <-> Json array of string
|
///si32-convertible identifier set <-> Json array of string
|
||||||
|
///Type U is only used for code & decode
|
||||||
|
///TODO: Auto deduce U based on T?
|
||||||
template <typename T, typename U = T>
|
template <typename T, typename U = T>
|
||||||
void serializeIdArray(const std::string & fieldName, std::set<T> & value, const std::set<T> & defaultValue)
|
void serializeIdArray(const std::string & fieldName, std::set<T> & value, const std::set<T> & defaultValue)
|
||||||
{
|
{
|
||||||
@@ -348,12 +350,14 @@ public:
|
|||||||
si32 item = static_cast<si32>(vitem);
|
si32 item = static_cast<si32>(vitem);
|
||||||
temp.push_back(item);
|
temp.push_back(item);
|
||||||
}
|
}
|
||||||
|
serializeInternal(fieldName, temp, &U::decode, &U::encode);
|
||||||
}
|
}
|
||||||
|
|
||||||
serializeInternal(fieldName, temp, &U::decode, &U::encode);
|
|
||||||
if(!saving)
|
if(!saving)
|
||||||
{
|
{
|
||||||
if(temp.empty())
|
JsonNode node;
|
||||||
|
serializeRaw(fieldName, node, std::nullopt);
|
||||||
|
if(node.Vector().empty())
|
||||||
{
|
{
|
||||||
value = defaultValue;
|
value = defaultValue;
|
||||||
}
|
}
|
||||||
@@ -361,10 +365,12 @@ public:
|
|||||||
{
|
{
|
||||||
value.clear();
|
value.clear();
|
||||||
|
|
||||||
for(const si32 item : temp)
|
for(const auto & id : node.Vector())
|
||||||
{
|
{
|
||||||
T vitem = static_cast<T>(item);
|
VLC->modh->identifiers.requestIdentifier(U::scope(), id, [&value](int32_t identifier)
|
||||||
value.insert(vitem);
|
{
|
||||||
|
value.emplace(identifier);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user