- Rename the filename parameter to name and make it mandatory. Review all callers and ensure a useful string is provided as input, to ensure sufficient context is included for logging and debugging. This can be a filename, url, or any arbitrary text so include whatever context seems reasonable. - When several MiniYamls are created that have similar content, provide a shared string pool. This allows strings that are common between all the yaml to be shared, reducing long term memory usage. We also change the pool from a dictionary to a set. Originally a Dictionary had to be used so we could call TryGetValue to get a reference to the pooled string. Now that more recent versions of dotnet provide a TryGetValue on HashSet, we can use a set directly without the memory wasted by having to store both keys and values in a dictionary.
68 lines
2.2 KiB
C#
68 lines
2.2 KiB
C#
#region Copyright & License Information
|
|
/*
|
|
* Copyright (c) The OpenRA Developers and Contributors
|
|
* This file is part of OpenRA, which is free software. It is made
|
|
* available to you under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation, either version 3 of
|
|
* the License, or (at your option) any later version. For more
|
|
* information, see COPYING.
|
|
*/
|
|
#endregion
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using OpenRA.Traits;
|
|
|
|
namespace OpenRA.Graphics
|
|
{
|
|
public sealed class CursorProvider
|
|
{
|
|
public readonly IReadOnlyDictionary<string, CursorSequence> Cursors;
|
|
public readonly IReadOnlyDictionary<string, ImmutablePalette> Palettes;
|
|
|
|
public CursorProvider(ModData modData)
|
|
{
|
|
var fileSystem = modData.DefaultFileSystem;
|
|
var stringPool = new HashSet<string>(); // Reuse common strings in YAML
|
|
var sequenceYaml = MiniYaml.Merge(modData.Manifest.Cursors.Select(
|
|
s => MiniYaml.FromStream(fileSystem.Open(s), s, stringPool: stringPool)));
|
|
|
|
var cursorsYaml = new MiniYaml(null, sequenceYaml).NodeWithKey("Cursors").Value;
|
|
|
|
// Overwrite previous definitions if there are duplicates
|
|
var pals = new Dictionary<string, IProvidesCursorPaletteInfo>();
|
|
foreach (var p in modData.DefaultRules.Actors[SystemActors.World].TraitInfos<IProvidesCursorPaletteInfo>())
|
|
if (p.Palette != null)
|
|
pals[p.Palette] = p;
|
|
|
|
Palettes = cursorsYaml.Nodes.Select(n => n.Value.Value)
|
|
.Where(p => p != null)
|
|
.Distinct()
|
|
.ToDictionary(p => p, p => pals[p].ReadPalette(modData.DefaultFileSystem));
|
|
|
|
var frameCache = new FrameCache(fileSystem, modData.SpriteLoaders);
|
|
var cursors = new Dictionary<string, CursorSequence>();
|
|
foreach (var s in cursorsYaml.Nodes)
|
|
foreach (var sequence in s.Value.Nodes)
|
|
cursors.Add(sequence.Key, new CursorSequence(frameCache, sequence.Key, s.Key, s.Value.Value, sequence.Value));
|
|
|
|
Cursors = cursors;
|
|
}
|
|
|
|
public bool HasCursorSequence(string cursor)
|
|
{
|
|
return Cursors.ContainsKey(cursor);
|
|
}
|
|
|
|
public CursorSequence GetCursorSequence(string cursor)
|
|
{
|
|
try { return Cursors[cursor]; }
|
|
catch (KeyNotFoundException)
|
|
{
|
|
throw new InvalidOperationException($"Cursor does not have a sequence `{cursor}`");
|
|
}
|
|
}
|
|
}
|
|
}
|