Fix doubled hook.

This commit is contained in:
Ottermandias 2024-06-22 23:04:09 +02:00
parent 045abc787d
commit b07af32dee
3 changed files with 23 additions and 41 deletions

View file

@ -3,6 +3,7 @@ using OtterGui.Classes;
using OtterGui.Services;
using Penumbra.GameData;
using Penumbra.Interop.Structs;
using Penumbra.UI.ResourceWatcher;
namespace Penumbra.Interop.Hooks.Resources;
@ -15,6 +16,9 @@ public sealed unsafe class ResourceHandleDestructor : EventWrapperPtr<ResourceHa
/// <seealso cref="ShaderReplacementFixer"/>
ShaderReplacementFixer,
/// <seealso cref="ResourceWatcher.OnResourceDestroyed"/>
ResourceWatcher,
}
public ResourceHandleDestructor(HookManager hooks)

View file

@ -26,7 +26,6 @@ public unsafe class ResourceService : IDisposable, IRequiredService
interop.InitializeFromAttributes(this);
_getResourceSyncHook.Enable();
_getResourceAsyncHook.Enable();
_resourceHandleDestructorHook.Enable();
_incRefHook = interop.HookFromAddress<ResourceHandlePrototype>(
(nint)CSResourceHandle.MemberFunctionPointers.IncRef,
ResourceHandleIncRefDetour);
@ -51,7 +50,6 @@ public unsafe class ResourceService : IDisposable, IRequiredService
{
_getResourceSyncHook.Dispose();
_getResourceAsyncHook.Dispose();
_resourceHandleDestructorHook.Dispose();
_incRefHook.Dispose();
_decRefHook.Dispose();
}
@ -67,8 +65,7 @@ public unsafe class ResourceService : IDisposable, IRequiredService
/// <param name="sync">Whether to request the resource synchronously or asynchronously.</param>
/// <param name="returnValue">The returned resource handle. If this is not null, calling original will be skipped. </param>
public delegate void GetResourcePreDelegate(ref ResourceCategory category, ref ResourceType type, ref int hash, ref Utf8GamePath path,
Utf8GamePath original,
GetResourceParameters* parameters, ref bool sync, ref ResourceHandle* returnValue);
Utf8GamePath original, GetResourceParameters* parameters, ref bool sync, ref ResourceHandle* returnValue);
/// <summary> <inheritdoc cref="GetResourcePreDelegate"/> <para/>
/// Subscribers should be exception-safe.</summary>
@ -192,27 +189,4 @@ public unsafe class ResourceService : IDisposable, IRequiredService
}
#endregion
#region Destructor
/// <summary> Invoked before a resource handle is destructed. </summary>
/// <param name="handle">The resource handle.</param>
public delegate void ResourceHandleDtorDelegate(ResourceHandle* handle);
/// <summary>
/// <inheritdoc cref="ResourceHandleDtorDelegate"/> <para/>
/// Subscribers should be exception-safe.
/// </summary>
public event ResourceHandleDtorDelegate? ResourceHandleDestructor;
[Signature(Sigs.ResourceHandleDestructor, DetourName = nameof(ResourceHandleDestructorDetour))]
private readonly Hook<ResourceHandlePrototype> _resourceHandleDestructorHook = null!;
private nint ResourceHandleDestructorDetour(ResourceHandle* handle)
{
ResourceHandleDestructor?.Invoke(handle);
return _resourceHandleDestructorHook.OriginalDisposeSafe(handle);
}
#endregion
}

View file

@ -8,8 +8,10 @@ using Penumbra.Api.Enums;
using Penumbra.Collections;
using Penumbra.GameData.Actors;
using Penumbra.GameData.Enums;
using Penumbra.Interop.Hooks.Resources;
using Penumbra.Interop.ResourceLoading;
using Penumbra.Interop.Structs;
using Penumbra.Services;
using Penumbra.String;
using Penumbra.String.Classes;
using Penumbra.UI.Classes;
@ -21,28 +23,30 @@ public sealed class ResourceWatcher : IDisposable, ITab, IUiService
public const int DefaultMaxEntries = 1024;
public const RecordType AllRecords = RecordType.Request | RecordType.ResourceLoad | RecordType.FileLoad | RecordType.Destruction;
private readonly Configuration _config;
private readonly EphemeralConfig _ephemeral;
private readonly ResourceService _resources;
private readonly ResourceLoader _loader;
private readonly ActorManager _actors;
private readonly List<Record> _records = [];
private readonly ConcurrentQueue<Record> _newRecords = [];
private readonly ResourceWatcherTable _table;
private string _logFilter = string.Empty;
private Regex? _logRegex;
private int _newMaxEntries;
private readonly Configuration _config;
private readonly EphemeralConfig _ephemeral;
private readonly ResourceService _resources;
private readonly ResourceLoader _loader;
private readonly ResourceHandleDestructor _destructor;
private readonly ActorManager _actors;
private readonly List<Record> _records = [];
private readonly ConcurrentQueue<Record> _newRecords = [];
private readonly ResourceWatcherTable _table;
private string _logFilter = string.Empty;
private Regex? _logRegex;
private int _newMaxEntries;
public unsafe ResourceWatcher(ActorManager actors, Configuration config, ResourceService resources, ResourceLoader loader)
public unsafe ResourceWatcher(ActorManager actors, Configuration config, ResourceService resources, ResourceLoader loader, ResourceHandleDestructor destructor)
{
_actors = actors;
_config = config;
_ephemeral = config.Ephemeral;
_resources = resources;
_destructor = destructor;
_loader = loader;
_table = new ResourceWatcherTable(config.Ephemeral, _records);
_resources.ResourceRequested += OnResourceRequested;
_resources.ResourceHandleDestructor += OnResourceDestroyed;
_destructor.Subscribe(OnResourceDestroyed, ResourceHandleDestructor.Priority.ResourceWatcher);
_loader.ResourceLoaded += OnResourceLoaded;
_loader.FileLoaded += OnFileLoaded;
UpdateFilter(_ephemeral.ResourceLoggingFilter, false);
@ -54,7 +58,7 @@ public sealed class ResourceWatcher : IDisposable, ITab, IUiService
Clear();
_records.TrimExcess();
_resources.ResourceRequested -= OnResourceRequested;
_resources.ResourceHandleDestructor -= OnResourceDestroyed;
_destructor.Unsubscribe(OnResourceDestroyed);
_loader.ResourceLoaded -= OnResourceLoaded;
_loader.FileLoaded -= OnFileLoaded;
}