From eb1c36fdfb2456c310398008f945468cc77c9073 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 25 Apr 2018 22:07:14 +0200 Subject: [PATCH] Added IMGUI_CHECKVERSION() macro to compare version string and data structure sizes in order to catch issues with mismatching compilation unit settings. (#1695, #1769) --- CHANGELOG.txt | 2 ++ examples/allegro5_example/main.cpp | 3 ++- examples/directx10_example/main.cpp | 3 ++- examples/directx11_example/main.cpp | 3 ++- examples/directx12_example/main.cpp | 3 ++- examples/directx9_example/main.cpp | 3 ++- examples/marmalade_example/main.cpp | 3 ++- examples/null_example/main.cpp | 1 + examples/opengl2_example/main.cpp | 3 ++- examples/opengl3_example/main.cpp | 3 ++- examples/sdl_opengl2_example/main.cpp | 3 ++- examples/sdl_opengl3_example/main.cpp | 3 ++- examples/vulkan_example/main.cpp | 3 ++- imgui.cpp | 14 ++++++++++++++ imgui.h | 23 ++++++++++++----------- 15 files changed, 51 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 73644a92e..8af43b8c7 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -57,7 +57,9 @@ Other Changes: - InputText: On Mac OS X, filter out characters when the Cmd modifier is held. (#1747) [@sivu] - InputText: On Mac OS X, support Cmd+Shift+Z for Redo. Cmd+Y is also supported as major apps seems to default to support both. (#1765) [@lfnoise] - Style: Changed default style.DisplaySafeAreaPadding values from (4,4) to (3,3) so it is smaller than FramePadding and has no effect on main menu bar on a computer. (#1439) +- Misc: Added IMGUI_CHECKVERSION() macro to compare version string and data structure sizes in order to catch issues with mismatching compilation unit settings. (#1695, #1769) - Demo: Fixed Overlay: Added a context menu item to enable freely moving the window. +- Examples: Calling IMGUI_CHECKVERSION() in the main.cpp of every example application. - Examples: Allegro 5: Added support for 32-bit indices setup via defining ImDrawIdx, to avoid an unnecessary conversion (Allegro 5 doesn't support 16-bit indices). - Examples: Allegro 5: Renamed bindings from imgui_impl_a5.cpp to imgui_impl_allegro5.cpp. - Various minor fixes, tweaks, refactoring, comments. diff --git a/examples/allegro5_example/main.cpp b/examples/allegro5_example/main.cpp index 5ecd41253..aa54057ab 100644 --- a/examples/allegro5_example/main.cpp +++ b/examples/allegro5_example/main.cpp @@ -22,7 +22,8 @@ int main(int, char**) al_register_event_source(queue, al_get_keyboard_event_source()); al_register_event_source(queue, al_get_mouse_event_source()); - // Setup ImGui binding + // Setup Dear ImGui binding + IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls diff --git a/examples/directx10_example/main.cpp b/examples/directx10_example/main.cpp index b69919d07..15ed99852 100644 --- a/examples/directx10_example/main.cpp +++ b/examples/directx10_example/main.cpp @@ -111,7 +111,8 @@ int main(int, char**) ShowWindow(hwnd, SW_SHOWDEFAULT); UpdateWindow(hwnd); - // Setup ImGui binding + // Setup Dear ImGui binding + IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp index f91a181c0..8b3586984 100644 --- a/examples/directx11_example/main.cpp +++ b/examples/directx11_example/main.cpp @@ -114,7 +114,8 @@ int main(int, char**) ShowWindow(hwnd, SW_SHOWDEFAULT); UpdateWindow(hwnd); - // Setup ImGui binding + // Setup Dear ImGui binding + IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls diff --git a/examples/directx12_example/main.cpp b/examples/directx12_example/main.cpp index 24bf58cf2..1e7c27489 100644 --- a/examples/directx12_example/main.cpp +++ b/examples/directx12_example/main.cpp @@ -285,7 +285,8 @@ int main(int, char**) ShowWindow(hwnd, SW_SHOWDEFAULT); UpdateWindow(hwnd); - // Setup ImGui binding + // Setup Dear ImGui binding + IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls diff --git a/examples/directx9_example/main.cpp b/examples/directx9_example/main.cpp index cb75a43f8..8b27b5dc7 100644 --- a/examples/directx9_example/main.cpp +++ b/examples/directx9_example/main.cpp @@ -74,7 +74,8 @@ int main(int, char**) return 0; } - // Setup ImGui binding + // Setup Dear ImGui binding + IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls diff --git a/examples/marmalade_example/main.cpp b/examples/marmalade_example/main.cpp index cb9113edf..3fcf15263 100644 --- a/examples/marmalade_example/main.cpp +++ b/examples/marmalade_example/main.cpp @@ -16,7 +16,8 @@ int main(int, char**) { IwGxInit(); - // Setup ImGui binding + // Setup Dear ImGui binding + IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls diff --git a/examples/null_example/main.cpp b/examples/null_example/main.cpp index 482d689bf..547ed3c15 100644 --- a/examples/null_example/main.cpp +++ b/examples/null_example/main.cpp @@ -4,6 +4,7 @@ int main(int, char**) { + IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); diff --git a/examples/opengl2_example/main.cpp b/examples/opengl2_example/main.cpp index 92abfbd15..2dfa129e7 100644 --- a/examples/opengl2_example/main.cpp +++ b/examples/opengl2_example/main.cpp @@ -26,7 +26,8 @@ int main(int, char**) glfwMakeContextCurrent(window); glfwSwapInterval(1); // Enable vsync - // Setup ImGui binding + // Setup Dear ImGui binding + IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls diff --git a/examples/opengl3_example/main.cpp b/examples/opengl3_example/main.cpp index 4ca766365..4542c8912 100644 --- a/examples/opengl3_example/main.cpp +++ b/examples/opengl3_example/main.cpp @@ -31,7 +31,8 @@ int main(int, char**) glfwSwapInterval(1); // Enable vsync gl3wInit(); - // Setup ImGui binding + // Setup Dear ImGui binding + IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls diff --git a/examples/sdl_opengl2_example/main.cpp b/examples/sdl_opengl2_example/main.cpp index 797650377..ac349be39 100644 --- a/examples/sdl_opengl2_example/main.cpp +++ b/examples/sdl_opengl2_example/main.cpp @@ -33,7 +33,8 @@ int main(int, char**) SDL_GLContext gl_context = SDL_GL_CreateContext(window); SDL_GL_SetSwapInterval(1); // Enable vsync - // Setup ImGui binding + // Setup Dear ImGui binding + IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls diff --git a/examples/sdl_opengl3_example/main.cpp b/examples/sdl_opengl3_example/main.cpp index 1cac6b16a..8b1e3f40e 100644 --- a/examples/sdl_opengl3_example/main.cpp +++ b/examples/sdl_opengl3_example/main.cpp @@ -33,7 +33,8 @@ int main(int, char**) SDL_GL_SetSwapInterval(1); // Enable vsync gl3wInit(); - // Setup ImGui binding + // Setup Dear ImGui binding + IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls diff --git a/examples/vulkan_example/main.cpp b/examples/vulkan_example/main.cpp index cd0b0e49c..57cab6abd 100644 --- a/examples/vulkan_example/main.cpp +++ b/examples/vulkan_example/main.cpp @@ -625,7 +625,8 @@ int main(int, char**) setup_vulkan(window); glfwSetFramebufferSizeCallback(window, glfw_resize_callback); - // Setup ImGui binding + // Setup Dear ImGui binding + IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; ImGui_ImplGlfwVulkan_Init_Data init_data = {}; diff --git a/imgui.cpp b/imgui.cpp index 127d07d3a..13181e92d 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2644,6 +2644,20 @@ void ImGui::SetCurrentContext(ImGuiContext* ctx) #endif } +// Helper function to verify that the type sizes are matching between the calling file's compilation unit and imgui.cpp's compilation unit +// If the user has inconsistent compilation settings, imgui configuration #define, packing pragma, etc. you may see different structures from what imgui.cpp sees which is highly problematic. +bool ImGui::DebugCheckVersionAndDataLayout(const char* version, size_t sz_io, size_t sz_style, size_t sz_vec2, size_t sz_vec4, size_t sz_vert) +{ + bool error = false; + if (strcmp(version, IMGUI_VERSION)!=0) { error = true; IM_ASSERT(strcmp(version,IMGUI_VERSION)==0 && "Mismatch version string!"); } + if (sz_io != sizeof(ImGuiIO)) { error = true; IM_ASSERT(sz_io == sizeof(ImGuiIO) && "Mismatched struct layout!"); } + if (sz_style != sizeof(ImGuiStyle)) { error = true; IM_ASSERT(sz_style == sizeof(ImGuiStyle) && "Mismatched struct layout!"); } + if (sz_vec2 != sizeof(ImVec2)) { error = true; IM_ASSERT(sz_vec2 == sizeof(ImVec2) && "Mismatched struct layout!"); } + if (sz_vec4 != sizeof(ImVec4)) { error = true; IM_ASSERT(sz_vec4 == sizeof(ImVec4) && "Mismatched struct layout!"); } + if (sz_vert != sizeof(ImDrawVert)) { error = true; IM_ASSERT(sz_vert == sizeof(ImDrawVert) && "Mismatched struct layout!"); } + return !error; +} + void ImGui::SetAllocatorFunctions(void* (*alloc_func)(size_t sz, void* user_data), void(*free_func)(void* ptr, void* user_data), void* user_data) { GImAllocatorAllocFunc = alloc_func; diff --git a/imgui.h b/imgui.h index 6fd1399ff..2bdebb990 100644 --- a/imgui.h +++ b/imgui.h @@ -16,25 +16,25 @@ #include "imconfig.h" #endif -#include // FLT_MAX -#include // va_list -#include // ptrdiff_t, NULL -#include // memset, memmove, memcpy, strlen, strchr, strcpy, strcmp +#include // FLT_MAX +#include // va_list +#include // ptrdiff_t, NULL +#include // memset, memmove, memcpy, strlen, strchr, strcpy, strcmp -#define IMGUI_VERSION "1.61 WIP" +// Version +#define IMGUI_VERSION "1.61 WIP" +#define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert)) -// Define attributes of all API symbols declarations, e.g. for DLL under Windows. +// Define attributes of all API symbols declarations (e.g. for DLL under Windows) #ifndef IMGUI_API #define IMGUI_API #endif -// Define assertion handler. +// Helpers #ifndef IM_ASSERT #include -#define IM_ASSERT(_EXPR) assert(_EXPR) +#define IM_ASSERT(_EXPR) assert(_EXPR) #endif - -// Helpers #if defined(__clang__) || defined(__GNUC__) #define IM_FMTARGS(FMT) __attribute__((format(printf, FMT, FMT+1))) // Apply printf-style warnings to user functions. #define IM_FMTLIST(FMT) __attribute__((format(printf, FMT, 0))) @@ -60,7 +60,7 @@ struct ImDrawVert; // A single vertex (20 bytes by default, ove struct ImFont; // Runtime data for a single font within a parent ImFontAtlas struct ImFontAtlas; // Runtime data for multiple fonts, bake multiple fonts into a single texture, TTF/OTF font loader struct ImFontConfig; // Configuration data when adding a font or merging fonts -struct ImColor; // Helper functions to create a color that can be converted to either u32 or float4 +struct ImColor; // Helper functions to create a color that can be converted to either u32 or float4 (*obsolete* please avoid using) struct ImGuiIO; // Main configuration and I/O between your application and ImGui struct ImGuiOnceUponAFrame; // Simple helper for running a block of code not more than once a frame, used by IMGUI_ONCE_UPON_A_FRAME macro struct ImGuiStorage; // Simple custom key value storage @@ -143,6 +143,7 @@ namespace ImGui IMGUI_API void DestroyContext(ImGuiContext* ctx = NULL); // NULL = destroy current context IMGUI_API ImGuiContext* GetCurrentContext(); IMGUI_API void SetCurrentContext(ImGuiContext* ctx); + IMGUI_API bool DebugCheckVersionAndDataLayout(const char* version_str, size_t sz_io, size_t sz_style, size_t sz_vec2, size_t sz_vec4, size_t sz_drawvert); // Main IMGUI_API ImGuiIO& GetIO();