1
0
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:
AlexVinS 2016-02-23 16:36:21 +03:00
parent 8ed6aa762b
commit 17e557be17
8 changed files with 133 additions and 46 deletions

View File

@ -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
}

View File

@ -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)

View File

@ -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;
}
}
}

View File

@ -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);
};

View File

@ -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_):

View File

@ -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)

View File

@ -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));
}
}
}

View File

@ -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);
};