summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/release-notes.md6
-rw-r--r--src/SMAPI/Framework/ContentCoordinator.cs30
-rw-r--r--src/SMAPI/Framework/ContentManagers/BaseContentManager.cs16
-rw-r--r--src/SMAPI/Framework/ContentManagers/GameContentManager.cs5
-rw-r--r--src/SMAPI/Framework/ContentManagers/GameContentManagerForAssetPropagation.cs4
-rw-r--r--src/SMAPI/Framework/ContentManagers/ModContentManager.cs5
-rw-r--r--src/SMAPI/Framework/Models/SConfig.cs8
-rw-r--r--src/SMAPI/Framework/SCore.cs1
-rw-r--r--src/SMAPI/Metadata/CoreAssetPropagator.cs51
-rw-r--r--src/SMAPI/SMAPI.config.json7
10 files changed, 27 insertions, 106 deletions
diff --git a/docs/release-notes.md b/docs/release-notes.md
index 11cccee2..2fff0c58 100644
--- a/docs/release-notes.md
+++ b/docs/release-notes.md
@@ -3,8 +3,10 @@
# Release notes
## Upcoming release
* For players:
- * Case-insensitive file paths (introduced in 3.14.0) are now disabled by default.
- _You can enable them via `smapi-internal/config.json` if needed. These will be re-enabled in a later version after reworking them to reduce performance impact._
+ * Disabled case-insensitive file paths (introduced in 3.14.0) by default.
+ _You can enable them by editing `smapi-internal/config.json` if needed. They'll be re-enabled in a later version after they're reworked to reduce performance impact._
+ * Removed experimental 'aggressive memory optimizations' option.
+ _This was disabled by default and is no longer needed in most cases. Memory usage will be better reduced by reworked asset propagation in the upcoming SMAPI 4.0.0._
* Updated compatibility list.
## 3.14.0
diff --git a/src/SMAPI/Framework/ContentCoordinator.cs b/src/SMAPI/Framework/ContentCoordinator.cs
index 1a82d194..ef442fbe 100644
--- a/src/SMAPI/Framework/ContentCoordinator.cs
+++ b/src/SMAPI/Framework/ContentCoordinator.cs
@@ -32,9 +32,6 @@ namespace StardewModdingAPI.Framework
/// <summary>An asset key prefix for assets from SMAPI mod folders.</summary>
private readonly string ManagedPrefix = "SMAPI";
- /// <summary>Whether to enable more aggressive memory optimizations.</summary>
- private readonly bool AggressiveMemoryOptimizations;
-
/// <summary>Get a file path lookup for the given directory.</summary>
private readonly Func<string, IFilePathLookup> GetFilePathLookup;
@@ -118,13 +115,11 @@ namespace StardewModdingAPI.Framework
/// <param name="jsonHelper">Encapsulates SMAPI's JSON file parsing.</param>
/// <param name="onLoadingFirstAsset">A callback to invoke the first time *any* game content manager loads an asset.</param>
/// <param name="onAssetLoaded">A callback to invoke when an asset is fully loaded.</param>
- /// <param name="aggressiveMemoryOptimizations">Whether to enable more aggressive memory optimizations.</param>
/// <param name="getFilePathLookup">Get a file path lookup for the given directory.</param>
/// <param name="onAssetsInvalidated">A callback to invoke when any asset names have been invalidated from the cache.</param>
/// <param name="requestAssetOperations">Get the load/edit operations to apply to an asset by querying registered <see cref="IContentEvents.AssetRequested"/> event handlers.</param>
- public ContentCoordinator(IServiceProvider serviceProvider, string rootDirectory, CultureInfo currentCulture, IMonitor monitor, Reflector reflection, JsonHelper jsonHelper, Action onLoadingFirstAsset, Action<BaseContentManager, IAssetName> onAssetLoaded, bool aggressiveMemoryOptimizations, Func<string, IFilePathLookup> getFilePathLookup, Action<IList<IAssetName>> onAssetsInvalidated, Func<IAssetInfo, IList<AssetOperationGroup>> requestAssetOperations)
+ public ContentCoordinator(IServiceProvider serviceProvider, string rootDirectory, CultureInfo currentCulture, IMonitor monitor, Reflector reflection, JsonHelper jsonHelper, Action onLoadingFirstAsset, Action<BaseContentManager, IAssetName> onAssetLoaded, Func<string, IFilePathLookup> getFilePathLookup, Action<IList<IAssetName>> onAssetsInvalidated, Func<IAssetInfo, IList<AssetOperationGroup>> requestAssetOperations)
{
- this.AggressiveMemoryOptimizations = aggressiveMemoryOptimizations;
this.GetFilePathLookup = getFilePathLookup;
this.Monitor = monitor ?? throw new ArgumentNullException(nameof(monitor));
this.Reflection = reflection;
@@ -145,26 +140,11 @@ namespace StardewModdingAPI.Framework
reflection: reflection,
onDisposing: this.OnDisposing,
onLoadingFirstAsset: onLoadingFirstAsset,
- onAssetLoaded: onAssetLoaded,
- aggressiveMemoryOptimizations: aggressiveMemoryOptimizations
+ onAssetLoaded: onAssetLoaded
)
);
- var contentManagerForAssetPropagation = new GameContentManagerForAssetPropagation(
- name: nameof(GameContentManagerForAssetPropagation),
- serviceProvider: serviceProvider,
- rootDirectory: rootDirectory,
- currentCulture: currentCulture,
- coordinator: this,
- monitor: monitor,
- reflection: reflection,
- onDisposing: this.OnDisposing,
- onLoadingFirstAsset: onLoadingFirstAsset,
- onAssetLoaded: onAssetLoaded,
- aggressiveMemoryOptimizations: aggressiveMemoryOptimizations
- );
- this.ContentManagers.Add(contentManagerForAssetPropagation);
this.VanillaContentManager = new LocalizedContentManager(serviceProvider, rootDirectory);
- this.CoreAssets = new CoreAssetPropagator(this.MainContentManager, contentManagerForAssetPropagation, this.Monitor, reflection, aggressiveMemoryOptimizations, name => this.ParseAssetName(name, allowLocales: true));
+ this.CoreAssets = new CoreAssetPropagator(this.MainContentManager, this.Monitor, reflection, name => this.ParseAssetName(name, allowLocales: true));
this.LocaleCodes = new Lazy<Dictionary<string, LocalizedContentManager.LanguageCode>>(() => this.GetLocaleCodes(customLanguages: Enumerable.Empty<ModLanguage>()));
}
@@ -184,8 +164,7 @@ namespace StardewModdingAPI.Framework
reflection: this.Reflection,
onDisposing: this.OnDisposing,
onLoadingFirstAsset: this.OnLoadingFirstAsset,
- onAssetLoaded: this.OnAssetLoaded,
- aggressiveMemoryOptimizations: this.AggressiveMemoryOptimizations
+ onAssetLoaded: this.OnAssetLoaded
);
this.ContentManagers.Add(manager);
return manager;
@@ -213,7 +192,6 @@ namespace StardewModdingAPI.Framework
reflection: this.Reflection,
jsonHelper: this.JsonHelper,
onDisposing: this.OnDisposing,
- aggressiveMemoryOptimizations: this.AggressiveMemoryOptimizations,
relativePathLookup: this.GetFilePathLookup(rootDirectory)
);
this.ContentManagers.Add(manager);
diff --git a/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs b/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs
index b2e3ec0f..db2934a0 100644
--- a/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs
+++ b/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs
@@ -11,7 +11,6 @@ using StardewModdingAPI.Framework.Content;
using StardewModdingAPI.Framework.Exceptions;
using StardewModdingAPI.Framework.Reflection;
using StardewValley;
-using xTile;
namespace StardewModdingAPI.Framework.ContentManagers
{
@@ -33,9 +32,6 @@ namespace StardewModdingAPI.Framework.ContentManagers
/// <summary>Simplifies access to private code.</summary>
protected readonly Reflector Reflection;
- /// <summary>Whether to enable more aggressive memory optimizations.</summary>
- protected readonly bool AggressiveMemoryOptimizations;
-
/// <summary>Whether to automatically try resolving keys to a localized form if available.</summary>
protected bool TryLocalizeKeys = true;
@@ -82,8 +78,7 @@ namespace StardewModdingAPI.Framework.ContentManagers
/// <param name="reflection">Simplifies access to private code.</param>
/// <param name="onDisposing">A callback to invoke when the content manager is being disposed.</param>
/// <param name="isNamespaced">Whether this content manager handles managed asset keys (e.g. to load assets from a mod folder).</param>
- /// <param name="aggressiveMemoryOptimizations">Whether to enable more aggressive memory optimizations.</param>
- protected BaseContentManager(string name, IServiceProvider serviceProvider, string rootDirectory, CultureInfo currentCulture, ContentCoordinator coordinator, IMonitor monitor, Reflector reflection, Action<BaseContentManager> onDisposing, bool isNamespaced, bool aggressiveMemoryOptimizations)
+ protected BaseContentManager(string name, IServiceProvider serviceProvider, string rootDirectory, CultureInfo currentCulture, ContentCoordinator coordinator, IMonitor monitor, Reflector reflection, Action<BaseContentManager> onDisposing, bool isNamespaced)
: base(serviceProvider, rootDirectory, currentCulture)
{
// init
@@ -95,7 +90,6 @@ namespace StardewModdingAPI.Framework.ContentManagers
this.Reflection = reflection;
this.OnDisposing = onDisposing;
this.IsNamespaced = isNamespaced;
- this.AggressiveMemoryOptimizations = aggressiveMemoryOptimizations;
// get asset data
this.BaseDisposableReferences = reflection.GetField<List<IDisposable>?>(this, "disposableAssets").GetValue()
@@ -231,14 +225,6 @@ namespace StardewModdingAPI.Framework.ContentManagers
removeAssets[baseAssetName] = asset;
remove = true;
}
-
- // dispose if safe
- if (remove && this.AggressiveMemoryOptimizations)
- {
- if (asset is Map map)
- map.DisposeTileSheets(Game1.mapDisplayDevice);
- }
-
return remove;
}, dispose);
diff --git a/src/SMAPI/Framework/ContentManagers/GameContentManager.cs b/src/SMAPI/Framework/ContentManagers/GameContentManager.cs
index 083df454..c53040e1 100644
--- a/src/SMAPI/Framework/ContentManagers/GameContentManager.cs
+++ b/src/SMAPI/Framework/ContentManagers/GameContentManager.cs
@@ -51,9 +51,8 @@ namespace StardewModdingAPI.Framework.ContentManagers
/// <param name="onDisposing">A callback to invoke when the content manager is being disposed.</param>
/// <param name="onLoadingFirstAsset">A callback to invoke the first time *any* game content manager loads an asset.</param>
/// <param name="onAssetLoaded">A callback to invoke when an asset is fully loaded.</param>
- /// <param name="aggressiveMemoryOptimizations">Whether to enable more aggressive memory optimizations.</param>
- public GameContentManager(string name, IServiceProvider serviceProvider, string rootDirectory, CultureInfo currentCulture, ContentCoordinator coordinator, IMonitor monitor, Reflector reflection, Action<BaseContentManager> onDisposing, Action onLoadingFirstAsset, Action<BaseContentManager, IAssetName> onAssetLoaded, bool aggressiveMemoryOptimizations)
- : base(name, serviceProvider, rootDirectory, currentCulture, coordinator, monitor, reflection, onDisposing, isNamespaced: false, aggressiveMemoryOptimizations: aggressiveMemoryOptimizations)
+ public GameContentManager(string name, IServiceProvider serviceProvider, string rootDirectory, CultureInfo currentCulture, ContentCoordinator coordinator, IMonitor monitor, Reflector reflection, Action<BaseContentManager> onDisposing, Action onLoadingFirstAsset, Action<BaseContentManager, IAssetName> onAssetLoaded)
+ : base(name, serviceProvider, rootDirectory, currentCulture, coordinator, monitor, reflection, onDisposing, isNamespaced: false)
{
this.OnLoadingFirstAsset = onLoadingFirstAsset;
this.OnAssetLoaded = onAssetLoaded;
diff --git a/src/SMAPI/Framework/ContentManagers/GameContentManagerForAssetPropagation.cs b/src/SMAPI/Framework/ContentManagers/GameContentManagerForAssetPropagation.cs
index 1b0e1016..5c574a1a 100644
--- a/src/SMAPI/Framework/ContentManagers/GameContentManagerForAssetPropagation.cs
+++ b/src/SMAPI/Framework/ContentManagers/GameContentManagerForAssetPropagation.cs
@@ -21,8 +21,8 @@ namespace StardewModdingAPI.Framework.ContentManagers
** Public methods
*********/
/// <inheritdoc />
- public GameContentManagerForAssetPropagation(string name, IServiceProvider serviceProvider, string rootDirectory, CultureInfo currentCulture, ContentCoordinator coordinator, IMonitor monitor, Reflector reflection, Action<BaseContentManager> onDisposing, Action onLoadingFirstAsset, Action<BaseContentManager, IAssetName> onAssetLoaded, bool aggressiveMemoryOptimizations)
- : base(name, serviceProvider, rootDirectory, currentCulture, coordinator, monitor, reflection, onDisposing, onLoadingFirstAsset, onAssetLoaded, aggressiveMemoryOptimizations) { }
+ public GameContentManagerForAssetPropagation(string name, IServiceProvider serviceProvider, string rootDirectory, CultureInfo currentCulture, ContentCoordinator coordinator, IMonitor monitor, Reflector reflection, Action<BaseContentManager> onDisposing, Action onLoadingFirstAsset, Action<BaseContentManager, IAssetName> onAssetLoaded)
+ : base(name, serviceProvider, rootDirectory, currentCulture, coordinator, monitor, reflection, onDisposing, onLoadingFirstAsset, onAssetLoaded) { }
/// <inheritdoc />
public override T LoadExact<T>(IAssetName assetName, bool useCache)
diff --git a/src/SMAPI/Framework/ContentManagers/ModContentManager.cs b/src/SMAPI/Framework/ContentManagers/ModContentManager.cs
index 91de769f..65dffd8b 100644
--- a/src/SMAPI/Framework/ContentManagers/ModContentManager.cs
+++ b/src/SMAPI/Framework/ContentManagers/ModContentManager.cs
@@ -55,10 +55,9 @@ namespace StardewModdingAPI.Framework.ContentManagers
/// <param name="reflection">Simplifies access to private code.</param>
/// <param name="jsonHelper">Encapsulates SMAPI's JSON file parsing.</param>
/// <param name="onDisposing">A callback to invoke when the content manager is being disposed.</param>
- /// <param name="aggressiveMemoryOptimizations">Whether to enable more aggressive memory optimizations.</param>
/// <param name="relativePathLookup">A lookup for relative paths within the <paramref name="rootDirectory"/>.</param>
- public ModContentManager(string name, IContentManager gameContentManager, IServiceProvider serviceProvider, string modName, string rootDirectory, CultureInfo currentCulture, ContentCoordinator coordinator, IMonitor monitor, Reflector reflection, JsonHelper jsonHelper, Action<BaseContentManager> onDisposing, bool aggressiveMemoryOptimizations, IFilePathLookup relativePathLookup)
- : base(name, serviceProvider, rootDirectory, currentCulture, coordinator, monitor, reflection, onDisposing, isNamespaced: true, aggressiveMemoryOptimizations: aggressiveMemoryOptimizations)
+ public ModContentManager(string name, IContentManager gameContentManager, IServiceProvider serviceProvider, string modName, string rootDirectory, CultureInfo currentCulture, ContentCoordinator coordinator, IMonitor monitor, Reflector reflection, JsonHelper jsonHelper, Action<BaseContentManager> onDisposing, IFilePathLookup relativePathLookup)
+ : base(name, serviceProvider, rootDirectory, currentCulture, coordinator, monitor, reflection, onDisposing, isNamespaced: true)
{
this.GameContentManager = gameContentManager;
this.RelativePathLookup = relativePathLookup;
diff --git a/src/SMAPI/Framework/Models/SConfig.cs b/src/SMAPI/Framework/Models/SConfig.cs
index b4184abb..80d0d9ba 100644
--- a/src/SMAPI/Framework/Models/SConfig.cs
+++ b/src/SMAPI/Framework/Models/SConfig.cs
@@ -22,7 +22,6 @@ namespace StardewModdingAPI.Framework.Models
[nameof(VerboseLogging)] = false,
[nameof(LogNetworkTraffic)] = false,
[nameof(RewriteMods)] = true,
- [nameof(AggressiveMemoryOptimizations)] = false,
[nameof(UsePintail)] = true,
[nameof(UseCaseInsensitivePaths)] = false
};
@@ -63,9 +62,6 @@ namespace StardewModdingAPI.Framework.Models
/// <summary>Whether SMAPI should rewrite mods for compatibility.</summary>
public bool RewriteMods { get; }
- /// <summary>Whether to enable more aggressive memory optimizations.</summary>
- public bool AggressiveMemoryOptimizations { get; }
-
/// <summary>Whether to use the experimental Pintail API proxying library, instead of the original proxying built into SMAPI itself.</summary>
public bool UsePintail { get; }
@@ -94,13 +90,12 @@ namespace StardewModdingAPI.Framework.Models
/// <param name="webApiBaseUrl">The base URL for SMAPI's web API, used to perform update checks.</param>
/// <param name="verboseLogging">Whether SMAPI should log more information about the game context.</param>
/// <param name="rewriteMods">Whether SMAPI should rewrite mods for compatibility.</param>
- /// <param name="aggressiveMemoryOptimizations">Whether to enable more aggressive memory optimizations.</param>
/// <param name="usePintail">Whether to use the experimental Pintail API proxying library, instead of the original proxying built into SMAPI itself.</param>
/// <param name="useCaseInsensitivePaths">>Whether to make SMAPI file APIs case-insensitive, even on Linux.</param>
/// <param name="logNetworkTraffic">Whether SMAPI should log network traffic.</param>
/// <param name="consoleColors">The colors to use for text written to the SMAPI console.</param>
/// <param name="suppressUpdateChecks">The mod IDs SMAPI should ignore when performing update checks or validating update keys.</param>
- public SConfig(bool developerMode, bool checkForUpdates, bool? paranoidWarnings, bool? useBetaChannel, string gitHubProjectName, string webApiBaseUrl, bool verboseLogging, bool? rewriteMods, bool? aggressiveMemoryOptimizations, bool? usePintail, bool? useCaseInsensitivePaths, bool logNetworkTraffic, ColorSchemeConfig consoleColors, string[]? suppressUpdateChecks)
+ public SConfig(bool developerMode, bool checkForUpdates, bool? paranoidWarnings, bool? useBetaChannel, string gitHubProjectName, string webApiBaseUrl, bool verboseLogging, bool? rewriteMods, bool? usePintail, bool? useCaseInsensitivePaths, bool logNetworkTraffic, ColorSchemeConfig consoleColors, string[]? suppressUpdateChecks)
{
this.DeveloperMode = developerMode;
this.CheckForUpdates = checkForUpdates;
@@ -110,7 +105,6 @@ namespace StardewModdingAPI.Framework.Models
this.WebApiBaseUrl = webApiBaseUrl;
this.VerboseLogging = verboseLogging;
this.RewriteMods = rewriteMods ?? (bool)SConfig.DefaultValues[nameof(SConfig.RewriteMods)];
- this.AggressiveMemoryOptimizations = aggressiveMemoryOptimizations ?? (bool)SConfig.DefaultValues[nameof(SConfig.AggressiveMemoryOptimizations)];
this.UsePintail = usePintail ?? (bool)SConfig.DefaultValues[nameof(SConfig.UsePintail)];
this.UseCaseInsensitivePaths = useCaseInsensitivePaths ?? (bool)SConfig.DefaultValues[nameof(SConfig.UseCaseInsensitivePaths)];
this.LogNetworkTraffic = logNetworkTraffic;
diff --git a/src/SMAPI/Framework/SCore.cs b/src/SMAPI/Framework/SCore.cs
index 50765083..a9296d9b 100644
--- a/src/SMAPI/Framework/SCore.cs
+++ b/src/SMAPI/Framework/SCore.cs
@@ -1253,7 +1253,6 @@ namespace StardewModdingAPI.Framework
onLoadingFirstAsset: this.InitializeBeforeFirstAssetLoaded,
onAssetLoaded: this.OnAssetLoaded,
onAssetsInvalidated: this.OnAssetsInvalidated,
- aggressiveMemoryOptimizations: this.Settings.AggressiveMemoryOptimizations,
getFilePathLookup: this.GetFilePathLookup,
requestAssetOperations: this.RequestAssetOperations
);
diff --git a/src/SMAPI/Metadata/CoreAssetPropagator.cs b/src/SMAPI/Metadata/CoreAssetPropagator.cs
index 5dee2c4d..12b73515 100644
--- a/src/SMAPI/Metadata/CoreAssetPropagator.cs
+++ b/src/SMAPI/Metadata/CoreAssetPropagator.cs
@@ -5,7 +5,6 @@ using System.IO;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
-using StardewModdingAPI.Framework.ContentManagers;
using StardewModdingAPI.Framework.Reflection;
using StardewModdingAPI.Internal;
using StardewModdingAPI.Toolkit.Utilities;
@@ -33,18 +32,12 @@ namespace StardewModdingAPI.Metadata
/// <summary>The main content manager through which to reload assets.</summary>
private readonly LocalizedContentManager MainContentManager;
- /// <summary>An internal content manager used only for asset propagation. See remarks on <see cref="GameContentManagerForAssetPropagation"/>.</summary>
- private readonly GameContentManagerForAssetPropagation DisposableContentManager;
-
/// <summary>Writes messages to the console.</summary>
private readonly IMonitor Monitor;
/// <summary>Simplifies access to private game code.</summary>
private readonly Reflector Reflection;
- /// <summary>Whether to enable more aggressive memory optimizations.</summary>
- private readonly bool AggressiveMemoryOptimizations;
-
/// <summary>Parse a raw asset name.</summary>
private readonly Func<string, IAssetName> ParseAssetName;
@@ -67,18 +60,14 @@ namespace StardewModdingAPI.Metadata
*********/
/// <summary>Initialize the core asset data.</summary>
/// <param name="mainContent">The main content manager through which to reload assets.</param>
- /// <param name="disposableContent">An internal content manager used only for asset propagation.</param>
/// <param name="monitor">Writes messages to the console.</param>
/// <param name="reflection">Simplifies access to private code.</param>
- /// <param name="aggressiveMemoryOptimizations">Whether to enable more aggressive memory optimizations.</param>
/// <param name="parseAssetName">Parse a raw asset name.</param>
- public CoreAssetPropagator(LocalizedContentManager mainContent, GameContentManagerForAssetPropagation disposableContent, IMonitor monitor, Reflector reflection, bool aggressiveMemoryOptimizations, Func<string, IAssetName> parseAssetName)
+ public CoreAssetPropagator(LocalizedContentManager mainContent, IMonitor monitor, Reflector reflection, Func<string, IAssetName> parseAssetName)
{
this.MainContentManager = mainContent;
- this.DisposableContentManager = disposableContent;
this.Monitor = monitor;
this.Reflection = reflection;
- this.AggressiveMemoryOptimizations = aggressiveMemoryOptimizations;
this.ParseAssetName = parseAssetName;
}
@@ -230,7 +219,7 @@ namespace StardewModdingAPI.Metadata
** Buildings
****/
case "buildings/houses": // Farm
- Farm.houseTextures = this.LoadAndDisposeIfNeeded(Farm.houseTextures, key);
+ Farm.houseTextures = this.LoadTexture(key);
return true;
case "buildings/houses_paintmask": // Farm
@@ -247,7 +236,7 @@ namespace StardewModdingAPI.Metadata
** Content\Characters\Farmer
****/
case "characters/farmer/accessories": // Game1.LoadContent
- FarmerRenderer.accessoriesTexture = this.LoadAndDisposeIfNeeded(FarmerRenderer.accessoriesTexture, key);
+ FarmerRenderer.accessoriesTexture = this.LoadTexture(key);
return true;
case "characters/farmer/farmer_base": // Farmer
@@ -257,19 +246,19 @@ namespace StardewModdingAPI.Metadata
return !ignoreWorld && this.ReloadPlayerSprites(assetName);
case "characters/farmer/hairstyles": // Game1.LoadContent
- FarmerRenderer.hairStylesTexture = this.LoadAndDisposeIfNeeded(FarmerRenderer.hairStylesTexture, key);
+ FarmerRenderer.hairStylesTexture = this.LoadTexture(key);
return true;
case "characters/farmer/hats": // Game1.LoadContent
- FarmerRenderer.hatsTexture = this.LoadAndDisposeIfNeeded(FarmerRenderer.hatsTexture, key);
+ FarmerRenderer.hatsTexture = this.LoadTexture(key);
return true;
case "characters/farmer/pants": // Game1.LoadContent
- FarmerRenderer.pantsTexture = this.LoadAndDisposeIfNeeded(FarmerRenderer.pantsTexture, key);
+ FarmerRenderer.pantsTexture = this.LoadTexture(key);
return true;
case "characters/farmer/shirts": // Game1.LoadContent
- FarmerRenderer.shirtsTexture = this.LoadAndDisposeIfNeeded(FarmerRenderer.shirtsTexture, key);
+ FarmerRenderer.shirtsTexture = this.LoadTexture(key);
return true;
/****
@@ -905,9 +894,6 @@ namespace StardewModdingAPI.Metadata
GameLocation location = locationInfo.Location;
Vector2? playerPos = Game1.player?.Position;
- 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();
@@ -973,7 +959,7 @@ namespace StardewModdingAPI.Metadata
// update sprite
foreach (var target in characters)
{
- target.Npc.Sprite.spriteTexture = this.LoadAndDisposeIfNeeded(target.Npc.Sprite.spriteTexture, target.AssetName.BaseName);
+ target.Npc.Sprite.spriteTexture = this.LoadTexture(target.AssetName.BaseName);
propagated[target.AssetName] = true;
}
}
@@ -1012,7 +998,7 @@ namespace StardewModdingAPI.Metadata
// update portrait
foreach (var target in characters)
{
- target.Npc.Portrait = this.LoadAndDisposeIfNeeded(target.Npc.Portrait, target.AssetName.BaseName);
+ target.Npc.Portrait = this.LoadTexture(target.AssetName.BaseName);
propagated[target.AssetName] = true;
}
}
@@ -1284,25 +1270,10 @@ namespace StardewModdingAPI.Metadata
: Array.Empty<string>();
}
- /// <summary>Load a texture, and dispose the old one if <see cref="AggressiveMemoryOptimizations"/> is enabled and it's different from the new instance.</summary>
- /// <param name="oldTexture">The previous texture to dispose.</param>
+ /// <summary>Load a texture from the main content manager.</summary>
/// <param name="key">The asset key to load.</param>
- private Texture2D LoadAndDisposeIfNeeded(Texture2D? oldTexture, string key)
+ private Texture2D LoadTexture(string key)
{
- // if aggressive memory optimizations are enabled, load the asset from the disposable
- // content manager and dispose the old instance if needed.
- if (this.AggressiveMemoryOptimizations)
- {
- GameContentManagerForAssetPropagation content = this.DisposableContentManager;
-
- Texture2D newTexture = content.Load<Texture2D>(key);
- if (oldTexture?.IsDisposed == false && !object.ReferenceEquals(oldTexture, newTexture) && content.IsResponsibleFor(oldTexture))
- oldTexture.Dispose();
-
- return newTexture;
- }
-
- // else just (re)load it from the main content manager
return this.MainContentManager.Load<Texture2D>(key);
}
diff --git a/src/SMAPI/SMAPI.config.json b/src/SMAPI/SMAPI.config.json
index 544aeaec..bdd6374a 100644
--- a/src/SMAPI/SMAPI.config.json
+++ b/src/SMAPI/SMAPI.config.json
@@ -40,13 +40,6 @@ copy all the settings, or you may cause bugs due to overridden changes in future
"RewriteMods": true,
/**
- * Whether to enable more aggressive memory optimizations.
- * If you get frequent 'OutOfMemoryException' errors, you can try enabling this to reduce their
- * frequency. This may cause crashes for farmhands in multiplayer.
- */
- "AggressiveMemoryOptimizations": false,
-
- /**
* Whether to make SMAPI file APIs case-insensitive, even on Linux.
* This is experimental, and the initial implementation may impact load times.
*/