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

View file

@ -5,12 +5,20 @@
/// </summary> /// </summary>
public class AddonDrawArgs : AddonArgs, ICloneable 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/> /// <inheritdoc/>
public override AddonArgsType Type => AddonArgsType.Draw; public override AddonArgsType Type => AddonArgsType.Draw;
/// <inheritdoc cref="ICloneable.Clone"/> /// <inheritdoc cref="ICloneable.Clone"/>
public AddonDrawArgs Clone() => (AddonDrawArgs)this.MemberwiseClone(); public AddonDrawArgs Clone() => (AddonDrawArgs)this.MemberwiseClone();
/// <inheritdoc cref="Clone"/> /// <inheritdoc cref="Clone"/>
object ICloneable.Clone() => this.Clone(); object ICloneable.Clone() => this.Clone();
} }

View file

@ -5,12 +5,20 @@ namespace Dalamud.Game.Addon.Lifecycle.AddonArgTypes;
/// </summary> /// </summary>
public class AddonFinalizeArgs : AddonArgs, ICloneable 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/> /// <inheritdoc/>
public override AddonArgsType Type => AddonArgsType.Finalize; public override AddonArgsType Type => AddonArgsType.Finalize;
/// <inheritdoc cref="ICloneable.Clone"/> /// <inheritdoc cref="ICloneable.Clone"/>
public AddonFinalizeArgs Clone() => (AddonFinalizeArgs)this.MemberwiseClone(); public AddonFinalizeArgs Clone() => (AddonFinalizeArgs)this.MemberwiseClone();
/// <inheritdoc cref="Clone"/> /// <inheritdoc cref="Clone"/>
object ICloneable.Clone() => this.Clone(); object ICloneable.Clone() => this.Clone();
} }

View file

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

View file

@ -7,19 +7,27 @@ namespace Dalamud.Game.Addon.Lifecycle.AddonArgTypes;
/// </summary> /// </summary>
public class AddonRefreshArgs : AddonArgs, ICloneable 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/> /// <inheritdoc/>
public override AddonArgsType Type => AddonArgsType.Refresh; public override AddonArgsType Type => AddonArgsType.Refresh;
/// <summary> /// <summary>
/// Gets or sets the number of AtkValues. /// Gets or sets the number of AtkValues.
/// </summary> /// </summary>
public uint AtkValueCount { get; set; } public uint AtkValueCount { get; set; }
/// <summary> /// <summary>
/// Gets or sets the address of the AtkValue array. /// Gets or sets the address of the AtkValue array.
/// </summary> /// </summary>
public nint AtkValues { get; set; } public nint AtkValues { get; set; }
/// <summary> /// <summary>
/// Gets the AtkValues in the form of a span. /// Gets the AtkValues in the form of a span.
/// </summary> /// </summary>
@ -27,7 +35,7 @@ public class AddonRefreshArgs : AddonArgs, ICloneable
/// <inheritdoc cref="ICloneable.Clone"/> /// <inheritdoc cref="ICloneable.Clone"/>
public AddonRefreshArgs Clone() => (AddonRefreshArgs)this.MemberwiseClone(); public AddonRefreshArgs Clone() => (AddonRefreshArgs)this.MemberwiseClone();
/// <inheritdoc cref="Clone"/> /// <inheritdoc cref="Clone"/>
object ICloneable.Clone() => this.Clone(); object ICloneable.Clone() => this.Clone();
} }

View file

@ -5,14 +5,22 @@
/// </summary> /// </summary>
public class AddonRequestedUpdateArgs : AddonArgs, ICloneable 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/> /// <inheritdoc/>
public override AddonArgsType Type => AddonArgsType.RequestedUpdate; public override AddonArgsType Type => AddonArgsType.RequestedUpdate;
/// <summary> /// <summary>
/// Gets or sets the NumberArrayData** for this event. /// Gets or sets the NumberArrayData** for this event.
/// </summary> /// </summary>
public nint NumberArrayData { get; set; } public nint NumberArrayData { get; set; }
/// <summary> /// <summary>
/// Gets or sets the StringArrayData** for this event. /// Gets or sets the StringArrayData** for this event.
/// </summary> /// </summary>
@ -20,7 +28,7 @@ public class AddonRequestedUpdateArgs : AddonArgs, ICloneable
/// <inheritdoc cref="ICloneable.Clone"/> /// <inheritdoc cref="ICloneable.Clone"/>
public AddonRequestedUpdateArgs Clone() => (AddonRequestedUpdateArgs)this.MemberwiseClone(); public AddonRequestedUpdateArgs Clone() => (AddonRequestedUpdateArgs)this.MemberwiseClone();
/// <inheritdoc cref="Clone"/> /// <inheritdoc cref="Clone"/>
object ICloneable.Clone() => this.Clone(); object ICloneable.Clone() => this.Clone();
} }

