From 66fde2d4589516ac5cb687ac102ed6040f94b5d0 Mon Sep 17 00:00:00 2001 From: CMDRNuffin <4348470+CMDRNuffin@users.noreply.github.com> Date: Sat, 20 Dec 2025 03:19:20 +0100 Subject: [PATCH] Prevent unnecessary string creation in ImGui TextInput methods We now only create a new string if we either know the buffer changed or the EnterReturnsTrue flag was set (because that one does a LOT while still updating the buffer on every actual input), so I had to choose between replicating all that behavior in each of the various InputText methods (hell no, lol), scanning the buffer for actual changes (which would require making another copy) or accepting that in that case we would create a new string every frame. This still makes the GC happy in the majority of cases, while giving callers the option to take a slight performance hit for the convenience EnterReturnsTrue provides. --- .../Custom/ImGui.Manual.cs | 170 ++++++++++++++---- 1 file changed, 136 insertions(+), 34 deletions(-) diff --git a/imgui/Dalamud.Bindings.ImGui/Custom/ImGui.Manual.cs b/imgui/Dalamud.Bindings.ImGui/Custom/ImGui.Manual.cs index 89b3cc3d6..e455e0778 100644 --- a/imgui/Dalamud.Bindings.ImGui/Custom/ImGui.Manual.cs +++ b/imgui/Dalamud.Bindings.ImGui/Custom/ImGui.Manual.cs @@ -127,8 +127,14 @@ public unsafe partial class ImGui var t = new ImU8String(buf); t.Reserve(maxLength + 1); var r = InputText(label, t.Buffer[..(maxLength + 1)], flags, callback); - var i = t.Buffer.IndexOf((byte)0); - buf = Encoding.UTF8.GetString(i == -1 ? t.Buffer : t.Buffer[..i]); + + var e = (flags & ImGuiInputTextFlags.EnterReturnsTrue) != 0; + if (r | e) + { + var i = t.Buffer.IndexOf((byte)0); + buf = Encoding.UTF8.GetString(i == -1 ? t.Buffer : t.Buffer[..i]); + } + t.Recycle(); return r; } @@ -140,8 +146,14 @@ public unsafe partial class ImGui var t = new ImU8String(buf); t.Reserve(maxLength + 1); var r = InputText(label, t.Buffer[..(maxLength + 1)], flags, callback); - var i = t.Buffer.IndexOf((byte)0); - buf = Encoding.UTF8.GetString(i == -1 ? t.Buffer : t.Buffer[..i]); + + var e = (flags & ImGuiInputTextFlags.EnterReturnsTrue) != 0; + if (r | e) + { + var i = t.Buffer.IndexOf((byte)0); + buf = Encoding.UTF8.GetString(i == -1 ? t.Buffer : t.Buffer[..i]); + } + t.Recycle(); return r; } @@ -153,8 +165,14 @@ public unsafe partial class ImGui var t = new ImU8String(buf); t.Reserve(maxLength + 1); var r = InputText(label, t.Buffer[..(maxLength + 1)], flags, callback, ref context); - var i = t.Buffer.IndexOf((byte)0); - buf = Encoding.UTF8.GetString(i == -1 ? t.Buffer : t.Buffer[..i]); + + var e = (flags & ImGuiInputTextFlags.EnterReturnsTrue) != 0; + if (r | e) + { + var i = t.Buffer.IndexOf((byte)0); + buf = Encoding.UTF8.GetString(i == -1 ? t.Buffer : t.Buffer[..i]); + } + t.Recycle(); return r; } @@ -166,8 +184,14 @@ public unsafe partial class ImGui var t = new ImU8String(buf); t.Reserve(maxLength + 1); var r = InputText(label, t.Buffer[..(maxLength + 1)], flags, callback, in context); - var i = t.Buffer.IndexOf((byte)0); - buf = Encoding.UTF8.GetString(i == -1 ? t.Buffer : t.Buffer[..i]); + + var e = (flags & ImGuiInputTextFlags.EnterReturnsTrue) != 0; + if (r | e) + { + var i = t.Buffer.IndexOf((byte)0); + buf = Encoding.UTF8.GetString(i == -1 ? t.Buffer : t.Buffer[..i]); + } + t.Recycle(); return r; } @@ -287,8 +311,14 @@ public unsafe partial class ImGui var t = new ImU8String(buf); t.Reserve(maxLength + 1); var r = InputTextEx(label, hint, t.Buffer[..(maxLength + 1)], sizeArg, flags, callback); - var i = t.Buffer.IndexOf((byte)0); - buf = Encoding.UTF8.GetString(i == -1 ? t.Buffer : t.Buffer[..i]); + + var e = (flags & ImGuiInputTextFlags.EnterReturnsTrue) != 0; + if (r | e) + { + var i = t.Buffer.IndexOf((byte)0); + buf = Encoding.UTF8.GetString(i == -1 ? t.Buffer : t.Buffer[..i]); + } + t.Recycle(); return r; } @@ -300,8 +330,14 @@ public unsafe partial class ImGui var t = new ImU8String(buf); t.Reserve(maxLength + 1); var r = InputTextEx(label, hint, t.Buffer[..(maxLength + 1)], sizeArg, flags, callback); - var i = t.Buffer.IndexOf((byte)0); - buf = Encoding.UTF8.GetString(i == -1 ? t.Buffer : t.Buffer[..i]); + + var e = (flags & ImGuiInputTextFlags.EnterReturnsTrue) != 0; + if (r | e) + { + var i = t.Buffer.IndexOf((byte)0); + buf = Encoding.UTF8.GetString(i == -1 ? t.Buffer : t.Buffer[..i]); + } + t.Recycle(); return r; } @@ -314,8 +350,14 @@ public unsafe partial class ImGui var t = new ImU8String(buf); t.Reserve(maxLength + 1); var r = InputTextEx(label, hint, t.Buffer[..(maxLength + 1)], sizeArg, flags, callback, ref context); - var i = t.Buffer.IndexOf((byte)0); - buf = Encoding.UTF8.GetString(i == -1 ? t.Buffer : t.Buffer[..i]); + + var e = (flags & ImGuiInputTextFlags.EnterReturnsTrue) != 0; + if (r | e) + { + var i = t.Buffer.IndexOf((byte)0); + buf = Encoding.UTF8.GetString(i == -1 ? t.Buffer : t.Buffer[..i]); + } + t.Recycle(); return r; } @@ -328,8 +370,14 @@ public unsafe partial class ImGui var t = new ImU8String(buf); t.Reserve(maxLength + 1); var r = InputTextEx(label, hint, t.Buffer[..(maxLength + 1)], sizeArg, flags, callback, in context); - var i = t.Buffer.IndexOf((byte)0); - buf = Encoding.UTF8.GetString(i == -1 ? t.Buffer : t.Buffer[..i]); + + var e = (flags & ImGuiInputTextFlags.EnterReturnsTrue) != 0; + if (r | e) + { + var i = t.Buffer.IndexOf((byte)0); + buf = Encoding.UTF8.GetString(i == -1 ? t.Buffer : t.Buffer[..i]); + } + t.Recycle(); return r; } @@ -388,8 +436,14 @@ public unsafe partial class ImGui var t = new ImU8String(buf); t.Reserve(maxLength + 1); var r = InputTextMultiline(label, t.Buffer[..(maxLength + 1)], size, flags, callback); - var i = t.Buffer.IndexOf((byte)0); - buf = Encoding.UTF8.GetString(i == -1 ? t.Buffer : t.Buffer[..i]); + + var e = (flags & ImGuiInputTextFlags.EnterReturnsTrue) != 0; + if (r | e) + { + var i = t.Buffer.IndexOf((byte)0); + buf = Encoding.UTF8.GetString(i == -1 ? t.Buffer : t.Buffer[..i]); + } + t.Recycle(); return r; } @@ -401,8 +455,14 @@ public unsafe partial class ImGui var t = new ImU8String(buf); t.Reserve(maxLength + 1); var r = InputTextMultiline(label, t.Buffer[..(maxLength + 1)], size, flags, callback); - var i = t.Buffer.IndexOf((byte)0); - buf = Encoding.UTF8.GetString(i == -1 ? t.Buffer : t.Buffer[..i]); + + var e = (flags & ImGuiInputTextFlags.EnterReturnsTrue) != 0; + if (r | e) + { + var i = t.Buffer.IndexOf((byte)0); + buf = Encoding.UTF8.GetString(i == -1 ? t.Buffer : t.Buffer[..i]); + } + t.Recycle(); return r; } @@ -414,8 +474,14 @@ public unsafe partial class ImGui var t = new ImU8String(buf); t.Reserve(maxLength + 1); var r = InputTextMultiline(label, t.Buffer[..(maxLength + 1)], size, flags, callback, ref context); - var i = t.Buffer.IndexOf((byte)0); - buf = Encoding.UTF8.GetString(i == -1 ? t.Buffer : t.Buffer[..i]); + + var e = (flags & ImGuiInputTextFlags.EnterReturnsTrue) != 0; + if (r | e) + { + var i = t.Buffer.IndexOf((byte)0); + buf = Encoding.UTF8.GetString(i == -1 ? t.Buffer : t.Buffer[..i]); + } + t.Recycle(); return r; } @@ -427,8 +493,14 @@ public unsafe partial class ImGui var t = new ImU8String(buf); t.Reserve(maxLength + 1); var r = InputTextMultiline(label, t.Buffer[..(maxLength + 1)], size, flags, callback, in context); - var i = t.Buffer.IndexOf((byte)0); - buf = Encoding.UTF8.GetString(i == -1 ? t.Buffer : t.Buffer[..i]); + + var e = (flags & ImGuiInputTextFlags.EnterReturnsTrue) != 0; + if (r | e) + { + var i = t.Buffer.IndexOf((byte)0); + buf = Encoding.UTF8.GetString(i == -1 ? t.Buffer : t.Buffer[..i]); + } + t.Recycle(); return r; } @@ -477,8 +549,14 @@ public unsafe partial class ImGui var t = new ImU8String(buf); t.Reserve(maxLength + 1); var r = InputTextWithHint(label, hint, t.Buffer[..(maxLength + 1)], flags, callback); - var i = t.Buffer.IndexOf((byte)0); - buf = Encoding.UTF8.GetString(i == -1 ? t.Buffer : t.Buffer[..i]); + + var e = (flags & ImGuiInputTextFlags.EnterReturnsTrue) != 0; + if (r | e) + { + var i = t.Buffer.IndexOf((byte)0); + buf = Encoding.UTF8.GetString(i == -1 ? t.Buffer : t.Buffer[..i]); + } + t.Recycle(); return r; } @@ -490,8 +568,14 @@ public unsafe partial class ImGui var t = new ImU8String(buf); t.Reserve(maxLength + 1); var r = InputTextWithHint(label, hint, t.Buffer[..(maxLength + 1)], flags, callback); - var i = t.Buffer.IndexOf((byte)0); - buf = Encoding.UTF8.GetString(i == -1 ? t.Buffer : t.Buffer[..i]); + + var e = (flags & ImGuiInputTextFlags.EnterReturnsTrue) != 0; + if (r | e) + { + var i = t.Buffer.IndexOf((byte)0); + buf = Encoding.UTF8.GetString(i == -1 ? t.Buffer : t.Buffer[..i]); + } + t.Recycle(); return r; } @@ -503,8 +587,14 @@ public unsafe partial class ImGui var t = new ImU8String(buf); t.Reserve(maxLength + 1); var r = InputTextWithHint(label, hint, t.Buffer[..(maxLength + 1)], flags, callback, ref context); - var i = t.Buffer.IndexOf((byte)0); - buf = Encoding.UTF8.GetString(i == -1 ? t.Buffer : t.Buffer[..i]); + + var e = (flags & ImGuiInputTextFlags.EnterReturnsTrue) != 0; + if (r | e) + { + var i = t.Buffer.IndexOf((byte)0); + buf = Encoding.UTF8.GetString(i == -1 ? t.Buffer : t.Buffer[..i]); + } + t.Recycle(); return r; } @@ -516,8 +606,14 @@ public unsafe partial class ImGui var t = new ImU8String(buf); t.Reserve(maxLength + 1); var r = InputTextWithHint(label, hint, t.Buffer[..(maxLength + 1)], flags, callback, in context); - var i = t.Buffer.IndexOf((byte)0); - buf = Encoding.UTF8.GetString(i == -1 ? t.Buffer : t.Buffer[..i]); + + var e = (flags & ImGuiInputTextFlags.EnterReturnsTrue) != 0; + if (r | e) + { + var i = t.Buffer.IndexOf((byte)0); + buf = Encoding.UTF8.GetString(i == -1 ? t.Buffer : t.Buffer[..i]); + } + t.Recycle(); return r; } @@ -541,8 +637,14 @@ public unsafe partial class ImGui var t = new ImU8String(buf); t.Reserve(maxLength + 1); var r = TempInputText(bb, id, label, t.Buffer[..(maxLength + 1)], flags); - var i = t.Buffer.IndexOf((byte)0); - buf = Encoding.UTF8.GetString(i == -1 ? t.Buffer : t.Buffer[..i]); + + var e = (flags & ImGuiInputTextFlags.EnterReturnsTrue) != 0; + if (r | e) + { + var i = t.Buffer.IndexOf((byte)0); + buf = Encoding.UTF8.GetString(i == -1 ? t.Buffer : t.Buffer[..i]); + } + t.Recycle(); return r; }