Dalamud/Dalamud/Game/TargetSigScanner.cs
srkizer 87b9edb448
Add IInternal/PublicDisposableService (#1696)
* Add IInternal/PublicDisposableService

Plugins are exposed interfaces that are not inherited from
`IDisposable`, but services implementing plugin interfaces often
implement `IDisposable`. Some plugins may try to call
`IDisposable.Dispose` on everything provided, and it also is possible to
use `using` clause too eagerly while working on Dalamud itself, such as
writing `using var smth = await Service<SomeService>.GetAsync();`. Such
behaviors often lead to a difficult-to-debug errors, and making those
services either not an `IDisposable` or making `IDisposable.Dispose` do
nothing if the object has been loaded would prevent such errors. As
`ServiceManager` must be the only class dealing with construction and
disposal of services, `IInternalDisposableService` has been added to
limit who can dispose the object. `IPublicDisposableService` also has
been added to classes that can be constructed and accessed directly by
plugins; for those, `Dispose` will be ignored if the instance is a
service instance, and only `DisposeService` will respond.

In addition, `DalamudPluginInterface` and `UiBuilder` also have been
changed so that their `IDisposable.Dispose` no longer respond, and
instead, internal functions have been added to only allow disposal from
Dalamud.

* Cleanup

* Postmerge fixes

* More explanation on RunOnFrameworkThread(ClearHooks)

* Mark ReliableFileStorage public ctor obsolete

---------

Co-authored-by: goat <16760685+goaaats@users.noreply.github.com>
2024-03-16 15:58:05 +00:00

39 lines
1.2 KiB
C#

using System.Diagnostics;
using System.IO;
using Dalamud.IoC;
using Dalamud.IoC.Internal;
namespace Dalamud.Game;
/// <summary>
/// A SigScanner facilitates searching for memory signatures in a given ProcessModule.
/// </summary>
[PluginInterface]
[InterfaceVersion("1.0")]
[ServiceManager.ProvidedService]
#pragma warning disable SA1015
[ResolveVia<ISigScanner>]
#pragma warning restore SA1015
internal class TargetSigScanner : SigScanner, IPublicDisposableService
{
/// <summary>
/// Initializes a new instance of the <see cref="TargetSigScanner"/> class.
/// </summary>
/// <param name="doCopy">Whether or not to copy the module upon initialization for search operations to use, as to not get disturbed by possible hooks.</param>
/// <param name="cacheFile">File used to cached signatures.</param>
public TargetSigScanner(bool doCopy = false, FileInfo? cacheFile = null)
: base(Process.GetCurrentProcess().MainModule!, doCopy, cacheFile)
{
}
/// <inheritdoc/>
void IInternalDisposableService.DisposeService()
{
if (this.IsService)
this.DisposeCore();
}
/// <inheritdoc/>
void IPublicDisposableService.MarkDisposeOnlyFromService() => this.IsService = true;
}