View file

@ -7,19 +7,27 @@ namespace Dalamud.Game.Addon.Lifecycle.AddonArgTypes;
/// </summary> /// </summary>
public class AddonSetupArgs : AddonArgs, ICloneable 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/> /// <inheritdoc/>
public override AddonArgsType Type => AddonArgsType.Setup; public override AddonArgsType Type => AddonArgsType.Setup;
/// <summary> /// <summary>
/// Gets or sets the number of AtkValues. /// Gets or sets the number of AtkValues.
/// </summary> /// </summary>
public uint AtkValueCount { get; set; } public uint AtkValueCount { get; set; }
/// <summary> /// <summary>
/// Gets or sets the address of the AtkValue array. /// Gets or sets the address of the AtkValue array.
/// </summary> /// </summary>
public nint AtkValues { get; set; } public nint AtkValues { get; set; }
/// <summary> /// <summary>
/// Gets the AtkValues in the form of a span. /// Gets the AtkValues in the form of a span.
/// </summary> /// </summary>
@ -27,7 +35,7 @@ public class AddonSetupArgs : AddonArgs, ICloneable
/// <inheritdoc cref="ICloneable.Clone"/> /// <inheritdoc cref="ICloneable.Clone"/>
public AddonSetupArgs Clone() => (AddonSetupArgs)this.MemberwiseClone(); public AddonSetupArgs Clone() => (AddonSetupArgs)this.MemberwiseClone();
/// <inheritdoc cref="Clone"/> /// <inheritdoc cref="Clone"/>
object ICloneable.Clone() => this.Clone(); object ICloneable.Clone() => this.Clone();
} }

View file

