fix broken merging of yaml overrides in maps; we now have a strict mode and a liberal mode.

This commit is contained in:
Chris Forbes
2011-04-09 10:54:49 +12:00
parent 7cd983a83b
commit ca81871b7b
7 changed files with 35 additions and 12 deletions

View File

@@ -29,7 +29,7 @@ namespace OpenRA.FileFormats
Mods = mods; Mods = mods;
var yaml = mods var yaml = mods
.Select(m => MiniYaml.FromFile("mods/" + m + "/mod.yaml")) .Select(m => MiniYaml.FromFile("mods/" + m + "/mod.yaml"))
.Aggregate(MiniYaml.Merge); .Aggregate(MiniYaml.MergeLiberal);
// Todo: Use fieldloader // Todo: Use fieldloader
Folders = YamlList(yaml, "Folders"); Folders = YamlList(yaml, "Folders");

View File

@@ -164,7 +164,17 @@ namespace OpenRA.FileFormats
return FromLines(text.Split(new[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries), "<no filename available>"); return FromLines(text.Split(new[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries), "<no filename available>");
} }
public static List<MiniYamlNode> Merge( List<MiniYamlNode> a, List<MiniYamlNode> b ) public static List<MiniYamlNode> MergeLiberal(List<MiniYamlNode> a, List<MiniYamlNode> b)
{
return Merge(a, b, false);
}
public static List<MiniYamlNode> MergeStrict(List<MiniYamlNode> a, List<MiniYamlNode> b)
{
return Merge(a, b, true);
}
static List<MiniYamlNode> Merge( List<MiniYamlNode> a, List<MiniYamlNode> b, bool throwErrors )
{ {
if( a.Count == 0 ) if( a.Count == 0 )
return b; return b;
@@ -188,18 +198,21 @@ namespace OpenRA.FileFormats
if( noInherit.ContainsKey( key ) ) if( noInherit.ContainsKey( key ) )
{ {
// if( aa != null ) if (!throwErrors)
// ret.Add( aa ); if (aa != null)
ret.Add(aa);
noInherit[key] = true; noInherit[key] = true;
} }
else else
{ {
var loc = aa == null ? default( MiniYamlNode.SourceLocation ) : aa.Location; var loc = aa == null ? default( MiniYamlNode.SourceLocation ) : aa.Location;
var merged = ( aa == null || bb == null ) ? aa ?? bb : new MiniYamlNode( key, Merge( aa.Value, bb.Value ), loc ); var merged = ( aa == null || bb == null ) ? aa ?? bb : new MiniYamlNode( key, Merge( aa.Value, bb.Value, throwErrors ), loc );
ret.Add( merged ); ret.Add( merged );
} }
} }
if (throwErrors)
if (noInherit.ContainsValue(false)) if (noInherit.ContainsValue(false))
throw new YamlException("Bogus yaml removals: {0}".F( throw new YamlException("Bogus yaml removals: {0}".F(
string.Join(", ", noInherit.Where(x => !x.Value).Select(x => x.Key).ToArray()))); string.Join(", ", noInherit.Where(x => !x.Value).Select(x => x.Key).ToArray())));
@@ -207,14 +220,24 @@ namespace OpenRA.FileFormats
return ret; return ret;
} }
public static MiniYaml Merge( MiniYaml a, MiniYaml b ) public static MiniYaml MergeLiberal(MiniYaml a, MiniYaml b)
{
return Merge(a, b, false);
}
public static MiniYaml MergeStrict(MiniYaml a, MiniYaml b)
{
return Merge(a, b, true);
}
static MiniYaml Merge( MiniYaml a, MiniYaml b, bool throwErrors )
{ {
if( a == null ) if( a == null )
return b; return b;
if( b == null ) if( b == null )
return a; return a;
return new MiniYaml( a.Value ?? b.Value, Merge( a.Nodes, b.Nodes ) ); return new MiniYaml( a.Value ?? b.Value, Merge( a.Nodes, b.Nodes, throwErrors ) );
} }
public IEnumerable<string> ToLines(string name) public IEnumerable<string> ToLines(string name)

