Include argument data in event information.

This commit is contained in:
MidoriKami 2023-09-21 15:26:08 -07:00
parent dc54f040b9
commit 0636a03e41
14 changed files with 209 additions and 45 deletions

View file

@ -160,7 +160,7 @@ internal unsafe class AddonEventManager : IDisposable, IServiceType
/// </summary> /// </summary>
/// <param name="eventType">Event type that triggered this call.</param> /// <param name="eventType">Event type that triggered this call.</param>
/// <param name="addonInfo">Addon that triggered this call.</param> /// <param name="addonInfo">Addon that triggered this call.</param>
private void OnAddonFinalize(AddonEvent eventType, AddonArgs addonInfo) private void OnAddonFinalize(AddonEvent eventType, IAddonArgs addonInfo)
{ {
// It shouldn't be possible for this event to be anything other than PreFinalize. // It shouldn't be possible for this event to be anything other than PreFinalize.
if (eventType != AddonEvent.PreFinalize) return; if (eventType != AddonEvent.PreFinalize) return;

View file

@ -0,0 +1,13 @@
namespace Dalamud.Game.Addon.AddonArgTypes;
/// <summary>
/// Addon argument data for Finalize events.
/// </summary>
public class AddonDrawArgs : IAddonArgs
{
/// <inheritdoc/>
public nint Addon { get; init; }
/// <inheritdoc/>
public AddonArgsType Type => AddonArgsType.Draw;
}

View file

@ -0,0 +1,13 @@
namespace Dalamud.Game.Addon.AddonArgTypes;
/// <summary>
/// Addon argument data for Finalize events.
/// </summary>
public class AddonFinalizeArgs : IAddonArgs
{
/// <inheritdoc/>
public nint Addon { get; init; }
/// <inheritdoc/>
public AddonArgsType Type => AddonArgsType.Finalize;
}

View file

@ -0,0 +1,23 @@
namespace Dalamud.Game.Addon.AddonArgTypes;
/// <summary>
/// Addon argument data for Finalize events.
/// </summary>
public class AddonRefreshArgs : IAddonArgs
{
/// <inheritdoc/>
public nint Addon { get; init; }
/// <inheritdoc/>
public AddonArgsType Type => AddonArgsType.Refresh;
/// <summary>
/// Gets the number of AtkValues.
/// </summary>
public uint AtkValueCount { get; init; }
/// <summary>
/// Gets the address of the AtkValue array.
/// </summary>
public nint AtkValues { get; init; }
}

View file

@ -0,0 +1,23 @@
namespace Dalamud.Game.Addon.AddonArgTypes;
/// <summary>
/// Addon argument data for Finalize events.
/// </summary>
public class AddonRequestedUpdateArgs : IAddonArgs
{
/// <inheritdoc/>
public nint Addon { get; init; }
/// <inheritdoc/>
public AddonArgsType Type => AddonArgsType.RequestedUpdate;
/// <summary>
/// Gets the NumberArrayData** for this event.
/// </summary>
public nint NumberArrayData { get; init; }
/// <summary>
/// Gets the StringArrayData** for this event.
/// </summary>
public nint StringArrayData { get; init; }
}

View file

@ -0,0 +1,13 @@
namespace Dalamud.Game.Addon.AddonArgTypes;
/// <summary>
/// Addon argument data for Setup events.
/// </summary>
public class AddonSetupArgs : IAddonArgs
{
/// <inheritdoc/>
public nint Addon { get; init; }
/// <inheritdoc/>
public AddonArgsType Type => AddonArgsType.Setup;
}

View file

@ -0,0 +1,18 @@
namespace Dalamud.Game.Addon.AddonArgTypes;
/// <summary>
/// Addon argument data for Finalize events.
/// </summary>
public class AddonUpdateArgs : IAddonArgs
{
/// <inheritdoc/>
public nint Addon { get; init; }
/// <inheritdoc/>
public AddonArgsType Type => AddonArgsType.Update;
/// <summary>
/// Gets the time since the last update.
/// </summary>
public float TimeDelta { get; init; }
}

View file

@ -1,22 +0,0 @@
using Dalamud.Memory;
using FFXIVClientStructs.FFXIV.Component.GUI;
namespace Dalamud.Game.Addon;
/// <summary>
/// Addon argument data for use in event subscribers.
/// </summary>
public unsafe class AddonArgs
{
private string? addonName;
/// <summary>
/// Gets the name of the addon this args referrers to.
/// </summary>
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.
/// </summary>
required public nint Addon { get; init; }
}

View file

@ -0,0 +1,37 @@
namespace Dalamud.Game.Addon;
/// <summary>
/// Enumeration for available AddonLifecycle arg data
/// </summary>
public enum AddonArgsType
{
/// <summary>
/// Contains argument data for Setup.
/// </summary>
Setup,
/// <summary>
/// Contains argument data for Update.
/// </summary>
Update,
/// <summary>
/// Contains argument data for Draw.
/// </summary>
Draw,
/// <summary>
/// Contains argument data for Finalize.
/// </summary>
Finalize,
/// <summary>
/// Contains argument data for RequestedUpdate.
/// </summary>
RequestedUpdate,
/// <summary>
/// Contains argument data for Refresh.
/// </summary>
Refresh,
}

View file

@ -3,6 +3,7 @@ using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Dalamud.Game.Addon.AddonArgTypes;
using Dalamud.Hooking; using Dalamud.Hooking;
using Dalamud.Hooking.Internal; using Dalamud.Hooking.Internal;
using Dalamud.IoC; using Dalamud.IoC;
@ -127,7 +128,7 @@ internal unsafe class AddonLifecycle : IDisposable, IServiceType
this.onAddonRequestedUpdateHook.Enable(); this.onAddonRequestedUpdateHook.Enable();
} }
private void InvokeListeners(AddonEvent eventType, AddonArgs args) private void InvokeListeners(AddonEvent eventType, IAddonArgs args)
{ {
// Match on string.empty for listeners that want events for all addons. // Match on string.empty for listeners that want events for all addons.
foreach (var listener in this.eventListeners.Where(listener => listener.EventType == eventType && (listener.AddonName == args.AddonName || listener.AddonName == string.Empty))) foreach (var listener in this.eventListeners.Where(listener => listener.EventType == eventType && (listener.AddonName == args.AddonName || listener.AddonName == string.Empty)))
@ -140,7 +141,7 @@ internal unsafe class AddonLifecycle : IDisposable, IServiceType
{ {
try try
{ {
this.InvokeListeners(AddonEvent.PreSetup, new AddonArgs { Addon = (nint)addon }); this.InvokeListeners(AddonEvent.PreSetup, new AddonSetupArgs { Addon = (nint)addon });
} }
catch (Exception e) catch (Exception e)
{ {
@ -151,7 +152,7 @@ internal unsafe class AddonLifecycle : IDisposable, IServiceType
try try
{ {
this.InvokeListeners(AddonEvent.PostSetup, new AddonArgs { Addon = (nint)addon }); this.InvokeListeners(AddonEvent.PostSetup, new AddonSetupArgs { Addon = (nint)addon });
} }
catch (Exception e) catch (Exception e)
{ {
@ -165,7 +166,7 @@ internal unsafe class AddonLifecycle : IDisposable, IServiceType
{ {
try try
{ {
this.InvokeListeners(AddonEvent.PreFinalize, new AddonArgs { Addon = (nint)atkUnitBase[0] }); this.InvokeListeners(AddonEvent.PreFinalize, new AddonFinalizeArgs { Addon = (nint)atkUnitBase[0] });
} }
catch (Exception e) catch (Exception e)
{ {
@ -179,7 +180,7 @@ internal unsafe class AddonLifecycle : IDisposable, IServiceType
{ {
try try
{ {
this.InvokeListeners(AddonEvent.PreDraw, new AddonArgs { Addon = (nint)addon }); this.InvokeListeners(AddonEvent.PreDraw, new AddonDrawArgs { Addon = (nint)addon });
} }
catch (Exception e) catch (Exception e)
{ {
@ -190,7 +191,7 @@ internal unsafe class AddonLifecycle : IDisposable, IServiceType
try try
{ {
this.InvokeListeners(AddonEvent.PostDraw, new AddonArgs { Addon = (nint)addon }); this.InvokeListeners(AddonEvent.PostDraw, new AddonDrawArgs { Addon = (nint)addon });
} }
catch (Exception e) catch (Exception e)
{ {
@ -202,7 +203,7 @@ internal unsafe class AddonLifecycle : IDisposable, IServiceType
{ {
try try
{ {
this.InvokeListeners(AddonEvent.PreUpdate, new AddonArgs { Addon = (nint)addon }); this.InvokeListeners(AddonEvent.PreUpdate, new AddonUpdateArgs { Addon = (nint)addon, TimeDelta = delta });
} }
catch (Exception e) catch (Exception e)
{ {
@ -213,7 +214,7 @@ internal unsafe class AddonLifecycle : IDisposable, IServiceType
try try
{ {
this.InvokeListeners(AddonEvent.PostUpdate, new AddonArgs { Addon = (nint)addon }); this.InvokeListeners(AddonEvent.PostUpdate, new AddonUpdateArgs { Addon = (nint)addon, TimeDelta = delta });
} }
catch (Exception e) catch (Exception e)
{ {
@ -225,7 +226,12 @@ internal unsafe class AddonLifecycle : IDisposable, IServiceType
{ {
try try
{ {
this.InvokeListeners(AddonEvent.PreRefresh, new AddonArgs { Addon = (nint)addon }); this.InvokeListeners(AddonEvent.PreRefresh, new AddonRefreshArgs
{
Addon = (nint)addon,
AtkValueCount = valueCount,
AtkValues = (nint)values,
});
} }
catch (Exception e) catch (Exception e)
{ {
@ -236,7 +242,12 @@ internal unsafe class AddonLifecycle : IDisposable, IServiceType
try try
{ {
this.InvokeListeners(AddonEvent.PostRefresh, new AddonArgs { Addon = (nint)addon }); this.InvokeListeners(AddonEvent.PostRefresh, new AddonRefreshArgs
{
Addon = (nint)addon,
AtkValueCount = valueCount,
AtkValues = (nint)values,
});
} }
catch (Exception e) catch (Exception e)
{ {
@ -250,7 +261,12 @@ internal unsafe class AddonLifecycle : IDisposable, IServiceType
{ {
try try
{ {
this.InvokeListeners(AddonEvent.PreRequestedUpdate, new AddonArgs { Addon = (nint)addon }); this.InvokeListeners(AddonEvent.PreRequestedUpdate, new AddonRequestedUpdateArgs
{
Addon = (nint)addon,
NumberArrayData = (nint)numberArrayData,
StringArrayData = (nint)stringArrayData,
});
} }
catch (Exception e) catch (Exception e)
{ {
@ -261,7 +277,12 @@ internal unsafe class AddonLifecycle : IDisposable, IServiceType
try try
{ {
this.InvokeListeners(AddonEvent.PostRequestedUpdate, new AddonArgs { Addon = (nint)addon }); this.InvokeListeners(AddonEvent.PostRequestedUpdate, new AddonRequestedUpdateArgs
{
Addon = (nint)addon,
NumberArrayData = (nint)numberArrayData,
StringArrayData = (nint)stringArrayData,
});
} }
catch (Exception e) catch (Exception e)
{ {

View file

@ -0,0 +1,25 @@
using Dalamud.Memory;
using FFXIVClientStructs.FFXIV.Component.GUI;
namespace Dalamud.Game.Addon;
/// <summary>
/// Interface representing the argument data for AddonLifecycle events.
/// </summary>
public unsafe interface IAddonArgs
{
/// <summary>
/// Gets the name of the addon this args referrers to.
/// </summary>
string AddonName => this.Addon == nint.Zero ? "NullAddon" : MemoryHelper.ReadString((nint)((AtkUnitBase*)this.Addon)->Name, 0x20);
/// <summary>
/// Gets the pointer to the addons AtkUnitBase.
/// </summary>
nint Addon { get; init; }
/// <summary>
/// Gets the type of these args.
/// </summary>
AddonArgsType Type { get; }
}

View file

@ -255,7 +255,7 @@ public sealed unsafe class DtrBar : IDisposable, IServiceType, IDtrBar
} }
} }
private void OnDtrPostDraw(AddonEvent eventType, AddonArgs addonInfo) private void OnDtrPostDraw(AddonEvent eventType, IAddonArgs addonInfo)
{ {
var addon = (AtkUnitBase*)addonInfo.Addon; var addon = (AtkUnitBase*)addonInfo.Addon;
@ -300,7 +300,7 @@ public sealed unsafe class DtrBar : IDisposable, IServiceType, IDtrBar
} }
} }
private void OnAddonRequestedUpdateDetour(AddonEvent eventType, AddonArgs addonInfo) private void OnAddonRequestedUpdateDetour(AddonEvent eventType, IAddonArgs addonInfo)
{ {
var addon = (AtkUnitBase*)addonInfo.Addon; var addon = (AtkUnitBase*)addonInfo.Addon;

View file

@ -100,32 +100,32 @@ internal class AddonLifecycleAgingStep : IAgingStep
} }
} }
private void PostSetup(AddonEvent eventType, AddonArgs addonInfo) private void PostSetup(AddonEvent eventType, IAddonArgs addonInfo)
{ {
if (this.currentStep is TestStep.CharacterSetup) this.currentStep++; if (this.currentStep is TestStep.CharacterSetup) this.currentStep++;
} }
private void PostUpdate(AddonEvent eventType, AddonArgs addonInfo) private void PostUpdate(AddonEvent eventType, IAddonArgs addonInfo)
{ {
if (this.currentStep is TestStep.CharacterUpdate) this.currentStep++; if (this.currentStep is TestStep.CharacterUpdate) this.currentStep++;
} }
private void PostDraw(AddonEvent eventType, AddonArgs addonInfo) private void PostDraw(AddonEvent eventType, IAddonArgs addonInfo)
{ {
if (this.currentStep is TestStep.CharacterDraw) this.currentStep++; if (this.currentStep is TestStep.CharacterDraw) this.currentStep++;
} }
private void PostRefresh(AddonEvent eventType, AddonArgs addonInfo) private void PostRefresh(AddonEvent eventType, IAddonArgs addonInfo)
{ {
if (this.currentStep is TestStep.CharacterRefresh) this.currentStep++; if (this.currentStep is TestStep.CharacterRefresh) this.currentStep++;
} }
private void PostRequestedUpdate(AddonEvent eventType, AddonArgs addonInfo) private void PostRequestedUpdate(AddonEvent eventType, IAddonArgs addonInfo)
{ {
if (this.currentStep is TestStep.CharacterRequestedUpdate) this.currentStep++; if (this.currentStep is TestStep.CharacterRequestedUpdate) this.currentStep++;
} }
private void PreFinalize(AddonEvent eventType, AddonArgs addonInfo) private void PreFinalize(AddonEvent eventType, IAddonArgs addonInfo)
{ {
if (this.currentStep is TestStep.CharacterFinalize) this.currentStep++; if (this.currentStep is TestStep.CharacterFinalize) this.currentStep++;
} }

View file

@ -14,8 +14,8 @@ public interface IAddonLifecycle
/// Delegate for receiving addon lifecycle event messages. /// Delegate for receiving addon lifecycle event messages.
/// </summary> /// </summary>
/// <param name="eventType">The event type that triggered the message.</param> /// <param name="eventType">The event type that triggered the message.</param>
/// <param name="addonInfo">Information about what addon triggered the message.</param> /// <param name="args">Information about what addon triggered the message.</param>
public delegate void AddonEventDelegate(AddonEvent eventType, AddonArgs addonInfo); public delegate void AddonEventDelegate(AddonEvent eventType, IAddonArgs args);
/// <summary> /// <summary>
/// Register a listener that will trigger on the specified event and any of the specified addons. /// Register a listener that will trigger on the specified event and any of the specified addons.