Penumbra/Penumbra/Interop/Hooks/Resources/ResourceHandleDestructor.cs
2024-06-22 23:04:16 +02:00

53 lines
1.5 KiB
C#

using Dalamud.Hooking;
using OtterGui.Classes;
using OtterGui.Services;
using Penumbra.GameData;
using Penumbra.Interop.Structs;
using Penumbra.UI.ResourceWatcher;
namespace Penumbra.Interop.Hooks.Resources;
public sealed unsafe class ResourceHandleDestructor : EventWrapperPtr<ResourceHandle, ResourceHandleDestructor.Priority>, IHookService
{
public enum Priority
{
/// <seealso cref="PathResolving.SubfileHelper"/>
SubfileHelper,
/// <seealso cref="ShaderReplacementFixer"/>
ShaderReplacementFixer,
/// <seealso cref="ResourceWatcher.OnResourceDestroyed"/>
ResourceWatcher,
}
public ResourceHandleDestructor(HookManager hooks)
: base("Destroy ResourceHandle")
=> _task = hooks.CreateHook<Delegate>(Name, Sigs.ResourceHandleDestructor, Detour, true);
private readonly Task<Hook<Delegate>> _task;
public nint Address
=> _task.Result.Address;
public void Enable()
=> _task.Result.Enable();
public void Disable()
=> _task.Result.Disable();
public Task Awaiter
=> _task;
public bool Finished
=> _task.IsCompletedSuccessfully;
private delegate nint Delegate(ResourceHandle* resourceHandle);
private nint Detour(ResourceHandle* resourceHandle)
{
Penumbra.Log.Excessive($"[{Name}] Triggered with 0x{(nint)resourceHandle:X}.");
Invoke(resourceHandle);
return _task.Result.Original(resourceHandle);
}
}