Fix AddonLifecycle ABI; deprecate arg class public ctors (#1570)

This commit is contained in:
srkizer 2023-12-10 12:35:40 +09:00 committed by GitHub
parent 3611785357
commit 4d0cce134f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 119 additions and 38 deletions

View file

@ -1,4 +1,5 @@
using Dalamud.Memory;
using FFXIVClientStructs.FFXIV.Component.GUI;
namespace Dalamud.Game.Addon.Lifecycle.AddonArgTypes;
@ -12,7 +13,7 @@ public abstract unsafe class AddonArgs
/// Constant string representing the name of an addon that is invalid.
/// </summary>
public const string InvalidAddon = "NullAddon";
private string? addonName;
private IntPtr addon;
@ -26,8 +27,22 @@ public abstract unsafe class AddonArgs
/// </summary>
public nint Addon
{
get => this.addon;
internal set
get => this.AddonInternal;
init => this.AddonInternal = value;
}
/// <summary>
/// Gets the type of these args.
/// </summary>
public abstract AddonArgsType Type { get; }
/// <summary>
/// Gets or sets the pointer to the addons AtkUnitBase.
/// </summary>
internal nint AddonInternal
{
get => this.Addon;
set
{
if (this.addon == value)
return;
@ -37,11 +52,6 @@ public abstract unsafe class AddonArgs
}
}
/// <summary>
/// Gets the type of these args.
/// </summary>
public abstract AddonArgsType Type { get; }
/// <summary>
/// Checks if addon name matches the given span of char.
/// </summary>
@ -55,7 +65,7 @@ public abstract unsafe class AddonArgs
var addonPointer = (AtkUnitBase*)this.Addon;
if (addonPointer->Name is null) return false;
return MemoryHelper.EqualsZeroTerminatedString(name, (nint)addonPointer->Name, null, 0x20);
}

View file

@ -5,12 +5,20 @@
/// </summary>
public class AddonDrawArgs : AddonArgs, ICloneable
{
/// <summary>
/// Initializes a new instance of the <see cref="AddonDrawArgs"/> class.
/// </summary>
[Obsolete("Not intended for public construction.", false)]
public AddonDrawArgs()
{
}
/// <inheritdoc/>
public override AddonArgsType Type => AddonArgsType.Draw;
/// <inheritdoc cref="ICloneable.Clone"/>
public AddonDrawArgs Clone() => (AddonDrawArgs)this.MemberwiseClone();
/// <inheritdoc cref="Clone"/>
object ICloneable.Clone() => this.Clone();
}

View file

@ -5,12 +5,20 @@ namespace Dalamud.Game.Addon.Lifecycle.AddonArgTypes;
/// </summary>
public class AddonFinalizeArgs : AddonArgs, ICloneable
{
/// <summary>
/// Initializes a new instance of the <see cref="AddonFinalizeArgs"/> class.
/// </summary>
[Obsolete("Not intended for public construction.", false)]
public AddonFinalizeArgs()
{
}
/// <inheritdoc/>
public override AddonArgsType Type => AddonArgsType.Finalize;
/// <inheritdoc cref="ICloneable.Clone"/>
public AddonFinalizeArgs Clone() => (AddonFinalizeArgs)this.MemberwiseClone();
/// <inheritdoc cref="Clone"/>
object ICloneable.Clone() => this.Clone();
}

View file

@ -5,24 +5,32 @@ namespace Dalamud.Game.Addon.Lifecycle.AddonArgTypes;
/// </summary>
public class AddonReceiveEventArgs : AddonArgs, ICloneable
{
/// <summary>
/// Initializes a new instance of the <see cref="AddonReceiveEventArgs"/> class.
/// </summary>
[Obsolete("Not intended for public construction.", false)]
public AddonReceiveEventArgs()
{
}
/// <inheritdoc/>
public override AddonArgsType Type => AddonArgsType.ReceiveEvent;
/// <summary>
/// Gets or sets the AtkEventType for this event message.
/// </summary>
public byte AtkEventType { get; set; }
/// <summary>
/// Gets or sets the event id for this event message.
/// </summary>
public int EventParam { get; set; }
/// <summary>
/// Gets or sets the pointer to an AtkEvent for this event message.
/// </summary>
public nint AtkEvent { get; set; }
/// <summary>
/// Gets or sets the pointer to a block of data for this event message.
/// </summary>
@ -30,7 +38,7 @@ public class AddonReceiveEventArgs : AddonArgs, ICloneable
/// <inheritdoc cref="ICloneable.Clone"/>
public AddonReceiveEventArgs Clone() => (AddonReceiveEventArgs)this.MemberwiseClone();
/// <inheritdoc cref="Clone"/>
object ICloneable.Clone() => this.Clone();
}

View file

