Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AddonLifecycle AbstractAddonArgs #1415

Merged
merged 4 commits into from
Sep 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions Dalamud/Game/AddonLifecycle/AddonArgTypes/AddonArgs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using Dalamud.Memory;
using FFXIVClientStructs.FFXIV.Component.GUI;

namespace Dalamud.Game.Addon;

/// <summary>
/// Base class for AddonLifecycle AddonArgTypes.
/// </summary>
public abstract unsafe class AddonArgs
{
/// <summary>
/// Constant string representing the name of an addon that is invalid.
/// </summary>
public const string InvalidAddon = "NullAddon";

private string? addonName;

/// <summary>
/// Gets the name of the addon this args referrers to.
/// </summary>
public string AddonName => this.GetAddonName();

/// <summary>
/// Gets the pointer to the addons AtkUnitBase.
/// </summary>
public nint Addon { get; init; }

/// <summary>
/// Gets the type of these args.
/// </summary>
public abstract AddonArgsType Type { get; }

/// <summary>
/// Helper method for ensuring the name of the addon is valid.
/// </summary>
/// <returns>The name of the addon for this object. <see cref="InvalidAddon"/> when invalid.</returns>
private string GetAddonName()
{
if (this.Addon == nint.Zero) return InvalidAddon;

var addonPointer = (AtkUnitBase*)this.Addon;
if (addonPointer->Name is null) return InvalidAddon;

return this.addonName ??= MemoryHelper.ReadString((nint)addonPointer->Name, 0x20);
}
}
10 changes: 10 additions & 0 deletions Dalamud/Game/AddonLifecycle/AddonArgTypes/AddonDrawArgs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Dalamud.Game.Addon;

/// <summary>
/// Addon argument data for Finalize events.
/// </summary>
public class AddonDrawArgs : AddonArgs
{
/// <inheritdoc/>
public override AddonArgsType Type => AddonArgsType.Draw;
}
10 changes: 10 additions & 0 deletions Dalamud/Game/AddonLifecycle/AddonArgTypes/AddonFinalizeArgs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Dalamud.Game.Addon;

/// <summary>
/// Addon argument data for Finalize events.
/// </summary>
public class AddonFinalizeArgs : AddonArgs
{
/// <inheritdoc/>
public override AddonArgsType Type => AddonArgsType.Finalize;
}
28 changes: 28 additions & 0 deletions Dalamud/Game/AddonLifecycle/AddonArgTypes/AddonRefreshArgs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System;
using FFXIVClientStructs.FFXIV.Component.GUI;

namespace Dalamud.Game.Addon;

/// <summary>
/// Addon argument data for Finalize events.
/// </summary>
public class AddonRefreshArgs : AddonArgs
{
/// <inheritdoc/>
public override 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; }

/// <summary>
/// Gets the AtkValues in the form of a span.
/// </summary>
public unsafe Span<AtkValue> AtkValueSpan => new(this.AtkValues.ToPointer(), (int)this.AtkValueCount);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
namespace Dalamud.Game.Addon;

/// <summary>
/// Addon argument data for Finalize events.
/// </summary>
public class AddonRequestedUpdateArgs : AddonArgs
{
/// <inheritdoc/>
public override 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; }
}
29 changes: 29 additions & 0 deletions Dalamud/Game/AddonLifecycle/AddonArgTypes/AddonSetupArgs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System;

using FFXIVClientStructs.FFXIV.Component.GUI;

namespace Dalamud.Game.Addon;

/// <summary>
/// Addon argument data for Setup events.
/// </summary>
public class AddonSetupArgs : AddonArgs
{
/// <inheritdoc/>
public override AddonArgsType Type => AddonArgsType.Setup;

/// <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; }

/// <summary>
/// Gets the AtkValues in the form of a span.
/// </summary>
public unsafe Span<AtkValue> AtkValueSpan => new(this.AtkValues.ToPointer(), (int)this.AtkValueCount);
}
15 changes: 15 additions & 0 deletions Dalamud/Game/AddonLifecycle/AddonArgTypes/AddonUpdateArgs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace Dalamud.Game.Addon;

/// <summary>
/// Addon argument data for Finalize events.
/// </summary>
public class AddonUpdateArgs : AddonArgs
{
/// <inheritdoc/>
public override AddonArgsType Type => AddonArgsType.Update;

/// <summary>
/// Gets the time since the last update.
/// </summary>
public float TimeDelta { get; init; }
}
22 changes: 0 additions & 22 deletions Dalamud/Game/AddonLifecycle/AddonArgs.cs

This file was deleted.

37 changes: 37 additions & 0 deletions Dalamud/Game/AddonLifecycle/AddonArgsType.cs
Original file line number Diff line number Diff line change
@@ -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,
}
64 changes: 46 additions & 18 deletions Dalamud/Game/AddonLifecycle/AddonLifecycle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ internal unsafe class AddonLifecycle : IDisposable, IServiceType
private readonly Framework framework = Service<Framework>.Get();

private readonly AddonLifecycleAddressResolver address;
private readonly Hook<AddonSetupDelegate> onAddonSetupHook;
private readonly CallHook<AddonSetupDelegate> onAddonSetupHook;
private readonly Hook<AddonFinalizeDelegate> onAddonFinalizeHook;
private readonly CallHook<AddonDrawDelegate> onAddonDrawHook;
private readonly CallHook<AddonUpdateDelegate> onAddonUpdateHook;
Expand All @@ -45,15 +45,15 @@ private AddonLifecycle(SigScanner sigScanner)

