diff options
author | Jesse Plamondon-Willard <github@jplamondonw.com> | 2017-05-09 22:02:17 -0400 |
---|---|---|
committer | Jesse Plamondon-Willard <github@jplamondonw.com> | 2017-05-09 22:02:17 -0400 |
commit | 494f9366a8e74f40e085581e8f085a03e3fc9e49 (patch) | |
tree | c0e97393a152e04f4fff889d966164075fb8e732 /src/StardewModdingAPI | |
parent | 7ba0518bfdfc06f2e80b6a0891689beda7f43aa7 (diff) | |
download | SMAPI-494f9366a8e74f40e085581e8f085a03e3fc9e49.tar.gz SMAPI-494f9366a8e74f40e085581e8f085a03e3fc9e49.tar.bz2 SMAPI-494f9366a8e74f40e085581e8f085a03e3fc9e49.zip |
let mods dispose unmanaged resources when SMAPI is disposing (#282)
Diffstat (limited to 'src/StardewModdingAPI')
-rw-r--r-- | src/StardewModdingAPI/Mod.cs | 20 | ||||
-rw-r--r-- | src/StardewModdingAPI/Program.cs | 17 |
2 files changed, 33 insertions, 4 deletions
diff --git a/src/StardewModdingAPI/Mod.cs b/src/StardewModdingAPI/Mod.cs index 8033e1fd..a3169fb3 100644 --- a/src/StardewModdingAPI/Mod.cs +++ b/src/StardewModdingAPI/Mod.cs @@ -5,7 +5,7 @@ using StardewModdingAPI.Framework; namespace StardewModdingAPI { /// <summary>The base class for a mod.</summary> - public class Mod : IMod + public class Mod : IMod, IDisposable { /********* ** Properties @@ -88,6 +88,14 @@ namespace StardewModdingAPI /// <param name="helper">Provides simplified APIs for writing mods.</param> public virtual void Entry(IModHelper helper) { } + /// <summary>Release or reset unmanaged resources.</summary> + public void Dispose() + { + (this.Helper as IDisposable)?.Dispose(); // deliberate do this outside overridable dispose method so mods don't accidentally suppress it + this.Dispose(true); + GC.SuppressFinalize(this); + } + /********* ** Private methods @@ -106,5 +114,15 @@ namespace StardewModdingAPI } return Path.Combine(this.PathOnDisk, "psconfigs"); } + + /// <summary>Release or reset unmanaged resources.</summary> + /// <param name="disposing">Whether the instance is being disposed explicitly rather than finalised. If this is false, the instance shouldn't dispose other objects since they may already be finalised.</param> + protected virtual void Dispose(bool disposing) { } + + /// <summary>Destruct the instance.</summary> + ~Mod() + { + this.Dispose(false); + } } } diff --git a/src/StardewModdingAPI/Program.cs b/src/StardewModdingAPI/Program.cs index 725ac94f..a5905805 100644 --- a/src/StardewModdingAPI/Program.cs +++ b/src/StardewModdingAPI/Program.cs @@ -228,14 +228,25 @@ namespace StardewModdingAPI /// <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.</summary> public void Dispose() { + this.Monitor.Log("Disposing...", LogLevel.Trace); + // skip if already disposed if (this.IsDisposed) return; this.IsDisposed = true; - // dispose mod helpers - foreach (var mod in this.ModRegistry.GetMods()) - (mod.Helper as IDisposable)?.Dispose(); + // dispose mod data + foreach (IMod mod in this.ModRegistry.GetMods()) + { + try + { + (mod as IDisposable)?.Dispose(); + } + catch (Exception ex) + { + this.Monitor.Log($"The {mod.ModManifest.Name} mod failed during disposal: {ex.GetLogSummary()}.", LogLevel.Warn); + } + } // dispose core components this.IsGameRunning = false; |