diff --git a/lib/CCreatureHandler.cpp b/lib/CCreatureHandler.cpp index eb03049ce..2b723aac5 100644 --- a/lib/CCreatureHandler.cpp +++ b/lib/CCreatureHandler.cpp @@ -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); diff --git a/lib/CSkillHandler.cpp b/lib/CSkillHandler.cpp index 82338746c..de080a1c1 100644 --- a/lib/CSkillHandler.cpp +++ b/lib/CSkillHandler.cpp @@ -262,23 +262,4 @@ std::vector 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 diff --git a/lib/CSkillHandler.h b/lib/CSkillHandler.h index d8f84a3dd..83fe729bb 100644 --- a/lib/CSkillHandler.h +++ b/lib/CSkillHandler.h @@ -111,11 +111,6 @@ public: std::vector 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 void serialize(Handler & h, const int version) { h & objects; diff --git a/lib/battle/Unit.cpp b/lib/battle/Unit.cpp index 7e0c9be2d..1355ba089 100644 --- a/lib/battle/Unit.cpp +++ b/lib/battle/Unit.cpp @@ -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); diff --git a/lib/mapObjects/CQuest.cpp b/lib/mapObjects/CQuest.cpp index 640641685..c08ca9f4f 100644 --- a/lib/mapObjects/CQuest.cpp +++ b/lib/mapObjects/CQuest.cpp @@ -392,15 +392,15 @@ void CQuest::serializeJson(JsonSerializeFormat & handler, const std::string & fi if(missionType == "Hero") { - ui32 temp; - handler.serializeId("hero", temp, 0); + HeroTypeID temp; + handler.serializeId("hero", temp, HeroTypeID::NONE); mission.heroes.emplace_back(temp); } if(missionType == "Player") { - ui32 temp; - handler.serializeId("player", temp, PlayerColor::NEUTRAL); + PlayerColor temp; + handler.serializeId("player", temp, PlayerColor::NEUTRAL); mission.players.emplace_back(temp); } } diff --git a/lib/rewardable/Limiter.cpp b/lib/rewardable/Limiter.cpp index 6f78d4868..2df9a6c24 100644 --- a/lib/rewardable/Limiter.cpp +++ b/lib/rewardable/Limiter.cpp @@ -249,7 +249,7 @@ void Rewardable::Limiter::serializeJson(JsonSerializeFormat & handler) std::vector> fieldValue(secondary.begin(), secondary.end()); a.serializeStruct>(fieldValue, [](JsonSerializeFormat & h, std::pair & 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); diff --git a/lib/serializer/CSerializer.h b/lib/serializer/CSerializer.h index df7278f00..706a0de9b 100644 --- a/lib/serializer/CSerializer.h +++ b/lib/serializer/CSerializer.h @@ -53,14 +53,14 @@ struct VectorizedObjectInfo /// Base class for serializers capable of reading or writing data class DLL_LINKAGE CSerializer { - template - static si32 idToNumber(const T &t, typename std::enable_if::value>::type * dummy = nullptr) + template, bool> = true> + static int32_t idToNumber(const Numeric &t) { return t; } - template - static NT idToNumber(const IdentifierBase &t) + template, bool> = true> + static int32_t idToNumber(const IdentifierType &t) { return t.getNum(); } diff --git a/lib/serializer/JsonSerializeFormat.h b/lib/serializer/JsonSerializeFormat.h index c5b274005..1d5efaeea 100644 --- a/lib/serializer/JsonSerializeFormat.h +++ b/lib/serializer/JsonSerializeFormat.h @@ -295,14 +295,16 @@ public: } ///si32-convertible identifier <-> Json string - template - void serializeId(const std::string & fieldName, T & value, const U & defaultValue) + template + void serializeId(const std::string & fieldName, IdentifierType & value, const IdentifierTypeBase & defaultValue = IdentifierType::NONE) { + static_assert(std::is_base_of_v, "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 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 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(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