Move yaml removals to the end of the merge.

This commit is contained in:
Paul Chote
2015-05-10 16:07:11 +01:00
committed by Oliver Brakmann
parent a074bb1d4b
commit c7249e6fa6
12 changed files with 83 additions and 74 deletions

View File

@@ -35,20 +35,16 @@ namespace OpenRA
{ {
try try
{ {
Name = name;
var allParents = new HashSet<string>(); var allParents = new HashSet<string>();
var abstractActorType = name.StartsWith("^"); var abstractActorType = name.StartsWith("^");
// Guard against circular inheritance // Guard against circular inheritance
allParents.Add(name); allParents.Add(name);
var mergedNode = MergeWithParents(node, allUnits, allParents).ToDictionary();
Name = name;
foreach (var t in mergedNode)
{
if (t.Key[0] == '-')
throw new YamlException("Bogus trait removal: " + t.Key);
var partial = MergeWithParents(node, allUnits, allParents);
foreach (var t in MiniYaml.ApplyRemovals(partial.Nodes))
if (t.Key != "Inherits" && !t.Key.StartsWith("Inherits@")) if (t.Key != "Inherits" && !t.Key.StartsWith("Inherits@"))
try try
{ {
@@ -60,7 +56,6 @@ namespace OpenRA
throw new YamlException(e.Message); throw new YamlException(e.Message);
} }
} }
}
catch (YamlException e) catch (YamlException e)
{ {
throw new YamlException("Actor type {0}: {1}".F(name, e.Message)); throw new YamlException("Actor type {0}: {1}".F(name, e.Message));
@@ -98,7 +93,7 @@ namespace OpenRA
throw new YamlException( throw new YamlException(
"Bogus inheritance -- duplicate inheritance of {0}.".F(kv.Key)); "Bogus inheritance -- duplicate inheritance of {0}.".F(kv.Key));
node = MiniYaml.Merge(node, MergeWithParents(kv.Value, allUnits, allParents)); node = MiniYaml.MergePartial(node, MergeWithParents(kv.Value, allUnits, allParents));
} }
return node; return node;

View File

@@ -99,7 +99,7 @@ namespace OpenRA
var inputKey = string.Concat(string.Join("|", files), "|", nodes.WriteToString()); var inputKey = string.Concat(string.Join("|", files), "|", nodes.WriteToString());
var mergedNodes = files var partial = files
.Select(s => MiniYaml.FromFile(s)) .Select(s => MiniYaml.FromFile(s))
.Aggregate(nodes, MiniYaml.MergePartial); .Aggregate(nodes, MiniYaml.MergePartial);
@@ -117,8 +117,8 @@ namespace OpenRA
return t; return t;
}; };
var yy = mergedNodes.ToDictionary(x => x.Key, x => x.Value); var yy = partial.ToDictionary(x => x.Key, x => x.Value);
var itemSet = mergedNodes.ToDictionaryWithConflictLog(kv => kv.Key.ToLowerInvariant(), kv => wrap(kv, yy), "LoadYamlRules", null, null); var itemSet = partial.ToDictionaryWithConflictLog(kv => kv.Key.ToLowerInvariant(), kv => wrap(kv, yy), "LoadYamlRules", null, null);
RaiseProgress(); RaiseProgress();
return itemSet; return itemSet;

View File

@@ -33,7 +33,11 @@ namespace OpenRA.Graphics
cachedSheets = new Dictionary<string, Sheet>(); cachedSheets = new Dictionary<string, Sheet>();
cachedSprites = new Dictionary<string, Dictionary<string, Sprite>>(); cachedSprites = new Dictionary<string, Dictionary<string, Sprite>>();
var chrome = chromeFiles.Select(s => MiniYaml.FromFile(s)).Aggregate(MiniYaml.MergePartial); var partial = chromeFiles
.Select(s => MiniYaml.FromFile(s))
.Aggregate(MiniYaml.MergePartial);
var chrome = MiniYaml.ApplyRemovals(partial);
foreach (var c in chrome) foreach (var c in chrome)
LoadCollection(c.Key, c.Value); LoadCollection(c.Key, c.Value);

