Allow sprites to store custom metadata.

This commit is contained in:
Paul Chote
2018-10-01 10:57:00 +00:00
parent 0b89883012
commit dee6d03626
10 changed files with 56 additions and 16 deletions

View File

@@ -21,7 +21,7 @@ namespace OpenRA.Graphics
{ {
public interface ISpriteLoader public interface ISpriteLoader
{ {
bool TryParseSprite(Stream s, out ISpriteFrame[] frames); bool TryParseSprite(Stream s, out ISpriteFrame[] frames, out TypeDictionary metadata);
} }
public interface ISpriteFrame public interface ISpriteFrame
@@ -50,6 +50,7 @@ namespace OpenRA.Graphics
readonly Dictionary<string, List<Sprite[]>> sprites = new Dictionary<string, List<Sprite[]>>(); readonly Dictionary<string, List<Sprite[]>> sprites = new Dictionary<string, List<Sprite[]>>();
readonly Dictionary<string, ISpriteFrame[]> unloadedFrames = new Dictionary<string, ISpriteFrame[]>(); readonly Dictionary<string, ISpriteFrame[]> unloadedFrames = new Dictionary<string, ISpriteFrame[]>();
readonly Dictionary<string, TypeDictionary> metadata = new Dictionary<string, TypeDictionary>();
public SpriteCache(IReadOnlyFileSystem fileSystem, ISpriteLoader[] loaders, SheetBuilder sheetBuilder) public SpriteCache(IReadOnlyFileSystem fileSystem, ISpriteLoader[] loaders, SheetBuilder sheetBuilder)
{ {
@@ -80,8 +81,10 @@ namespace OpenRA.Graphics
// the loaded cache (initially empty) // the loaded cache (initially empty)
if (sprite == null) if (sprite == null)
{ {
unloaded = FrameLoader.GetFrames(fileSystem, filename, loaders); TypeDictionary fileMetadata = null;
unloaded = FrameLoader.GetFrames(fileSystem, filename, loaders, out fileMetadata);
unloadedFrames[filename] = unloaded; unloadedFrames[filename] = unloaded;
metadata[filename] = fileMetadata;
sprite = new Sprite[unloaded.Length]; sprite = new Sprite[unloaded.Length];
allSprites.Add(sprite); allSprites.Add(sprite);
@@ -111,6 +114,22 @@ namespace OpenRA.Graphics
return sprite; return sprite;
} }
} }
/// <summary>
/// Returns a TypeDictionary containing any metadata defined by the frame
/// or null if the frame does not define metadata.
/// </summary>
public TypeDictionary FrameMetadata(string filename)
{
TypeDictionary fileMetadata;
if (!metadata.TryGetValue(filename, out fileMetadata))
{
FrameLoader.GetFrames(fileSystem, filename, loaders, out fileMetadata);
metadata[filename] = fileMetadata;
}
return fileMetadata;
}
} }
public class FrameCache public class FrameCache
@@ -119,7 +138,8 @@ namespace OpenRA.Graphics
public FrameCache(IReadOnlyFileSystem fileSystem, ISpriteLoader[] loaders) public FrameCache(IReadOnlyFileSystem fileSystem, ISpriteLoader[] loaders)
{ {
frames = new Cache<string, ISpriteFrame[]>(filename => FrameLoader.GetFrames(fileSystem, filename, loaders)); TypeDictionary metadata;
frames = new Cache<string, ISpriteFrame[]>(filename => FrameLoader.GetFrames(fileSystem, filename, loaders, out metadata));
} }
public ISpriteFrame[] this[string filename] { get { return frames[filename]; } } public ISpriteFrame[] this[string filename] { get { return frames[filename]; } }
@@ -127,11 +147,11 @@ namespace OpenRA.Graphics
public static class FrameLoader public static class FrameLoader
{ {
public static ISpriteFrame[] GetFrames(IReadOnlyFileSystem fileSystem, string filename, ISpriteLoader[] loaders) public static ISpriteFrame[] GetFrames(IReadOnlyFileSystem fileSystem, string filename, ISpriteLoader[] loaders, out TypeDictionary metadata)
{ {
using (var stream = fileSystem.Open(filename)) using (var stream = fileSystem.Open(filename))
{ {
var spriteFrames = GetFrames(stream, loaders); var spriteFrames = GetFrames(stream, loaders, out metadata);
if (spriteFrames == null) if (spriteFrames == null)
throw new InvalidDataException(filename + " is not a valid sprite file!"); throw new InvalidDataException(filename + " is not a valid sprite file!");
@@ -139,11 +159,13 @@ namespace OpenRA.Graphics
} }
} }
public static ISpriteFrame[] GetFrames(Stream stream, ISpriteLoader[] loaders) public static ISpriteFrame[] GetFrames(Stream stream, ISpriteLoader[] loaders, out TypeDictionary metadata)
{ {
ISpriteFrame[] frames; ISpriteFrame[] frames;
metadata = null;
foreach (var loader in loaders) foreach (var loader in loaders)
if (loader.TryParseSprite(stream, out frames)) if (loader.TryParseSprite(stream, out frames, out metadata))
return frames; return frames;
return null; return null;

View File

@@ -12,6 +12,7 @@
using System.Drawing; using System.Drawing;
using System.IO; using System.IO;
using OpenRA.Graphics; using OpenRA.Graphics;
using OpenRA.Primitives;
namespace OpenRA.Mods.Cnc.SpriteLoaders namespace OpenRA.Mods.Cnc.SpriteLoaders
{ {
@@ -182,8 +183,9 @@ namespace OpenRA.Mods.Cnc.SpriteLoaders
return tiles; return tiles;
} }
public bool TryParseSprite(Stream s, out ISpriteFrame[] frames) public bool TryParseSprite(Stream s, out ISpriteFrame[] frames, out TypeDictionary metadata)
{ {
metadata = null;
if (!IsTmpTS(s)) if (!IsTmpTS(s))
{ {
frames = null; frames = null;

View File

@@ -16,6 +16,7 @@ using System.IO;
using System.Linq; using System.Linq;
using OpenRA.FileFormats; using OpenRA.FileFormats;
using OpenRA.Graphics; using OpenRA.Graphics;
using OpenRA.Primitives;
namespace OpenRA.Mods.Common.SpriteLoaders namespace OpenRA.Mods.Common.SpriteLoaders
{ {
@@ -30,8 +31,9 @@ namespace OpenRA.Mods.Common.SpriteLoaders
public bool DisableExportPadding { get { return false; } } public bool DisableExportPadding { get { return false; } }
} }
public bool TryParseSprite(Stream s, out ISpriteFrame[] frames) public bool TryParseSprite(Stream s, out ISpriteFrame[] frames, out TypeDictionary metadata)
{ {
metadata = null;
if (!Png.Verify(s)) if (!Png.Verify(s))
{ {
frames = null; frames = null;

View File

@@ -14,6 +14,7 @@ using System.Drawing;
using System.IO; using System.IO;
using OpenRA.Graphics; using OpenRA.Graphics;
using OpenRA.Mods.Common.FileFormats; using OpenRA.Mods.Common.FileFormats;
using OpenRA.Primitives;
namespace OpenRA.Mods.Common.SpriteLoaders namespace OpenRA.Mods.Common.SpriteLoaders
{ {
@@ -152,8 +153,9 @@ namespace OpenRA.Mods.Common.SpriteLoaders
return frames; return frames;
} }
public bool TryParseSprite(Stream s, out ISpriteFrame[] frames) public bool TryParseSprite(Stream s, out ISpriteFrame[] frames, out TypeDictionary metadata)
{ {
metadata = null;
if (!IsShpD2(s)) if (!IsShpD2(s))
{ {
frames = null; frames = null;

View File

@@ -16,6 +16,7 @@ using System.IO;
using System.Linq; using System.Linq;
using OpenRA.Graphics; using OpenRA.Graphics;
using OpenRA.Mods.Common.FileFormats; using OpenRA.Mods.Common.FileFormats;
using OpenRA.Primitives;
namespace OpenRA.Mods.Common.SpriteLoaders namespace OpenRA.Mods.Common.SpriteLoaders
{ {
@@ -57,8 +58,9 @@ namespace OpenRA.Mods.Common.SpriteLoaders
return b == 0x20 || b == 0x40 || b == 0x80; return b == 0x20 || b == 0x40 || b == 0x80;
} }
public bool TryParseSprite(Stream s, out ISpriteFrame[] frames) public bool TryParseSprite(Stream s, out ISpriteFrame[] frames, out TypeDictionary metadata)
{ {
metadata = null;
if (!IsShpTD(s)) if (!IsShpTD(s))
{ {
frames = null; frames = null;

View File

@@ -13,6 +13,7 @@ using System.Drawing;
using System.IO; using System.IO;
using OpenRA.Graphics; using OpenRA.Graphics;
using OpenRA.Mods.Common.FileFormats; using OpenRA.Mods.Common.FileFormats;
using OpenRA.Primitives;
namespace OpenRA.Mods.Common.SpriteLoaders namespace OpenRA.Mods.Common.SpriteLoaders
{ {
@@ -145,8 +146,9 @@ namespace OpenRA.Mods.Common.SpriteLoaders
return frames; return frames;
} }
public bool TryParseSprite(Stream s, out ISpriteFrame[] frames) public bool TryParseSprite(Stream s, out ISpriteFrame[] frames, out TypeDictionary metadata)
{ {
metadata = null;
if (!IsShpTS(s)) if (!IsShpTS(s))
{ {
frames = null; frames = null;

View File

@@ -12,6 +12,7 @@
using System.Drawing; using System.Drawing;
using System.IO; using System.IO;
using OpenRA.Graphics; using OpenRA.Graphics;
using OpenRA.Primitives;
namespace OpenRA.Mods.Common.SpriteLoaders namespace OpenRA.Mods.Common.SpriteLoaders
{ {
@@ -84,8 +85,9 @@ namespace OpenRA.Mods.Common.SpriteLoaders
return tiles; return tiles;
} }
public bool TryParseSprite(Stream s, out ISpriteFrame[] frames) public bool TryParseSprite(Stream s, out ISpriteFrame[] frames, out TypeDictionary metadata)
{ {
metadata = null;
if (!IsTmpRA(s)) if (!IsTmpRA(s))
{ {
frames = null; frames = null;

View File

@@ -12,6 +12,7 @@
using System.Drawing; using System.Drawing;
using System.IO; using System.IO;
using OpenRA.Graphics; using OpenRA.Graphics;
using OpenRA.Primitives;
namespace OpenRA.Mods.Common.SpriteLoaders namespace OpenRA.Mods.Common.SpriteLoaders
{ {
@@ -81,8 +82,9 @@ namespace OpenRA.Mods.Common.SpriteLoaders
return tiles; return tiles;
} }
public bool TryParseSprite(Stream s, out ISpriteFrame[] frames) public bool TryParseSprite(Stream s, out ISpriteFrame[] frames, out TypeDictionary metadata)
{ {
metadata = null;
if (!IsTmpTD(s)) if (!IsTmpTD(s))
{ {
frames = null; frames = null;

View File

@@ -16,6 +16,7 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using OpenRA.Graphics; using OpenRA.Graphics;
using OpenRA.Primitives;
namespace OpenRA.Mods.Common.UtilityCommands namespace OpenRA.Mods.Common.UtilityCommands
{ {
@@ -47,7 +48,8 @@ namespace OpenRA.Mods.Common.UtilityCommands
var palette = new ImmutablePalette(args[2], shadowIndex); var palette = new ImmutablePalette(args[2], shadowIndex);
var frames = FrameLoader.GetFrames(File.OpenRead(src), modData.SpriteLoaders); TypeDictionary metadata;
var frames = FrameLoader.GetFrames(File.OpenRead(src), modData.SpriteLoaders, out metadata);
var usePadding = !args.Contains("--nopadding"); var usePadding = !args.Contains("--nopadding");
var count = 0; var count = 0;

View File

@@ -13,6 +13,7 @@ using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.IO; using System.IO;
using OpenRA.Graphics; using OpenRA.Graphics;
using OpenRA.Primitives;
namespace OpenRA.Mods.D2k.SpriteLoaders namespace OpenRA.Mods.D2k.SpriteLoaders
{ {
@@ -82,8 +83,9 @@ namespace OpenRA.Mods.D2k.SpriteLoaders
return d == 8; return d == 8;
} }
public bool TryParseSprite(Stream s, out ISpriteFrame[] frames) public bool TryParseSprite(Stream s, out ISpriteFrame[] frames, out TypeDictionary metadata)
{ {
metadata = null;
if (!IsR8(s)) if (!IsR8(s))
{ {
frames = null; frames = null;