Merge pull request #5731 from RoosterDragon/sequence-initialize-fix

Fix #5452
This commit is contained in:
Matthias Mailänder
2014-06-25 20:15:08 +02:00

View File

@@ -15,9 +15,12 @@ using System.Linq;
namespace OpenRA.Graphics
{
using Sequences = IReadOnlyDictionary<string, Lazy<IReadOnlyDictionary<string, Sequence>>>;
using UnitSequences = Lazy<IReadOnlyDictionary<string, Sequence>>;
public class SequenceProvider
{
readonly Lazy<IReadOnlyDictionary<string, Lazy<IReadOnlyDictionary<string, Sequence>>>> sequences;
readonly Lazy<Sequences> sequences;
public readonly SpriteLoader SpriteLoader;
public SequenceProvider(SequenceCache cache, Map map)
@@ -28,7 +31,7 @@ namespace OpenRA.Graphics
public Sequence GetSequence(string unitName, string sequenceName)
{
Lazy<IReadOnlyDictionary<string, Sequence>> unitSeq;
UnitSequences unitSeq;
if (!sequences.Value.TryGetValue(unitName, out unitSeq))
throw new InvalidOperationException("Unit `{0}` does not have any sequences defined.".F(unitName));
@@ -41,7 +44,7 @@ namespace OpenRA.Graphics
public bool HasSequence(string unitName, string sequenceName)
{
Lazy<IReadOnlyDictionary<string, Sequence>> unitSeq;
UnitSequences unitSeq;
if (!sequences.Value.TryGetValue(unitName, out unitSeq))
throw new InvalidOperationException("Unit `{0}` does not have any sequences defined.".F(unitName));
@@ -50,7 +53,7 @@ namespace OpenRA.Graphics
public IEnumerable<string> Sequences(string unitName)
{
Lazy<IReadOnlyDictionary<string, Sequence>> unitSeq;
UnitSequences unitSeq;
if (!sequences.Value.TryGetValue(unitName, out unitSeq))
throw new InvalidOperationException("Unit `{0}` does not have any sequences defined.".F(unitName));
@@ -60,16 +63,7 @@ namespace OpenRA.Graphics
public void Preload()
{
foreach (var unitSeq in sequences.Value.Values)
{
try
{
foreach (var seq in unitSeq.Value.Values);
}
catch (FileNotFoundException ex)
{
Log.Write("debug", ex.Message);
}
}
foreach (var seq in unitSeq.Value.Values) { }
}
}
@@ -79,7 +73,7 @@ namespace OpenRA.Graphics
readonly Lazy<SpriteLoader> spriteLoader;
public SpriteLoader SpriteLoader { get { return spriteLoader.Value; } }
readonly Dictionary<string, Lazy<IReadOnlyDictionary<string, Sequence>>> sequenceCache = new Dictionary<string, Lazy<IReadOnlyDictionary<string, Sequence>>>();
readonly Dictionary<string, UnitSequences> sequenceCache = new Dictionary<string, UnitSequences>();
public SequenceCache(ModData modData, TileSet tileSet)
{
@@ -88,13 +82,13 @@ namespace OpenRA.Graphics
spriteLoader = Exts.Lazy(() => new SpriteLoader(tileSet.Extensions, new SheetBuilder(SheetType.Indexed)));
}
public IReadOnlyDictionary<string, Lazy<IReadOnlyDictionary<string, Sequence>>> LoadSequences(Map map)
public Sequences LoadSequences(Map map)
{
using (new Support.PerfTimer("LoadSequences"))
return Load(map.SequenceDefinitions);
}
IReadOnlyDictionary<string, Lazy<IReadOnlyDictionary<string, Sequence>>> Load(List<MiniYamlNode> sequenceNodes)
Sequences Load(List<MiniYamlNode> sequenceNodes)
{
var sequenceFiles = modData.Manifest.Sequences;
@@ -102,7 +96,7 @@ namespace OpenRA.Graphics
.Select(s => MiniYaml.FromFile(s))
.Aggregate(sequenceNodes, MiniYaml.MergeLiberal);
var items = new Dictionary<string, Lazy<IReadOnlyDictionary<string, Sequence>>>();
var items = new Dictionary<string, UnitSequences>();
foreach (var n in nodes)
{
// Work around the loop closure issue in older versions of C#
@@ -110,23 +104,40 @@ namespace OpenRA.Graphics
var key = node.Value.ToLines(node.Key).JoinWith("|");
Lazy<IReadOnlyDictionary<string, Sequence>> t;
UnitSequences t;
if (sequenceCache.TryGetValue(key, out t))
items.Add(node.Key, t);
else
{
t = Exts.Lazy(() => (IReadOnlyDictionary<string, Sequence>)new ReadOnlyDictionary<string, Sequence>(
node.Value.ToDictionary().ToDictionary(x => x.Key, x =>
{
using (new Support.PerfTimer("new Sequence(\"{0}\")".F(node.Key), 20))
return new Sequence(spriteLoader.Value, node.Key, x.Key, x.Value);
})));
t = Exts.Lazy(() => CreateUnitSequences(node));
sequenceCache.Add(key, t);
items.Add(node.Key, t);
}
}
return new ReadOnlyDictionary<string, Lazy<IReadOnlyDictionary<string, Sequence>>>(items);
return new ReadOnlyDictionary<string, UnitSequences>(items);
}
IReadOnlyDictionary<string, Sequence> CreateUnitSequences(MiniYamlNode node)
{
var unitSequences = new Dictionary<string, Sequence>();
foreach (var kvp in node.Value.ToDictionary())
{
using (new Support.PerfTimer("new Sequence(\"{0}\")".F(node.Key), 20))
{
try
{
unitSequences.Add(kvp.Key, new Sequence(spriteLoader.Value, node.Key, kvp.Key, kvp.Value));
}
catch (FileNotFoundException ex)
{
Log.Write("debug", ex.Message);
}
}
}
return new ReadOnlyDictionary<string, Sequence>(unitSequences);
}
}
}