let mods dispose unmanaged resources when SMAPI is disposing (#282)
This commit is contained in:
parent
7ba0518bfd
commit
494f9366a8
|
@ -20,6 +20,7 @@ For players:
|
||||||
For mod developers:
|
For mod developers:
|
||||||
* Added log entries for basic context changes (e.g. loaded save) to simplify troubleshooting. More detailed logging can be enabled by setting `VerboseLogging: true` in `StardewModdingAPI.config.json`.
|
* Added log entries for basic context changes (e.g. loaded save) to simplify troubleshooting. More detailed logging can be enabled by setting `VerboseLogging: true` in `StardewModdingAPI.config.json`.
|
||||||
* Added `debug` console command to TrainerMod which lets you pass debug commands to the game (e.g. `debug warp FarmHouse 1 1` warps the player to the farmhouse).
|
* Added `debug` console command to TrainerMod which lets you pass debug commands to the game (e.g. `debug warp FarmHouse 1 1` warps the player to the farmhouse).
|
||||||
|
* Mods now implement `IDisposable` to let them release any unmanaged resources.
|
||||||
|
|
||||||
## 1.12
|
## 1.12
|
||||||
See [log](https://github.com/Pathoschild/SMAPI/compare/1.11...1.12).
|
See [log](https://github.com/Pathoschild/SMAPI/compare/1.11...1.12).
|
||||||
|
|
|
@ -5,7 +5,7 @@ using StardewModdingAPI.Framework;
|
||||||
namespace StardewModdingAPI
|
namespace StardewModdingAPI
|
||||||
{
|
{
|
||||||
/// <summary>The base class for a mod.</summary>
|
/// <summary>The base class for a mod.</summary>
|
||||||
public class Mod : IMod
|
public class Mod : IMod, IDisposable
|
||||||
{
|
{
|
||||||
/*********
|
/*********
|
||||||
** Properties
|
** Properties
|
||||||
|
@ -88,6 +88,14 @@ namespace StardewModdingAPI
|
||||||
/// <param name="helper">Provides simplified APIs for writing mods.</param>
|
/// <param name="helper">Provides simplified APIs for writing mods.</param>
|
||||||
public virtual void Entry(IModHelper helper) { }
|
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
|
** Private methods
|
||||||
|
@ -106,5 +114,15 @@ namespace StardewModdingAPI
|
||||||
}
|
}
|
||||||
return Path.Combine(this.PathOnDisk, "psconfigs");
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -228,14 +228,25 @@ namespace StardewModdingAPI
|
||||||
/// <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.</summary>
|
/// <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.</summary>
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
|
this.Monitor.Log("Disposing...", LogLevel.Trace);
|
||||||
|
|
||||||
// skip if already disposed
|
// skip if already disposed
|
||||||
if (this.IsDisposed)
|
if (this.IsDisposed)
|
||||||
return;
|
return;
|
||||||
this.IsDisposed = true;
|
this.IsDisposed = true;
|
||||||
|
|
||||||
// dispose mod helpers
|
// dispose mod data
|
||||||
foreach (var mod in this.ModRegistry.GetMods())
|
foreach (IMod mod in this.ModRegistry.GetMods())
|
||||||
(mod.Helper as IDisposable)?.Dispose();
|
{
|
||||||
|
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
|
// dispose core components
|
||||||
this.IsGameRunning = false;
|
this.IsGameRunning = false;
|
||||||
|
|
Loading…
Reference in New Issue