View File

@@ -25,7 +25,11 @@ namespace OpenRA.Graphics
public CursorProvider(ModData modData) public CursorProvider(ModData modData)
{ {
var sequenceFiles = modData.Manifest.Cursors; var sequenceFiles = modData.Manifest.Cursors;
var sequences = new MiniYaml(null, sequenceFiles.Select(s => MiniYaml.FromFile(s)).Aggregate(MiniYaml.MergePartial)); var partial = sequenceFiles
.Select(s => MiniYaml.FromFile(s))
.Aggregate(MiniYaml.MergePartial);
var sequences = new MiniYaml(null, MiniYaml.ApplyRemovals(partial));
var shadowIndex = new int[] { }; var shadowIndex = new int[] { };
var nodesDict = sequences.ToDictionary(); var nodesDict = sequences.ToDictionary();

View File

@@ -127,10 +127,11 @@ namespace OpenRA.Graphics
{ {
var sequenceFiles = modData.Manifest.Sequences; var sequenceFiles = modData.Manifest.Sequences;
var nodes = sequenceFiles var partial = sequenceFiles
.Select(s => MiniYaml.FromFile(s)) .Select(s => MiniYaml.FromFile(s))
.Aggregate(sequenceNodes, MiniYaml.MergePartial); .Aggregate(sequenceNodes, MiniYaml.MergePartial);
var nodes = MiniYaml.ApplyRemovals(partial);
var items = new Dictionary<string, UnitSequences>(); var items = new Dictionary<string, UnitSequences>();
foreach (var n in nodes) foreach (var n in nodes)
{ {

View File

@@ -23,10 +23,11 @@ namespace OpenRA.Graphics
{ {
units = new Dictionary<string, Dictionary<string, Voxel>>(); units = new Dictionary<string, Dictionary<string, Voxel>>();
var sequences = voxelFiles var partial = voxelFiles
.Select(s => MiniYaml.FromFile(s)) .Select(s => MiniYaml.FromFile(s))
.Aggregate(voxelNodes, MiniYaml.MergePartial); .Aggregate(voxelNodes, MiniYaml.MergePartial);
var sequences = MiniYaml.ApplyRemovals(partial);
foreach (var s in sequences) foreach (var s in sequences)
LoadVoxelsForUnit(s.Key, s.Value); LoadVoxelsForUnit(s.Key, s.Value);

View File

@@ -264,15 +264,10 @@ namespace OpenRA
public static List<MiniYamlNode> Merge(List<MiniYamlNode> a, List<MiniYamlNode> b) public static List<MiniYamlNode> Merge(List<MiniYamlNode> a, List<MiniYamlNode> b)
{ {
return Merge(a, b, false); return ApplyRemovals(MergePartial(a, b));
} }
public static List<MiniYamlNode> MergePartial(List<MiniYamlNode> a, List<MiniYamlNode> b) public static List<MiniYamlNode> MergePartial(List<MiniYamlNode> a, List<MiniYamlNode> b)
{
return Merge(a, b, true);
}
static List<MiniYamlNode> Merge(List<MiniYamlNode> a, List<MiniYamlNode> b, bool allowUnresolvedRemoves = false)
{ {
if (a.Count == 0) if (a.Count == 0)
return b; return b;
@@ -286,58 +281,49 @@ namespace OpenRA
var dictB = b.ToDictionaryWithConflictLog(x => x.Key, "MiniYaml.Merge", null, x => "{0} (at {1})".F(x.Key, x.Location)); var dictB = b.ToDictionaryWithConflictLog(x => x.Key, "MiniYaml.Merge", null, x => "{0} (at {1})".F(x.Key, x.Location));
var allKeys = dictA.Keys.Union(dictB.Keys); var allKeys = dictA.Keys.Union(dictB.Keys);
var keys = allKeys.Where(x => x.Length == 0 || x[0] != '-').ToList(); foreach (var key in allKeys)
var removeKeys = allKeys.Where(x => x.Length > 0 && x[0] == '-')
.Select(k => k.Substring(1)).ToHashSet();
foreach (var key in keys)
{ {
MiniYamlNode aa, bb; MiniYamlNode aa, bb;
dictA.TryGetValue(key, out aa); dictA.TryGetValue(key, out aa);
dictB.TryGetValue(key, out bb); dictB.TryGetValue(key, out bb);
if (removeKeys.Contains(key))
removeKeys.Remove(key);
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, allowUnresolvedRemoves), loc); var merged = (aa == null || bb == null) ? aa ?? bb : new MiniYamlNode(key, MergePartial(aa.Value, bb.Value), loc);
ret.Add(merged); ret.Add(merged);
} }
}
return ret;
if (removeKeys.Any()) }
{
if (allowUnresolvedRemoves) public static List<MiniYamlNode> ApplyRemovals(List<MiniYamlNode> a)
{ {
// Add the removal nodes back for the next pass to deal with var removeKeys = a.Select(x => x.Key)
foreach (var k in removeKeys) .Where(x => x.Length > 0 && x[0] == '-')
{ .Select(k => k.Substring(1))
var key = "-" + k; .ToHashSet();
MiniYamlNode rem;
if (!dictA.TryGetValue(key, out rem)) var ret = new List<MiniYamlNode>();
rem = dictB[key]; foreach (var x in a)
ret.Add(rem); {
} if (x.Key[0] == '-')
} continue;
else
throw new YamlException("Bogus yaml removals: {0}".F(removeKeys.JoinWith(", "))); if (removeKeys.Contains(x.Key))
} removeKeys.Remove(x.Key);
else
{
x.Value.Nodes = ApplyRemovals(x.Value.Nodes);
ret.Add(x);
}
}
if (removeKeys.Any())
throw new YamlException("Bogus yaml removals: {0}".F(removeKeys.JoinWith(", ")));
return ret; return ret;
} }
public static MiniYaml MergePartial(MiniYaml a, MiniYaml b) public static MiniYaml MergePartial(MiniYaml a, MiniYaml b)
{
return Merge(a, b, true);
}
public static MiniYaml Merge(MiniYaml a, MiniYaml b)
{
return Merge(a, b, false);
}
static MiniYaml Merge(MiniYaml a, MiniYaml b, bool allowUnresolvedRemoves)
{ {
if (a == null) if (a == null)
return b; return b;
@@ -345,7 +331,18 @@ namespace OpenRA
if (b == null) if (b == null)
return a; return a;
return new MiniYaml(a.Value ?? b.Value, Merge(a.Nodes, b.Nodes, allowUnresolvedRemoves)); return new MiniYaml(a.Value ?? b.Value, MergePartial(a.Nodes, b.Nodes));
}
public static MiniYaml Merge(MiniYaml a, MiniYaml b)
{
if (a == null)
return b;
if (b == null)
return a;
return new MiniYaml(a.Value ?? b.Value, Merge(a.Nodes, b.Nodes));
} }
public IEnumerable<string> ToLines(string name) public IEnumerable<string> ToLines(string name)

View File

@@ -119,11 +119,10 @@ namespace OpenRA
return; return;
} }
var yaml = Manifest.Translations.Select(MiniYaml.FromFile).Aggregate(MiniYaml.MergePartial); var partial = Manifest.Translations.Select(MiniYaml.FromFile).Aggregate(MiniYaml.MergePartial);
Languages = yaml.Select(t => t.Key).ToArray(); Languages = partial.Select(t => t.Key).ToArray();
yaml = MiniYaml.MergePartial(map.TranslationDefinitions, yaml);
var yaml = MiniYaml.Merge(map.TranslationDefinitions, partial);
foreach (var y in yaml) foreach (var y in yaml)
{ {
if (y.Key == Game.Settings.Graphics.Language) if (y.Key == Game.Settings.Graphics.Language)

View File

@@ -20,9 +20,11 @@ namespace OpenRA.Widgets
public static void Initialize(IEnumerable<string> yaml) public static void Initialize(IEnumerable<string> yaml)
{ {
data = new Dictionary<string, string>(); data = new Dictionary<string, string>();
var metrics = yaml.Select(y => MiniYaml.FromFile(y)) var partial = yaml
.Select(y => MiniYaml.FromFile(y))
.Aggregate(MiniYaml.MergePartial); .Aggregate(MiniYaml.MergePartial);
var metrics = MiniYaml.ApplyRemovals(partial);
foreach (var m in metrics) foreach (var m in metrics)
foreach (var n in m.Value.Nodes) foreach (var n in m.Value.Nodes)
data[n.Key] = n.Value.Value; data[n.Key] = n.Value.Value;

View File

@@ -32,8 +32,10 @@ namespace OpenRA.Mods.Common.Lint
this.emitError = emitError; this.emitError = emitError;
var sequenceSource = map != null ? map.SequenceDefinitions : new List<MiniYamlNode>(); var sequenceSource = map != null ? map.SequenceDefinitions : new List<MiniYamlNode>();
sequenceDefinitions = MiniYaml.MergePartial(sequenceSource, var partial = Game.ModData.Manifest.Sequences
Game.ModData.Manifest.Sequences.Select(MiniYaml.FromFile).Aggregate(MiniYaml.MergePartial)); .Select(MiniYaml.FromFile)
.Aggregate(MiniYaml.MergePartial);
sequenceDefinitions = MiniYaml.Merge(sequenceSource, partial);
var rules = map == null ? Game.ModData.DefaultRules : map.Rules; var rules = map == null ? Game.ModData.DefaultRules : map.Rules;
var factions = rules.Actors["world"].TraitInfos<FactionInfo>().Select(f => f.InternalName).ToArray(); var factions = rules.Actors["world"].TraitInfos<FactionInfo>().Select(f => f.InternalName).ToArray();

View File

@@ -39,10 +39,11 @@ namespace OpenRA.Mods.Common.UtilityCommands
var sc = new SpriteCache(modData.SpriteLoaders, new SheetBuilder(SheetType.Indexed)); var sc = new SpriteCache(modData.SpriteLoaders, new SheetBuilder(SheetType.Indexed));
var sequenceFiles = modData.Manifest.Sequences; var sequenceFiles = modData.Manifest.Sequences;
var nodes = sequenceFiles var partial = sequenceFiles
.Select(s => MiniYaml.FromFile(s)) .Select(s => MiniYaml.FromFile(s))
.Aggregate(MiniYaml.MergePartial); .Aggregate(MiniYaml.MergePartial);
var nodes = MiniYaml.ApplyRemovals(partial);
foreach (var n in nodes) foreach (var n in nodes)
Game.ModData.SpriteSequenceLoader.ParseSequences(Game.ModData, ts, sc, n); Game.ModData.SpriteSequenceLoader.ParseSequences(Game.ModData, ts, sc, n);
} }

View File

@@ -97,8 +97,11 @@ namespace OpenRA.Mods.Common.Widgets.Logic
// Add a group for each campaign // Add a group for each campaign
if (Game.ModData.Manifest.Missions.Any()) if (Game.ModData.Manifest.Missions.Any())
{ {
var yaml = Game.ModData.Manifest.Missions.Select(MiniYaml.FromFile).Aggregate(MiniYaml.MergePartial); var partial = Game.ModData.Manifest.Missions
.Select(MiniYaml.FromFile)
.Aggregate(MiniYaml.MergePartial);
var yaml = MiniYaml.ApplyRemovals(partial);
foreach (var kv in yaml) foreach (var kv in yaml)
{ {
var missionMapPaths = kv.Value.Nodes.Select(n => Path.GetFullPath(n.Key)); var missionMapPaths = kv.Value.Nodes.Select(n => Path.GetFullPath(n.Key));