From 26e993be675f28e609df6799e54ef09aab875d9a Mon Sep 17 00:00:00 2001 From: Infi Date: Mon, 13 May 2024 15:24:51 +0200 Subject: [PATCH] Temp fix for FPS drops with too many messages rendered - Also replaces TextWrap with an ImRaii using version --- ChatTwo/ChatTwo.csproj | 2 +- ChatTwo/PayloadHandler.cs | 19 +++++-------------- ChatTwo/Ui/ChatLogWindow.cs | 32 ++++++++++++++++++++++++++------ ChatTwo/Ui/Debugger.cs | 11 +++++++++++ ChatTwo/Util/ImGuiUtil.cs | 30 ++++++++++++++++++++++++++++++ 5 files changed, 73 insertions(+), 21 deletions(-) diff --git a/ChatTwo/ChatTwo.csproj b/ChatTwo/ChatTwo.csproj index bd8a9bf..c788535 100755 --- a/ChatTwo/ChatTwo.csproj +++ b/ChatTwo/ChatTwo.csproj @@ -1,6 +1,6 @@ - 1.24.2 + 1.24.3 net8.0-windows enable enable diff --git a/ChatTwo/PayloadHandler.cs b/ChatTwo/PayloadHandler.cs index e9a7946..70224ff 100755 --- a/ChatTwo/PayloadHandler.cs +++ b/ChatTwo/PayloadHandler.cs @@ -222,7 +222,7 @@ public sealed class PayloadHandler { } internal void Hover(Payload payload) { - var hoverSize = 250f * ImGuiHelpers.GlobalScale; + var hoverSize = 350f * ImGuiHelpers.GlobalScale; switch (payload) { @@ -260,20 +260,11 @@ public sealed class PayloadHandler { { ImGui.SetNextWindowSize(new Vector2(width, -1f)); - ImGui.BeginTooltip(); - ImGui.PushTextWrapPos(); - ImGui.PushStyleColor(ImGuiCol.Text, LogWindow.DefaultText); + using var tooltip = ImRaii.Tooltip(); + using var color = ImRaii.PushColor(ImGuiCol.Text, LogWindow.DefaultText); + using var wrap = ImGuiUtil.TextWrapPos(); - try - { - inside(); - } - finally - { - ImGui.PopStyleColor(); - ImGui.PopTextWrapPos(); - ImGui.EndTooltip(); - } + inside(); } public unsafe void MoveTooltip(AddonEvent type, AddonArgs args) diff --git a/ChatTwo/Ui/ChatLogWindow.cs b/ChatTwo/Ui/ChatLogWindow.cs index dba351b..2e28570 100644 --- a/ChatTwo/Ui/ChatLogWindow.cs +++ b/ChatTwo/Ui/ChatLogWindow.cs @@ -896,6 +896,12 @@ public sealed class ChatLogWindow : Window private void DrawMessages(Tab tab, PayloadHandler handler, bool isTable, bool moreCompact = false, float oldCellPaddingY = 0) { + // TODO Remove when the temp fix is replaced with a perm one + Plugin.DebuggerWindow.InvisibleMessages = 0; + Plugin.DebuggerWindow.InvisibleAfter = 0; + Plugin.DebuggerWindow.HeightNull = 0; + Plugin.DebuggerWindow.HeightCalculationsInside = 0; + try { tab.MessagesMutex.Wait(); @@ -963,13 +969,19 @@ public sealed class ChatLogWindow : Window if (i > 0) { var prevMessage = tab.Messages[i - 1]; - if (prevMessage.IsVisible.TryGetValue(tab.Identifier, out var prevVisible) && prevVisible) + + // TODO: TryGetValue isn't always true for some strange reason + // This should be looked into, because default will be null for the prevHeight in that case + prevMessage.Height.TryGetValue(tab.Identifier, out var prevHeight); + if (prevHeight == null || (prevMessage.IsVisible.TryGetValue(tab.Identifier, out var prevVisible) && prevVisible)) { + Plugin.DebuggerWindow.HeightCalculationsInside++; var newHeight = ImGui.GetCursorPosY() - lastPosY; + + // Remove the padding from the bottom of the previous row and the top of the current row. if (isTable && !moreCompact) - // Remove the padding from the bottom of the - // previous row and the top of the current row. newHeight -= oldCellPaddingY * 2; + if (newHeight != 0) prevMessage.Height[tab.Identifier] = newHeight; } @@ -979,9 +991,12 @@ public sealed class ChatLogWindow : Window // message has rendered once // message isn't visible, so render dummy message.Height.TryGetValue(tab.Identifier, out var height); + if (height == null) + Plugin.DebuggerWindow.HeightNull++; message.IsVisible.TryGetValue(tab.Identifier, out var visible); if (height != null && !visible) { + Plugin.DebuggerWindow.InvisibleMessages++; var beforeDummy = ImGui.GetCursorPos(); // skip to the message column for vis test @@ -999,7 +1014,9 @@ public sealed class ChatLogWindow : Window ImGui.SetCursorPos(beforeDummy); } else + { continue; + } } if (tab.DisplayTimestamp) @@ -1034,14 +1051,17 @@ public sealed class ChatLogWindow : Window ImGui.SameLine(); } + // We need to draw something otherwise the item visibility check below won't work. if (message.Content.Count == 0) - // We need to draw something otherwise the item visibility - // check below won't work. DrawChunks(new[] { new TextChunk(ChunkSource.Content, null, " ") }, true, handler, lineWidth); else DrawChunks(message.Content, true, handler, lineWidth); - message.IsVisible[tab.Identifier] = ImGui.IsItemVisible(); + var vis = ImGui.IsItemVisible(); + if (!vis) + Plugin.DebuggerWindow.InvisibleAfter++; + + message.IsVisible[tab.Identifier] = vis; } } finally diff --git a/ChatTwo/Ui/Debugger.cs b/ChatTwo/Ui/Debugger.cs index fac39f0..5ba0b6d 100644 --- a/ChatTwo/Ui/Debugger.cs +++ b/ChatTwo/Ui/Debugger.cs @@ -11,6 +11,11 @@ public class DebuggerWindow : Window private readonly Plugin Plugin; private readonly ChatLogWindow ChatLogWindow; + public int InvisibleMessages; + public int InvisibleAfter; + public int HeightNull; + public int HeightCalculationsInside; + public DebuggerWindow(Plugin plugin) : base($"Debugger###chat2-debugger") { Plugin = plugin; @@ -50,5 +55,11 @@ public class DebuggerWindow : Window ImGui.TextUnformatted($"Hovered Item: {ChatLogWindow.PayloadHandler._hoveredItem}"); ImGui.TextUnformatted($"Hover Counter: {ChatLogWindow.PayloadHandler._hoverCounter}"); ImGui.TextUnformatted($"Last Hover Counter: {ChatLogWindow.PayloadHandler._lastHoverCounter}"); + ImGui.NewLine(); + ImGui.NewLine(); + ImGui.TextUnformatted($"Invisible Messages: {InvisibleMessages}"); + ImGui.TextUnformatted($"Invisible After: {InvisibleAfter}"); + ImGui.TextUnformatted($"Height was null: {HeightNull}"); + ImGui.TextUnformatted($"Actual Height Calculations {HeightCalculationsInside}"); } } diff --git a/ChatTwo/Util/ImGuiUtil.cs b/ChatTwo/Util/ImGuiUtil.cs index ee5b2d1..3e8b177 100755 --- a/ChatTwo/Util/ImGuiUtil.cs +++ b/ChatTwo/Util/ImGuiUtil.cs @@ -417,4 +417,34 @@ internal static class ImGuiUtil return result != 0 || key == VirtualKey.NO_KEY; } + + private struct EndUnconditionally(Action endAction, bool success) : ImRaii.IEndObject + { + private Action EndAction { get; } = endAction; + + public bool Success { get; } = success; + + public bool Disposed { get; private set; } = false; + + public void Dispose() + { + if (!Disposed) + { + EndAction(); + Disposed = true; + } + } + } + + public static ImRaii.IEndObject TextWrapPos() + { + ImGui.PushTextWrapPos(); + return new EndUnconditionally(ImGui.PopTextWrapPos, true); + } + + public static ImRaii.IEndObject TextWrapPos(float wrapLocalPosX) + { + ImGui.PushTextWrapPos(wrapLocalPosX); + return new EndUnconditionally(ImGui.PopTextWrapPos, true); + } }