瀏覽代碼

Fixed meta field handling in JsonUtils::inherit function, removed
workarounds

Ivan Savenko 2 年之前
父節點
當前提交
5cd405bce8
共有 3 個文件被更改,包括 21 次插入18 次删除
  1. 17 6
      lib/JsonNode.cpp
  2. 2 2
      lib/JsonNode.h
  3. 2 10
      lib/mapObjects/CObjectClassesHandler.cpp

+ 17 - 6
lib/JsonNode.cpp

@@ -1014,7 +1014,7 @@ const JsonNode & JsonUtils::getSchema(std::string URI)
 		return getSchemaByName(filename).resolvePointer(URI.substr(posHash + 1));
 }
 
-void JsonUtils::merge(JsonNode & dest, JsonNode & source, bool noOverride)
+void JsonUtils::merge(JsonNode & dest, JsonNode & source, bool ignoreOverride, bool copyMeta)
 {
 	if (dest.getType() == JsonNode::JsonType::DATA_NULL)
 	{
@@ -1022,6 +1022,14 @@ void JsonUtils::merge(JsonNode & dest, JsonNode & source, bool noOverride)
 		return;
 	}
 
+	bool hasNull = dest.isNull() || source.isNull();
+	bool sameType = dest.getType() == source.getType();
+	bool sourceNumeric = source.getType() == JsonNode::JsonType::DATA_FLOAT || source.getType() == JsonNode::JsonType::DATA_INTEGER;
+	bool destNumeric = dest.getType() == JsonNode::JsonType::DATA_FLOAT || dest.getType() == JsonNode::JsonType::DATA_INTEGER;
+	bool bothNumeric = sourceNumeric && destNumeric;
+
+	assert( hasNull || sameType || bothNumeric );
+
 	switch (source.getType())
 	{
 		case JsonNode::JsonType::DATA_NULL:
@@ -1040,30 +1048,33 @@ void JsonUtils::merge(JsonNode & dest, JsonNode & source, bool noOverride)
 		}
 		case JsonNode::JsonType::DATA_STRUCT:
 		{
-			if(!noOverride && vstd::contains(source.flags, "override"))
+			if(!ignoreOverride && vstd::contains(source.flags, "override"))
 			{
 				std::swap(dest, source);
 			}
 			else
 			{
+				if (copyMeta)
+					dest.meta = source.meta;
+
 				//recursively merge all entries from struct
 				for(auto & node : source.Struct())
-					merge(dest[node.first], node.second, noOverride);
+					merge(dest[node.first], node.second, ignoreOverride);
 			}
 		}
 	}
 }
 
-void JsonUtils::mergeCopy(JsonNode & dest, JsonNode source, bool noOverride)
+void JsonUtils::mergeCopy(JsonNode & dest, JsonNode source, bool ignoreOverride, bool copyMeta)
 {
 	// uses copy created in stack to safely merge two nodes
-	merge(dest, source, noOverride);
+	merge(dest, source, ignoreOverride, copyMeta);
 }
 
 void JsonUtils::inherit(JsonNode & descendant, const JsonNode & base)
 {
 	JsonNode inheritedNode(base);
-	merge(inheritedNode, descendant, true);
+	merge(inheritedNode, descendant, true, true);
 	descendant.swap(inheritedNode);
 }
 

+ 2 - 2
lib/JsonNode.h

@@ -184,7 +184,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, bool noOverride = false);
+	DLL_LINKAGE void merge(JsonNode & dest, JsonNode & source, bool ignoreOverride = false, bool copyMeta = false);
 
 	/**
 	 * @brief recursively merges source into dest, replacing identical fields
@@ -194,7 +194,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, bool noOverride = false);
+	DLL_LINKAGE void mergeCopy(JsonNode & dest, JsonNode source, bool ignoreOverride = false, bool copyMeta = false);
 
     /** @brief recursively merges descendant into copy of base node
      * Result emulates inheritance semantic

+ 2 - 10
lib/mapObjects/CObjectClassesHandler.cpp

@@ -360,17 +360,9 @@ void CObjectClassesHandler::beforeValidate(JsonNode & object)
 {
 	for (auto & entry : object["types"].Struct())
 	{
-		JsonNode base = object["base"];
-		base.setMeta(entry.second.meta);
-
-		JsonUtils::inherit(entry.second, base);
+		JsonUtils::inherit(entry.second, object["base"]);
 		for (auto & templ : entry.second["templates"].Struct())
-		{
-			JsonNode subBase = entry.second["base"];
-			subBase.setMeta(entry.second.meta);
-
-			JsonUtils::inherit(templ.second, subBase);
-		}
+			JsonUtils::inherit(templ.second, entry.second["base"]);
 	}
 }