@ -7,19 +7,27 @@ namespace Dalamud.Game.Addon.Lifecycle.AddonArgTypes;
/// </summary>
public class AddonRefreshArgs : AddonArgs, ICloneable
{
/// <summary>
/// Initializes a new instance of the <see cref="AddonRefreshArgs"/> class.
/// </summary>
[Obsolete("Not intended for public construction.", false)]
public AddonRefreshArgs()
{
}
/// <inheritdoc/>
public override AddonArgsType Type => AddonArgsType.Refresh;
/// <summary>
/// Gets or sets the number of AtkValues.
/// </summary>
public uint AtkValueCount { get; set; }
/// <summary>
/// Gets or sets the address of the AtkValue array.
/// </summary>
public nint AtkValues { get; set; }
/// <summary>
/// Gets the AtkValues in the form of a span.
/// </summary>
@ -27,7 +35,7 @@ public class AddonRefreshArgs : AddonArgs, ICloneable
/// <inheritdoc cref="ICloneable.Clone"/>
public AddonRefreshArgs Clone() => (AddonRefreshArgs)this.MemberwiseClone();
/// <inheritdoc cref="Clone"/>
object ICloneable.Clone() => this.Clone();
}

View file

@ -5,14 +5,22 @@
/// </summary>
public class AddonRequestedUpdateArgs : AddonArgs, ICloneable
{
/// <summary>
/// Initializes a new instance of the <see cref="AddonRequestedUpdateArgs"/> class.
/// </summary>
[Obsolete("Not intended for public construction.", false)]
public AddonRequestedUpdateArgs()
{
}
/// <inheritdoc/>
public override AddonArgsType Type => AddonArgsType.RequestedUpdate;
/// <summary>
/// Gets or sets the NumberArrayData** for this event.
/// </summary>
public nint NumberArrayData { get; set; }
/// <summary>
/// Gets or sets the StringArrayData** for this event.
/// </summary>
@ -20,7 +28,7 @@ public class AddonRequestedUpdateArgs : AddonArgs, ICloneable
/// <inheritdoc cref="ICloneable.Clone"/>
public AddonRequestedUpdateArgs Clone() => (AddonRequestedUpdateArgs)this.MemberwiseClone();
/// <inheritdoc cref="Clone"/>
object ICloneable.Clone() => this.Clone();
}

View file

@ -7,19 +7,27 @@ namespace Dalamud.Game.Addon.Lifecycle.AddonArgTypes;
/// </summary>
public class AddonSetupArgs : AddonArgs, ICloneable
{
/// <summary>
/// Initializes a new instance of the <see cref="AddonSetupArgs"/> class.
/// </summary>
[Obsolete("Not intended for public construction.", false)]
public AddonSetupArgs()
{
}
/// <inheritdoc/>
public override AddonArgsType Type => AddonArgsType.Setup;
/// <summary>
/// Gets or sets the number of AtkValues.
/// </summary>
public uint AtkValueCount { get; set; }
/// <summary>
/// Gets or sets the address of the AtkValue array.
/// </summary>
public nint AtkValues { get; set; }
/// <summary>
/// Gets the AtkValues in the form of a span.
/// </summary>
@ -27,7 +35,7 @@ public class AddonSetupArgs : AddonArgs, ICloneable
/// <inheritdoc cref="ICloneable.Clone"/>
public AddonSetupArgs Clone() => (AddonSetupArgs)this.MemberwiseClone();
/// <inheritdoc cref="Clone"/>
object ICloneable.Clone() => this.Clone();
}

View file

@ -5,17 +5,34 @@ namespace Dalamud.Game.Addon.Lifecycle.AddonArgTypes;
/// </summary>
public class AddonUpdateArgs : AddonArgs, ICloneable
{
/// <summary>
/// Initializes a new instance of the <see cref="AddonUpdateArgs"/> class.
/// </summary>
[Obsolete("Not intended for public construction.", false)]
public AddonUpdateArgs()
{
}
/// <inheritdoc/>
public override AddonArgsType Type => AddonArgsType.Update;
/// <summary>
/// Gets the time since the last update.
/// </summary>
public float TimeDelta { get; internal set; }
public float TimeDelta
{
get => this.TimeDeltaInternal;
init => this.TimeDeltaInternal = value;
}
/// <summary>
/// Gets or sets the time since the last update.
/// </summary>
internal float TimeDeltaInternal { get; set; }
/// <inheritdoc cref="ICloneable.Clone"/>
public AddonUpdateArgs Clone() => (AddonUpdateArgs)this.MemberwiseClone();
/// <inheritdoc cref="Clone"/>
object ICloneable.Clone() => this.Clone();
}

View file

