Hashing: handling of "###" operator to reset to seed within a string identifier doesn't include the "###" characters in the output hash anymore.

This has various simplifying properties.
Need a test engine update too.
+ Demo: removed misleading/unnecessary usage of ###.
This commit is contained in:
omar
2019-12-26 21:40:58 +01:00
committed by ocornut
parent 1e7d2adc29
commit fc89c61089
4 changed files with 23 additions and 9 deletions

View File

@@ -41,6 +41,14 @@ HOW TO UPDATE?
Breaking Changes: Breaking Changes:
- Hashing: handling of "###" operator to reset to seed within a string identifier
doesn't include the "###" characters in the output hash anymore:
Before: GetID("Hello###World") == GetID("###World") != GetID("World");
Now: GetID("Hello###World") == GetID("###World") == GetID("World");
- This has the property of facilitating concatenating and manipulating
identifers using "###", and will allow fixing other dangling issues.
- This will invalidate hashes (stored in .ini data) for Tables and Windows
that are using the "###" operators. (#713, #1698)
- Fonts: Fixed handling of `ImFontConfig::FontDataOwnedByAtlas = false` which - Fonts: Fixed handling of `ImFontConfig::FontDataOwnedByAtlas = false` which
did erroneously make a copy of the font data, essentially defeating the purpose did erroneously make a copy of the font data, essentially defeating the purpose
of this flag and wasting memory (undetected since July 2015 and now spotted of this flag and wasting memory (undetected since July 2015 and now spotted

View File

@@ -2368,11 +2368,8 @@ ImGuiID ImHashData(const void* data_p, size_t data_size, ImGuiID seed)
#endif #endif
} }
// Zero-terminated string hash, with support for ### to reset back to seed value // Zero-terminated string hash, with support for ### to reset back to seed value.
// We support a syntax of "label###id" where only "###id" is included in the hash, and only "label" gets displayed. // e.g. "label###id" outputs the same hash as "id" (and "label" is generally displayed by the UI functions)
// Because this syntax is rarely used we are optimizing for the common case.
// - If we reach ### in the string we discard the hash so far and reset to the seed.
// - We don't do 'current += 2; continue;' after handling ### to keep the code smaller/faster (measured ~10% diff in Debug build)
// FIXME-OPT: Replace with e.g. FNV1a hash? CRC32 pretty much randomly access 1KB. Need to do proper measurements. // FIXME-OPT: Replace with e.g. FNV1a hash? CRC32 pretty much randomly access 1KB. Need to do proper measurements.
ImGuiID ImHashStr(const char* data_p, size_t data_size, ImGuiID seed) ImGuiID ImHashStr(const char* data_p, size_t data_size, ImGuiID seed)
{ {
@@ -2384,11 +2381,16 @@ ImGuiID ImHashStr(const char* data_p, size_t data_size, ImGuiID seed)
#endif #endif
if (data_size != 0) if (data_size != 0)
{ {
while (data_size-- != 0) while (data_size-- > 0)
{ {
unsigned char c = *data++; unsigned char c = *data++;
if (c == '#' && data_size >= 2 && data[0] == '#' && data[1] == '#') if (c == '#' && data_size >= 2 && data[0] == '#' && data[1] == '#')
{
crc = seed; crc = seed;
data += 2;
data_size -= 2;
continue;
}
#ifndef IMGUI_ENABLE_SSE4_2_CRC #ifndef IMGUI_ENABLE_SSE4_2_CRC
crc = (crc >> 8) ^ crc32_lut[(crc & 0xFF) ^ c]; crc = (crc >> 8) ^ crc32_lut[(crc & 0xFF) ^ c];
#else #else
@@ -2401,7 +2403,11 @@ ImGuiID ImHashStr(const char* data_p, size_t data_size, ImGuiID seed)
while (unsigned char c = *data++) while (unsigned char c = *data++)
{ {
if (c == '#' && data[0] == '#' && data[1] == '#') if (c == '#' && data[0] == '#' && data[1] == '#')
{
crc = seed; crc = seed;
data += 2;
continue;
}
#ifndef IMGUI_ENABLE_SSE4_2_CRC #ifndef IMGUI_ENABLE_SSE4_2_CRC
crc = (crc >> 8) ^ crc32_lut[(crc & 0xFF) ^ c]; crc = (crc >> 8) ^ crc32_lut[(crc & 0xFF) ^ c];
#else #else
@@ -2419,7 +2425,7 @@ const char* ImHashSkipUncontributingPrefix(const char* label)
const char* result = label; const char* result = label;
while (unsigned char c = *label++) while (unsigned char c = *label++)
if (c == '#' && label[0] == '#' && label[1] == '#') if (c == '#' && label[0] == '#' && label[1] == '#')
result = label - 1; result = label + 2;
return result; return result;
} }

View File

@@ -30,7 +30,7 @@
// Library Version // Library Version
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345') // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
#define IMGUI_VERSION "1.92.6 WIP" #define IMGUI_VERSION "1.92.6 WIP"
#define IMGUI_VERSION_NUM 19254 #define IMGUI_VERSION_NUM 19255
#define IMGUI_HAS_TABLE // Added BeginTable() - from IMGUI_VERSION_NUM >= 18000 #define IMGUI_HAS_TABLE // Added BeginTable() - from IMGUI_VERSION_NUM >= 18000
#define IMGUI_HAS_TEXTURES // Added ImGuiBackendFlags_RendererHasTextures - from IMGUI_VERSION_NUM >= 19198 #define IMGUI_HAS_TEXTURES // Added ImGuiBackendFlags_RendererHasTextures - from IMGUI_VERSION_NUM >= 19198

View File

@@ -3358,7 +3358,7 @@ static void DemoWindowWidgetsSelectionAndMultiSelect(ImGuiDemoWindowData* demo_d
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::SetNextItemWidth(-FLT_MIN); ImGui::SetNextItemWidth(-FLT_MIN);
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0)); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
ImGui::InputText("###NoLabel", (char*)(void*)item_category, strlen(item_category), ImGuiInputTextFlags_ReadOnly); ImGui::InputText("##NoLabel", (char*)(void*)item_category, strlen(item_category), ImGuiInputTextFlags_ReadOnly);
ImGui::PopStyleVar(); ImGui::PopStyleVar();
} }