mirror of
https://github.com/vcmi/vcmi.git
synced 2025-09-16 09:26:28 +02:00
Advance Logical identifier condition
This commit is contained in:
@@ -1123,10 +1123,20 @@ void CGTownInstance::battleFinished(const CGHeroInstance *hero, const BattleResu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGTownInstance::serializeJsonOptions(JsonSerializeFormat& handler)
|
void CGTownInstance::serializeJsonOptions(JsonSerializeFormat & handler)
|
||||||
{
|
{
|
||||||
CGObjectInstance::serializeJsonOwner(handler);
|
CGObjectInstance::serializeJsonOwner(handler);
|
||||||
CCreatureSet::serializeJson(handler, "army");
|
CCreatureSet::serializeJson(handler, "army");
|
||||||
|
handler.serializeBool<ui8>("tightFormation", 1, 0, formation);
|
||||||
|
handler.serializeString("name", name);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if(!handler.saving)
|
||||||
|
{
|
||||||
|
builtBuildings.insert(BuildingID::DEFAULT);//just in case
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//todo: CGTownInstance::serializeJsonOptions
|
//todo: CGTownInstance::serializeJsonOptions
|
||||||
}
|
}
|
||||||
|
@@ -235,7 +235,7 @@ void CMapFormatJson::serializePlayerInfo(JsonSerializeFormat & handler)
|
|||||||
|
|
||||||
serializeAllowedFactions(handler, info.allowedFactions);
|
serializeAllowedFactions(handler, info.allowedFactions);
|
||||||
|
|
||||||
handler.serializeBoolEnum("canPlay", "PlayerOrAI", "AIOnly", info.canHumanPlay);
|
handler.serializeEnum("canPlay", "PlayerOrAI", "AIOnly", info.canHumanPlay);
|
||||||
|
|
||||||
//mainTown
|
//mainTown
|
||||||
if(handler.saving)
|
if(handler.saving)
|
||||||
|
@@ -25,7 +25,7 @@ void JsonDeserializer::serializeBool(const std::string & fieldName, bool & value
|
|||||||
value = current->operator[](fieldName).Bool();
|
value = current->operator[](fieldName).Bool();
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonDeserializer::serializeBoolEnum(const std::string & fieldName, const std::string & trueValue, const std::string & falseValue, bool & value)
|
void JsonDeserializer::serializeEnum(const std::string & fieldName, const std::string & trueValue, const std::string & falseValue, bool & value)
|
||||||
{
|
{
|
||||||
const JsonNode & tmp = current->operator[](fieldName);
|
const JsonNode & tmp = current->operator[](fieldName);
|
||||||
|
|
||||||
@@ -72,32 +72,11 @@ void JsonDeserializer::serializeLIC(const std::string & fieldName, const TDecode
|
|||||||
if(field.isNull())
|
if(field.isNull())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto loadPart = [&](const JsonVector & part, const bool val)
|
const JsonNode & anyOf = field["anyOf"];
|
||||||
{
|
const JsonNode & allOf = field["allOf"];
|
||||||
for(size_t index = 0; index < part.size(); index++)
|
const JsonNode & noneOf = field["noneOf"];
|
||||||
{
|
|
||||||
const std::string & identifier = part[index].String();
|
|
||||||
|
|
||||||
si32 rawId = decoder(identifier);
|
if(anyOf.Vector().empty() && allOf.Vector().empty())
|
||||||
if(rawId >= 0)
|
|
||||||
{
|
|
||||||
if(rawId < value.size())
|
|
||||||
value[rawId] = val;
|
|
||||||
else
|
|
||||||
logGlobal->errorStream() << "JsonDeserializer::serializeLIC: " << fieldName <<" id out of bounds " << rawId;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
logGlobal->errorStream() << "JsonDeserializer::serializeLIC: " << fieldName <<" identifier not resolved " << identifier;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const JsonVector & anyOf = field["anyOf"].Vector();
|
|
||||||
const JsonVector & allOf = field["allOf"].Vector();
|
|
||||||
const JsonVector & noneOf = field["noneOf"].Vector();
|
|
||||||
|
|
||||||
if(anyOf.empty() && allOf.empty())
|
|
||||||
{
|
{
|
||||||
//permissive mode
|
//permissive mode
|
||||||
value = standard;
|
value = standard;
|
||||||
@@ -108,11 +87,37 @@ void JsonDeserializer::serializeLIC(const std::string & fieldName, const TDecode
|
|||||||
value.clear();
|
value.clear();
|
||||||
value.resize(standard.size(), false);
|
value.resize(standard.size(), false);
|
||||||
|
|
||||||
loadPart(anyOf, true);
|
readLICPart(anyOf, decoder, true, value);
|
||||||
loadPart(allOf, true);
|
readLICPart(allOf, decoder, true, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
loadPart(noneOf, false);
|
readLICPart(noneOf, decoder, false, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void JsonDeserializer::serializeLIC(const std::string & fieldName, LIC & value)
|
||||||
|
{
|
||||||
|
const JsonNode & field = current->operator[](fieldName);
|
||||||
|
|
||||||
|
const JsonNode & anyOf = field["anyOf"];
|
||||||
|
const JsonNode & allOf = field["allOf"];
|
||||||
|
const JsonNode & noneOf = field["noneOf"];
|
||||||
|
|
||||||
|
if(anyOf.Vector().empty())
|
||||||
|
{
|
||||||
|
//permissive mode
|
||||||
|
value.any = value.standard;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//restrictive mode
|
||||||
|
value.any.clear();
|
||||||
|
value.any.resize(value.standard.size(), false);
|
||||||
|
|
||||||
|
readLICPart(anyOf, value.decoder, true, value.any);
|
||||||
|
}
|
||||||
|
|
||||||
|
readLICPart(allOf, value.decoder, true, value.all);
|
||||||
|
readLICPart(noneOf, value.decoder, true, value.none);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonDeserializer::serializeString(const std::string & fieldName, std::string & value)
|
void JsonDeserializer::serializeString(const std::string & fieldName, std::string & value)
|
||||||
@@ -120,3 +125,20 @@ void JsonDeserializer::serializeString(const std::string & fieldName, std::strin
|
|||||||
value = current->operator[](fieldName).String();
|
value = current->operator[](fieldName).String();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void JsonDeserializer::readLICPart(const JsonNode & part, const TDecoder & decoder, const bool val, std::vector<bool> & value)
|
||||||
|
{
|
||||||
|
for(size_t index = 0; index < part.Vector().size(); index++)
|
||||||
|
{
|
||||||
|
const std::string & identifier = part.Vector()[index].String();
|
||||||
|
|
||||||
|
const si32 rawId = decoder(identifier);
|
||||||
|
if(rawId >= 0)
|
||||||
|
{
|
||||||
|
if(rawId < value.size())
|
||||||
|
value[rawId] = val;
|
||||||
|
else
|
||||||
|
logGlobal->errorStream() << "JsonDeserializer::serializeLIC: id out of bounds " << rawId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -20,12 +20,15 @@ public:
|
|||||||
JsonDeserializer(JsonNode & root_);
|
JsonDeserializer(JsonNode & root_);
|
||||||
|
|
||||||
void serializeBool(const std::string & fieldName, bool & value) override;
|
void serializeBool(const std::string & fieldName, bool & value) override;
|
||||||
void serializeBoolEnum(const std::string & fieldName, const std::string & trueValue, const std::string & falseValue, bool & value) override;
|
void serializeEnum(const std::string & fieldName, const std::string & trueValue, const std::string & falseValue, bool & value) override;
|
||||||
void serializeLIC(const std::string & fieldName, const TDecoder & decoder, const TEncoder & encoder, const std::vector<bool> & standard, std::vector<bool> & value) override;
|
void serializeLIC(const std::string & fieldName, const TDecoder & decoder, const TEncoder & encoder, const std::vector<bool> & standard, std::vector<bool> & value) override;
|
||||||
|
void serializeLIC(const std::string & fieldName, LIC & value) override;
|
||||||
void serializeString(const std::string & fieldName, std::string & value) override;
|
void serializeString(const std::string & fieldName, std::string & value) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void serializeFloat(const std::string & fieldName, double & value) override;
|
void serializeFloat(const std::string & fieldName, double & value) override;
|
||||||
void serializeIntEnum(const std::string & fieldName, const std::vector<std::string> & enumMap, const si32 defaultValue, si32 & value) override;
|
void serializeIntEnum(const std::string & fieldName, const std::vector<std::string> & enumMap, const si32 defaultValue, si32 & value) override;
|
||||||
void serializeIntId(const std::string & fieldName, const TDecoder & decoder, const TEncoder & encoder, const si32 defaultValue, si32 & value) override;
|
void serializeIntId(const std::string & fieldName, const TDecoder & decoder, const TEncoder & encoder, const si32 defaultValue, si32 & value) override;
|
||||||
|
private:
|
||||||
|
void readLICPart(const JsonNode & part, const TDecoder & decoder, const bool val, std::vector<bool> & value);
|
||||||
};
|
};
|
||||||
|
@@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
#include "../JsonNode.h"
|
#include "../JsonNode.h"
|
||||||
|
|
||||||
|
|
||||||
//JsonStructSerializer
|
//JsonStructSerializer
|
||||||
JsonStructSerializer::JsonStructSerializer(JsonStructSerializer&& other):
|
JsonStructSerializer::JsonStructSerializer(JsonStructSerializer&& other):
|
||||||
restoreState(false),
|
restoreState(false),
|
||||||
@@ -48,7 +49,6 @@ JsonStructSerializer::JsonStructSerializer(JsonStructSerializer & parent, const
|
|||||||
owner.current = thisNode;
|
owner.current = thisNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
JsonStructSerializer JsonStructSerializer::enterStruct(const std::string & fieldName)
|
JsonStructSerializer JsonStructSerializer::enterStruct(const std::string & fieldName)
|
||||||
{
|
{
|
||||||
return JsonStructSerializer(*this, fieldName);
|
return JsonStructSerializer(*this, fieldName);
|
||||||
@@ -64,6 +64,14 @@ JsonSerializeFormat * JsonStructSerializer::operator->()
|
|||||||
return &owner;
|
return &owner;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JsonSerializeFormat::LIC::LIC(const std::vector<bool> & Standard, const TDecoder & Decoder, const TEncoder & Encoder):
|
||||||
|
standard(Standard), decoder(Decoder), encoder(Encoder)
|
||||||
|
{
|
||||||
|
any = standard;
|
||||||
|
all.resize(standard.size(), false);
|
||||||
|
none.resize(standard.size(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//JsonSerializeFormat
|
//JsonSerializeFormat
|
||||||
JsonSerializeFormat::JsonSerializeFormat(JsonNode & root_, const bool saving_):
|
JsonSerializeFormat::JsonSerializeFormat(JsonNode & root_, const bool saving_):
|
||||||
|
@@ -47,6 +47,16 @@ public:
|
|||||||
///may assume that object index is valid
|
///may assume that object index is valid
|
||||||
typedef std::function<std::string(si32)> TEncoder;
|
typedef std::function<std::string(si32)> TEncoder;
|
||||||
|
|
||||||
|
struct LIC
|
||||||
|
{
|
||||||
|
LIC(const std::vector<bool> & Standard, const TDecoder & Decoder, const TEncoder & Encoder);
|
||||||
|
|
||||||
|
const std::vector<bool> & standard;
|
||||||
|
const TDecoder & decoder;
|
||||||
|
const TEncoder & encoder;
|
||||||
|
std::vector<bool> all, any, none;
|
||||||
|
};
|
||||||
|
|
||||||
const bool saving;
|
const bool saving;
|
||||||
|
|
||||||
JsonSerializeFormat() = delete;
|
JsonSerializeFormat() = delete;
|
||||||
@@ -64,10 +74,20 @@ public:
|
|||||||
|
|
||||||
JsonStructSerializer enterStruct(const std::string & fieldName);
|
JsonStructSerializer enterStruct(const std::string & fieldName);
|
||||||
|
|
||||||
virtual void serializeBool(const std::string & fieldName, bool & value) = 0;
|
template <typename T>
|
||||||
virtual void serializeBoolEnum(const std::string & fieldName, const std::string & trueValue, const std::string & falseValue, bool & value) = 0;
|
void serializeBool(const std::string & fieldName, const T trueValue, const T falseValue, T & value)
|
||||||
|
{
|
||||||
|
bool temp = (value == trueValue);
|
||||||
|
serializeBool(fieldName, temp);
|
||||||
|
if(!saving)
|
||||||
|
value = temp ? trueValue : falseValue;
|
||||||
|
}
|
||||||
|
|
||||||
/** @brief Restrictive serialization of Logical identifier condition (only "anyOf" used), full deserialization
|
virtual void serializeBool(const std::string & fieldName, bool & value) = 0;
|
||||||
|
|
||||||
|
virtual void serializeEnum(const std::string & fieldName, const std::string & trueValue, const std::string & falseValue, bool & value) = 0;
|
||||||
|
|
||||||
|
/** @brief Restrictive ("anyOf") simple serialization of Logical identifier condition, simple deserialization (allOf=anyOf)
|
||||||
*
|
*
|
||||||
* @param fieldName
|
* @param fieldName
|
||||||
* @param decoder resolve callback, should report errors itself and do not throw
|
* @param decoder resolve callback, should report errors itself and do not throw
|
||||||
@@ -77,6 +97,9 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual void serializeLIC(const std::string & fieldName, const TDecoder & decoder, const TEncoder & encoder, const std::vector<bool> & standard, std::vector<bool> & value) = 0;
|
virtual void serializeLIC(const std::string & fieldName, const TDecoder & decoder, const TEncoder & encoder, const std::vector<bool> & standard, std::vector<bool> & value) = 0;
|
||||||
|
|
||||||
|
/** @brief Complete serialization of Logical identifier condition
|
||||||
|
*/
|
||||||
|
virtual void serializeLIC(const std::string & fieldName, LIC & value) = 0;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void serializeNumericEnum(const std::string & fieldName, const std::vector<std::string> & enumMap, const T defaultValue, T & value)
|
void serializeNumericEnum(const std::string & fieldName, const std::vector<std::string> & enumMap, const T defaultValue, T & value)
|
||||||
|
@@ -26,7 +26,7 @@ void JsonSerializer::serializeBool(const std::string & fieldName, bool & value)
|
|||||||
current->operator[](fieldName).Bool() = true;
|
current->operator[](fieldName).Bool() = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonSerializer::serializeBoolEnum(const std::string & fieldName, const std::string & trueValue, const std::string & falseValue, bool & value)
|
void JsonSerializer::serializeEnum(const std::string & fieldName, const std::string & trueValue, const std::string & falseValue, bool & value)
|
||||||
{
|
{
|
||||||
current->operator[](fieldName).String() = value ? trueValue : falseValue;
|
current->operator[](fieldName).String() = value ? trueValue : falseValue;
|
||||||
}
|
}
|
||||||
@@ -57,16 +57,19 @@ void JsonSerializer::serializeLIC(const std::string & fieldName, const TDecoder
|
|||||||
assert(standard.size() == value.size());
|
assert(standard.size() == value.size());
|
||||||
if(standard == value)
|
if(standard == value)
|
||||||
return;
|
return;
|
||||||
auto & target = current->operator[](fieldName)["anyOf"].Vector();
|
|
||||||
for(si32 idx = 0; idx < value.size(); idx ++)
|
writeLICPart(fieldName, "anyOf", encoder, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void JsonSerializer::serializeLIC(const std::string & fieldName, LIC & value)
|
||||||
|
{
|
||||||
|
if(value.any != value.standard)
|
||||||
{
|
{
|
||||||
if(value[idx])
|
writeLICPart(fieldName, "anyOf", value.encoder, value.any);
|
||||||
{
|
|
||||||
JsonNode val(JsonNode::DATA_STRING);
|
|
||||||
val.String() = encoder(idx);
|
|
||||||
target.push_back(std::move(val));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
writeLICPart(fieldName, "allOf", value.encoder, value.all);
|
||||||
|
writeLICPart(fieldName, "noneOf", value.encoder, value.none);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonSerializer::serializeString(const std::string & fieldName, std::string & value)
|
void JsonSerializer::serializeString(const std::string & fieldName, std::string & value)
|
||||||
@@ -75,3 +78,17 @@ void JsonSerializer::serializeString(const std::string & fieldName, std::string
|
|||||||
current->operator[](fieldName).String() = value;
|
current->operator[](fieldName).String() = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void JsonSerializer::writeLICPart(const std::string& fieldName, const std::string& partName, const TEncoder& encoder, const std::vector<bool> & data)
|
||||||
|
{
|
||||||
|
auto & target = current->operator[](fieldName)[partName].Vector();
|
||||||
|
for(si32 idx = 0; idx < data.size(); idx ++)
|
||||||
|
{
|
||||||
|
if(data[idx])
|
||||||
|
{
|
||||||
|
JsonNode val(JsonNode::DATA_STRING);
|
||||||
|
val.String() = encoder(idx);
|
||||||
|
target.push_back(std::move(val));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -20,12 +20,16 @@ public:
|
|||||||
JsonSerializer(JsonNode & root_);
|
JsonSerializer(JsonNode & root_);
|
||||||
|
|
||||||
void serializeBool(const std::string & fieldName, bool & value) override;
|
void serializeBool(const std::string & fieldName, bool & value) override;
|
||||||
void serializeBoolEnum(const std::string & fieldName, const std::string & trueValue, const std::string & falseValue, bool & value) override;
|
void serializeEnum(const std::string & fieldName, const std::string & trueValue, const std::string & falseValue, bool & value) override;
|
||||||
void serializeLIC(const std::string & fieldName, const TDecoder & decoder, const TEncoder & encoder, const std::vector<bool> & standard, std::vector<bool> & value) override;
|
void serializeLIC(const std::string & fieldName, const TDecoder & decoder, const TEncoder & encoder, const std::vector<bool> & standard, std::vector<bool> & value) override;
|
||||||
|
void serializeLIC(const std::string & fieldName, LIC & value) override;
|
||||||
void serializeString(const std::string & fieldName, std::string & value) override;
|
void serializeString(const std::string & fieldName, std::string & value) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void serializeFloat(const std::string & fieldName, double & value) override;
|
void serializeFloat(const std::string & fieldName, double & value) override;
|
||||||
void serializeIntEnum(const std::string & fieldName, const std::vector<std::string> & enumMap, const si32 defaultValue, si32 & value) override;
|
void serializeIntEnum(const std::string & fieldName, const std::vector<std::string> & enumMap, const si32 defaultValue, si32 & value) override;
|
||||||
void serializeIntId(const std::string & fieldName, const TDecoder & decoder, const TEncoder & encoder, const si32 defaultValue, si32 & value) override;
|
void serializeIntId(const std::string & fieldName, const TDecoder & decoder, const TEncoder & encoder, const si32 defaultValue, si32 & value) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void writeLICPart(const std::string & fieldName, const std::string & partName, const TEncoder & encoder, const std::vector<bool> & data);
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user