mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-12 02:28:11 +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:
parent
f126a34a5e
commit
4ee9d7f65a
@ -46,6 +46,8 @@ void JsonWriter::writeEntry(JsonMap::const_iterator entry)
|
||||
{
|
||||
if (!entry->second.meta.empty())
|
||||
out << prefix << " // " << entry->second.meta << "\n";
|
||||
if(!entry->second.flags.empty())
|
||||
out << prefix << " // flags: " << boost::algorithm::join(entry->second.flags, ", ") << "\n";
|
||||
out << prefix;
|
||||
}
|
||||
writeString(entry->first);
|
||||
@ -59,6 +61,8 @@ void JsonWriter::writeEntry(JsonVector::const_iterator entry)
|
||||
{
|
||||
if (!entry->meta.empty())
|
||||
out << prefix << " // " << entry->meta << "\n";
|
||||
if(!entry->flags.empty())
|
||||
out << prefix << " // flags: " << boost::algorithm::join(entry->flags, ", ") << "\n";
|
||||
out << prefix;
|
||||
}
|
||||
writeNode(*entry);
|
||||
@ -389,6 +393,18 @@ bool JsonParser::extractStruct(JsonNode &node)
|
||||
if (!extractString(key))
|
||||
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())
|
||||
error("Dublicated element encountered!", true);
|
||||
|
||||
@ -398,6 +414,10 @@ bool JsonParser::extractStruct(JsonNode &node)
|
||||
if (!extractElement(node.Struct()[key], '}'))
|
||||
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] == '}')
|
||||
{
|
||||
pos++;
|
||||
|
@ -70,7 +70,8 @@ JsonNode::JsonNode(ResourceID && fileURI, bool &isValidSyntax):
|
||||
|
||||
JsonNode::JsonNode(const JsonNode ©):
|
||||
type(JsonType::DATA_NULL),
|
||||
meta(copy.meta)
|
||||
meta(copy.meta),
|
||||
flags(copy.flags)
|
||||
{
|
||||
setType(copy.getType());
|
||||
switch(type)
|
||||
@ -96,6 +97,7 @@ void JsonNode::swap(JsonNode &b)
|
||||
swap(meta, b.meta);
|
||||
swap(data, b.data);
|
||||
swap(type, b.type);
|
||||
swap(flags, b.flags);
|
||||
}
|
||||
|
||||
JsonNode & JsonNode::operator =(JsonNode node)
|
||||
@ -846,7 +848,7 @@ const JsonNode & JsonUtils::getSchema(std::string URI)
|
||||
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)
|
||||
{
|
||||
@ -872,23 +874,30 @@ void JsonUtils::merge(JsonNode & dest, JsonNode & source)
|
||||
}
|
||||
case JsonNode::JsonType::DATA_STRUCT:
|
||||
{
|
||||
//recursively merge all entries from struct
|
||||
for(auto & node : source.Struct())
|
||||
merge(dest[node.first], node.second);
|
||||
if(!noOverride && vstd::contains(source.flags, "override"))
|
||||
{
|
||||
std::swap(dest, source);
|
||||
}
|
||||
else
|
||||
{
|
||||
//recursively merge all entries from struct
|
||||
for(auto & node : source.Struct())
|
||||
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
|
||||
merge(dest, source);
|
||||
merge(dest, source, noOverride);
|
||||
}
|
||||
|
||||
void JsonUtils::inherit(JsonNode & descendant, const JsonNode & base)
|
||||
{
|
||||
JsonNode inheritedNode(base);
|
||||
merge(inheritedNode,descendant);
|
||||
merge(inheritedNode, descendant, true);
|
||||
descendant.swap(inheritedNode);
|
||||
}
|
||||
|
||||
|
@ -45,8 +45,10 @@ private:
|
||||
JsonData data;
|
||||
|
||||
public:
|
||||
/// free to use metadata field
|
||||
/// free to use metadata fields
|
||||
std::string meta;
|
||||
// meta-flags like override
|
||||
std::vector<std::string> flags;
|
||||
|
||||
//Create empty node
|
||||
JsonNode(JsonType Type = JsonType::DATA_NULL);
|
||||
@ -119,6 +121,10 @@ public:
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & meta;
|
||||
if(version >= 782)
|
||||
{
|
||||
h & flags;
|
||||
}
|
||||
h & 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
|
||||
* @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
|
||||
@ -183,7 +189,7 @@ namespace JsonUtils
|
||||
* 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
|
||||
*/
|
||||
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
|
||||
* Result emulates inheritance semantic
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include "../ConstTransitivePtr.h"
|
||||
#include "../GameConstants.h"
|
||||
|
||||
const ui32 SERIALIZATION_VERSION = 781;
|
||||
const ui32 SERIALIZATION_VERSION = 782;
|
||||
const ui32 MINIMAL_SERIALIZATION_VERSION = 753;
|
||||
const std::string SAVEGAME_MAGIC = "VCMISVG";
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user