Use IReadOnlyFileSystem in artwork loaders.

This commit is contained in:
Paul Chote
2016-02-15 01:04:00 +00:00
parent a1bc70cb58
commit b347fade71
15 changed files with 70 additions and 66 deletions

View File

@@ -11,6 +11,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using OpenRA.FileSystem;
using OpenRA.GameRules;
using OpenRA.Graphics;
using OpenRA.Support;
@@ -47,7 +48,7 @@ namespace OpenRA
/// Cache and return the Ruleset for a given map.
/// If a map isn't specified then return the default mod Ruleset.
/// </summary>
public Ruleset Load(Map map = null)
public Ruleset Load(IReadOnlyFileSystem fileSystem, Map map = null)
{
var m = modData.Manifest;
@@ -59,38 +60,38 @@ namespace OpenRA
Dictionary<string, TileSet> tileSets;
using (new PerfTimer("Actors"))
actors = LoadYamlRules(actorCache, m.Rules,
actors = LoadYamlRules(fileSystem, actorCache, m.Rules,
map != null ? map.RuleDefinitions : NoMapRules,
k => new ActorInfo(Game.ModData.ObjectCreator, k.Key.ToLowerInvariant(), k.Value));
using (new PerfTimer("Weapons"))
weapons = LoadYamlRules(weaponCache, m.Weapons,
weapons = LoadYamlRules(fileSystem, weaponCache, m.Weapons,
map != null ? map.WeaponDefinitions : NoMapRules,
k => new WeaponInfo(k.Key.ToLowerInvariant(), k.Value));
using (new PerfTimer("Voices"))
voices = LoadYamlRules(voiceCache, m.Voices,
voices = LoadYamlRules(fileSystem, voiceCache, m.Voices,
map != null ? map.VoiceDefinitions : NoMapRules,
k => new SoundInfo(k.Value));
using (new PerfTimer("Notifications"))
notifications = LoadYamlRules(notificationCache, m.Notifications,
notifications = LoadYamlRules(fileSystem, notificationCache, m.Notifications,
map != null ? map.NotificationDefinitions : NoMapRules,
k => new SoundInfo(k.Value));
using (new PerfTimer("Music"))
music = LoadYamlRules(musicCache, m.Music,
music = LoadYamlRules(fileSystem, musicCache, m.Music,
map != null ? map.MusicDefinitions : NoMapRules,
k => new MusicInfo(k.Key, k.Value));
using (new PerfTimer("TileSets"))
tileSets = LoadTileSets(tileSetCache, sequenceCaches, m.TileSets);
tileSets = LoadTileSets(fileSystem, tileSetCache, sequenceCaches, m.TileSets);
var sequences = sequenceCaches.ToDictionary(kvp => kvp.Key, kvp => new SequenceProvider(kvp.Value, map));
var sequences = sequenceCaches.ToDictionary(kvp => kvp.Key, kvp => new SequenceProvider(fileSystem, kvp.Value, map));
return new Ruleset(actors, weapons, voices, notifications, music, tileSets, sequences);
}
Dictionary<string, T> LoadYamlRules<T>(
Dictionary<string, T> LoadYamlRules<T>(IReadOnlyFileSystem fileSystem,
Dictionary<string, T> itemCache,
string[] files, List<MiniYamlNode> nodes,
Func<MiniYamlNode, T> f)
@@ -112,7 +113,7 @@ namespace OpenRA
return t;
};
var tree = MiniYaml.Merge(files.Select(s => MiniYaml.FromStream(modData.ModFiles.Open(s))).Append(nodes))
var tree = MiniYaml.Merge(files.Select(s => MiniYaml.FromStream(fileSystem.Open(s))).Append(nodes))
.ToDictionaryWithConflictLog(n => n.Key, n => n.Value, "LoadYamlRules", null, null);
RaiseProgress();
@@ -121,7 +122,7 @@ namespace OpenRA
return itemSet;
}
Dictionary<string, TileSet> LoadTileSets(Dictionary<string, TileSet> itemCache, Dictionary<string, SequenceCache> sequenceCaches, string[] files)
Dictionary<string, TileSet> LoadTileSets(IReadOnlyFileSystem fileSystem, Dictionary<string, TileSet> itemCache, Dictionary<string, SequenceCache> sequenceCaches, string[] files)
{
var items = new Dictionary<string, TileSet>();
@@ -136,7 +137,7 @@ namespace OpenRA
itemCache.Add(file, t);
// every time we load a tile set, we create a sequence cache for it
var sc = new SequenceCache(modData, t);
var sc = new SequenceCache(modData, fileSystem, t);
sequenceCaches.Add(t.Id, sc);
items.Add(t.Id, t);

View File

@@ -21,8 +21,9 @@ namespace OpenRA.Graphics
public CursorProvider(ModData modData)
{
var fileSystem = modData.DefaultFileSystem;
var sequenceYaml = MiniYaml.Merge(modData.Manifest.Cursors.Select(
s => MiniYaml.FromStream(modData.ModFiles.Open(s))));
s => MiniYaml.FromStream(fileSystem.Open(s))));
var shadowIndex = new int[] { };
@@ -36,11 +37,11 @@ namespace OpenRA.Graphics
var palettes = new Dictionary<string, ImmutablePalette>();
foreach (var p in nodesDict["Palettes"].Nodes)
palettes.Add(p.Key, new ImmutablePalette(modData.ModFiles.Open(p.Value.Value), shadowIndex));
palettes.Add(p.Key, new ImmutablePalette(fileSystem.Open(p.Value.Value), shadowIndex));
Palettes = palettes.AsReadOnly();
var frameCache = new FrameCache(modData.SpriteLoaders);
var frameCache = new FrameCache(fileSystem, modData.SpriteLoaders);
var cursors = new Dictionary<string, CursorSequence>();
foreach (var s in nodesDict["Cursors"].Nodes)
foreach (var sequence in s.Value.Nodes)

View File

@@ -11,6 +11,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using OpenRA.FileSystem;
namespace OpenRA.Graphics
{
@@ -46,9 +47,9 @@ namespace OpenRA.Graphics
readonly Lazy<Sequences> sequences;
public readonly SpriteCache SpriteCache;
public SequenceProvider(SequenceCache cache, Map map)
public SequenceProvider(IReadOnlyFileSystem fileSystem, SequenceCache cache, Map map)
{
sequences = Exts.Lazy(() => cache.LoadSequences(map));
sequences = Exts.Lazy(() => cache.LoadSequences(fileSystem, map));
SpriteCache = cache.SpriteCache;
}
@@ -106,25 +107,25 @@ namespace OpenRA.Graphics
readonly Dictionary<string, UnitSequences> sequenceCache = new Dictionary<string, UnitSequences>();
public SequenceCache(ModData modData, TileSet tileSet)
public SequenceCache(ModData modData, IReadOnlyFileSystem fileSystem, TileSet tileSet)
{
this.modData = modData;
this.tileSet = tileSet;
// Every time we load a tile set, we create a sequence cache for it
spriteCache = Exts.Lazy(() => new SpriteCache(modData.SpriteLoaders, new SheetBuilder(SheetType.Indexed)));
spriteCache = Exts.Lazy(() => new SpriteCache(fileSystem, modData.SpriteLoaders, new SheetBuilder(SheetType.Indexed)));
}
public Sequences LoadSequences(Map map)
public Sequences LoadSequences(IReadOnlyFileSystem fileSystem, Map map)
{
using (new Support.PerfTimer("LoadSequences"))
return Load(map != null ? map.SequenceDefinitions : new List<MiniYamlNode>());
return Load(fileSystem, map != null ? map.SequenceDefinitions : new List<MiniYamlNode>());
}
Sequences Load(List<MiniYamlNode> sequenceNodes)
Sequences Load(IReadOnlyFileSystem fileSystem, List<MiniYamlNode> sequenceNodes)
{
var nodes = MiniYaml.Merge(modData.Manifest.Sequences
.Select(s => MiniYaml.FromStream(modData.ModFiles.Open(s)))
.Select(s => MiniYaml.FromStream(fileSystem.Open(s)))
.Append(sequenceNodes));
var items = new Dictionary<string, UnitSequences>();

View File

@@ -11,6 +11,7 @@
using System.Drawing;
using System.IO;
using System.Linq;
using OpenRA.FileSystem;
using OpenRA.Primitives;
namespace OpenRA.Graphics
@@ -34,11 +35,11 @@ namespace OpenRA.Graphics
public readonly SheetBuilder SheetBuilder;
readonly Cache<string, Sprite[]> sprites;
public SpriteCache(ISpriteLoader[] loaders, SheetBuilder sheetBuilder)
public SpriteCache(IReadOnlyFileSystem fileSystem, ISpriteLoader[] loaders, SheetBuilder sheetBuilder)
{
SheetBuilder = sheetBuilder;
sprites = new Cache<string, Sprite[]>(filename => SpriteLoader.GetSprites(filename, loaders, sheetBuilder));
sprites = new Cache<string, Sprite[]>(filename => SpriteLoader.GetSprites(fileSystem, filename, loaders, sheetBuilder));
}
public Sprite[] this[string filename] { get { return sprites[filename]; } }
@@ -48,9 +49,9 @@ namespace OpenRA.Graphics
{
readonly Cache<string, ISpriteFrame[]> frames;
public FrameCache(ISpriteLoader[] loaders)
public FrameCache(IReadOnlyFileSystem fileSystem, ISpriteLoader[] loaders)
{
frames = new Cache<string, ISpriteFrame[]>(filename => SpriteLoader.GetFrames(filename, loaders));
frames = new Cache<string, ISpriteFrame[]>(filename => SpriteLoader.GetFrames(fileSystem, filename, loaders));
}
public ISpriteFrame[] this[string filename] { get { return frames[filename]; } }
@@ -58,14 +59,14 @@ namespace OpenRA.Graphics
public static class SpriteLoader
{
public static Sprite[] GetSprites(string filename, ISpriteLoader[] loaders, SheetBuilder sheetBuilder)
public static Sprite[] GetSprites(IReadOnlyFileSystem fileSystem, string filename, ISpriteLoader[] loaders, SheetBuilder sheetBuilder)
{
return GetFrames(filename, loaders).Select(a => sheetBuilder.Add(a)).ToArray();
return GetFrames(fileSystem, filename, loaders).Select(a => sheetBuilder.Add(a)).ToArray();
}
public static ISpriteFrame[] GetFrames(string filename, ISpriteLoader[] loaders)
public static ISpriteFrame[] GetFrames(IReadOnlyFileSystem fileSystem, string filename, ISpriteLoader[] loaders)
{
using (var stream = Game.ModData.ModFiles.Open(filename))
using (var stream = fileSystem.Open(filename))
{
ISpriteFrame[] frames;
foreach (var loader in loaders)

View File

@@ -56,7 +56,7 @@ namespace OpenRA.Graphics
sheetBuilder = new SheetBuilder(type, allocate);
random = new MersenneTwister();
var frameCache = new FrameCache(Game.ModData.SpriteLoaders);
var frameCache = new FrameCache(Game.ModData.DefaultFileSystem, Game.ModData.SpriteLoaders);
foreach (var t in tileset.Templates)
{
var variants = new List<Sprite[]>();

View File

@@ -372,7 +372,7 @@ namespace OpenRA
{
try
{
return Game.ModData.RulesetCache.Load(this);
return Game.ModData.RulesetCache.Load(Game.ModData.DefaultFileSystem, this);
}
catch (Exception e)
{

View File

@@ -72,7 +72,7 @@ namespace OpenRA
SpriteSequenceLoader = (ISpriteSequenceLoader)ctor.Invoke(new[] { this });
SpriteSequenceLoader.OnMissingSpriteError = s => Log.Write("debug", s);
defaultRules = Exts.Lazy(() => RulesetCache.Load());
defaultRules = Exts.Lazy(() => RulesetCache.Load(DefaultFileSystem));
initialThreadId = System.Threading.Thread.CurrentThread.ManagedThreadId;
}

View File

@@ -36,8 +36,8 @@ namespace OpenRA.Mods.Common.UtilityCommands
{
var ts = new TileSet(modData, t);
Console.WriteLine("Tileset: " + ts.Name);
var sc = new SpriteCache(modData.SpriteLoaders, new SheetBuilder(SheetType.Indexed));
var nodes = MiniYaml.Merge(modData.Manifest.Sequences.Select(s => MiniYaml.FromStream(modData.ModFiles.Open(s))));
var sc = new SpriteCache(modData.DefaultFileSystem, modData.SpriteLoaders, new SheetBuilder(SheetType.Indexed));
var nodes = MiniYaml.Merge(modData.Manifest.Sequences.Select(s => MiniYaml.FromStream(modData.DefaultFileSystem.Open(s))));
foreach (var n in nodes)
modData.SpriteSequenceLoader.ParseSequences(modData, ts, sc, n);
}

View File

@@ -56,17 +56,17 @@ namespace OpenRA.Mods.Common.UtilityCommands
var maps = new List<Map>();
if (args.Length < 2)
{
Console.WriteLine("Testing mod: {0}".F(Game.ModData.Manifest.Mod.Title));
Console.WriteLine("Testing mod: {0}".F(modData.Manifest.Mod.Title));
// Run all rule checks on the default mod rules.
CheckRules(Game.ModData.DefaultRules);
CheckRules(modData, modData.DefaultRules);
// Run all generic (not mod-level) checks here.
foreach (var customPassType in Game.ModData.ObjectCreator.GetTypesImplementing<ILintPass>())
foreach (var customPassType in modData.ObjectCreator.GetTypesImplementing<ILintPass>())
{
try
{
var customPass = (ILintPass)Game.ModData.ObjectCreator.CreateBasic(customPassType);
var customPass = (ILintPass)modData.ObjectCreator.CreateBasic(customPassType);
customPass.Run(EmitError, EmitWarning);
}
catch (Exception e)
@@ -75,8 +75,8 @@ namespace OpenRA.Mods.Common.UtilityCommands
}
}
Game.ModData.MapCache.LoadMaps();
maps.AddRange(Game.ModData.MapCache
modData.MapCache.LoadMaps();
maps.AddRange(modData.MapCache
.Where(m => m.Status == MapStatus.Available)
.Select(m => new Map(m.Path)));
}
@@ -90,14 +90,14 @@ namespace OpenRA.Mods.Common.UtilityCommands
// Run all rule checks on the map if it defines custom rules.
if (testMap.RuleDefinitions.Any() || testMap.VoiceDefinitions.Any() || testMap.WeaponDefinitions.Any())
CheckRules(testMap.Rules, testMap);
CheckRules(modData, testMap.Rules, testMap);
// Run all map-level checks here.
foreach (var customMapPassType in Game.ModData.ObjectCreator.GetTypesImplementing<ILintMapPass>())
foreach (var customMapPassType in modData.ObjectCreator.GetTypesImplementing<ILintMapPass>())
{
try
{
var customMapPass = (ILintMapPass)Game.ModData.ObjectCreator.CreateBasic(customMapPassType);
var customMapPass = (ILintMapPass)modData.ObjectCreator.CreateBasic(customMapPassType);
customMapPass.Run(EmitError, EmitWarning, testMap);
}
catch (Exception e)
@@ -120,14 +120,14 @@ namespace OpenRA.Mods.Common.UtilityCommands
}
}
void CheckRules(Ruleset rules, Map map = null)
void CheckRules(ModData modData, Ruleset rules, Map map = null)
{
foreach (var customRulesPassType in Game.ModData.ObjectCreator.GetTypesImplementing<ILintRulesPass>())
foreach (var customRulesPassType in modData.ObjectCreator.GetTypesImplementing<ILintRulesPass>())
{
try
{
Game.ModData.RulesetCache.Load(map);
var customRulesPass = (ILintRulesPass)Game.ModData.ObjectCreator.CreateBasic(customRulesPassType);
modData.RulesetCache.Load(modData.DefaultFileSystem, map);
var customRulesPass = (ILintRulesPass)modData.ObjectCreator.CreateBasic(customRulesPassType);
customRulesPass.Run(EmitError, EmitWarning, rules);
}
catch (Exception e)

View File

@@ -46,7 +46,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
var palette = new ImmutablePalette(args[2], shadowIndex);
var frames = SpriteLoader.GetFrames(src, modData.SpriteLoaders);
var frames = SpriteLoader.GetFrames(modData.DefaultFileSystem, src, modData.SpriteLoaders);
var usePadding = !args.Contains("--nopadding");
var count = 0;

View File

@@ -29,13 +29,13 @@ namespace OpenRA.Mods.Common.UtilityCommands
{
// HACK: The engine code assumes that Game.modData is set.
Game.ModData = modData;
Game.ModData.RulesetCache.Load();
modData.RulesetCache.Load(modData.DefaultFileSystem);
var types = Game.ModData.ObjectCreator.GetTypes();
var translatableFields = types.SelectMany(t => t.GetFields())
.Where(f => f.HasAttribute<TranslateAttribute>()).Distinct();
foreach (var filename in Game.ModData.Manifest.ChromeLayout)
foreach (var filename in modData.Manifest.ChromeLayout)
{
Console.WriteLine("# {0}:", filename);
var yaml = MiniYaml.FromFile(filename);

View File

@@ -31,7 +31,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
{
// HACK: The engine code assumes that Game.modData is set.
Game.ModData = modData;
modData.ModFiles.LoadFromManifest(Game.ModData.Manifest);
modData.ModFiles.LoadFromManifest(modData.Manifest);
var imageField = typeof(TerrainTemplateInfo).GetField("Image");
var pickAnyField = typeof(TerrainTemplateInfo).GetField("PickAny");
@@ -43,10 +43,10 @@ namespace OpenRA.Mods.Common.UtilityCommands
var single = new int2(1, 1);
var exts = new[] { "" }.Concat(args[1].Split(','));
foreach (var t in Game.ModData.Manifest.TileSets)
foreach (var t in modData.Manifest.TileSets)
{
var ts = new TileSet(Game.ModData, t);
var frameCache = new FrameCache(Game.ModData.SpriteLoaders);
var ts = new TileSet(modData, t);
var frameCache = new FrameCache(modData.DefaultFileSystem, modData.SpriteLoaders);
Console.WriteLine("Tileset: " + ts.Name);
foreach (var template in ts.Templates.Values)

View File

@@ -45,10 +45,10 @@ namespace OpenRA.Mods.Common.UtilityCommands
// HACK: The engine code assumes that Game.modData is set.
Game.ModData = modData;
Rules = Game.ModData.RulesetCache.Load();
Rules = modData.RulesetCache.Load(modData.DefaultFileSystem);
var filename = args[1];
using (var stream = Game.ModData.ModFiles.Open(filename))
using (var stream = modData.ModFiles.Open(filename))
{
var file = new IniFile(stream);
var basic = file.GetSection("Basic");
@@ -66,7 +66,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
Map.Description = ExtractBriefing(file);
Map.RequiresMod = Game.ModData.Manifest.Mod.Id;
Map.RequiresMod = modData.Manifest.Mod.Id;
SetBounds(Map, mapSection);

View File

@@ -38,17 +38,17 @@ namespace OpenRA.Mods.Common.UtilityCommands
remap[i] = i;
var srcMod = args[1].Split(':')[0];
var srcModData = new ModData(srcMod);
Game.ModData = srcModData;
Game.ModData = new ModData(srcMod);
Game.ModData.ModFiles.LoadFromManifest(Game.ModData.Manifest);
var srcRules = Game.ModData.RulesetCache.Load();
var srcRules = srcModData.RulesetCache.Load(srcModData.DefaultFileSystem);
var srcPaletteInfo = srcRules.Actors["player"].TraitInfo<PlayerColorPaletteInfo>();
var srcRemapIndex = srcPaletteInfo.RemapIndex;
var destMod = args[2].Split(':')[0];
Game.ModData = new ModData(destMod);
Game.ModData.ModFiles.LoadFromManifest(Game.ModData.Manifest);
var destRules = Game.ModData.RulesetCache.Load();
var destModData = new ModData(destMod);
Game.ModData = destModData;
var destRules = destModData.RulesetCache.Load(destModData.DefaultFileSystem);
var destPaletteInfo = destRules.Actors["player"].TraitInfo<PlayerColorPaletteInfo>();
var destRemapIndex = destPaletteInfo.RemapIndex;
var shadowIndex = new int[] { };

View File

@@ -28,7 +28,7 @@ namespace OpenRA.Mods.D2k.UtilityCommands
// HACK: The engine code assumes that Game.modData is set.
Game.ModData = modData;
var rules = Game.ModData.RulesetCache.Load();
var rules = modData.RulesetCache.Load(modData.DefaultFileSystem);
var map = D2kMapImporter.Import(args[1], modData.Manifest.Mod.Id, args[2], rules);