diff --git a/Wobble.Tests/Screens/Tests/Audio/TestAudioScreen.cs b/Wobble.Tests/Screens/Tests/Audio/TestAudioScreen.cs
index c199483a..7a3678db 100644
--- a/Wobble.Tests/Screens/Tests/Audio/TestAudioScreen.cs
+++ b/Wobble.Tests/Screens/Tests/Audio/TestAudioScreen.cs
@@ -55,6 +55,7 @@ public override void Destroy()
{
Song?.Dispose();
Train?.Dispose();
+ HitSound?.Dispose();
base.Destroy();
}
diff --git a/Wobble.Tests/Screens/Tests/Background/TestBackgroundImageScreenView.cs b/Wobble.Tests/Screens/Tests/Background/TestBackgroundImageScreenView.cs
index 482653c4..ed992cdb 100644
--- a/Wobble.Tests/Screens/Tests/Background/TestBackgroundImageScreenView.cs
+++ b/Wobble.Tests/Screens/Tests/Background/TestBackgroundImageScreenView.cs
@@ -17,7 +17,7 @@ public class TestBackgroundImageScreenView : ScreenView
///
///
///
- public TestBackgroundImageScreenView(Screen screen) : base(screen) => Background = new BackgroundImage(WobbleAssets.WhiteBox, 60)
+ public TestBackgroundImageScreenView(Screen screen) : base(screen) => Background = new BackgroundImage(WobbleAssets.Wallpaper, 60)
{
Parent = Container
};
diff --git a/Wobble.Tests/Screens/Tests/BlurContainer/TestBlurContainerScreenView.cs b/Wobble.Tests/Screens/Tests/BlurContainer/TestBlurContainerScreenView.cs
index 7cba8a53..967a5682 100644
--- a/Wobble.Tests/Screens/Tests/BlurContainer/TestBlurContainerScreenView.cs
+++ b/Wobble.Tests/Screens/Tests/BlurContainer/TestBlurContainerScreenView.cs
@@ -23,6 +23,8 @@ public class TestBlurContainerScreenView : ScreenView
///
public SpriteText BlurStrengthText { get; }
+ private int _lastStrength;
+
///
///
///
@@ -57,6 +59,8 @@ public TestBlurContainerScreenView(Screen screen) : base(screen)
Alignment = Alignment.TopCenter,
Y = 15,
};
+
+ _lastStrength = (int)Blur.Strength;
}
///
@@ -85,7 +89,11 @@ public override void Update(GameTime gameTime)
if (KeyboardManager.IsUniqueKeyPress(Keys.Right))
Blur.Strength += 1;
- BlurStrengthText.Text = $"Blur Strength: {Blur.Strength}";
+ if ((int)Blur.Strength != _lastStrength)
+ {
+ _lastStrength = (int)Blur.Strength;
+ BlurStrengthText.Text = $"Blur Strength: {Blur.Strength}";
+ }
Container?.Update(gameTime);
}
@@ -104,4 +112,4 @@ public override void Draw(GameTime gameTime)
///
public override void Destroy() => Container?.Destroy();
}
-}
\ No newline at end of file
+}
diff --git a/Wobble.Tests/Screens/Tests/BlurredBgImage/TestBlurredBackgroundImageScreenView.cs b/Wobble.Tests/Screens/Tests/BlurredBgImage/TestBlurredBackgroundImageScreenView.cs
index e68fb7c5..7f15db4d 100644
--- a/Wobble.Tests/Screens/Tests/BlurredBgImage/TestBlurredBackgroundImageScreenView.cs
+++ b/Wobble.Tests/Screens/Tests/BlurredBgImage/TestBlurredBackgroundImageScreenView.cs
@@ -11,7 +11,7 @@ public class TestBlurredBackgroundImageScreenView : ScreenView
{
public TestBlurredBackgroundImageScreenView(Screen screen) : base(screen)
{
- var blur = new GaussianBlur(1.1f);
+ using var blur = new GaussianBlur(1.1f);
var image = blur.PerformGaussianBlur(WobbleAssets.Wallpaper);
var background = new BackgroundImage(image)
@@ -42,4 +42,4 @@ public override void Draw(GameTime gameTime)
///
public override void Destroy() => Container?.Destroy();
}
-}
\ No newline at end of file
+}
diff --git a/Wobble.Tests/Screens/Tests/ScheduledUpdates/TestScheduledUpdatesScreenView.cs b/Wobble.Tests/Screens/Tests/ScheduledUpdates/TestScheduledUpdatesScreenView.cs
index c06f0859..881fc875 100644
--- a/Wobble.Tests/Screens/Tests/ScheduledUpdates/TestScheduledUpdatesScreenView.cs
+++ b/Wobble.Tests/Screens/Tests/ScheduledUpdates/TestScheduledUpdatesScreenView.cs
@@ -17,6 +17,8 @@ namespace Wobble.Tests.Screens.Tests.ScheduledUpdates
public class TestScheduledUpdatesScreenView: ScreenView
{
private SpriteTextPlus Scheduled { get; }
+ private CancellationTokenSource _updateTokenSource;
+ private Task _updateTask;
///
///
@@ -27,20 +29,25 @@ public TestScheduledUpdatesScreenView(Screen screen) : base(screen)
Scheduled = new SpriteTextPlus(FontManager.GetWobbleFont("exo2-semibold"),
"", 36)
{
+ Parent = Container,
Alignment = Alignment.TopCenter,
Y = 250
};
- Task.Run(() =>
+ _updateTokenSource = new CancellationTokenSource();
+ var token = _updateTokenSource.Token;
+ _updateTask = Task.Run(async () =>
{
- while (!Scheduled.IsDisposed)
+ while (!token.IsCancellationRequested && !Scheduled.IsDisposed)
{
if (IsScheduled)
Scheduled.ScheduleUpdate(() => Scheduled.Text = $"Scheduled - {DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}");
else
Scheduled.Text = $"Unscheduled - {DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}";
+
+ await Task.Delay(16, token);
}
- });
+ }, token);
new SpriteText("exo2-semibold", "Press 1 to toggle between scheduled & unscheduled", 32)
{
@@ -62,10 +69,16 @@ public override void Draw(GameTime gameTime)
{
GameBase.Game.GraphicsDevice.Clear(Color.CornflowerBlue);
Container?.Draw(gameTime);
-
- Scheduled.Draw(gameTime);
}
- public override void Destroy() => Container?.Destroy();
+ public override void Destroy()
+ {
+ _updateTokenSource?.Cancel();
+ _updateTokenSource?.Dispose();
+ _updateTokenSource = null;
+ _updateTask = null;
+
+ Container?.Destroy();
+ }
}
-}
\ No newline at end of file
+}
diff --git a/Wobble.Tests/WobbleTestsGame.cs b/Wobble.Tests/WobbleTestsGame.cs
index 6a8a8fb2..dc7803e1 100644
--- a/Wobble.Tests/WobbleTestsGame.cs
+++ b/Wobble.Tests/WobbleTestsGame.cs
@@ -1,15 +1,14 @@
using System;
using System.Collections.Generic;
-using System.Drawing;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Wobble.Graphics;
-using Wobble.Graphics.BitmapFonts;
using Wobble.Graphics.Sprites;
using Wobble.Graphics.Sprites.Text;
using Wobble.Graphics.UI.Debugging;
using Wobble.Input;
using Wobble.IO;
+using Wobble.Logging;
using Wobble.Managers;
using Wobble.Screens;
using Wobble.Tests.Screens.Selection;
@@ -24,7 +23,11 @@ public class WobbleTestsGame : WobbleGame
private FpsCounter FpsCounter { get; set; }
- private SpriteText WaylandState { get; set; }
+ private SpriteTextPlus WaylandState { get; set; }
+
+ private bool _logGc;
+ private double _gcLogTimer;
+ private readonly int[] _lastGcCounts = new int[3];
public WobbleTestsGame() : base(true)
{
@@ -72,36 +75,30 @@ protected override void LoadContent()
Resources.AddStore(new DllResourceStore("Wobble.Tests.Resources.dll"));
- if (!BitmapFontFactory.CustomFonts.ContainsKey("exo2-bold"))
- BitmapFontFactory.AddFont("exo2-bold", GameBase.Game.Resources.Get("Wobble.Tests.Resources/Fonts/exo2-bold.ttf"));
-
- if (!BitmapFontFactory.CustomFonts.ContainsKey("exo2-regular"))
- BitmapFontFactory.AddFont("exo2-regular", GameBase.Game.Resources.Get("Wobble.Tests.Resources/Fonts/exo2-regular.ttf"));
-
- if (!BitmapFontFactory.CustomFonts.ContainsKey("exo2-semibold"))
- BitmapFontFactory.AddFont("exo2-semibold", GameBase.Game.Resources.Get("Wobble.Tests.Resources/Fonts/exo2-semibold.ttf"));
-
- if (!BitmapFontFactory.CustomFonts.ContainsKey("exo2-medium"))
- BitmapFontFactory.AddFont("exo2-medium", GameBase.Game.Resources.Get("Wobble.Tests.Resources/Fonts/exo2-medium.ttf"));
+ var fonts = new List { "exo2-bold", "exo2-regular", "exo2-semibold", "exo2-medium" };
+ foreach (var fontName in fonts)
+ {
+ FontManager.CacheWobbleFont(fontName, new WobbleFontStore(20, GameBase.Game.Resources.Get($"Wobble.Tests.Resources/Fonts/{fontName}.ttf")));
+ }
- var font = new WobbleFontStore(20, GameBase.Game.Resources.Get("Wobble.Tests.Resources/Fonts/exo2-semibold.ttf"), new Dictionary()
+ var japaneseFont = new WobbleFontStore(20, GameBase.Game.Resources.Get("Wobble.Tests.Resources/Fonts/exo2-semibold.ttf"), new Dictionary()
{
{"Emoji", GameBase.Game.Resources.Get("Wobble.Tests.Resources/Fonts/symbola-emoji.ttf")},
{"Japanese", GameBase.Game.Resources.Get("Wobble.Tests.Resources/Fonts/droid-sans-japanese.ttf")}
});
- FontManager.CacheWobbleFont("exo2-semibold", font);
+ FontManager.CacheWobbleFont("exo2-semibold-japanese", japaneseFont);
IsReadyToUpdate = true;
- FpsCounter = new FpsCounter(FontManager.LoadBitmapFont("Content/gotham"), 18)
+ FpsCounter = new FpsCounter(FontManager.GetWobbleFont("exo2-semibold"), 18)
{
Parent = GlobalUserInterface,
Alignment = Alignment.BotRight,
Size = new ScalableVector2(70, 30),
};
- WaylandState = new SpriteText("exo2-semibold", $"Wayland: {WaylandVsync}", 18)
+ WaylandState = new SpriteTextPlus(FontManager.GetWobbleFont("exo2-semibold"), $"Wayland: {WaylandVsync}", 18)
{
Parent = GlobalUserInterface,
Alignment = Alignment.BotRight,
@@ -137,7 +134,33 @@ protected override void Update(GameTime gameTime)
if (KeyboardManager.IsUniqueKeyPress(Keys.W) && OperatingSystem.IsLinux())
{
WaylandVsync = !WaylandVsync;
- WaylandState.ScheduleUpdate(() => WaylandState.Text = $"Wayland: {WaylandVsync}");
+ WaylandState.Text = $"Wayland: {WaylandVsync}";
+ }
+
+ if (KeyboardManager.IsUniqueKeyPress(Keys.F10))
+ {
+ _logGc = !_logGc;
+ _gcLogTimer = 0;
+ Logger.Debug($"GC logging {(_logGc ? "enabled" : "disabled")}.", LogType.Runtime);
+ LogGc("GC toggle");
+ }
+
+ if (KeyboardManager.IsUniqueKeyPress(Keys.F9))
+ {
+ GC.Collect();
+ GC.WaitForPendingFinalizers();
+ GC.Collect();
+ LogGc("GC forced");
+ }
+
+ if (_logGc)
+ {
+ _gcLogTimer += gameTime.ElapsedGameTime.TotalMilliseconds;
+ if (_gcLogTimer >= 1000)
+ {
+ _gcLogTimer = 0;
+ LogGc("GC tick");
+ }
}
}
@@ -150,5 +173,25 @@ protected override void Draw(GameTime gameTime)
GlobalUserInterface?.Draw(gameTime);
GameBase.Game.TryEndBatch();
}
+
+ private void LogGc(string tag)
+ {
+ var totalBytes = GC.GetTotalMemory(false);
+ var gen0 = GC.CollectionCount(0);
+ var gen1 = GC.CollectionCount(1);
+ var gen2 = GC.CollectionCount(2);
+
+ var delta0 = gen0 - _lastGcCounts[0];
+ var delta1 = gen1 - _lastGcCounts[1];
+ var delta2 = gen2 - _lastGcCounts[2];
+
+ _lastGcCounts[0] = gen0;
+ _lastGcCounts[1] = gen1;
+ _lastGcCounts[2] = gen2;
+
+ Logger.Debug(
+ $"{tag}: managed={totalBytes / (1024 * 1024)}MB gen0={gen0}(+{delta0}) gen1={gen1}(+{delta1}) gen2={gen2}(+{delta2})",
+ LogType.Runtime);
+ }
}
}
diff --git a/Wobble/Assets/WobbleAssets.cs b/Wobble/Assets/WobbleAssets.cs
index 3a3f0269..1f290a68 100644
--- a/Wobble/Assets/WobbleAssets.cs
+++ b/Wobble/Assets/WobbleAssets.cs
@@ -27,6 +27,10 @@ internal static void Load()
///
/// Disposes of all the assets that Wobble has included
///
- internal static void Dispose() => WhiteBox.Dispose();
+ internal static void Dispose()
+ {
+ WhiteBox?.Dispose();
+ Wallpaper?.Dispose();
+ }
}
-}
\ No newline at end of file
+}
diff --git a/Wobble/Audio/AudioManager.cs b/Wobble/Audio/AudioManager.cs
index 14331a38..833ba2d8 100644
--- a/Wobble/Audio/AudioManager.cs
+++ b/Wobble/Audio/AudioManager.cs
@@ -64,7 +64,21 @@ public static void Initialize(int? devicePeriod, int? deviceBufferLength, int? d
///
/// Disposes of any resources used by BASS.
///
- internal static void Dispose() => Bass.Free();
+ internal static void Dispose()
+ {
+ if (Tracks != null)
+ {
+ lock (Tracks)
+ {
+ for (var i = 0; i < Tracks.Count; i++)
+ Tracks[i]?.Dispose();
+
+ Tracks.Clear();
+ }
+ }
+
+ Bass.Free();
+ }
///
/// Updates the AudioManager and keeps things up-to-date.
diff --git a/Wobble/Graphics/BitmapFonts/BitmapFontFactory.cs b/Wobble/Graphics/BitmapFonts/BitmapFontFactory.cs
index 1dc5249f..1045321b 100644
--- a/Wobble/Graphics/BitmapFonts/BitmapFontFactory.cs
+++ b/Wobble/Graphics/BitmapFonts/BitmapFontFactory.cs
@@ -106,6 +106,9 @@ internal static Texture2D Create(string fontName, string text, float fontSize, C
textSize.Width = Math.Max(1, textSize.Width);
textSize.Height = Math.Max(1, textSize.Height);
+ // Add a pad based on font size to avoid descender clipping when rendering into the bitmap.
+ textSize.Height += Math.Max(2f, fontSize * 0.25f);
+
// Create the actual bitmap using the size of the text.
using (var bmp = new Bitmap((int)(textSize.Width + 0.5), (int)(textSize.Height + 0.5), PixelFormat.Format32bppArgb))
using (var g = System.Drawing.Graphics.FromImage(bmp))
@@ -220,4 +223,4 @@ internal static void Dispose()
font.Value.Family.Dispose();
}
}
-}
\ No newline at end of file
+}
diff --git a/Wobble/Graphics/Drawable.cs b/Wobble/Graphics/Drawable.cs
index 18a8812f..b4990733 100644
--- a/Wobble/Graphics/Drawable.cs
+++ b/Wobble/Graphics/Drawable.cs
@@ -539,6 +539,12 @@ public virtual void Draw(GameTime gameTime)
for (var i = 0; i < Children.Count; i++)
{
var drawable = Children[i];
+ if (drawable == null)
+ {
+ Children.RemoveAt(i);
+ i--;
+ continue;
+ }
drawable.Draw(gameTime);
TotalDrawn++;
diff --git a/Wobble/Graphics/ImGUI/ImGuiRenderer.cs b/Wobble/Graphics/ImGUI/ImGuiRenderer.cs
index fb8959e9..f22b5e77 100644
--- a/Wobble/Graphics/ImGUI/ImGuiRenderer.cs
+++ b/Wobble/Graphics/ImGUI/ImGuiRenderer.cs
@@ -172,7 +172,13 @@ public IntPtr BindTexture(Texture2D texture)
///
/// Removes a previously created texture pointer, releasing its reference and allowing it to be deallocated
///
- public void UnbindTexture(IntPtr textureId) => LoadedTextures.Remove(textureId);
+ public void UnbindTexture(IntPtr textureId)
+ {
+ if (LoadedTextures.TryGetValue(textureId, out var texture))
+ texture.Dispose();
+
+ LoadedTextures.Remove(textureId);
+ }
///
/// Sets up ImGui for a new frame, should be called at frame start
@@ -546,6 +552,10 @@ public void Dispose()
if (DestroyContext)
ImGui.DestroyContext(Context);
+ foreach (var texture in LoadedTextures.Values)
+ texture.Dispose();
+
+ LoadedTextures.Clear();
Effect?.Dispose();
RasterizerState?.Dispose();
VertexBuffer?.Dispose();
diff --git a/Wobble/Graphics/Shaders/GaussianBlur.cs b/Wobble/Graphics/Shaders/GaussianBlur.cs
index a9ae29b0..d60cdb16 100644
--- a/Wobble/Graphics/Shaders/GaussianBlur.cs
+++ b/Wobble/Graphics/Shaders/GaussianBlur.cs
@@ -81,7 +81,7 @@ namespace Wobble.Graphics.Shaders
/// offsetsHoriz and offsetsVert fields.
///
///
- public class GaussianBlur
+ public class GaussianBlur : IDisposable
{
private Game game => GameBase.Game;
private Effect effect;
@@ -142,6 +142,15 @@ public GaussianBlur(float strength)
ComputeKernel(7, strength);
}
+ ///
+ ///
+ ///
+ public void Dispose()
+ {
+ effect?.Dispose();
+ effect = null;
+ }
+
///
/// Calculates the Gaussian blur filter kernel. This implementation is
/// ported from the original Java code appearing in chapter 16 of
@@ -280,4 +289,4 @@ public Texture2D PerformGaussianBlur(Texture2D srcTexture)
return outputTexture;
}
}
-}
\ No newline at end of file
+}
diff --git a/Wobble/Graphics/Sprites/BakeableSprite.cs b/Wobble/Graphics/Sprites/BakeableSprite.cs
index bcb6039e..b09580c0 100644
--- a/Wobble/Graphics/Sprites/BakeableSprite.cs
+++ b/Wobble/Graphics/Sprites/BakeableSprite.cs
@@ -68,5 +68,16 @@ private void Bake(GameTime gameTime)
HasBeenBaked = true;
}
+
+ ///
+ ///
+ ///
+ public override void Destroy()
+ {
+ if (BakedRenderTarget != null && !BakedRenderTarget.IsDisposed)
+ BakedRenderTarget.Dispose();
+
+ base.Destroy();
+ }
}
}
diff --git a/Wobble/Graphics/Sprites/BlurContainer.cs b/Wobble/Graphics/Sprites/BlurContainer.cs
index 0d8338ce..a897b416 100644
--- a/Wobble/Graphics/Sprites/BlurContainer.cs
+++ b/Wobble/Graphics/Sprites/BlurContainer.cs
@@ -76,6 +76,31 @@ public override void Draw(GameTime gameTime)
base.Draw(gameTime);
}
+
+ ///
+ ///
+ ///
+ public override void Destroy()
+ {
+ var activeEffect = SpriteBatchOptions?.Shader?.ShaderEffect;
+
+ if (SpriteBatchOptions?.Shader != null)
+ {
+ SpriteBatchOptions.Shader.Dispose();
+ SpriteBatchOptions.Shader = null;
+ }
+
+ if (BlurEffects != null)
+ {
+ foreach (var effect in BlurEffects.Values)
+ {
+ if (!ReferenceEquals(effect, activeEffect))
+ effect.Dispose();
+ }
+ }
+
+ base.Destroy();
+ }
}
///
@@ -87,4 +112,4 @@ public enum BlurType
Frosty,
Fast
}
-}
\ No newline at end of file
+}
diff --git a/Wobble/Graphics/Sprites/RenderTargetContainer.cs b/Wobble/Graphics/Sprites/RenderTargetContainer.cs
index 4ad03a0b..094b6c60 100644
--- a/Wobble/Graphics/Sprites/RenderTargetContainer.cs
+++ b/Wobble/Graphics/Sprites/RenderTargetContainer.cs
@@ -69,5 +69,16 @@ public override void Draw(GameTime gameTime)
// Attempt to end the spritebatch
_ = GameBase.Game.TryEndBatch();
}
+
+ ///
+ ///
+ ///
+ public override void Destroy()
+ {
+ if (RenderTarget != null && !RenderTarget.IsDisposed)
+ RenderTarget.Dispose();
+
+ base.Destroy();
+ }
}
}
diff --git a/Wobble/Graphics/Sprites/Sprite.cs b/Wobble/Graphics/Sprites/Sprite.cs
index 42052fa0..867e2027 100644
--- a/Wobble/Graphics/Sprites/Sprite.cs
+++ b/Wobble/Graphics/Sprites/Sprite.cs
@@ -135,7 +135,7 @@ public bool IndependentRotation
public override void Draw(GameTime gameTime)
{
// If there is no image set, create a dummy 1px one.
- if (Image == null)
+ if (Image == null || Image.IsDisposed)
Image = WobbleAssets.WhiteBox;
if (SpriteBatchOptions != null)
diff --git a/Wobble/Graphics/Sprites/SpriteAlphaMaskBlend.cs b/Wobble/Graphics/Sprites/SpriteAlphaMaskBlend.cs
index a3cfcb6a..4d19dd5d 100644
--- a/Wobble/Graphics/Sprites/SpriteAlphaMaskBlend.cs
+++ b/Wobble/Graphics/Sprites/SpriteAlphaMaskBlend.cs
@@ -17,6 +17,12 @@ public class SpriteAlphaMaskBlend : Sprite
public Texture2D PerformBlend(Texture2D srcTexture, Texture2D srcMask)
{
+ if (RenderTarget != null && !RenderTarget.IsDisposed)
+ {
+ RenderTarget.Dispose();
+ RenderTarget = null;
+ }
+
RenderTarget = new RenderTarget2D(GameBase.Game.GraphicsDevice, srcTexture.Width, srcTexture.Height, false,
GameBase.Game.GraphicsDevice.PresentationParameters.BackBufferFormat, DepthFormat.None);
diff --git a/Wobble/Graphics/Sprites/Text/SpriteTextPlusLine.cs b/Wobble/Graphics/Sprites/Text/SpriteTextPlusLine.cs
index 5b838e00..847a4d9c 100644
--- a/Wobble/Graphics/Sprites/Text/SpriteTextPlusLine.cs
+++ b/Wobble/Graphics/Sprites/Text/SpriteTextPlusLine.cs
@@ -112,7 +112,10 @@ public SpriteTextPlusLine(WobbleFontStore font, string text, float size = 0)
private static float GetScale()
{
var scale = WindowManager.ScreenScale.X;
- Debug.Assert(scale > 0, "You're setting up text too early (WindowManager.ScreenScale.X is 0).");
+
+ // Some stuff (namely DrawableLog and the FPS counter) wants to draw text before anything is initialized.
+ if (scale == 0)
+ scale = 1;
if (GameBase.Game.Graphics.PreferredBackBufferWidth < 1600)
return scale * 2;
diff --git a/Wobble/Graphics/Sprites/Text/SpriteTextPlusLineRaw.cs b/Wobble/Graphics/Sprites/Text/SpriteTextPlusLineRaw.cs
index acaad78f..445488e1 100644
--- a/Wobble/Graphics/Sprites/Text/SpriteTextPlusLineRaw.cs
+++ b/Wobble/Graphics/Sprites/Text/SpriteTextPlusLineRaw.cs
@@ -1,3 +1,4 @@
+using System;
using Wobble.Window;
namespace Wobble.Graphics.Sprites.Text
@@ -67,7 +68,9 @@ private void RefreshSize()
Font.FontSize = FontSize;
var (x, y) = Font.Store.MeasureString(Text);
- Size = new ScalableVector2(x, y);
+ var padding = Math.Max(2f, FontSize * 0.25f);
+ var height = Math.Max(y, Font.Store.LineHeight) + padding;
+ Size = new ScalableVector2(x, height);
}
}
-}
\ No newline at end of file
+}
diff --git a/Wobble/Graphics/UI/Debugging/FpsCounter.cs b/Wobble/Graphics/UI/Debugging/FpsCounter.cs
index a46dc876..36d51d67 100644
--- a/Wobble/Graphics/UI/Debugging/FpsCounter.cs
+++ b/Wobble/Graphics/UI/Debugging/FpsCounter.cs
@@ -1,9 +1,9 @@
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
-using MonoGame.Extended.BitmapFonts;
-using Wobble.Graphics.BitmapFonts;
using Wobble.Graphics.Sprites;
+using Wobble.Graphics.Sprites.Text;
+using Wobble.Managers;
namespace Wobble.Graphics.UI.Debugging
{
@@ -20,9 +20,9 @@ public class FpsCounter : Container
private int FrameCounter { get; set; }
///
- /// The SpriteText that displays the FPS value.
+ /// The SpriteTextPlus that displays the FPS value.
///
- public SpriteTextBitmap TextFps { get; }
+ public SpriteTextPlus TextFps { get; }
///
/// The current update rate.
@@ -35,9 +35,9 @@ public class FpsCounter : Container
private int UpdateCounter { get; set; }
///
- /// The SpriteText that displays the UPS value.
+ /// The SpriteTextPlus that displays the UPS value.
///
- public SpriteTextBitmap TextUps { get; }
+ public SpriteTextPlus TextUps { get; }
///
/// The amount of time elapsed so we can begin counting each second.
@@ -48,20 +48,18 @@ public class FpsCounter : Container
///
/// Ctor
///
- public FpsCounter(BitmapFont font, int size)
+ public FpsCounter(WobbleFontStore font, int size)
{
- TextFps = new SpriteTextBitmap(font, "0 FPS", false)
+ TextFps = new SpriteTextPlus(font, "0 FPS", size)
{
Parent = this,
Alignment = Alignment.TopRight,
- FontSize = size
};
- TextUps = new SpriteTextBitmap(font, "0 UPS", false)
+ TextUps = new SpriteTextPlus(font, "0 UPS", size)
{
Parent = this,
Alignment = Alignment.TopRight,
- FontSize = size,
Y = TextFps.Size.Y.Value
};
}
diff --git a/Wobble/Logging/Logger.cs b/Wobble/Logging/Logger.cs
index 8234500b..6d17d091 100644
--- a/Wobble/Logging/Logger.cs
+++ b/Wobble/Logging/Logger.cs
@@ -152,7 +152,7 @@ public static void Log(string m, LogLevel level, LogType type, bool writeToFile
catch (Exception e)
{
// If it fails, we can't really handle the error here. This shouldn't happen though.
- Console.WriteLine(e);
+ // Console.WriteLine(e);
}
}
diff --git a/Wobble/Managers/TextureManager.cs b/Wobble/Managers/TextureManager.cs
index 8f2b525a..7ffe281f 100644
--- a/Wobble/Managers/TextureManager.cs
+++ b/Wobble/Managers/TextureManager.cs
@@ -45,10 +45,29 @@ public static List LoadAtlas(string name, int rows, int columns)
var tex = AssetLoader.LoadTexture2D(GameBase.Game.Resources.Get(name));
var textures = AssetLoader.LoadSpritesheetFromTexture(tex, rows, columns);
+ tex.Dispose();
TextureAtlases.Add(name, textures);
return textures;
}
+
+ ///
+ /// Disposes all cached textures and clears the caches.
+ ///
+ internal static void Dispose()
+ {
+ foreach (var texture in Textures.Values)
+ texture?.Dispose();
+
+ foreach (var atlas in TextureAtlases.Values)
+ {
+ for (var i = 0; i < atlas.Count; i++)
+ atlas[i]?.Dispose();
+ }
+
+ Textures.Clear();
+ TextureAtlases.Clear();
+ }
}
-}
\ No newline at end of file
+}
diff --git a/Wobble/Window/WindowManager.cs b/Wobble/Window/WindowManager.cs
index 6e0c8a1b..4ab30c84 100644
--- a/Wobble/Window/WindowManager.cs
+++ b/Wobble/Window/WindowManager.cs
@@ -106,7 +106,11 @@ public static void Update()
///
/// Unhooks all events from the WindowManager.
///
- public static void UnHookEvents() => ResolutionChanged = null;
+ public static void UnHookEvents()
+ {
+ ResolutionChanged = null;
+ VirtualScreenSizeChanged = null;
+ }
///
/// Changes the size of the virtual screen to be used.
@@ -173,4 +177,4 @@ private static void UpdateBackBufferSize()
GameBase.Game.Graphics.PreferredBackBufferHeight = GameBase.Game.Window.ClientBounds.Height;
}
}
-}
\ No newline at end of file
+}
diff --git a/Wobble/Wobble.csproj b/Wobble/Wobble.csproj
index dd2e6473..b1d5c56b 100644
--- a/Wobble/Wobble.csproj
+++ b/Wobble/Wobble.csproj
@@ -2,7 +2,7 @@
net6.0
true
- 7.1
+ 7.2
false
diff --git a/Wobble/WobbleGame.cs b/Wobble/WobbleGame.cs
index 8b2ab2c8..89958ffd 100644
--- a/Wobble/WobbleGame.cs
+++ b/Wobble/WobbleGame.cs
@@ -17,6 +17,7 @@
using Wobble.Input;
using Wobble.IO;
using Wobble.Logging;
+using Wobble.Managers;
using Wobble.Platform;
using Wobble.Platform.Linux;
using Wobble.Screens;
@@ -216,6 +217,9 @@ protected override void LoadContent()
protected override void UnloadContent()
{
WobbleAssets.Dispose();
+ TextureManager.Dispose();
+ Resources?.Dispose();
+ Window.ClientSizeChanged -= WindowManager.OnClientSizeChanged;
WindowManager.UnHookEvents();
AudioManager.Dispose();
DiscordManager.Dispose();