this.framework.Update += this.OnFrameworkUpdate;

this.onAddonSetupHook = Hook<AddonSetupDelegate>.FromAddress(this.address.AddonSetup, this.OnAddonSetup);
this.onAddonSetupHook = new CallHook<AddonSetupDelegate>(this.address.AddonSetup, this.OnAddonSetup);
this.onAddonFinalizeHook = Hook<AddonFinalizeDelegate>.FromAddress(this.address.AddonFinalize, this.OnAddonFinalize);
this.onAddonDrawHook = new CallHook<AddonDrawDelegate>(this.address.AddonDraw, this.OnAddonDraw);
this.onAddonUpdateHook = new CallHook<AddonUpdateDelegate>(this.address.AddonUpdate, this.OnAddonUpdate);
this.onAddonRefreshHook = Hook<AddonOnRefreshDelegate>.FromAddress(this.address.AddonOnRefresh, this.OnAddonRefresh);
this.onAddonRequestedUpdateHook = new CallHook<AddonOnRequestedUpdateDelegate>(this.address.AddonOnRequestedUpdate, this.OnRequestedUpdate);
}

private delegate nint AddonSetupDelegate(AtkUnitBase* addon);
private delegate void AddonSetupDelegate(AtkUnitBase* addon, uint valueCount, AtkValue* values);

private delegate void AddonFinalizeDelegate(AtkUnitManager* unitManager, AtkUnitBase** atkUnitBase);

Expand Down Expand Up @@ -136,36 +136,44 @@ private void InvokeListeners(AddonEvent eventType, AddonArgs args)
}
}

private nint OnAddonSetup(AtkUnitBase* addon)
private void OnAddonSetup(AtkUnitBase* addon, uint valueCount, AtkValue* values)
{
try
{
this.InvokeListeners(AddonEvent.PreSetup, new AddonArgs { Addon = (nint)addon });
this.InvokeListeners(AddonEvent.PreSetup, new AddonSetupArgs
{
Addon = (nint)addon,
AtkValueCount = valueCount,
AtkValues = (nint)values,
});
}
catch (Exception e)
{
Log.Error(e, "Exception in OnAddonSetup pre-setup invoke.");
}

var result = this.onAddonSetupHook.Original(addon);
addon->OnSetup(valueCount, values);

try
{
this.InvokeListeners(AddonEvent.PostSetup, new AddonArgs { Addon = (nint)addon });
this.InvokeListeners(AddonEvent.PostSetup, new AddonSetupArgs
{
Addon = (nint)addon,
AtkValueCount = valueCount,
AtkValues = (nint)values,
});
}
catch (Exception e)
{
Log.Error(e, "Exception in OnAddonSetup post-setup invoke.");
}

return result;
}

private void OnAddonFinalize(AtkUnitManager* unitManager, AtkUnitBase** atkUnitBase)
{
try
{
this.InvokeListeners(AddonEvent.PreFinalize, new AddonArgs { Addon = (nint)atkUnitBase[0] });
this.InvokeListeners(AddonEvent.PreFinalize, new AddonFinalizeArgs { Addon = (nint)atkUnitBase[0] });
}
catch (Exception e)
{
Expand All @@ -179,7 +187,7 @@ private void OnAddonDraw(AtkUnitBase* addon)
{
try
{
this.InvokeListeners(AddonEvent.PreDraw, new AddonArgs { Addon = (nint)addon });
this.InvokeListeners(AddonEvent.PreDraw, new AddonDrawArgs { Addon = (nint)addon });
}
catch (Exception e)
{
Expand All @@ -190,7 +198,7 @@ private void OnAddonDraw(AtkUnitBase* addon)

try
{
this.InvokeListeners(AddonEvent.PostDraw, new AddonArgs { Addon = (nint)addon });
this.InvokeListeners(AddonEvent.PostDraw, new AddonDrawArgs { Addon = (nint)addon });
}
catch (Exception e)
{
Expand All @@ -202,7 +210,7 @@ private void OnAddonUpdate(AtkUnitBase* addon, float delta)
{
try
{
this.InvokeListeners(AddonEvent.PreUpdate, new AddonArgs { Addon = (nint)addon });
this.InvokeListeners(AddonEvent.PreUpdate, new AddonUpdateArgs { Addon = (nint)addon, TimeDelta = delta });
}
catch (Exception e)
{
Expand All @@ -213,7 +221,7 @@ private void OnAddonUpdate(AtkUnitBase* addon, float delta)

try
{
this.InvokeListeners(AddonEvent.PostUpdate, new AddonArgs { Addon = (nint)addon });
this.InvokeListeners(AddonEvent.PostUpdate, new AddonUpdateArgs { Addon = (nint)addon, TimeDelta = delta });
}
catch (Exception e)
{
Expand All @@ -225,7 +233,12 @@ private byte OnAddonRefresh(AtkUnitManager* atkUnitManager, AtkUnitBase* addon,
{
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)
{
Expand All @@ -236,7 +249,12 @@ private byte OnAddonRefresh(AtkUnitManager* atkUnitManager, AtkUnitBase* addon,

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)
{
Expand All @@ -250,7 +268,12 @@ private void OnRequestedUpdate(AtkUnitBase* addon, NumberArrayData** numberArray
{
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)
{
Expand All @@ -261,7 +284,12 @@ private void OnRequestedUpdate(AtkUnitBase* addon, NumberArrayData** numberArray

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)
{
Expand Down
Loading
Loading