summaryrefslogtreecommitdiff
path: root/src/StardewModdingAPI
diff options
context:
space:
mode:
authorJesse Plamondon-Willard <github@jplamondonw.com>2017-05-09 22:02:17 -0400
committerJesse Plamondon-Willard <github@jplamondonw.com>2017-05-09 22:02:17 -0400
commit494f9366a8e74f40e085581e8f085a03e3fc9e49 (patch)
treec0e97393a152e04f4fff889d966164075fb8e732 /src/StardewModdingAPI
parent7ba0518bfdfc06f2e80b6a0891689beda7f43aa7 (diff)
downloadSMAPI-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.cs20
-rw-r--r--src/StardewModdingAPI/Program.cs17
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;