Skip to content

Commit

Permalink
Bring back DeepCopy
Browse files Browse the repository at this point in the history
Apparently KSP's default implementation fails on badly formed nodes
  • Loading branch information
blowfishpro committed Sep 14, 2017
1 parent 8a81310 commit 5a468be
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 1 deletion.
13 changes: 13 additions & 0 deletions ModuleManager/Extensions/ConfigNodeExtensions.cs
Expand Up @@ -15,5 +15,18 @@ public static void ShallowCopyFrom(this ConfigNode toNode, ConfigNode fromeNode)
foreach (ConfigNode node in fromeNode.nodes)
toNode.nodes.Add(node);
}

public static ConfigNode DeepCopy(this ConfigNode from)
{
ConfigNode to = new ConfigNode(from.name);
foreach (ConfigNode.Value value in from.values)
to.AddValue(value.name, value.value);
foreach (ConfigNode node in from.nodes)
{
ConfigNode newNode = DeepCopy(node);
to.nodes.Add(newNode);
}
return to;
}
}
}
2 changes: 1 addition & 1 deletion ModuleManager/MMPatchLoader.cs
Expand Up @@ -1108,7 +1108,7 @@ public IEnumerator ApplyPatch(string Stage)
// it uses FindConfigNodeIn(src, nodeType, nodeName, nodeTag) to recurse.
public static ConfigNode ModifyNode(NodeStack original, ConfigNode mod, PatchContext context)
{
ConfigNode newNode = original.value.CreateCopy();
ConfigNode newNode = original.value.DeepCopy();
NodeStack nodeStack = original.ReplaceValue(newNode);

#region Values
Expand Down
62 changes: 62 additions & 0 deletions ModuleManagerTests/Extensions/ConfigNodeExtensionsTest.cs
Expand Up @@ -83,5 +83,67 @@ public void TestShallowCopyFrom()
Assert.Equal(0, innerNode2.nodes[0].values.Count);
Assert.Equal(0, innerNode2.nodes[0].nodes.Count);
}

[Fact]
public void TestDeepCopy()
{
ConfigNode fromNode = new TestConfigNode("SOME_NODE")
{
{ "abc", "def" },
{ "ghi", "jkl" },
new TestConfigNode("INNER_NODE_1")
{
{ "mno", "pqr" },
new TestConfigNode("INNER_INNER_NODE_1"),
},
new TestConfigNode("INNER_NODE_2")
{
{ "stu", "vwx" },
new TestConfigNode("INNER_INNER_NODE_2"),
},
};

ConfigNode toNode = fromNode.DeepCopy();

Assert.Equal("SOME_NODE", toNode.name);

Assert.Equal(2, toNode.values.Count);

Assert.NotSame(fromNode.values[0], toNode.values[0]);
Assert.Equal("abc", toNode.values[0].name);
Assert.Equal("def", toNode.values[0].value);

Assert.NotSame(fromNode.values[1], toNode.values[1]);
Assert.Equal("ghi", toNode.values[1].name);
Assert.Equal("jkl", toNode.values[1].value);

Assert.Equal(2, toNode.nodes.Count);

ConfigNode innerNode1 = toNode.nodes[0];
Assert.NotSame(fromNode.nodes[0], innerNode1);
Assert.Equal("INNER_NODE_1", innerNode1.name);
Assert.Equal(1, innerNode1.values.Count);
Assert.NotSame(fromNode.nodes[0].values[0], innerNode1.values[0]);
Assert.Equal("mno", innerNode1.values[0].name);
Assert.Equal("pqr", innerNode1.values[0].value);
Assert.Equal(1, toNode.nodes[0].nodes.Count);
Assert.NotSame(fromNode.nodes[0].nodes[0], innerNode1.nodes[0]);
Assert.Equal("INNER_INNER_NODE_1", innerNode1.nodes[0].name);
Assert.Equal(0, innerNode1.nodes[0].values.Count);
Assert.Equal(0, innerNode1.nodes[0].nodes.Count);

ConfigNode innerNode2 = toNode.nodes[1];
Assert.NotSame(fromNode.nodes[1], innerNode2);
Assert.Equal("INNER_NODE_2", innerNode2.name);
Assert.Equal(1, innerNode2.values.Count);
Assert.NotSame(fromNode.nodes[1].values[0], innerNode2.values[0]);
Assert.Equal("stu", innerNode2.values[0].name);
Assert.Equal("vwx", innerNode2.values[0].value);
Assert.Equal(1, innerNode2.nodes.Count);
Assert.NotSame(fromNode.nodes[1].nodes[0], innerNode2.nodes[0]);
Assert.Equal("INNER_INNER_NODE_2", innerNode2.nodes[0].name);
Assert.Equal(0, innerNode2.nodes[0].values.Count);
Assert.Equal(0, innerNode2.nodes[0].nodes.Count);
}
}
}

0 comments on commit 5a468be

Please sign in to comment.