Improve perf of InputText/Multiline.

internals
Eric Mellino 6 years ago
parent 1ed6432be0
commit 9212f835fa
  1. 19
      src/ImGui.NET/ImGui.Manual.cs
  2. 17
      src/ImGui.NET/Util.cs

@ -1,5 +1,6 @@
using System; using System;
using System.Numerics; using System.Numerics;
using System.Runtime.CompilerServices;
using System.Text; using System.Text;
namespace ImGuiNET namespace ImGuiNET
@ -88,14 +89,17 @@ namespace ImGuiNET
Encoding.UTF8.GetBytes(labelPtr, label.Length, labelBytes, labelByteCount); Encoding.UTF8.GetBytes(labelPtr, label.Length, labelBytes, labelByteCount);
} }
int bytesNeeded = Encoding.UTF8.GetByteCount(input); int originalByteCount = Encoding.UTF8.GetByteCount(input);
int stackBufSize = Math.Max((int)maxLength, bytesNeeded); int stackBufSize = Math.Max((int)maxLength, originalByteCount);
byte* bufBytes = stackalloc byte[stackBufSize]; byte* bufBytes = stackalloc byte[stackBufSize];
fixed (char* u16Ptr = input) fixed (char* u16Ptr = input)
{ {
Encoding.UTF8.GetBytes(u16Ptr, input.Length, bufBytes, stackBufSize); Encoding.UTF8.GetBytes(u16Ptr, input.Length, bufBytes, stackBufSize);
} }
byte* originalBufBytes = stackalloc byte[originalByteCount];
Unsafe.CopyBlock(originalBufBytes, bufBytes, (uint)originalByteCount);
byte result = ImGuiNative.igInputText( byte result = ImGuiNative.igInputText(
labelBytes, labelBytes,
bufBytes, bufBytes,
@ -103,7 +107,7 @@ namespace ImGuiNET
flags, flags,
callback, callback,
user_data.ToPointer()); user_data.ToPointer());
if (!Util.AreStringsEqual(input, bufBytes)) if (!Util.AreStringsEqual(originalBufBytes, originalByteCount, bufBytes))
{ {
input = Util.StringFromPtr(bufBytes); input = Util.StringFromPtr(bufBytes);
} }
@ -148,14 +152,17 @@ namespace ImGuiNET
Encoding.UTF8.GetBytes(labelPtr, label.Length, labelBytes, labelByteCount); Encoding.UTF8.GetBytes(labelPtr, label.Length, labelBytes, labelByteCount);
} }
int bytesNeeded = Encoding.UTF8.GetByteCount(input); int originalByteCount = Encoding.UTF8.GetByteCount(input);
int stackBufSize = Math.Max((int)maxLength, bytesNeeded); int stackBufSize = Math.Max((int)maxLength, originalByteCount);
byte* bufBytes = stackalloc byte[stackBufSize]; byte* bufBytes = stackalloc byte[stackBufSize];
fixed (char* u16Ptr = input) fixed (char* u16Ptr = input)
{ {
Encoding.UTF8.GetBytes(u16Ptr, input.Length, bufBytes, stackBufSize); Encoding.UTF8.GetBytes(u16Ptr, input.Length, bufBytes, stackBufSize);
} }
byte* originalBufBytes = stackalloc byte[originalByteCount];
Unsafe.CopyBlock(originalBufBytes, bufBytes, (uint)originalByteCount);
byte result = ImGuiNative.igInputTextMultiline( byte result = ImGuiNative.igInputTextMultiline(
labelBytes, labelBytes,
bufBytes, bufBytes,
@ -164,7 +171,7 @@ namespace ImGuiNET
flags, flags,
callback, callback,
user_data.ToPointer()); user_data.ToPointer());
if (!Util.AreStringsEqual(input, bufBytes)) if (!Util.AreStringsEqual(originalBufBytes, originalByteCount, bufBytes))
{ {
input = Util.StringFromPtr(bufBytes); input = Util.StringFromPtr(bufBytes);
} }

@ -15,23 +15,14 @@ namespace ImGuiNET
return Encoding.UTF8.GetString(ptr, characters); return Encoding.UTF8.GetString(ptr, characters);
} }
internal static unsafe bool AreStringsEqual(string a, byte* b) internal static unsafe bool AreStringsEqual(byte* a, int aLength, byte* b)
{ {
if (a.Length == 0) { return b[0] == 0; } for (int i = 0; i < aLength; i++)
int aCount = Encoding.UTF8.GetByteCount(a);
byte* aBytes = stackalloc byte[aCount];
fixed (char* labelPtr = a)
{
Encoding.UTF8.GetBytes(labelPtr, a.Length, aBytes, aCount);
}
for (int i = 0; i < aCount; i++)
{ {
if (aBytes[i] != b[i]) { return false; } if (a[i] != b[i]) { return false; }
} }
if (b[aCount] != 0) { return false; } if (b[aLength] != 0) { return false; }
return true; return true;
} }

Loading…
Cancel
Save