mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Advance Logical identifier condition
This commit is contained in:
parent
8ed6aa762b
commit
17e557be17
@ -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);
|
||||
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
|
||||
}
|
||||
|
@ -235,7 +235,7 @@ void CMapFormatJson::serializePlayerInfo(JsonSerializeFormat & handler)
|
||||
|
||||
serializeAllowedFactions(handler, info.allowedFactions);
|
||||
|
||||
handler.serializeBoolEnum("canPlay", "PlayerOrAI", "AIOnly", info.canHumanPlay);
|
||||
handler.serializeEnum("canPlay", "PlayerOrAI", "AIOnly", info.canHumanPlay);
|
||||
|
||||
//mainTown
|
||||
if(handler.saving)
|
||||
|
@ -25,7 +25,7 @@ void JsonDeserializer::serializeBool(const std::string & fieldName, bool & value
|
||||
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);
|
||||
|
||||
@ -72,32 +72,11 @@ void JsonDeserializer::serializeLIC(const std::string & fieldName, const TDecode
|
||||
if(field.isNull())
|
||||
return;
|
||||
|
||||
auto loadPart = [&](const JsonVector & part, const bool val)
|
||||
{
|
||||
for(size_t index = 0; index < part.size(); index++)
|
||||
{
|
||||
const std::string & identifier = part[index].String();
|
||||
const JsonNode & anyOf = field["anyOf"];
|
||||
const JsonNode & allOf = field["allOf"];
|
||||
const JsonNode & noneOf = field["noneOf"];
|
||||
|
||||
si32 rawId = decoder(identifier);
|
||||
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())
|
||||
if(anyOf.Vector().empty() && allOf.Vector().empty())
|
||||
{
|
||||
//permissive mode
|
||||
value = standard;
|
||||
@ -108,11 +87,37 @@ void JsonDeserializer::serializeLIC(const std::string & fieldName, const TDecode
|
||||
value.clear();
|
||||
value.resize(standard.size(), false);
|
||||
|
||||
loadPart(anyOf, true);
|
||||
loadPart(allOf, true);
|
||||
readLICPart(anyOf, decoder, true, value);
|
||||
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)
|
||||
@ -120,3 +125,20 @@ void JsonDeserializer::serializeString(const std::string & fieldName, std::strin
|
||||
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_);
|
||||
|
||||
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, LIC & value) override;
|
||||
void serializeString(const std::string & fieldName, std::string & value) override;
|
||||
|
||||
protected:
|
||||
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 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"
|
||||
|
||||
|
||||
//JsonStructSerializer
|
||||
JsonStructSerializer::JsonStructSerializer(JsonStructSerializer&& other):
|
||||
restoreState(false),
|
||||
@ -48,7 +49,6 @@ JsonStructSerializer::JsonStructSerializer(JsonStructSerializer & parent, const
|
||||
owner.current = thisNode;
|
||||
}
|
||||
|
||||
|
||||
JsonStructSerializer JsonStructSerializer::enterStruct(const std::string & fieldName)
|
||||
{
|
||||
return JsonStructSerializer(*this, fieldName);
|
||||
@ -64,6 +64,14 @@ JsonSerializeFormat * JsonStructSerializer::operator->()
|
||||
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(JsonNode & root_, const bool saving_):
|
||||
|
@ -47,6 +47,16 @@ public:
|
||||
///may assume that object index is valid
|
||||
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;
|
||||
|
||||
JsonSerializeFormat() = delete;
|
||||
@ -64,10 +74,20 @@ public:
|
||||
|
||||
JsonStructSerializer enterStruct(const std::string & fieldName);
|
||||
|
||||
virtual void serializeBool(const std::string & fieldName, bool & value) = 0;
|
||||
virtual void serializeBoolEnum(const std::string & fieldName, const std::string & trueValue, const std::string & falseValue, bool & value) = 0;
|
||||
template <typename T>
|
||||
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 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;
|
||||
|
||||
/** @brief Complete serialization of Logical identifier condition
|
||||
*/
|
||||
virtual void serializeLIC(const std::string & fieldName, LIC & value) = 0;
|
||||
|
||||
template <typename T>
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
@ -57,16 +57,19 @@ void JsonSerializer::serializeLIC(const std::string & fieldName, const TDecoder
|
||||
assert(standard.size() == value.size());
|
||||
if(standard == value)
|
||||
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])
|
||||
{
|
||||
JsonNode val(JsonNode::DATA_STRING);
|
||||
val.String() = encoder(idx);
|
||||
target.push_back(std::move(val));
|
||||
}
|
||||
writeLICPart(fieldName, "anyOf", value.encoder, value.any);
|
||||
}
|
||||
|
||||
writeLICPart(fieldName, "allOf", value.encoder, value.all);
|
||||
writeLICPart(fieldName, "noneOf", value.encoder, value.none);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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_);
|
||||
|
||||
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, LIC & value) override;
|
||||
void serializeString(const std::string & fieldName, std::string & value) override;
|
||||
|
||||
protected:
|
||||
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 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);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user