View File

@@ -68,7 +68,7 @@ namespace OpenRA
var parent = GetParent( node, allUnits ); var parent = GetParent( node, allUnits );
if (parent != null) if (parent != null)
{ {
var result = MiniYaml.Merge(node, MergeWithParent(parent, allUnits)); var result = MiniYaml.MergeStrict(node, MergeWithParent(parent, allUnits));
// strip the '-' // strip the '-'
result.Nodes.RemoveAll(a => a.Key.StartsWith("-")); result.Nodes.RemoveAll(a => a.Key.StartsWith("-"));

View File

@@ -44,7 +44,7 @@ namespace OpenRA
static Dictionary<string, T> LoadYamlRules<T>(string[] files, List<MiniYamlNode> dict, Func<MiniYamlNode, Dictionary<string, MiniYaml>, T> f) static Dictionary<string, T> LoadYamlRules<T>(string[] files, List<MiniYamlNode> dict, Func<MiniYamlNode, Dictionary<string, MiniYaml>, T> f)
{ {
var y = files.Select(a => MiniYaml.FromFile(a)).Aggregate(dict,MiniYaml.Merge); var y = files.Select(a => MiniYaml.FromFile(a)).Aggregate(dict,MiniYaml.MergeLiberal);
var yy = y.ToDictionary( x => x.Key, x => x.Value ); var yy = y.ToDictionary( x => x.Key, x => x.Value );
return y.ToDictionary(kv => kv.Key.ToLowerInvariant(), kv => f(kv, yy)); return y.ToDictionary(kv => kv.Key.ToLowerInvariant(), kv => f(kv, yy));
} }

View File

@@ -36,7 +36,7 @@ namespace OpenRA.Graphics
if (chromeFiles.Length == 0) if (chromeFiles.Length == 0)
return; return;
var chrome = chromeFiles.Select(s => MiniYaml.FromFile(s)).Aggregate(MiniYaml.Merge); var chrome = chromeFiles.Select(s => MiniYaml.FromFile(s)).Aggregate(MiniYaml.MergeLiberal);
foreach (var c in chrome) foreach (var c in chrome)
LoadCollection(c.Key, c.Value); LoadCollection(c.Key, c.Value);

View File

@@ -24,7 +24,7 @@ namespace OpenRA.Graphics
public static void Initialize(string[] sequenceFiles) public static void Initialize(string[] sequenceFiles)
{ {
cursors = new Dictionary<string, CursorSequence>(); cursors = new Dictionary<string, CursorSequence>();
var sequences = new MiniYaml(null, sequenceFiles.Select(s => MiniYaml.FromFile(s)).Aggregate(MiniYaml.Merge)); var sequences = new MiniYaml(null, sequenceFiles.Select(s => MiniYaml.FromFile(s)).Aggregate(MiniYaml.MergeLiberal));
foreach (var s in sequences.NodesDict["Palettes"].Nodes) foreach (var s in sequences.NodesDict["Palettes"].Nodes)
Game.modData.Palette.AddPalette(s.Key, new Palette(FileSystem.Open(s.Value.Value), false)); Game.modData.Palette.AddPalette(s.Key, new Palette(FileSystem.Open(s.Value.Value), false));

View File

@@ -26,7 +26,7 @@ namespace OpenRA.Graphics
if (sequenceFiles.Length == 0) if (sequenceFiles.Length == 0)
return; return;
var sequences = sequenceFiles.Select(s => MiniYaml.FromFile(s)).Aggregate(sequenceNodes, MiniYaml.Merge); var sequences = sequenceFiles.Select(s => MiniYaml.FromFile(s)).Aggregate(sequenceNodes, MiniYaml.MergeLiberal);
foreach (var s in sequences) foreach (var s in sequences)
LoadSequencesForUnit(s.Key, s.Value); LoadSequencesForUnit(s.Key, s.Value);