mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-15 05:04:15 +01:00
Add AtkValuePtr
This commit is contained in:
parent
08512f3845
commit
ca99eee3f3
3 changed files with 245 additions and 15 deletions
|
|
@ -1,7 +1,9 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Numerics;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using FFXIVClientStructs.FFXIV.Component.GUI;
|
||||
using FFXIVClientStructs.Interop;
|
||||
|
||||
namespace Dalamud.Game.NativeWrapper;
|
||||
|
||||
|
|
@ -24,7 +26,7 @@ public readonly unsafe struct AtkUnitBasePtr(nint address) : IEquatable<AtkUnitB
|
|||
public readonly bool IsNull => this.Address == 0;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the OnSetup function of the AtkUnitBase has been called.
|
||||
/// Gets a value indicating whether the OnSetup function has been called.
|
||||
/// </summary>
|
||||
public readonly bool IsReady => !this.IsNull && this.Struct->IsReady;
|
||||
|
||||
|
|
@ -34,75 +36,103 @@ public readonly unsafe struct AtkUnitBasePtr(nint address) : IEquatable<AtkUnitB
|
|||
public readonly bool IsVisible => !this.IsNull && this.Struct->IsVisible;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the AtkUnitBase.
|
||||
/// Gets the name.
|
||||
/// </summary>
|
||||
public readonly string Name => this.IsNull ? string.Empty : this.Struct->NameString;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the id of the AtkUnitBase.
|
||||
/// Gets the id.
|
||||
/// </summary>
|
||||
public readonly ushort Id => this.IsNull ? (ushort)0 : this.Struct->Id;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the parent id of the AtkUnitBase.
|
||||
/// Gets the parent id.
|
||||
/// </summary>
|
||||
public readonly ushort ParentId => this.IsNull ? (ushort)0 : this.Struct->ParentId;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the host id of the AtkUnitBase.
|
||||
/// Gets the host id.
|
||||
/// </summary>
|
||||
public readonly ushort HostId => this.IsNull ? (ushort)0 : this.Struct->HostId;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the scale of the AtkUnitBase.
|
||||
/// Gets the scale.
|
||||
/// </summary>
|
||||
public readonly float Scale => this.IsNull ? 0f : this.Struct->Scale;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the x-position of the AtkUnitBase.
|
||||
/// Gets the x-position.
|
||||
/// </summary>
|
||||
public readonly short X => this.IsNull ? (short)0 : this.Struct->X;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the y-position of the AtkUnitBase.
|
||||
/// Gets the y-position.
|
||||
/// </summary>
|
||||
public readonly short Y => this.IsNull ? (short)0 : this.Struct->Y;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the width of the AtkUnitBase.
|
||||
/// Gets the width.
|
||||
/// </summary>
|
||||
public readonly float Width => this.IsNull ? 0f : this.Struct->GetScaledWidth(false);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the height of the AtkUnitBase.
|
||||
/// Gets the height.
|
||||
/// </summary>
|
||||
public readonly float Height => this.IsNull ? 0f : this.Struct->GetScaledHeight(false);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the scaled width of the AtkUnitBase.
|
||||
/// Gets the scaled width.
|
||||
/// </summary>
|
||||
public readonly float ScaledWidth => this.IsNull ? 0f : this.Struct->GetScaledWidth(true);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the scaled height of the AtkUnitBase.
|
||||
/// Gets the scaled height.
|
||||
/// </summary>
|
||||
public readonly float ScaledHeight => this.IsNull ? 0f : this.Struct->GetScaledHeight(true);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the position of the AtkUnitBase.
|
||||
/// Gets the position.
|
||||
/// </summary>
|
||||
public readonly Vector2 Position => new(this.X, this.Y);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the size of the AtkUnitBase.
|
||||
/// Gets the size.
|
||||
/// </summary>
|
||||
public readonly Vector2 Size => new(this.Width, this.Height);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the scaled size of the AtkUnitBase.
|
||||
/// Gets the scaled size.
|
||||
/// </summary>
|
||||
public readonly Vector2 ScaledSize => new(this.ScaledWidth, this.ScaledHeight);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of <see cref="AtkValue"/> entries.
|
||||
/// </summary>
|
||||
public readonly int AtkValuesCount => this.Struct->AtkValuesCount;
|
||||
|
||||
/// <summary>
|
||||
/// Gets an enumerable collection of <see cref="AtkValuePtr"/> of the addons current AtkValues.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// An <see cref="IEnumerable{T}"/> of <see cref="AtkValuePtr"/> corresponding to the addons AtkValues.
|
||||
/// </returns>
|
||||
public IEnumerable<AtkValuePtr> AtkValues
|
||||
{
|
||||
get
|
||||
{
|
||||
for (var i = 0; i < this.AtkValuesCount; i++)
|
||||
{
|
||||
AtkValuePtr ptr;
|
||||
unsafe
|
||||
{
|
||||
ptr = new AtkValuePtr((nint)this.Struct->AtkValuesSpan.GetPointer(i));
|
||||
}
|
||||
|
||||
yield return ptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the AtkUnitBase*.
|
||||
/// </summary>
|
||||
|
|
|
|||
113
Dalamud/Game/NativeWrapper/AtkValuePtr.cs
Normal file
113
Dalamud/Game/NativeWrapper/AtkValuePtr.cs
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using Dalamud.Utility;
|
||||
|
||||
using FFXIVClientStructs.FFXIV.Component.GUI;
|
||||
|
||||
namespace Dalamud.Game.NativeWrapper;
|
||||
|
||||
/// <summary>
|
||||
/// A readonly wrapper for AtkValue.
|
||||
/// </summary>
|
||||
/// <param name="address">The address to the AtkValue.</param>
|
||||
[StructLayout(LayoutKind.Explicit, Size = 0x08)]
|
||||
public readonly unsafe struct AtkValuePtr(nint address) : IEquatable<AtkValuePtr>
|
||||
{
|
||||
/// <summary>
|
||||
/// The address to the AtkValue.
|
||||
/// </summary>
|
||||
[FieldOffset(0x00)]
|
||||
public readonly nint Address = address;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the underlying pointer is a nullptr.
|
||||
/// </summary>
|
||||
public readonly bool IsNull => this.Address == 0;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value type.
|
||||
/// </summary>
|
||||
public readonly AtkValueType ValueType => (AtkValueType)this.Struct->Type;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the AtkValue*.
|
||||
/// </summary>
|
||||
/// <remarks> Internal use only. </remarks>
|
||||
internal readonly AtkValue* Struct => (AtkValue*)this.Address;
|
||||
|
||||
public static implicit operator nint(AtkValuePtr wrapper) => wrapper.Address;
|
||||
|
||||
public static implicit operator AtkValuePtr(nint address) => new(address);
|
||||
|
||||
public static implicit operator AtkValuePtr(void* ptr) => new((nint)ptr);
|
||||
|
||||
public static bool operator ==(AtkValuePtr left, AtkValuePtr right) => left.Address == right.Address;
|
||||
|
||||
public static bool operator !=(AtkValuePtr left, AtkValuePtr right) => left.Address != right.Address;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of the underlying <see cref="AtkValue"/> as a boxed object, based on its <see cref="AtkValueType"/>.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The boxed value represented by this <see cref="AtkValuePtr"/>, or <c>null</c> if the value is null or undefined.
|
||||
/// </returns>
|
||||
/// <exception cref="NotImplementedException">
|
||||
/// Thrown if the value type is not currently handled by this implementation.
|
||||
/// </exception>
|
||||
public unsafe object? GetValue()
|
||||
{
|
||||
if (this.Struct == null)
|
||||
return null;
|
||||
|
||||
return this.ValueType switch
|
||||
{
|
||||
AtkValueType.Undefined or AtkValueType.Null => null,
|
||||
AtkValueType.Bool => this.Struct->Bool,
|
||||
AtkValueType.Int => this.Struct->Int,
|
||||
AtkValueType.Int64 => this.Struct->Int64,
|
||||
AtkValueType.UInt => this.Struct->UInt,
|
||||
AtkValueType.UInt64 => this.Struct->UInt64,
|
||||
AtkValueType.Float => this.Struct->Float,
|
||||
AtkValueType.String or AtkValueType.String8 or AtkValueType.ManagedString => this.Struct->String == null ? default : this.Struct->String.AsReadOnlySeString(),
|
||||
AtkValueType.WideString => this.Struct->WideString == null ? string.Empty : new string(this.Struct->WideString),
|
||||
AtkValueType.Pointer => (nint)this.Struct->Pointer,
|
||||
_ => throw new NotImplementedException($"AtkValueType {this.ValueType} is currently not supported"),
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to retrieve the value as a strongly-typed object if the underlying type matches.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The expected value type to extract.</typeparam>
|
||||
/// <param name="result">
|
||||
/// When this method returns <c>true</c>, contains the extracted value of type <typeparamref name="T"/>.
|
||||
/// Otherwise, contains the default value of type <typeparamref name="T"/>.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the value was successfully extracted and matched <typeparamref name="T"/>; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public unsafe bool TryGet<T>([NotNullWhen(true)] out T? result) where T : struct
|
||||
{
|
||||
object? value = this.GetValue();
|
||||
if (value is T typed)
|
||||
{
|
||||
result = typed;
|
||||
return true;
|
||||
}
|
||||
|
||||
result = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>Determines whether the specified AtkValuePtr is equal to the current AtkValuePtr.</summary>
|
||||
/// <param name="other">The AtkValuePtr to compare with the current AtkValuePtr.</param>
|
||||
/// <returns><c>true</c> if the specified AtkValuePtr is equal to the current AtkValuePtr; otherwise, <c>false</c>.</returns>
|
||||
public readonly bool Equals(AtkValuePtr other) => this.Address == other.Address || this.Struct->EqualTo(other.Struct);
|
||||
|
||||
/// <inheritdoc cref="object.Equals(object?)"/>
|
||||
public override readonly bool Equals(object obj) => obj is AtkValuePtr wrapper && this.Equals(wrapper);
|
||||
|
||||
/// <inheritdoc cref="object.GetHashCode()"/>
|
||||
public override readonly int GetHashCode() => ((nuint)this.Address).GetHashCode();
|
||||
}
|
||||
87
Dalamud/Game/NativeWrapper/AtkValueType.cs
Normal file
87
Dalamud/Game/NativeWrapper/AtkValueType.cs
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
namespace Dalamud.Game.NativeWrapper;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the data type of the AtkValue.
|
||||
/// </summary>
|
||||
public enum AtkValueType
|
||||
{
|
||||
/// <summary>
|
||||
/// The value is undefined or invalid.
|
||||
/// </summary>
|
||||
Undefined = 0,
|
||||
|
||||
/// <summary>
|
||||
/// The value is null.
|
||||
/// </summary>
|
||||
Null = 0x1,
|
||||
|
||||
/// <summary>
|
||||
/// The value is a boolean.
|
||||
/// </summary>
|
||||
Bool = 0x2,
|
||||
|
||||
/// <summary>
|
||||
/// The value is a 32-bit signed integer.
|
||||
/// </summary>
|
||||
Int = 0x3,
|
||||
|
||||
/// <summary>
|
||||
/// The value is a 64-bit signed integer.
|
||||
/// </summary>
|
||||
Int64 = 0x4,
|
||||
|
||||
/// <summary>
|
||||
/// The value is a 32-bit unsigned integer.
|
||||
/// </summary>
|
||||
UInt = 0x5,
|
||||
|
||||
/// <summary>
|
||||
/// The value is a 64-bit unsigned integer.
|
||||
/// </summary>
|
||||
UInt64 = 0x6,
|
||||
|
||||
/// <summary>
|
||||
/// The value is a 32-bit floating-point number.
|
||||
/// </summary>
|
||||
Float = 0x7,
|
||||
|
||||
/// <summary>
|
||||
/// The value points to a null-terminated 8-bit character string (ASCII or UTF-8).
|
||||
/// </summary>
|
||||
String = 0x8,
|
||||
|
||||
/// <summary>
|
||||
/// The value points to a null-terminated 16-bit character string (UTF-16 / wide string).
|
||||
/// </summary>
|
||||
WideString = 0x9,
|
||||
|
||||
/// <summary>
|
||||
/// The value points to a constant null-terminated 8-bit character string (const char*).
|
||||
/// </summary>
|
||||
String8 = 0xA,
|
||||
|
||||
/// <summary>
|
||||
/// The value is a vector.
|
||||
/// </summary>
|
||||
Vector = 0xB,
|
||||
|
||||
/// <summary>
|
||||
/// The value is a pointer.
|
||||
/// </summary>
|
||||
Pointer = 0xC,
|
||||
|
||||
/// <summary>
|
||||
/// The value is pointing to an array of AtkValue entries.
|
||||
/// </summary>
|
||||
AtkValues = 0xD,
|
||||
|
||||
/// <summary>
|
||||
/// The value is a managed string. See <see cref="String"/>.
|
||||
/// </summary>
|
||||
ManagedString = 0x28,
|
||||
|
||||
/// <summary>
|
||||
/// The value is a managed vector. See <see cref="Vector"/>.
|
||||
/// </summary>
|
||||
ManagedVector = 0x2B,
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue