summaryrefslogtreecommitdiff
path: root/src/SMAPI/Framework/SContentManager.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/SMAPI/Framework/SContentManager.cs')
-rw-r--r--src/SMAPI/Framework/SContentManager.cs31
1 files changed, 30 insertions, 1 deletions
diff --git a/src/SMAPI/Framework/SContentManager.cs b/src/SMAPI/Framework/SContentManager.cs
index 8f008041..e9f46acb 100644
--- a/src/SMAPI/Framework/SContentManager.cs
+++ b/src/SMAPI/Framework/SContentManager.cs
@@ -43,12 +43,18 @@ namespace StardewModdingAPI.Framework
/// <summary>The path prefix for assets in mod folders.</summary>
private readonly string ModContentPrefix;
+ /// <summary>A callback to invoke when the content manager is being disposed.</summary>
+ private readonly Action<SContentManager> OnDisposing;
+
/// <summary>Interceptors which provide the initial versions of matching assets.</summary>
private IDictionary<IModMetadata, IList<IAssetLoader>> Loaders => this.Coordinator.Loaders;
/// <summary>Interceptors which edit matching assets after they're loaded.</summary>
private IDictionary<IModMetadata, IList<IAssetEditor>> Editors => this.Coordinator.Editors;
+ /// <summary>Whether the content coordinator has been disposed.</summary>
+ private bool IsDisposed;
+
/*********
** Accessors
@@ -78,7 +84,8 @@ namespace StardewModdingAPI.Framework
/// <param name="monitor">Encapsulates monitoring and logging.</param>
/// <param name="reflection">Simplifies access to private code.</param>
/// <param name="isModFolder">Whether this content manager is wrapped around a mod folder.</param>
- public SContentManager(string name, IServiceProvider serviceProvider, string rootDirectory, CultureInfo currentCulture, ContentCoordinator coordinator, IMonitor monitor, Reflector reflection, bool isModFolder)
+ /// <param name="onDisposing">A callback to invoke when the content manager is being disposed.</param>
+ public SContentManager(string name, IServiceProvider serviceProvider, string rootDirectory, CultureInfo currentCulture, ContentCoordinator coordinator, IMonitor monitor, Reflector reflection, Action<SContentManager> onDisposing, bool isModFolder)
: base(serviceProvider, rootDirectory, currentCulture)
{
// init
@@ -88,6 +95,7 @@ namespace StardewModdingAPI.Framework
this.Cache = new ContentCache(this, reflection);
this.Monitor = monitor ?? throw new ArgumentNullException(nameof(monitor));
this.ModContentPrefix = this.GetAssetNameFromFilePath(Constants.ModPath, ContentSource.GameContent);
+ this.OnDisposing = onDisposing;
// get asset data
this.LanguageCodes = this.GetKeyLocales().ToDictionary(p => p.Value, p => p.Key, StringComparer.InvariantCultureIgnoreCase);
@@ -291,6 +299,27 @@ namespace StardewModdingAPI.Framework
return removeAssetNames;
}
+ /// <summary>Dispose held resources.</summary>
+ /// <param name="isDisposing">Whether the content manager is being disposed (rather than finalized).</param>
+ protected override void Dispose(bool isDisposing)
+ {
+ if (this.IsDisposed)
+ return;
+ this.IsDisposed = true;
+
+ this.OnDisposing(this);
+ base.Dispose(isDisposing);
+ }
+
+ /// <inheritdoc />
+ public override void Unload()
+ {
+ if (this.IsDisposed)
+ return; // base logic doesn't allow unloading twice, which happens due to SMAPI and the game both unloading
+
+ base.Unload();
+ }
+
/*********
** Private methods