From 7e8f4518764a86e7d3589ae75235b1d3d4462f8b Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 31 Jan 2021 15:37:00 -0500 Subject: add experimental 'aggressive memory optimization' flag (#757) --- src/SMAPI/Metadata/CoreAssetPropagator.cs | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) (limited to 'src/SMAPI/Metadata') diff --git a/src/SMAPI/Metadata/CoreAssetPropagator.cs b/src/SMAPI/Metadata/CoreAssetPropagator.cs index 063804e0..829aa451 100644 --- a/src/SMAPI/Metadata/CoreAssetPropagator.cs +++ b/src/SMAPI/Metadata/CoreAssetPropagator.cs @@ -29,6 +29,9 @@ namespace StardewModdingAPI.Metadata /********* ** Fields *********/ + /// Whether to enable more aggressive memory optimizations. + private readonly bool AggressiveMemoryOptimizations; + /// Normalizes an asset key to match the cache key and assert that it's valid. private readonly Func AssertAndNormalizeAssetName; @@ -55,10 +58,12 @@ namespace StardewModdingAPI.Metadata /// Initialize the core asset data. /// Normalizes an asset key to match the cache key and assert that it's valid. /// Simplifies access to private code. - public CoreAssetPropagator(Func assertAndNormalizeAssetName, Reflector reflection) + /// Whether to enable more aggressive memory optimizations. + public CoreAssetPropagator(Func assertAndNormalizeAssetName, Reflector reflection, bool aggressiveMemoryOptimizations) { this.AssertAndNormalizeAssetName = assertAndNormalizeAssetName; this.Reflection = reflection; + this.AggressiveMemoryOptimizations = aggressiveMemoryOptimizations; } /// Reload one of the game's core assets (if applicable). @@ -582,7 +587,7 @@ namespace StardewModdingAPI.Metadata titleMenu.aboutButton.texture = texture; titleMenu.languageButton.texture = texture; foreach (ClickableTextureComponent button in titleMenu.buttons) - button.texture = titleMenu.titleButtonsTexture; + button.texture = texture; foreach (TemporaryAnimatedSprite bird in titleMenu.birds) bird.texture = texture; @@ -785,6 +790,9 @@ namespace StardewModdingAPI.Metadata /// The location whose map to reload. private void ReloadMap(GameLocation location) { + if (this.AggressiveMemoryOptimizations) + location.map.DisposeTileSheets(Game1.mapDisplayDevice); + // reload map location.interiorDoors.Clear(); // prevent errors when doors try to update tiles which no longer exist location.reloadMap(); @@ -843,7 +851,7 @@ namespace StardewModdingAPI.Metadata // update sprite foreach (var target in characters) { - target.Npc.Sprite.spriteTexture = content.Load(target.Key); + target.Npc.Sprite.spriteTexture = this.DisposeIfNeeded(target.Npc.Sprite.spriteTexture, content.Load(target.Key)); propagated[target.Key] = true; } } @@ -881,7 +889,7 @@ namespace StardewModdingAPI.Metadata // update portrait foreach (var target in characters) { - target.Npc.Portrait = content.Load(target.Key); + target.Npc.Portrait = this.DisposeIfNeeded(target.Npc.Portrait, content.Load(target.Key)); propagated[target.Key] = true; } } @@ -1146,5 +1154,16 @@ namespace StardewModdingAPI.Metadata { return this.GetSegments(path).Length; } + + /// Dispose a texture if are enabled and it's different from the new instance. + /// The previous texture to dispose. + /// The new texture being loaded. + private Texture2D DisposeIfNeeded(Texture2D oldTexture, Texture2D newTexture) + { + if (this.AggressiveMemoryOptimizations && oldTexture != null && !oldTexture.IsDisposed && !object.ReferenceEquals(oldTexture, newTexture)) + oldTexture.Dispose(); + + return newTexture; + } } } -- cgit