1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-28 08:48:48 +02:00

Serialize identifiers without implicit conversion to int

This commit is contained in:
Ivan Savenko 2023-11-02 16:31:12 +02:00
parent 2b9c362d5b
commit 8f25f1fd4b
8 changed files with 39 additions and 44 deletions

View File

@ -388,7 +388,7 @@ void CCreature::serializeJson(JsonSerializeFormat & handler)
if(handler.updating)
{
cost.serializeJson(handler, "cost");
handler.serializeInt("faction", faction);//TODO: unify with deferred resolve
handler.serializeId("faction", faction);
}
handler.serializeInt("level", level);

View File

@ -262,23 +262,4 @@ std::vector<bool> CSkillHandler::getDefaultAllowed() const
return allowedSkills;
}
si32 CSkillHandler::decodeSkill(const std::string & identifier)
{
auto rawId = VLC->identifiers()->getIdentifier(ModScope::scopeMap(), "skill", identifier);
if(rawId)
return rawId.value();
else
return -1;
}
std::string CSkillHandler::encodeSkill(const si32 index)
{
return (*VLC->skillh)[SecondarySkill(index)]->identifier;
}
std::string CSkillHandler::encodeSkillWithType(const si32 index)
{
return ModUtility::makeFullIdentifier("", "skill", encodeSkill(index));
}
VCMI_LIB_NAMESPACE_END

View File

@ -111,11 +111,6 @@ public:
std::vector<bool> getDefaultAllowed() const override;
///json serialization helpers
static si32 decodeSkill(const std::string & identifier);
static std::string encodeSkill(const si32 index);
static std::string encodeSkillWithType(const si32 index);
template <typename Handler> void serialize(Handler & h, const int version)
{
h & objects;

View File

@ -218,7 +218,7 @@ int Unit::getRawSurrenderCost() const
void UnitInfo::serializeJson(JsonSerializeFormat & handler)
{
handler.serializeInt("count", count);
handler.serializeId("type", type, CreatureID::NONE);
handler.serializeId("type", type, CreatureID(CreatureID::NONE));
handler.serializeInt("side", side);
handler.serializeInt("position", position);
handler.serializeBool("summoned", summoned);

View File

@ -392,15 +392,15 @@ void CQuest::serializeJson(JsonSerializeFormat & handler, const std::string & fi
if(missionType == "Hero")
{
ui32 temp;
handler.serializeId<ui32, ui32, HeroTypeID>("hero", temp, 0);
HeroTypeID temp;
handler.serializeId("hero", temp, HeroTypeID::NONE);
mission.heroes.emplace_back(temp);
}
if(missionType == "Player")
{
ui32 temp;
handler.serializeId<ui32, ui32, PlayerColor>("player", temp, PlayerColor::NEUTRAL);
PlayerColor temp;
handler.serializeId("player", temp, PlayerColor::NEUTRAL);
mission.players.emplace_back(temp);
}
}

View File

@ -249,7 +249,7 @@ void Rewardable::Limiter::serializeJson(JsonSerializeFormat & handler)
std::vector<std::pair<SecondarySkill, si32>> fieldValue(secondary.begin(), secondary.end());
a.serializeStruct<std::pair<SecondarySkill, si32>>(fieldValue, [](JsonSerializeFormat & h, std::pair<SecondarySkill, si32> & e)
{
h.serializeId("skill", e.first, SecondarySkill{}, VLC->skillh->decodeSkill, VLC->skillh->encodeSkill);
h.serializeId("skill", e.first, SecondarySkill(SecondarySkill::NONE));
h.serializeId("level", e.second, 0, [](const std::string & i){return vstd::find_pos(NSecondarySkill::levels, i);}, [](si32 i){return NSecondarySkill::levels.at(i);});
});
a.syncSize(fieldValue);

View File

@ -53,14 +53,14 @@ struct VectorizedObjectInfo
/// Base class for serializers capable of reading or writing data
class DLL_LINKAGE CSerializer
{
template<typename T>
static si32 idToNumber(const T &t, typename std::enable_if<std::is_convertible<T,si32>::value>::type * dummy = nullptr)
template<typename Numeric, std::enable_if_t<std::is_arithmetic_v<Numeric>, bool> = true>
static int32_t idToNumber(const Numeric &t)
{
return t;
}
template<typename T, typename NT>
static NT idToNumber(const IdentifierBase &t)
template<typename IdentifierType, std::enable_if_t<std::is_base_of_v<IdentifierBase, IdentifierType>, bool> = true>
static int32_t idToNumber(const IdentifierType &t)
{
return t.getNum();
}

View File

@ -295,14 +295,16 @@ public:
}
///si32-convertible identifier <-> Json string
template <typename T, typename U, typename E = T>
void serializeId(const std::string & fieldName, T & value, const U & defaultValue)
template <typename IdentifierType, typename IdentifierTypeBase = IdentifierType>
void serializeId(const std::string & fieldName, IdentifierType & value, const IdentifierTypeBase & defaultValue = IdentifierType::NONE)
{
static_assert(std::is_base_of_v<IdentifierBase, IdentifierType>, "This method can only serialize Identifier classes!");
if (saving)
{
if (value != defaultValue)
{
std::string fieldValue = E::encode(value);
std::string fieldValue = IdentifierType::encode(value.getNum());
serializeString(fieldName, fieldValue);
}
}
@ -313,13 +315,13 @@ public:
if (!fieldValue.empty())
{
VLC->identifiers()->requestIdentifier(ModScope::scopeGame(), E::entityType(), fieldValue, [&value](int32_t index){
value = T(index);
VLC->identifiers()->requestIdentifier(ModScope::scopeGame(), IdentifierType::entityType(), fieldValue, [&value](int32_t index){
value = IdentifierType(index);
});
}
else
{
value = T(defaultValue);
value = IdentifierType(defaultValue);
}
}
}
@ -333,7 +335,7 @@ public:
std::vector<std::string> fieldValue;
for(const T & vitem : value)
fieldValue.push_back(E::encode(vitem));
fieldValue.push_back(E::encode(vitem.getNum()));
serializeInternal(fieldName, fieldValue);
}
@ -362,7 +364,7 @@ public:
std::vector<std::string> fieldValue;
for(const T & vitem : value)
fieldValue.push_back(U::encode(vitem));
fieldValue.push_back(U::encode(vitem.getNum()));
serializeInternal(fieldName, fieldValue);
}
@ -387,7 +389,24 @@ public:
const TDecoder decoder = std::bind(&IInstanceResolver::decode, instanceResolver, _1);
const TEncoder encoder = std::bind(&IInstanceResolver::encode, instanceResolver, _1);
serializeId<T>(fieldName, value, defaultValue, decoder, encoder);
if (saving)
{
if (value != defaultValue)
{
std::string fieldValue = encoder(value.getNum());
serializeString(fieldName, fieldValue);
}
}
else
{
std::string fieldValue;
serializeString(fieldName, fieldValue);
if (!fieldValue.empty())
value = T(decoder(fieldValue));
else
value = T(defaultValue);
}
}
///any serializable object <-> Json struct