@ -43,12 +43,15 @@ internal unsafe class AddonLifecycle : IDisposable, IServiceType
// Note: these can be sourced from ObjectPool of appropriate types instead, but since we don't import that NuGet
// package, and these events are always called from the main thread, this is fine.
#pragma warning disable CS0618 // Type or member is obsolete
// TODO: turn constructors of these internal
private readonly AddonSetupArgs recyclingSetupArgs = new();
private readonly AddonFinalizeArgs recyclingFinalizeArgs = new();
private readonly AddonDrawArgs recyclingDrawArgs = new();
private readonly AddonUpdateArgs recyclingUpdateArgs = new();
private readonly AddonRefreshArgs recyclingRefreshArgs = new();
private readonly AddonRequestedUpdateArgs recyclingRequestedUpdateArgs = new();
#pragma warning restore CS0618 // Type or member is obsolete
[ServiceManager.ServiceConstructor]
private AddonLifecycle(TargetSigScanner sigScanner)
@ -275,7 +278,7 @@ internal unsafe class AddonLifecycle : IDisposable, IServiceType
Log.Error(e, "Exception in OnAddonSetup ReceiveEvent Registration.");
}
this.recyclingSetupArgs.Addon = (nint)addon;
this.recyclingSetupArgs.AddonInternal = (nint)addon;
this.recyclingSetupArgs.AtkValueCount = valueCount;
this.recyclingSetupArgs.AtkValues = (nint)values;
this.InvokeListenersSafely(AddonEvent.PreSetup, this.recyclingSetupArgs);
@ -306,7 +309,7 @@ internal unsafe class AddonLifecycle : IDisposable, IServiceType
Log.Error(e, "Exception in OnAddonFinalize ReceiveEvent Removal.");
}
this.recyclingFinalizeArgs.Addon = (nint)atkUnitBase[0];
this.recyclingFinalizeArgs.AddonInternal = (nint)atkUnitBase[0];
this.InvokeListenersSafely(AddonEvent.PreFinalize, this.recyclingFinalizeArgs);
try
@ -321,7 +324,7 @@ internal unsafe class AddonLifecycle : IDisposable, IServiceType
private void OnAddonDraw(AtkUnitBase* addon)
{
this.recyclingDrawArgs.Addon = (nint)addon;
this.recyclingDrawArgs.AddonInternal = (nint)addon;
this.InvokeListenersSafely(AddonEvent.PreDraw, this.recyclingDrawArgs);
try
@ -338,8 +341,8 @@ internal unsafe class AddonLifecycle : IDisposable, IServiceType
private void OnAddonUpdate(AtkUnitBase* addon, float delta)
{
this.recyclingUpdateArgs.Addon = (nint)addon;
this.recyclingUpdateArgs.TimeDelta = delta;
this.recyclingUpdateArgs.AddonInternal = (nint)addon;
this.recyclingUpdateArgs.TimeDeltaInternal = delta;
this.InvokeListenersSafely(AddonEvent.PreUpdate, this.recyclingUpdateArgs);
try
@ -358,7 +361,7 @@ internal unsafe class AddonLifecycle : IDisposable, IServiceType
{
byte result = 0;
this.recyclingRefreshArgs.Addon = (nint)addon;
this.recyclingRefreshArgs.AddonInternal = (nint)addon;
this.recyclingRefreshArgs.AtkValueCount = valueCount;
this.recyclingRefreshArgs.AtkValues = (nint)values;
this.InvokeListenersSafely(AddonEvent.PreRefresh, this.recyclingRefreshArgs);
@ -380,7 +383,7 @@ internal unsafe class AddonLifecycle : IDisposable, IServiceType
private void OnRequestedUpdate(AtkUnitBase* addon, NumberArrayData** numberArrayData, StringArrayData** stringArrayData)
{
this.recyclingRequestedUpdateArgs.Addon = (nint)addon;
this.recyclingRequestedUpdateArgs.AddonInternal = (nint)addon;
this.recyclingRequestedUpdateArgs.NumberArrayData = (nint)numberArrayData;
this.recyclingRequestedUpdateArgs.StringArrayData = (nint)stringArrayData;
this.InvokeListenersSafely(AddonEvent.PreRequestedUpdate, this.recyclingRequestedUpdateArgs);

View file

@ -18,7 +18,10 @@ internal unsafe class AddonLifecycleReceiveEventListener : IDisposable
// Note: these can be sourced from ObjectPool of appropriate types instead, but since we don't import that NuGet
// package, and these events are always called from the main thread, this is fine.
#pragma warning disable CS0618 // Type or member is obsolete
// TODO: turn constructors of these internal
private readonly AddonReceiveEventArgs recyclingReceiveEventArgs = new();
#pragma warning restore CS0618 // Type or member is obsolete
/// <summary>
/// Initializes a new instance of the <see cref="AddonLifecycleReceiveEventListener"/> class.
@ -79,7 +82,7 @@ internal unsafe class AddonLifecycleReceiveEventListener : IDisposable
return;
}
this.recyclingReceiveEventArgs.Addon = (nint)addon;
this.recyclingReceiveEventArgs.AddonInternal = (nint)addon;
this.recyclingReceiveEventArgs.AtkEventType = (byte)eventType;
this.recyclingReceiveEventArgs.EventParam = eventParam;
this.recyclingReceiveEventArgs.AtkEvent = (IntPtr)atkEvent;