@ -5,17 +5,34 @@ namespace Dalamud.Game.Addon.Lifecycle.AddonArgTypes;
/// </summary> /// </summary>
public class AddonUpdateArgs : AddonArgs, ICloneable 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/> /// <inheritdoc/>
public override AddonArgsType Type => AddonArgsType.Update; public override AddonArgsType Type => AddonArgsType.Update;
/// <summary> /// <summary>
/// Gets the time since the last update. /// Gets the time since the last update.
/// </summary> /// </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"/> /// <inheritdoc cref="ICloneable.Clone"/>
public AddonUpdateArgs Clone() => (AddonUpdateArgs)this.MemberwiseClone(); public AddonUpdateArgs Clone() => (AddonUpdateArgs)this.MemberwiseClone();
/// <inheritdoc cref="Clone"/> /// <inheritdoc cref="Clone"/>
object ICloneable.Clone() => this.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 // 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. // 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 AddonSetupArgs recyclingSetupArgs = new();
private readonly AddonFinalizeArgs recyclingFinalizeArgs = new(); private readonly AddonFinalizeArgs recyclingFinalizeArgs = new();
private readonly AddonDrawArgs recyclingDrawArgs = new(); private readonly AddonDrawArgs recyclingDrawArgs = new();
private readonly AddonUpdateArgs recyclingUpdateArgs = new(); private readonly AddonUpdateArgs recyclingUpdateArgs = new();
private readonly AddonRefreshArgs recyclingRefreshArgs = new(); private readonly AddonRefreshArgs recyclingRefreshArgs = new();
private readonly AddonRequestedUpdateArgs recyclingRequestedUpdateArgs = new(); private readonly AddonRequestedUpdateArgs recyclingRequestedUpdateArgs = new();
#pragma warning restore CS0618 // Type or member is obsolete
[ServiceManager.ServiceConstructor] [ServiceManager.ServiceConstructor]
private AddonLifecycle(TargetSigScanner sigScanner) private AddonLifecycle(TargetSigScanner sigScanner)
@ -275,7 +278,7 @@ internal unsafe class AddonLifecycle : IDisposable, IServiceType
Log.Error(e, "Exception in OnAddonSetup ReceiveEvent Registration."); Log.Error(e, "Exception in OnAddonSetup ReceiveEvent Registration.");
} }
this.recyclingSetupArgs.Addon = (nint)addon; this.recyclingSetupArgs.AddonInternal = (nint)addon;
this.recyclingSetupArgs.AtkValueCount = valueCount; this.recyclingSetupArgs.AtkValueCount = valueCount;
this.recyclingSetupArgs.AtkValues = (nint)values; this.recyclingSetupArgs.AtkValues = (nint)values;
this.InvokeListenersSafely(AddonEvent.PreSetup, this.recyclingSetupArgs); this.InvokeListenersSafely(AddonEvent.PreSetup, this.recyclingSetupArgs);
@ -306,7 +309,7 @@ internal unsafe class AddonLifecycle : IDisposable, IServiceType
Log.Error(e, "Exception in OnAddonFinalize ReceiveEvent Removal."); 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); this.InvokeListenersSafely(AddonEvent.PreFinalize, this.recyclingFinalizeArgs);
try try
@ -321,7 +324,7 @@ internal unsafe class AddonLifecycle : IDisposable, IServiceType
private void OnAddonDraw(AtkUnitBase* addon) private void OnAddonDraw(AtkUnitBase* addon)
{ {
this.recyclingDrawArgs.Addon = (nint)addon; this.recyclingDrawArgs.AddonInternal = (nint)addon;
this.InvokeListenersSafely(AddonEvent.PreDraw, this.recyclingDrawArgs); this.InvokeListenersSafely(AddonEvent.PreDraw, this.recyclingDrawArgs);
try try
@ -338,8 +341,8 @@ internal unsafe class AddonLifecycle : IDisposable, IServiceType
private void OnAddonUpdate(AtkUnitBase* addon, float delta) private void OnAddonUpdate(AtkUnitBase* addon, float delta)
{ {
this.recyclingUpdateArgs.Addon = (nint)addon; this.recyclingUpdateArgs.AddonInternal = (nint)addon;
this.recyclingUpdateArgs.TimeDelta = delta; this.recyclingUpdateArgs.TimeDeltaInternal = delta;
this.InvokeListenersSafely(AddonEvent.PreUpdate, this.recyclingUpdateArgs); this.InvokeListenersSafely(AddonEvent.PreUpdate, this.recyclingUpdateArgs);
try try
@ -358,7 +361,7 @@ internal unsafe class AddonLifecycle : IDisposable, IServiceType
{ {
byte result = 0; byte result = 0;
this.recyclingRefreshArgs.Addon = (nint)addon; this.recyclingRefreshArgs.AddonInternal = (nint)addon;
this.recyclingRefreshArgs.AtkValueCount = valueCount; this.recyclingRefreshArgs.AtkValueCount = valueCount;
this.recyclingRefreshArgs.AtkValues = (nint)values; this.recyclingRefreshArgs.AtkValues = (nint)values;
this.InvokeListenersSafely(AddonEvent.PreRefresh, this.recyclingRefreshArgs); 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) 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.NumberArrayData = (nint)numberArrayData;
this.recyclingRequestedUpdateArgs.StringArrayData = (nint)stringArrayData; this.recyclingRequestedUpdateArgs.StringArrayData = (nint)stringArrayData;
this.InvokeListenersSafely(AddonEvent.PreRequestedUpdate, this.recyclingRequestedUpdateArgs); 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 // 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. // 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(); private readonly AddonReceiveEventArgs recyclingReceiveEventArgs = new();
#pragma warning restore CS0618 // Type or member is obsolete
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="AddonLifecycleReceiveEventListener"/> class. /// Initializes a new instance of the <see cref="AddonLifecycleReceiveEventListener"/> class.
@ -79,7 +82,7 @@ internal unsafe class AddonLifecycleReceiveEventListener : IDisposable
return; return;
} }
this.recyclingReceiveEventArgs.Addon = (nint)addon; this.recyclingReceiveEventArgs.AddonInternal = (nint)addon;
this.recyclingReceiveEventArgs.AtkEventType = (byte)eventType; this.recyclingReceiveEventArgs.AtkEventType = (byte)eventType;
this.recyclingReceiveEventArgs.EventParam = eventParam; this.recyclingReceiveEventArgs.EventParam = eventParam;
this.recyclingReceiveEventArgs.AtkEvent = (IntPtr)atkEvent; this.recyclingReceiveEventArgs.AtkEvent = (IntPtr)atkEvent;