diff --git a/Dalamud/Interface/Components/ImGuiComponents.IconButton.cs b/Dalamud/Interface/Components/ImGuiComponents.IconButton.cs
index 5e64fe463..d2b1b4a36 100644
--- a/Dalamud/Interface/Components/ImGuiComponents.IconButton.cs
+++ b/Dalamud/Interface/Components/ImGuiComponents.IconButton.cs
@@ -270,7 +270,7 @@ public static partial class ImGuiComponents
/// Icon to use.
/// Text to use.
/// Width.
- internal static float GetIconButtonWithTextWidth(FontAwesomeIcon icon, string text)
+ public static float GetIconButtonWithTextWidth(FontAwesomeIcon icon, string text)
{
using (ImRaii.PushFont(UiBuilder.IconFont))
{
diff --git a/Dalamud/Interface/Components/ImGuiComponents.IconButtonSelect.cs b/Dalamud/Interface/Components/ImGuiComponents.IconButtonSelect.cs
index 3f9c469bb..ad83c7201 100644
--- a/Dalamud/Interface/Components/ImGuiComponents.IconButtonSelect.cs
+++ b/Dalamud/Interface/Components/ImGuiComponents.IconButtonSelect.cs
@@ -24,7 +24,7 @@ public static partial class ImGuiComponents
/// The color of the actively-selected button.
/// The color of the buttons when hovered.
/// True if any button is clicked.
- internal static bool IconButtonSelect(string label, ref T val, IEnumerable optionIcons, IEnumerable optionValues, uint columns = 0, Vector2? buttonSize = null, Vector4? defaultColor = null, Vector4? activeColor = null, Vector4? hoveredColor = null)
+ public static bool IconButtonSelect(string label, ref T val, IEnumerable optionIcons, IEnumerable optionValues, uint columns = 0, Vector2? buttonSize = null, Vector4? defaultColor = null, Vector4? activeColor = null, Vector4? hoveredColor = null)
{
var options = optionIcons.Zip(optionValues, static (icon, value) => new KeyValuePair(icon, value));
return IconButtonSelect(label, ref val, options, columns, buttonSize, defaultColor, activeColor, hoveredColor);
@@ -43,7 +43,7 @@ public static partial class ImGuiComponents
/// The color of the actively-selected button.
/// The color of the buttons when hovered.
/// True if any button is clicked.
- internal static unsafe bool IconButtonSelect(string label, ref T val, IEnumerable> options, uint columns = 0, Vector2? buttonSize = null, Vector4? defaultColor = null, Vector4? activeColor = null, Vector4? hoveredColor = null)
+ public static unsafe bool IconButtonSelect(string label, ref T val, IEnumerable> options, uint columns = 0, Vector2? buttonSize = null, Vector4? defaultColor = null, Vector4? activeColor = null, Vector4? hoveredColor = null)
{
defaultColor ??= *ImGui.GetStyleColorVec4(ImGuiCol.Button);
activeColor ??= *ImGui.GetStyleColorVec4(ImGuiCol.ButtonActive);
diff --git a/Dalamud/Interface/Internal/UiDebug2/Browsing/AddonTree.AtkValues.cs b/Dalamud/Interface/Internal/UiDebug2/Browsing/AddonTree.AtkValues.cs
index 4b7a531c0..c3930821b 100644
--- a/Dalamud/Interface/Internal/UiDebug2/Browsing/AddonTree.AtkValues.cs
+++ b/Dalamud/Interface/Internal/UiDebug2/Browsing/AddonTree.AtkValues.cs
@@ -11,6 +11,7 @@ using ValueType = FFXIVClientStructs.FFXIV.Component.GUI.ValueType;
namespace Dalamud.Interface.Internal.UiDebug2.Browsing;
+///
public unsafe partial class AddonTree
{
///
@@ -23,12 +24,11 @@ public unsafe partial class AddonTree
if (addon->AtkValuesCount > 0 && atkValue != null)
{
using var tree = ImRaii.TreeNode($"Atk Values [{addon->AtkValuesCount}]###atkValues_{addon->NameString}");
- if (tree)
+ if (tree.Success)
{
- using (ImRaii.Table(
- "atkUnitBase_atkValueTable",
- 3,
- ImGuiTableFlags.Borders | ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.RowBg))
+ using var tbl = ImRaii.Table("atkUnitBase_atkValueTable", 3, ImGuiTableFlags.Borders | ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.RowBg);
+
+ if (tbl.Success)
{
ImGui.TableSetupColumn("Index");
ImGui.TableSetupColumn("Type");
diff --git a/Dalamud/Interface/Internal/UiDebug2/Browsing/Events.cs b/Dalamud/Interface/Internal/UiDebug2/Browsing/Events.cs
index 45a2d90eb..c98cc933f 100644
--- a/Dalamud/Interface/Internal/UiDebug2/Browsing/Events.cs
+++ b/Dalamud/Interface/Internal/UiDebug2/Browsing/Events.cs
@@ -30,9 +30,11 @@ public static class Events
using var tree = ImRaii.TreeNode($"Events##{(nint)node:X}eventTree");
- if (tree)
+ if (tree.Success)
{
- using (ImRaii.Table($"##{(nint)node:X}eventTable", 7, Resizable | SizingFixedFit | Borders | RowBg))
+ using var tbl = ImRaii.Table($"##{(nint)node:X}eventTable", 7, Resizable | SizingFixedFit | Borders | RowBg);
+
+ if (tbl.Success)
{
ImGui.TableSetupColumn("#", WidthFixed);
ImGui.TableSetupColumn("Type", WidthFixed);
diff --git a/Dalamud/Interface/Internal/UiDebug2/Browsing/NodeTree.Editor.cs b/Dalamud/Interface/Internal/UiDebug2/Browsing/NodeTree.Editor.cs
index 6b6522bb4..1f5abd0bf 100644
--- a/Dalamud/Interface/Internal/UiDebug2/Browsing/NodeTree.Editor.cs
+++ b/Dalamud/Interface/Internal/UiDebug2/Browsing/NodeTree.Editor.cs
@@ -27,7 +27,8 @@ internal unsafe partial class ResNodeTree
///
private protected void DrawNodeEditorTable()
{
- using (ImRaii.Table($"###Editor{(nint)this.Node}", 2, SizingStretchProp | NoHostExtendX))
+ using var tbl = ImRaii.Table($"###Editor{(nint)this.Node}", 2, SizingStretchProp | NoHostExtendX);
+ if (tbl.Success)
{
this.DrawEditorRows();
}
diff --git a/Dalamud/Interface/Internal/UiDebug2/Browsing/NodeTree.Image.cs b/Dalamud/Interface/Internal/UiDebug2/Browsing/NodeTree.Image.cs
index 4929fa1d9..8d93b3e76 100644
--- a/Dalamud/Interface/Internal/UiDebug2/Browsing/NodeTree.Image.cs
+++ b/Dalamud/Interface/Internal/UiDebug2/Browsing/NodeTree.Image.cs
@@ -65,7 +65,7 @@ internal unsafe partial class ImageNodeTree : ResNodeTree
using var tree = ImRaii.TreeNode($"Texture##texture{(nint)this.TexData.Texture->D3D11ShaderResourceView:X}", SpanFullWidth);
- if (tree)
+ if (tree.Success)
{
PrintFieldValuePairs(
("Texture Type", $"{this.TexData.TexType}"),
@@ -189,7 +189,8 @@ internal unsafe partial class ImageNodeTree : ResNodeTree
private void PrintPartsTable()
{
- using (ImRaii.Table($"partsTable##{(nint)this.TexData.Texture->D3D11ShaderResourceView:X}", 3, Borders | RowBg | Reorderable))
+ using var tbl = ImRaii.Table($"partsTable##{(nint)this.TexData.Texture->D3D11ShaderResourceView:X}", 3, Borders | RowBg | Reorderable);
+ if (tbl.Success)
{
ImGui.TableSetupColumn("Part ID", WidthFixed);
ImGui.TableSetupColumn("Part Texture", WidthFixed);
diff --git a/Dalamud/Interface/Internal/UiDebug2/Browsing/NodeTree.NineGrid.Offsets.cs b/Dalamud/Interface/Internal/UiDebug2/Browsing/NodeTree.NineGrid.Offsets.cs
deleted file mode 100644
index 237303155..000000000
--- a/Dalamud/Interface/Internal/UiDebug2/Browsing/NodeTree.NineGrid.Offsets.cs
+++ /dev/null
@@ -1,69 +0,0 @@
-using System.Numerics;
-
-using FFXIVClientStructs.FFXIV.Component.GUI;
-
-using static Dalamud.Interface.Internal.UiDebug2.Utility.Gui;
-
-namespace Dalamud.Interface.Internal.UiDebug2.Browsing;
-
-///
-internal unsafe partial class NineGridNodeTree
-{
- ///
- /// A struct representing the four offsets of an .
- ///
- internal struct NineGridOffsets
- {
- /// Top offset.
- internal int Top;
-
- /// Left offset.
- internal int Left;
-
- /// Right offset.
- internal int Right;
-
- /// Bottom offset.
- internal int Bottom;
-
- ///
- /// Initializes a new instance of the struct.
- ///
- /// The top offset.
- /// The right offset.
- /// The bottom offset.
- /// The left offset.
- internal NineGridOffsets(int top, int right, int bottom, int left)
- {
- this.Top = top;
- this.Right = right;
- this.Left = left;
- this.Bottom = bottom;
- }
-
- ///
- /// Initializes a new instance of the struct.
- ///
- /// The node using these offsets.
- internal NineGridOffsets(AtkNineGridNode* ngNode)
- : this(ngNode->TopOffset, ngNode->RightOffset, ngNode->BottomOffset, ngNode->LeftOffset)
- {
- }
-
- private NineGridOffsets(Vector4 v)
- : this((int)v.X, (int)v.Y, (int)v.Z, (int)v.W)
- {
- }
-
- public static implicit operator NineGridOffsets(Vector4 v) => new(v);
-
- public static implicit operator Vector4(NineGridOffsets v) => new(v.Top, v.Right, v.Bottom, v.Left);
-
- public static NineGridOffsets operator *(float n, NineGridOffsets a) => n * (Vector4)a;
-
- public static NineGridOffsets operator *(NineGridOffsets a, float n) => n * a;
-
- /// Prints the offsets in ImGui.
- internal readonly void Print() => PrintFieldValuePairs(("Top", $"{this.Top}"), ("Bottom", $"{this.Bottom}"), ("Left", $"{this.Left}"), ("Right", $"{this.Right}"));
- }
-}
diff --git a/Dalamud/Interface/Internal/UiDebug2/Browsing/NodeTree.NineGrid.cs b/Dalamud/Interface/Internal/UiDebug2/Browsing/NodeTree.NineGrid.cs
index 8f4e8c196..48825becb 100644
--- a/Dalamud/Interface/Internal/UiDebug2/Browsing/NodeTree.NineGrid.cs
+++ b/Dalamud/Interface/Internal/UiDebug2/Browsing/NodeTree.NineGrid.cs
@@ -1,3 +1,5 @@
+using Dalamud.Interface.Internal.UiDebug2.Utility;
+
using FFXIVClientStructs.FFXIV.Component.GUI;
using ImGuiNET;
@@ -85,4 +87,62 @@ internal unsafe partial class NineGridNodeTree : ImageNodeTree
this.DrawTextureAndParts();
}
+
+ ///
+ /// A struct representing the four offsets of an .
+ ///
+ internal struct NineGridOffsets
+ {
+ /// Top offset.
+ internal int Top;
+
+ /// Left offset.
+ internal int Left;
+
+ /// Right offset.
+ internal int Right;
+
+ /// Bottom offset.
+ internal int Bottom;
+
+ ///
+ /// Initializes a new instance of the struct.
+ ///
+ /// The top offset.
+ /// The right offset.
+ /// The bottom offset.
+ /// The left offset.
+ internal NineGridOffsets(int top, int right, int bottom, int left)
+ {
+ this.Top = top;
+ this.Right = right;
+ this.Left = left;
+ this.Bottom = bottom;
+ }
+
+ ///
+ /// Initializes a new instance of the struct.
+ ///
+ /// The node using these offsets.
+ internal NineGridOffsets(AtkNineGridNode* ngNode)
+ : this(ngNode->TopOffset, ngNode->RightOffset, ngNode->BottomOffset, ngNode->LeftOffset)
+ {
+ }
+
+ private NineGridOffsets(Vector4 v)
+ : this((int)v.X, (int)v.Y, (int)v.Z, (int)v.W)
+ {
+ }
+
+ public static implicit operator NineGridOffsets(Vector4 v) => new(v);
+
+ public static implicit operator Vector4(NineGridOffsets v) => new(v.Top, v.Right, v.Bottom, v.Left);
+
+ public static NineGridOffsets operator *(float n, NineGridOffsets a) => n * (Vector4)a;
+
+ public static NineGridOffsets operator *(NineGridOffsets a, float n) => n * a;
+
+ /// Prints the offsets in ImGui.
+ internal readonly void Print() => Gui.PrintFieldValuePairs(("Top", $"{this.Top}"), ("Bottom", $"{this.Bottom}"), ("Left", $"{this.Left}"), ("Right", $"{this.Right}"));
+ }
}
diff --git a/Dalamud/Interface/Internal/UiDebug2/Browsing/NodeTree.Res.cs b/Dalamud/Interface/Internal/UiDebug2/Browsing/NodeTree.Res.cs
index 2edf4e570..6c12d3b4c 100644
--- a/Dalamud/Interface/Internal/UiDebug2/Browsing/NodeTree.Res.cs
+++ b/Dalamud/Interface/Internal/UiDebug2/Browsing/NodeTree.Res.cs
@@ -128,11 +128,11 @@ internal unsafe partial class ResNodeTree : IDisposable
return;
}
- using var c = ImRaii.PushColor(Text, color);
+ using var col = ImRaii.PushColor(Text, color);
using var tree = ImRaii.TreeNode($"{label}##{(nint)nodeList:X}", SpanFullWidth);
- c.Pop();
+ col.Pop();
- if (tree)
+ if (tree.Success)
{
var lineStart = ImGui.GetCursorScreenPos() + new Vector2(-10, 2);
@@ -319,7 +319,7 @@ internal unsafe partial class ResNodeTree : IDisposable
col.Pop();
- if (tree)
+ if (tree.Success)
{
var lineStart = ImGui.GetCursorScreenPos() + new Vector2(-10, 2);
try
diff --git a/Dalamud/Interface/Internal/UiDebug2/Browsing/NodeTree.Text.cs b/Dalamud/Interface/Internal/UiDebug2/Browsing/NodeTree.Text.cs
index d9b4e7986..7c924f503 100644
--- a/Dalamud/Interface/Internal/UiDebug2/Browsing/NodeTree.Text.cs
+++ b/Dalamud/Interface/Internal/UiDebug2/Browsing/NodeTree.Text.cs
@@ -85,7 +85,7 @@ internal unsafe partial class TextNodeTree : ResNodeTree
{
using var tree = ImRaii.TreeNode($"Text Payloads##{(nint)this.Node:X}");
- if (tree)
+ if (tree.Success)
{
var utf8String = this.NodeText;
var seStringBytes = new byte[utf8String.BufUsed];
diff --git a/Dalamud/Interface/Internal/UiDebug2/Browsing/TimelineTree.cs b/Dalamud/Interface/Internal/UiDebug2/Browsing/TimelineTree.cs
index 8e21f4030..57e5eff99 100644
--- a/Dalamud/Interface/Internal/UiDebug2/Browsing/TimelineTree.cs
+++ b/Dalamud/Interface/Internal/UiDebug2/Browsing/TimelineTree.cs
@@ -58,7 +58,7 @@ public readonly unsafe partial struct TimelineTree
{
using var tree = ImRaii.TreeNode($"Timeline##{(nint)this.node:X}timeline", SpanFullWidth);
- if (tree)
+ if (tree.Success)
{
PrintFieldValuePair("Timeline", $"{(nint)this.NodeTimeline:X}");
@@ -312,7 +312,7 @@ public readonly unsafe partial struct TimelineTree
{
using var tree = ImRaii.TreeNode($"[#{a}] [Frames {animation.StartFrameIdx}-{animation.EndFrameIdx}] {(isActive ? " (Active)" : string.Empty)}###{(nint)this.node}animTree{a}");
- if (tree)
+ if (tree.Success)
{
PrintFieldValuePair("Animation", $"{address:X}");
@@ -320,10 +320,9 @@ public readonly unsafe partial struct TimelineTree
if (columns.Count > 0)
{
- using (ImRaii.Table(
- $"##{(nint)this.node}animTable{a}",
- columns.Count,
- Borders | SizingFixedFit | RowBg | NoHostExtendX))
+ using var tbl = ImRaii.Table($"##{(nint)this.node}animTable{a}", columns.Count, Borders | SizingFixedFit | RowBg | NoHostExtendX);
+
+ if (tbl.Success)
{
foreach (var c in columns)
{
diff --git a/Dalamud/Interface/Internal/UiDebug2/ElementSelector.cs b/Dalamud/Interface/Internal/UiDebug2/ElementSelector.cs
index 6693c3fb0..65537e210 100644
--- a/Dalamud/Interface/Internal/UiDebug2/ElementSelector.cs
+++ b/Dalamud/Interface/Internal/UiDebug2/ElementSelector.cs
@@ -79,7 +79,9 @@ internal unsafe class ElementSelector : IDisposable
///
internal void DrawInterface()
{
- using (ImRaii.Child("###sidebar_elementSelector", new(250, -1), true))
+ using var ch = ImRaii.Child("###sidebar_elementSelector", new(250, -1), true);
+
+ if (ch.Success)
{
using (ImRaii.PushFont(IconFont))
{
@@ -153,9 +155,11 @@ internal unsafe class ElementSelector : IDisposable
using (ImRaii.PushColor(WindowBg, new Vector4(0.5f)))
{
- using (ImRaii.Child("noClick", new(800, 2000), false, NoInputs | NoBackground | NoScrollWithMouse))
+ using var ch = ImRaii.Child("noClick", new(800, 2000), false, NoInputs | NoBackground | NoScrollWithMouse);
+ if (ch.Success)
{
- using (ImRaii.Group())
+ using var gr = ImRaii.Group();
+ if (gr.Success)
{
Gui.PrintFieldValuePair("Mouse Position", $"{mousePos.X}, {mousePos.Y}");
ImGui.Spacing();
diff --git a/Dalamud/Interface/Internal/UiDebug2/Popout.Addon.cs b/Dalamud/Interface/Internal/UiDebug2/Popout.Addon.cs
index 91dfc8067..76112945e 100644
--- a/Dalamud/Interface/Internal/UiDebug2/Popout.Addon.cs
+++ b/Dalamud/Interface/Internal/UiDebug2/Popout.Addon.cs
@@ -39,7 +39,8 @@ internal class AddonPopoutWindow : Window, IDisposable
///
public override void Draw()
{
- using (ImRaii.Child($"{this.WindowName}child", new(-1, -1), true))
+ using var ch = ImRaii.Child($"{this.WindowName}child", new(-1, -1), true);
+ if (ch.Success)
{
this.addonTree.Draw();
}
diff --git a/Dalamud/Interface/Internal/UiDebug2/Popout.Node.cs b/Dalamud/Interface/Internal/UiDebug2/Popout.Node.cs
index c07806823..fe8bc87ea 100644
--- a/Dalamud/Interface/Internal/UiDebug2/Popout.Node.cs
+++ b/Dalamud/Interface/Internal/UiDebug2/Popout.Node.cs
@@ -50,7 +50,8 @@ internal unsafe class NodePopoutWindow : Window, IDisposable
{
if (this.Node != null && this.AddonTree.ContainsNode(this.Node))
{
- using (ImRaii.Child($"{(nint)this.Node:X}popoutChild", new(-1, -1), true))
+ using var ch = ImRaii.Child($"{(nint)this.Node:X}popoutChild", new(-1, -1), true);
+ if (ch.Success)
{
ResNodeTree.GetOrCreate(this.Node, this.AddonTree).Print(null, this.firstDraw);
this.firstDraw = false;
diff --git a/Dalamud/Interface/Internal/UiDebug2/UiDebug2.Sidebar.cs b/Dalamud/Interface/Internal/UiDebug2/UiDebug2.Sidebar.cs
index 4253f13bc..50967453d 100644
--- a/Dalamud/Interface/Internal/UiDebug2/UiDebug2.Sidebar.cs
+++ b/Dalamud/Interface/Internal/UiDebug2/UiDebug2.Sidebar.cs
@@ -53,7 +53,8 @@ internal unsafe partial class UiDebug2
private void DrawSidebar()
{
- using (ImRaii.Group())
+ using var gr = ImRaii.Group();
+ if (gr.Success)
{
this.DrawNameSearch();
this.DrawAddonSelectionList();
@@ -63,7 +64,9 @@ internal unsafe partial class UiDebug2
private void DrawNameSearch()
{
- using (ImRaii.Child("###sidebar_nameSearch", new(250, 40), true))
+ using var ch = ImRaii.Child("###sidebar_nameSearch", new(250, 40), true);
+
+ if (ch.Success)
{
var atkUnitBaseSearch = this.addonNameSearch;
@@ -90,7 +93,8 @@ internal unsafe partial class UiDebug2
private void DrawAddonSelectionList()
{
- using (ImRaii.Child("###sideBar_addonList", new(250, -44), true, ImGuiWindowFlags.AlwaysVerticalScrollbar))
+ using var ch = ImRaii.Child("###sideBar_addonList", new(250, -44), true, ImGuiWindowFlags.AlwaysVerticalScrollbar);
+ if (ch.Success)
{
var unitListBaseAddr = GetUnitListBaseAddr();
@@ -146,11 +150,11 @@ internal unsafe partial class UiDebug2
var countStr = $"{(usingFilter ? $"{matchCount}/" : string.Empty)}{totalCount}";
- using var col1 = ImRaii.PushColor(ImGuiCol.Text, anyVisible ? new Vector4(1) : new Vector4(0.6f, 0.6f, 0.6f, 1));
+ using var col = ImRaii.PushColor(ImGuiCol.Text, anyVisible ? new Vector4(1) : new Vector4(0.6f, 0.6f, 0.6f, 1));
using var tree = ImRaii.TreeNode($"{unit.Name} [{countStr}]###unitListTree{unit.Index}");
- col1.Pop();
+ col.Pop();
- if (tree)
+ if (tree.Success)
{
foreach (var option in options)
{
diff --git a/Dalamud/Interface/Internal/UiDebug2/UiDebug2.cs b/Dalamud/Interface/Internal/UiDebug2/UiDebug2.cs
index 17c64ddca..74727f2a5 100644
--- a/Dalamud/Interface/Internal/UiDebug2/UiDebug2.cs
+++ b/Dalamud/Interface/Internal/UiDebug2/UiDebug2.cs
@@ -83,7 +83,9 @@ internal partial class UiDebug2 : IDisposable
{
ImGui.SameLine();
- using (ImRaii.Child("###uiDebugMainPanel", new(-1, -1), true, HorizontalScrollbar))
+ using var ch = ImRaii.Child("###uiDebugMainPanel", new(-1, -1), true, HorizontalScrollbar);
+
+ if (ch.Success)
{
if (this.elementSelector.Active)
{
diff --git a/Dalamud/Interface/Internal/UiDebug2/Utility/Gui.cs b/Dalamud/Interface/Internal/UiDebug2/Utility/Gui.cs
index cc73b79c6..cc4f1b698 100644
--- a/Dalamud/Interface/Internal/UiDebug2/Utility/Gui.cs
+++ b/Dalamud/Interface/Internal/UiDebug2/Utility/Gui.cs
@@ -68,10 +68,10 @@ internal static class Gui
/// Colors the text itself either white or black, depending on the luminosity of the background color.
internal static void PrintColor(Vector4 color, string fmt)
{
- using (new ImRaii.Color().Push(Text, Luminosity(color) < 0.5f ? new Vector4(1) : new(0, 0, 0, 1))
- .Push(Button, color)
- .Push(ButtonActive, color)
- .Push(ButtonHovered, color))
+ using (ImRaii.PushColor(Text, Luminosity(color) < 0.5f ? new Vector4(1) : new(0, 0, 0, 1))
+ .Push(Button, color)
+ .Push(ButtonActive, color)
+ .Push(ButtonHovered, color))
{
ImGui.SmallButton(fmt);
}
@@ -105,7 +105,9 @@ internal static class Gui
var index = (int)Math.Floor(prog * tooltips.Length);
- using (ImRaii.Tooltip())
+ using var tt = ImRaii.Tooltip();
+
+ if (tt.Success)
{
ImGui.TextUnformatted(tooltips[index]);
}
diff --git a/Dalamud/Utility/Util.cs b/Dalamud/Utility/Util.cs
index 805532025..c707081f4 100644
--- a/Dalamud/Utility/Util.cs
+++ b/Dalamud/Utility/Util.cs
@@ -28,6 +28,8 @@ using Windows.Win32.Storage.FileSystem;
using Windows.Win32.System.Memory;
using Windows.Win32.System.Ole;
+using Dalamud.Interface.Utility.Raii;
+
using static TerraFX.Interop.Windows.Windows;
using Win32_PInvoke = Windows.Win32.PInvoke;
@@ -1028,74 +1030,71 @@ public static class Util
dm.Invoke(null, new[] { obj, path, addr });
}
+#pragma warning disable CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type
+
private static unsafe void ShowSpanPrivate(ulong addr, IList path, int offset, bool isTop, in Span spanobj)
{
-#pragma warning disable CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type
if (isTop)
{
fixed (void* p = spanobj)
{
- if (!ImGui.TreeNode(
- $"Span<{typeof(T).Name}> of length {spanobj.Length:n0} (0x{spanobj.Length:X})" +
- $"##print-obj-{addr:X}-{string.Join("-", path)}-head"))
+ using var tree = ImRaii.TreeNode($"Span<{typeof(T).Name}> of length {spanobj.Length:n0} (0x{spanobj.Length:X})" + $"##print-obj-{addr:X}-{string.Join("-", path)}-head", ImGuiTreeNodeFlags.SpanFullWidth);
+ if (tree.Success)
{
- return;
+ ShowSpanEntryPrivate(addr, path, offset, spanobj);
}
}
}
-
- try
+ else
{
- const int batchSize = 20;
- if (spanobj.Length > batchSize)
- {
- var skip = batchSize;
- while ((spanobj.Length + skip - 1) / skip > batchSize)
- skip *= batchSize;
- for (var i = 0; i < spanobj.Length; i += skip)
- {
- var next = Math.Min(i + skip, spanobj.Length);
- path.Add($"{offset + i:X}_{skip}");
- if (ImGui.TreeNode(
- $"{offset + i:n0} ~ {offset + next - 1:n0} (0x{offset + i:X} ~ 0x{offset + next - 1:X})" +
- $"##print-obj-{addr:X}-{string.Join("-", path)}"))
- {
- try
- {
- ShowSpanPrivate(addr, path, offset + i, false, spanobj[i..next]);
- }
- finally
- {
- ImGui.TreePop();
- }
- }
-
- path.RemoveAt(path.Count - 1);
- }
- }
- else
- {
- fixed (T* p = spanobj)
- {
- var pointerType = typeof(T*);
- for (var i = 0; i < spanobj.Length; i++)
- {
- ImGui.TextUnformatted($"[{offset + i:n0} (0x{offset + i:X})] ");
- ImGui.SameLine();
- path.Add($"{offset + i}");
- ShowValue(addr, path, pointerType, Pointer.Box(p + i, pointerType), true);
- }
- }
- }
+ ShowSpanEntryPrivate(addr, path, offset, spanobj);
}
- finally
- {
- if (isTop)
- ImGui.TreePop();
- }
-#pragma warning restore CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type
}
+ private static unsafe void ShowSpanEntryPrivate(ulong addr, IList path, int offset, Span spanobj) {
+ const int batchSize = 20;
+ if (spanobj.Length > batchSize)
+ {
+ var skip = batchSize;
+ while ((spanobj.Length + skip - 1) / skip > batchSize)
+ {
+ skip *= batchSize;
+ }
+
+ for (var i = 0; i < spanobj.Length; i += skip)
+ {
+ var next = Math.Min(i + skip, spanobj.Length);
+ path.Add($"{offset + i:X}_{skip}");
+
+ using (var tree = ImRaii.TreeNode($"{offset + i:n0} ~ {offset + next - 1:n0} (0x{offset + i:X} ~ 0x{offset + next - 1:X})" + $"##print-obj-{addr:X}-{string.Join("-", path)}", ImGuiTreeNodeFlags.SpanFullWidth))
+ {
+ if (tree.Success)
+ {
+ ShowSpanEntryPrivate(addr, path, offset + i, spanobj[i..next]);
+ }
+ }
+
+ path.RemoveAt(path.Count - 1);
+ }
+ }
+ else
+ {
+ fixed (T* p = spanobj)
+ {
+ var pointerType = typeof(T*);
+ for (var i = 0; i < spanobj.Length; i++)
+ {
+ ImGui.TextUnformatted($"[{offset + i:n0} (0x{offset + i:X})] ");
+ ImGui.SameLine();
+ path.Add($"{offset + i}");
+ ShowValue(addr, path, pointerType, Pointer.Box(p + i, pointerType), true);
+ }
+ }
+ }
+ }
+
+#pragma warning restore CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type
+
private static unsafe void ShowValue(ulong addr, IList path, Type type, object value, bool hideAddress)
{
if (type.IsPointer)
@@ -1111,9 +1110,10 @@ public static class Util
if (moduleStartAddr > 0 && unboxedAddr >= moduleStartAddr && unboxedAddr <= moduleEndAddr)
{
ImGui.SameLine();
- ImGui.PushStyleColor(ImGuiCol.Text, 0xffcbc0ff);
- ImGuiHelpers.ClickToCopyText($"ffxiv_dx11.exe+{unboxedAddr - moduleStartAddr:X}");
- ImGui.PopStyleColor();
+ using (ImRaii.PushColor(ImGuiCol.Text, 0xffcbc0ff))
+ {
+ ImGuiHelpers.ClickToCopyText($"ffxiv_dx11.exe+{unboxedAddr - moduleStartAddr:X}");
+ }
}
ImGui.SameLine();
@@ -1165,125 +1165,135 @@ public static class Util
/// Do not print addresses. Use when displaying a copied value.
private static void ShowStructInternal(object obj, ulong addr, bool autoExpand = false, IEnumerable? path = null, bool hideAddress = false)
{
- ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, new Vector2(3, 2));
- path ??= new List();
- var pathList = path is List ? (List)path : path.ToList();
-
- if (moduleEndAddr == 0 && moduleStartAddr == 0)
+ using (ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, new Vector2(3, 2)))
{
- try
+ path ??= new List();
+ var pathList = path as List ?? path.ToList();
+
+ if (moduleEndAddr == 0 && moduleStartAddr == 0)
{
- var processModule = Process.GetCurrentProcess().MainModule;
- if (processModule != null)
+ try
{
- moduleStartAddr = (ulong)processModule.BaseAddress.ToInt64();
- moduleEndAddr = moduleStartAddr + (ulong)processModule.ModuleMemorySize;
+ var processModule = Process.GetCurrentProcess().MainModule;
+ if (processModule != null)
+ {
+ moduleStartAddr = (ulong)processModule.BaseAddress.ToInt64();
+ moduleEndAddr = moduleStartAddr + (ulong)processModule.ModuleMemorySize;
+ }
+ else
+ {
+ moduleEndAddr = 1;
+ }
}
- else
+ catch
{
moduleEndAddr = 1;
}
}
- catch
+
+ if (autoExpand)
{
- moduleEndAddr = 1;
+ ImGui.SetNextItemOpen(true, ImGuiCond.Appearing);
}
- }
- ImGui.PushStyleColor(ImGuiCol.Text, 0xFF00FFFF);
- if (autoExpand)
- {
- ImGui.SetNextItemOpen(true, ImGuiCond.Appearing);
- }
+ using var col = ImRaii.PushColor(ImGuiCol.Text, 0xFF00FFFF);
+ using var tree = ImRaii.TreeNode($"{obj}##print-obj-{addr:X}-{string.Join("-", pathList)}", ImGuiTreeNodeFlags.SpanFullWidth);
+ col.Pop();
- if (ImGui.TreeNode($"{obj}##print-obj-{addr:X}-{string.Join("-", pathList)}"))
- {
- ImGui.PopStyleColor();
- foreach (var f in obj.GetType()
- .GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.Instance))
+ if (tree.Success)
{
- var fixedBuffer = (FixedBufferAttribute)f.GetCustomAttribute(typeof(FixedBufferAttribute));
- var offset = (FieldOffsetAttribute)f.GetCustomAttribute(typeof(FieldOffsetAttribute));
+ ImGui.PopStyleColor();
+ foreach (var f in obj.GetType()
+ .GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.Instance))
+ {
+ var fixedBuffer = (FixedBufferAttribute)f.GetCustomAttribute(typeof(FixedBufferAttribute));
+ var offset = (FieldOffsetAttribute)f.GetCustomAttribute(typeof(FieldOffsetAttribute));
- if (fixedBuffer != null)
- {
- ImGui.Text($"fixed");
- ImGui.SameLine();
- ImGui.TextColored(new Vector4(0.2f, 0.9f, 0.9f, 1),
- $"{fixedBuffer.ElementType.Name}[0x{fixedBuffer.Length:X}]");
- }
- else
- {
- if (offset != null)
+ if (fixedBuffer != null)
{
- ImGui.TextDisabled($"[0x{offset.Value:X}]");
+ ImGui.Text("fixed");
ImGui.SameLine();
+ ImGui.TextColored(new Vector4(0.2f, 0.9f, 0.9f, 1), $"{fixedBuffer.ElementType.Name}[0x{fixedBuffer.Length:X}]");
}
- ImGui.TextColored(new Vector4(0.2f, 0.9f, 0.9f, 1), $"{f.FieldType.Name}");
- }
-
- ImGui.SameLine();
- ImGui.TextColored(new Vector4(0.2f, 0.9f, 0.4f, 1), $"{f.Name}: ");
- ImGui.SameLine();
-
- pathList.Add(f.Name);
- try
- {
- if (f.FieldType.IsGenericType && (f.FieldType.IsByRef || f.FieldType.IsByRefLike))
- ImGui.Text("Cannot preview ref typed fields."); // object never contains ref struct
- else if (f.FieldType == typeof(bool) && offset != null)
- ShowValue(addr, pathList, f.FieldType, Marshal.ReadByte((nint)addr + offset.Value) > 0, hideAddress);
else
- ShowValue(addr, pathList, f.FieldType, f.GetValue(obj), hideAddress);
+ {
+ if (offset != null)
+ {
+ ImGui.TextDisabled($"[0x{offset.Value:X}]");
+ ImGui.SameLine();
+ }
+ ImGui.TextColored(new Vector4(0.2f, 0.9f, 0.9f, 1), $"{f.FieldType.Name}");
+ }
+
+ ImGui.SameLine();
+ ImGui.TextColored(new Vector4(0.2f, 0.9f, 0.4f, 1), $"{f.Name}: ");
+ ImGui.SameLine();
+
+ pathList.Add(f.Name);
+ try
+ {
+ if (f.FieldType.IsGenericType && (f.FieldType.IsByRef || f.FieldType.IsByRefLike))
+ {
+ ImGui.Text("Cannot preview ref typed fields."); // object never contains ref struct
+ }
+ else if (f.FieldType == typeof(bool) && offset != null)
+ {
+ ShowValue(addr, pathList, f.FieldType, Marshal.ReadByte((nint)addr + offset.Value) > 0, hideAddress);
+ }
+ else
+ {
+ ShowValue(addr, pathList, f.FieldType, f.GetValue(obj), hideAddress);
+ }
+ }
+ catch (Exception ex)
+ {
+ using (ImRaii.PushColor(ImGuiCol.Text, new Vector4(1f, 0.4f, 0.4f, 1f)))
+ {
+ ImGui.TextUnformatted($"Error: {ex.GetType().Name}: {ex.Message}");
+ }
+ }
+ finally
+ {
+ pathList.RemoveAt(pathList.Count - 1);
+ }
}
- catch (Exception ex)
+
+ foreach (var p in obj.GetType().GetProperties().Where(static p => p.GetGetMethod()?.GetParameters().Length == 0))
{
- ImGui.PushStyleColor(ImGuiCol.Text, new Vector4(1f, 0.4f, 0.4f, 1f));
- ImGui.TextUnformatted($"Error: {ex.GetType().Name}: {ex.Message}");
- ImGui.PopStyleColor();
- }
- finally
- {
- pathList.RemoveAt(pathList.Count - 1);
+ ImGui.TextColored(new Vector4(0.2f, 0.9f, 0.9f, 1), $"{p.PropertyType.Name}");
+ ImGui.SameLine();
+ ImGui.TextColored(new Vector4(0.2f, 0.6f, 0.4f, 1), $"{p.Name}: ");
+ ImGui.SameLine();
+
+ pathList.Add(p.Name);
+ try
+ {
+ if (p.PropertyType.IsGenericType && p.PropertyType.GetGenericTypeDefinition() == GenericSpanType)
+ {
+ ShowSpanProperty(addr, pathList, p, obj);
+ }
+ else if (p.PropertyType.IsGenericType && (p.PropertyType.IsByRef || p.PropertyType.IsByRefLike))
+ {
+ ImGui.Text("Cannot preview ref typed properties.");
+ }
+ else
+ {
+ ShowValue(addr, pathList, p.PropertyType, p.GetValue(obj), hideAddress);
+ }
+ }
+ catch (Exception ex)
+ {
+ using (ImRaii.PushColor(ImGuiCol.Text, new Vector4(1f, 0.4f, 0.4f, 1f)))
+ {
+ ImGui.TextUnformatted($"Error: {ex.GetType().Name}: {ex.Message}");
+ }
+ }
+ finally
+ {
+ pathList.RemoveAt(pathList.Count - 1);
+ }
}
}
-
- foreach (var p in obj.GetType().GetProperties().Where(p => p.GetGetMethod()?.GetParameters().Length == 0))
- {
- ImGui.TextColored(new Vector4(0.2f, 0.9f, 0.9f, 1), $"{p.PropertyType.Name}");
- ImGui.SameLine();
- ImGui.TextColored(new Vector4(0.2f, 0.6f, 0.4f, 1), $"{p.Name}: ");
- ImGui.SameLine();
-
- pathList.Add(p.Name);
- try
- {
- if (p.PropertyType.IsGenericType && p.PropertyType.GetGenericTypeDefinition() == GenericSpanType)
- ShowSpanProperty(addr, pathList, p, obj);
- else if (p.PropertyType.IsGenericType && (p.PropertyType.IsByRef || p.PropertyType.IsByRefLike))
- ImGui.Text("Cannot preview ref typed properties.");
- else
- ShowValue(addr, pathList, p.PropertyType, p.GetValue(obj), hideAddress);
- }
- catch (Exception ex)
- {
- ImGui.PushStyleColor(ImGuiCol.Text, new Vector4(1f, 0.4f, 0.4f, 1f));
- ImGui.TextUnformatted($"Error: {ex.GetType().Name}: {ex.Message}");
- ImGui.PopStyleColor();
- }
- finally
- {
- pathList.RemoveAt(pathList.Count - 1);
- }
- }
-
- ImGui.TreePop();
}
- else
- {
- ImGui.PopStyleColor();
- }
-
- ImGui.PopStyleVar();
}
}