diff --git a/Dalamud/Game/Gui/GameGui.cs b/Dalamud/Game/Gui/GameGui.cs index 04b29f9d9..b021a2ad2 100644 --- a/Dalamud/Game/Gui/GameGui.cs +++ b/Dalamud/Game/Gui/GameGui.cs @@ -168,7 +168,7 @@ internal sealed unsafe class GameGui : IInternalDisposableService, IGameGui } /// - public IntPtr GetUIModule() + public UIModulePtr GetUIModule() { return (nint)UIModule.Instance(); } @@ -180,11 +180,7 @@ internal sealed unsafe class GameGui : IInternalDisposableService, IGameGui if (unitManager == null) return 0; - var addon = unitManager->GetAddonByName(name, index); - if (addon == null) - return 0; - - return (nint)addon; + return (nint)unitManager->GetAddonByName(name, index); } /// @@ -439,7 +435,7 @@ internal class GameGuiPluginScoped : IInternalDisposableService, IGameGui => this.gameGuiService.ScreenToWorld(screenPos, out worldPos, rayDistance); /// - public IntPtr GetUIModule() + public UIModulePtr GetUIModule() => this.gameGuiService.GetUIModule(); /// diff --git a/Dalamud/Game/NativeWrapper/UIModulePtr.cs b/Dalamud/Game/NativeWrapper/UIModulePtr.cs new file mode 100644 index 000000000..1604ea6bc --- /dev/null +++ b/Dalamud/Game/NativeWrapper/UIModulePtr.cs @@ -0,0 +1,49 @@ +using System.Runtime.InteropServices; + +using FFXIVClientStructs.FFXIV.Client.UI; + +namespace Dalamud.Game.NativeWrapper; + +/// +/// A wrapper for UIModule. +/// +/// The address to the UIModule. +[StructLayout(LayoutKind.Explicit, Size = 0x08)] +public readonly unsafe struct UIModulePtr(nint address) : IEquatable +{ + /// + /// The address to the UIModule. + /// + [FieldOffset(0x00)] + public readonly nint Address = address; + + /// + /// Gets a value indicating whether the underlying pointer is a nullptr. + /// + public readonly bool IsNull => this.Address == 0; + + /// + /// Gets the UIModule*. + /// + /// Internal use only. + internal readonly UIModule* Struct => (UIModule*)this.Address; + + public static implicit operator nint(UIModulePtr wrapper) => wrapper.Address; + + public static implicit operator UIModulePtr(nint address) => new(address); + + public static bool operator ==(UIModulePtr left, UIModulePtr right) => left.Address == right.Address; + + public static bool operator !=(UIModulePtr left, UIModulePtr right) => left.Address != right.Address; + + /// Determines whether the specified UIModulePtr is equal to the current UIModulePtr. + /// The UIModulePtr to compare with the current UIModulePtr. + /// true if the specified UIModulePtr is equal to the current UIModulePtr; otherwise, false. + public readonly bool Equals(UIModulePtr other) => this.Address == other.Address; + + /// + public override readonly bool Equals(object obj) => obj is UIModulePtr wrapper && this.Equals(wrapper); + + /// + public override readonly int GetHashCode() => ((nuint)this.Address).GetHashCode(); +} diff --git a/Dalamud/Plugin/Services/IGameGui.cs b/Dalamud/Plugin/Services/IGameGui.cs index 487987d3d..773ba61b4 100644 --- a/Dalamud/Plugin/Services/IGameGui.cs +++ b/Dalamud/Plugin/Services/IGameGui.cs @@ -76,37 +76,37 @@ public unsafe interface IGameGui public bool ScreenToWorld(Vector2 screenPos, out Vector3 worldPos, float rayDistance = 100000.0f); /// - /// Gets a pointer to the game's UI module. + /// Gets a pointer to the game's UIModule instance. /// - /// IntPtr pointing to UI module. - public nint GetUIModule(); + /// A pointer wrapper to UIModule. + public UIModulePtr GetUIModule(); /// /// Gets the pointer to the Addon with the given name and index. /// /// Name of addon to find. /// Index of addon to find (1-indexed). - /// A pointer to the addon. + /// A pointer wrapper to the addon. public AtkUnitBasePtr GetAddonByName(string name, int index = 1); /// /// Find the agent associated with an addon, if possible. /// /// The agent id. - /// A pointer to the agent interface. + /// A pointer wrapper to the agent interface. public AgentInterfacePtr GetAgentById(int id); /// /// Find the agent associated with an addon, if possible. /// /// The addon name. - /// A pointer to the agent interface. + /// A pointer wrapper to the agent interface. public AgentInterfacePtr FindAgentInterface(string addonName); /// /// Find the agent associated with an addon, if possible. /// /// The addon address. - /// A pointer to the agent interface. + /// A pointer wrapper to the agent interface. public AgentInterfacePtr FindAgentInterface(AtkUnitBasePtr addon); }