mirror of
https://github.com/vcmi/vcmi.git
synced 2025-06-21 00:19:29 +02:00
Configure JSON merge behaviour via #override flag (#423)
* added json flags; override flag affects how structs are merged
This commit is contained in:
committed by
ArseniyShestakov
parent
f126a34a5e
commit
4ee9d7f65a
@ -46,6 +46,8 @@ void JsonWriter::writeEntry(JsonMap::const_iterator entry)
|
|||||||
{
|
{
|
||||||
if (!entry->second.meta.empty())
|
if (!entry->second.meta.empty())
|
||||||
out << prefix << " // " << entry->second.meta << "\n";
|
out << prefix << " // " << entry->second.meta << "\n";
|
||||||
|
if(!entry->second.flags.empty())
|
||||||
|
out << prefix << " // flags: " << boost::algorithm::join(entry->second.flags, ", ") << "\n";
|
||||||
out << prefix;
|
out << prefix;
|
||||||
}
|
}
|
||||||
writeString(entry->first);
|
writeString(entry->first);
|
||||||
@ -59,6 +61,8 @@ void JsonWriter::writeEntry(JsonVector::const_iterator entry)
|
|||||||
{
|
{
|
||||||
if (!entry->meta.empty())
|
if (!entry->meta.empty())
|
||||||
out << prefix << " // " << entry->meta << "\n";
|
out << prefix << " // " << entry->meta << "\n";
|
||||||
|
if(!entry->flags.empty())
|
||||||
|
out << prefix << " // flags: " << boost::algorithm::join(entry->flags, ", ") << "\n";
|
||||||
out << prefix;
|
out << prefix;
|
||||||
}
|
}
|
||||||
writeNode(*entry);
|
writeNode(*entry);
|
||||||
@ -389,6 +393,18 @@ bool JsonParser::extractStruct(JsonNode &node)
|
|||||||
if (!extractString(key))
|
if (!extractString(key))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// split key string into actual key and meta-flags
|
||||||
|
std::vector<std::string> keyAndFlags;
|
||||||
|
boost::split(keyAndFlags, key, boost::is_any_of("#"));
|
||||||
|
key = keyAndFlags[0];
|
||||||
|
// check for unknown flags - helps with debugging
|
||||||
|
std::vector<std::string> knownFlags = { "override" };
|
||||||
|
for(int i = 1; i < keyAndFlags.size(); i++)
|
||||||
|
{
|
||||||
|
if(!vstd::contains(knownFlags, keyAndFlags[i]))
|
||||||
|
error("Encountered unknown flag #" + keyAndFlags[i], true);
|
||||||
|
}
|
||||||
|
|
||||||
if (node.Struct().find(key) != node.Struct().end())
|
if (node.Struct().find(key) != node.Struct().end())
|
||||||
error("Dublicated element encountered!", true);
|
error("Dublicated element encountered!", true);
|
||||||
|
|
||||||
@ -398,6 +414,10 @@ bool JsonParser::extractStruct(JsonNode &node)
|
|||||||
if (!extractElement(node.Struct()[key], '}'))
|
if (!extractElement(node.Struct()[key], '}'))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// flags from key string belong to referenced element
|
||||||
|
for(int i = 1; i < keyAndFlags.size(); i++)
|
||||||
|
node.Struct()[key].flags.push_back(keyAndFlags[i]);
|
||||||
|
|
||||||
if (input[pos] == '}')
|
if (input[pos] == '}')
|
||||||
{
|
{
|
||||||
pos++;
|
pos++;
|
||||||
|
@ -70,7 +70,8 @@ JsonNode::JsonNode(ResourceID && fileURI, bool &isValidSyntax):
|
|||||||
|
|
||||||
JsonNode::JsonNode(const JsonNode ©):
|
JsonNode::JsonNode(const JsonNode ©):
|
||||||
type(JsonType::DATA_NULL),
|
type(JsonType::DATA_NULL),
|
||||||
meta(copy.meta)
|
meta(copy.meta),
|
||||||
|
flags(copy.flags)
|
||||||
{
|
{
|
||||||
setType(copy.getType());
|
setType(copy.getType());
|
||||||
switch(type)
|
switch(type)
|
||||||
@ -96,6 +97,7 @@ void JsonNode::swap(JsonNode &b)
|
|||||||
swap(meta, b.meta);
|
swap(meta, b.meta);
|
||||||
swap(data, b.data);
|
swap(data, b.data);
|
||||||
swap(type, b.type);
|
swap(type, b.type);
|
||||||
|
swap(flags, b.flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonNode & JsonNode::operator =(JsonNode node)
|
JsonNode & JsonNode::operator =(JsonNode node)
|
||||||
@ -846,7 +848,7 @@ const JsonNode & JsonUtils::getSchema(std::string URI)
|
|||||||
return getSchemaByName(filename).resolvePointer(URI.substr(posHash + 1));
|
return getSchemaByName(filename).resolvePointer(URI.substr(posHash + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonUtils::merge(JsonNode & dest, JsonNode & source)
|
void JsonUtils::merge(JsonNode & dest, JsonNode & source, bool noOverride)
|
||||||
{
|
{
|
||||||
if (dest.getType() == JsonNode::JsonType::DATA_NULL)
|
if (dest.getType() == JsonNode::JsonType::DATA_NULL)
|
||||||
{
|
{
|
||||||
@ -871,24 +873,31 @@ void JsonUtils::merge(JsonNode & dest, JsonNode & source)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case JsonNode::JsonType::DATA_STRUCT:
|
case JsonNode::JsonType::DATA_STRUCT:
|
||||||
|
{
|
||||||
|
if(!noOverride && vstd::contains(source.flags, "override"))
|
||||||
|
{
|
||||||
|
std::swap(dest, source);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
//recursively merge all entries from struct
|
//recursively merge all entries from struct
|
||||||
for(auto & node : source.Struct())
|
for(auto & node : source.Struct())
|
||||||
merge(dest[node.first], node.second);
|
merge(dest[node.first], node.second, noOverride);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonUtils::mergeCopy(JsonNode & dest, JsonNode source)
|
void JsonUtils::mergeCopy(JsonNode & dest, JsonNode source, bool noOverride)
|
||||||
{
|
{
|
||||||
// uses copy created in stack to safely merge two nodes
|
// uses copy created in stack to safely merge two nodes
|
||||||
merge(dest, source);
|
merge(dest, source, noOverride);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonUtils::inherit(JsonNode & descendant, const JsonNode & base)
|
void JsonUtils::inherit(JsonNode & descendant, const JsonNode & base)
|
||||||
{
|
{
|
||||||
JsonNode inheritedNode(base);
|
JsonNode inheritedNode(base);
|
||||||
merge(inheritedNode,descendant);
|
merge(inheritedNode, descendant, true);
|
||||||
descendant.swap(inheritedNode);
|
descendant.swap(inheritedNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,8 +45,10 @@ private:
|
|||||||
JsonData data;
|
JsonData data;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// free to use metadata field
|
/// free to use metadata fields
|
||||||
std::string meta;
|
std::string meta;
|
||||||
|
// meta-flags like override
|
||||||
|
std::vector<std::string> flags;
|
||||||
|
|
||||||
//Create empty node
|
//Create empty node
|
||||||
JsonNode(JsonType Type = JsonType::DATA_NULL);
|
JsonNode(JsonType Type = JsonType::DATA_NULL);
|
||||||
@ -119,6 +121,10 @@ public:
|
|||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
h & meta;
|
h & meta;
|
||||||
|
if(version >= 782)
|
||||||
|
{
|
||||||
|
h & flags;
|
||||||
|
}
|
||||||
h & type;
|
h & type;
|
||||||
switch(type)
|
switch(type)
|
||||||
{
|
{
|
||||||
@ -173,7 +179,7 @@ namespace JsonUtils
|
|||||||
* null : if value in source is present but set to null it will delete entry in dest
|
* null : if value in source is present but set to null it will delete entry in dest
|
||||||
* @note this function will destroy data in source
|
* @note this function will destroy data in source
|
||||||
*/
|
*/
|
||||||
DLL_LINKAGE void merge(JsonNode & dest, JsonNode & source);
|
DLL_LINKAGE void merge(JsonNode & dest, JsonNode & source, bool noOverride = false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief recursively merges source into dest, replacing identical fields
|
* @brief recursively merges source into dest, replacing identical fields
|
||||||
@ -183,7 +189,7 @@ namespace JsonUtils
|
|||||||
* null : if value in source is present but set to null it will delete entry in dest
|
* null : if value in source is present but set to null it will delete entry in dest
|
||||||
* @note this function will preserve data stored in source by creating copy
|
* @note this function will preserve data stored in source by creating copy
|
||||||
*/
|
*/
|
||||||
DLL_LINKAGE void mergeCopy(JsonNode & dest, JsonNode source);
|
DLL_LINKAGE void mergeCopy(JsonNode & dest, JsonNode source, bool noOverride = false);
|
||||||
|
|
||||||
/** @brief recursively merges descendant into copy of base node
|
/** @brief recursively merges descendant into copy of base node
|
||||||
* Result emulates inheritance semantic
|
* Result emulates inheritance semantic
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
#include "../ConstTransitivePtr.h"
|
#include "../ConstTransitivePtr.h"
|
||||||
#include "../GameConstants.h"
|
#include "../GameConstants.h"
|
||||||
|
|
||||||
const ui32 SERIALIZATION_VERSION = 781;
|
const ui32 SERIALIZATION_VERSION = 782;
|
||||||
const ui32 MINIMAL_SERIALIZATION_VERSION = 753;
|
const ui32 MINIMAL_SERIALIZATION_VERSION = 753;
|
||||||
const std::string SAVEGAME_MAGIC = "VCMISVG";
|
const std::string SAVEGAME_MAGIC = "VCMISVG";
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user