diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d36f01..4449806 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,6 +36,9 @@ Fixes - Fixed text not being pasted into a text field at all if it contains characters that don't match the input rule ### MLEM.Data +Additions +- Allow RuntimeTexturePacker to automatically dispose submitted textures when packing + Improvements - Use TitleContainer for opening streams where possible diff --git a/MLEM.Data/RuntimeTexturePacker.cs b/MLEM.Data/RuntimeTexturePacker.cs index dcdf5ba..440b628 100644 --- a/MLEM.Data/RuntimeTexturePacker.cs +++ b/MLEM.Data/RuntimeTexturePacker.cs @@ -15,11 +15,6 @@ namespace MLEM.Data { /// public class RuntimeTexturePacker : IDisposable { - private readonly List textures = new List(); - private readonly bool autoIncreaseMaxWidth; - private readonly bool forcePowerOfTwo; - private readonly bool forceSquare; - /// /// The generated packed texture. /// This value is null before is called. @@ -37,6 +32,13 @@ namespace MLEM.Data { /// The time that took the last time it was called /// public TimeSpan LastTotalTime => this.LastCalculationTime + this.LastPackTime; + + private readonly List textures = new List(); + private readonly bool autoIncreaseMaxWidth; + private readonly bool forcePowerOfTwo; + private readonly bool forceSquare; + private readonly bool disposeTextures; + private int maxWidth; /// @@ -46,11 +48,13 @@ namespace MLEM.Data { /// Whether the maximum width should be increased if there is a texture to be packed that is wider than . Defaults to false. /// Whether the resulting should have a width and height that is a power of two /// Whether the resulting should be square regardless of required size - public RuntimeTexturePacker(int maxWidth = 2048, bool autoIncreaseMaxWidth = false, bool forcePowerOfTwo = false, bool forceSquare = false) { + /// Whether the original textures submitted to this texture packer should be disposed after packing + public RuntimeTexturePacker(int maxWidth = 2048, bool autoIncreaseMaxWidth = false, bool forcePowerOfTwo = false, bool forceSquare = false, bool disposeTextures = false) { this.maxWidth = maxWidth; this.autoIncreaseMaxWidth = autoIncreaseMaxWidth; this.forcePowerOfTwo = forcePowerOfTwo; this.forceSquare = forceSquare; + this.disposeTextures = disposeTextures; } /// @@ -124,8 +128,12 @@ namespace MLEM.Data { this.LastPackTime = stopwatch.Elapsed; // invoke callbacks - foreach (var request in this.textures) + foreach (var request in this.textures) { request.Result.Invoke(new TextureRegion(this.PackedTexture, request.PackedArea)); + if (this.disposeTextures) + request.Texture.Texture.Dispose(); + } + this.textures.Clear(); } diff --git a/Tests/TexturePackerTests.cs b/Tests/TexturePackerTests.cs index a6ea05a..2e18635 100644 --- a/Tests/TexturePackerTests.cs +++ b/Tests/TexturePackerTests.cs @@ -8,18 +8,21 @@ namespace Tests { public class TexturePackerTests { private Texture2D testTexture; + private Texture2D disposedTestTexture; private TestGame game; [SetUp] public void SetUp() { this.game = TestGame.Create(); this.testTexture = new Texture2D(this.game.GraphicsDevice, 256, 256); + this.disposedTestTexture = new Texture2D(this.game.GraphicsDevice, 16, 16); } [TearDown] public void TearDown() { this.game?.Dispose(); this.testTexture?.Dispose(); + this.disposedTestTexture?.Dispose(); } [Test] @@ -37,6 +40,16 @@ namespace Tests { Assert.AreEqual(packer.PackedTexture.Height, 64); } + [Test] + public void TestDisposal() { + using var packer = new RuntimeTexturePacker(128, disposeTextures: true); + packer.Add(new TextureRegion(this.disposedTestTexture), StubResult); + packer.Add(new TextureRegion(this.disposedTestTexture, 0, 0, 8, 8), StubResult); + packer.Pack(this.game.GraphicsDevice); + Assert.True(this.disposedTestTexture.IsDisposed); + Assert.False(packer.PackedTexture.IsDisposed); + } + [Test] public void TestBounds() { // test forced max width