Merge pull request #1365 from MidoriKami/AddonLifecycle_ExceptionSafety

This commit is contained in:
goat 2023-08-31 00:31:24 +02:00 committed by GitHub
commit fc2042ea4f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 11 additions and 29 deletions

View file

@ -1,5 +1,4 @@
using System;
using System.Runtime.InteropServices;
using Dalamud.Hooking;
using Dalamud.IoC;
@ -29,13 +28,11 @@ internal unsafe class AddonLifecycle : IDisposable, IServiceType, IAddonLifecycl
this.address.Setup(sigScanner);
this.onAddonSetupHook = Hook<AddonSetupDelegate>.FromAddress(this.address.AddonSetup, this.OnAddonSetup);
this.onAddonFinalizeHook = Hook<AddonFinalizeDelegate>.FromAddress(this.address.AddonSetup, this.OnAddonFinalize);
this.onAddonFinalizeHook = Hook<AddonFinalizeDelegate>.FromAddress(this.address.AddonFinalize, this.OnAddonFinalize);
}
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
private delegate nint AddonSetupDelegate(AtkUnitBase* addon);
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
private delegate void AddonFinalizeDelegate(AtkUnitManager* unitManager, AtkUnitBase** atkUnitBase);
/// <inheritdoc/>
@ -47,9 +44,6 @@ internal unsafe class AddonLifecycle : IDisposable, IServiceType, IAddonLifecycl
/// <inheritdoc/>
public event Action<IAddonLifecycle.AddonArgs>? AddonPreFinalize;
/// <inheritdoc/>
public event Action<IAddonLifecycle.AddonArgs>? AddonPostFinalize;
/// <inheritdoc/>
public void Dispose()
{
@ -66,6 +60,9 @@ internal unsafe class AddonLifecycle : IDisposable, IServiceType, IAddonLifecycl
private nint OnAddonSetup(AtkUnitBase* addon)
{
if (addon is null)
return this.onAddonSetupHook.Original(addon);
try
{
this.AddonPreSetup?.Invoke(new IAddonLifecycle.AddonArgs { Addon = (nint)addon });
@ -91,6 +88,12 @@ internal unsafe class AddonLifecycle : IDisposable, IServiceType, IAddonLifecycl
private void OnAddonFinalize(AtkUnitManager* unitManager, AtkUnitBase** atkUnitBase)
{
if (atkUnitBase is null || atkUnitBase[0] is null)
{
this.onAddonFinalizeHook.Original(unitManager, atkUnitBase);
return;
}
try
{
this.AddonPreFinalize?.Invoke(new IAddonLifecycle.AddonArgs { Addon = (nint)atkUnitBase[0] });
@ -101,15 +104,6 @@ internal unsafe class AddonLifecycle : IDisposable, IServiceType, IAddonLifecycl
}
this.onAddonFinalizeHook.Original(unitManager, atkUnitBase);
try
{
this.AddonPostFinalize?.Invoke(new IAddonLifecycle.AddonArgs { Addon = (nint)atkUnitBase[0] });
}
catch (Exception e)
{
Log.Error(e, "Exception in OnAddonFinalize post-finalize invoke.");
}
}
}
@ -135,7 +129,6 @@ internal class AddonLifecyclePluginScoped : IDisposable, IServiceType, IAddonLif
this.addonLifecycleService.AddonPreSetup += this.AddonPreSetupForward;
this.addonLifecycleService.AddonPostSetup += this.AddonPostSetupForward;
this.addonLifecycleService.AddonPreFinalize += this.AddonPreFinalizeForward;
this.addonLifecycleService.AddonPostFinalize += this.AddonPostFinalizeForward;
}
/// <inheritdoc/>
@ -147,16 +140,12 @@ internal class AddonLifecyclePluginScoped : IDisposable, IServiceType, IAddonLif
/// <inheritdoc/>
public event Action<IAddonLifecycle.AddonArgs>? AddonPreFinalize;
/// <inheritdoc/>
public event Action<IAddonLifecycle.AddonArgs>? AddonPostFinalize;
/// <inheritdoc/>
public void Dispose()
{
this.addonLifecycleService.AddonPreSetup -= this.AddonPreSetupForward;
this.addonLifecycleService.AddonPostSetup -= this.AddonPostSetupForward;
this.addonLifecycleService.AddonPreFinalize -= this.AddonPreFinalizeForward;
this.addonLifecycleService.AddonPostFinalize -= this.AddonPostFinalizeForward;
}
private void AddonPreSetupForward(IAddonLifecycle.AddonArgs args) => this.AddonPreSetup?.Invoke(args);
@ -164,6 +153,4 @@ internal class AddonLifecyclePluginScoped : IDisposable, IServiceType, IAddonLif
private void AddonPostSetupForward(IAddonLifecycle.AddonArgs args) => this.AddonPostSetup?.Invoke(args);
private void AddonPreFinalizeForward(IAddonLifecycle.AddonArgs args) => this.AddonPreFinalize?.Invoke(args);
private void AddonPostFinalizeForward(IAddonLifecycle.AddonArgs args) => this.AddonPostFinalize?.Invoke(args);
}

View file

@ -25,11 +25,6 @@ public interface IAddonLifecycle
/// </summary>
public event Action<AddonArgs> AddonPreFinalize;
/// <summary>
/// Event that fires after an addon is done being finalized.
/// </summary>
public event Action<AddonArgs> AddonPostFinalize;
/// <summary>
/// Addon argument data for use in event subscribers.
/// </summary>
@ -40,7 +35,7 @@ public interface IAddonLifecycle
/// <summary>
/// Gets the name of the addon this args referrers to.
/// </summary>
public string AddonName => this.addonName ??= MemoryHelper.ReadString((nint)((AtkUnitBase*)this.Addon)->Name, 0x20);
public string AddonName => this.Addon == nint.Zero ? "NullAddon" : this.addonName ??= MemoryHelper.ReadString((nint)((AtkUnitBase*)this.Addon)->Name, 0x20);
/// <summary>
/// Gets the pointer to the addons AtkUnitBase.