From 5a301c29dc1c334e2469783f57d1aa40889c270a Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 20 Jan 2018 21:41:46 +0100 Subject: [PATCH 1/7] Context: Removed allocator parameters from CreateContext(), they are now setup with SetMemoryAllocators() and shared by all contexts. (#1565, #586, #992, #1007, #1558) --- imgui.cpp | 43 +++++++++++++++++++++++++++---------------- imgui.h | 12 ++++-------- 2 files changed, 31 insertions(+), 24 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index c34190b4..71e6371d 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -213,6 +213,7 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2018/01/20 (1.XX) - removed allocator parameters from CreateContext(), they are now setup with SetMemoryAllocators() and shared by all contexts. - 2018/01/11 (1.54) - obsoleted IsAnyWindowHovered() in favor of IsWindowHovered(ImGuiHoveredFlags_AnyWindow). Kept redirection function (will obsolete). - 2018/01/11 (1.54) - obsoleted IsAnyWindowFocused() in favor of IsWindowFocused(ImGuiFocusedFlags_AnyWindow). Kept redirection function (will obsolete). - 2018/01/03 (1.54) - renamed ImGuiSizeConstraintCallback to ImGuiSizeCallback, ImGuiSizeConstraintCallbackData to ImGuiSizeCallbackData. @@ -709,6 +710,17 @@ static ImGuiContext GImDefaultContext; ImGuiContext* GImGui = &GImDefaultContext; #endif +// Memory Allocator Functions. Use SetMemoryAllocators() to change them. +// If you use DLL hotreloading you might need to call SetMemoryAllocators() after reloading code from this file. +// Otherwise, you probably don't want to modify them mid-program, and if you use global/static e.g. ImVector<> instances you may need to keep them accessible during program destruction. +static void* MallocWrapper(size_t size, void* user_data) { (void)user_data; return malloc(size); } +static void FreeWrapper(void* ptr, void* user_data) { (void)user_data; free(ptr); } + +static void* (*GImAllocatorAllocFunc)(size_t size, void* user_data) = MallocWrapper; +static void (*GImAllocatorFreeFunc)(void* ptr, void* user_data) = FreeWrapper; +static void* GImAllocatorUserData = NULL; +static size_t GImAllocatorActiveCount = 0; + //----------------------------------------------------------------------------- // User facing structures //----------------------------------------------------------------------------- @@ -807,8 +819,6 @@ ImGuiIO::ImGuiIO() // Settings (User Functions) RenderDrawListsFn = NULL; - MemAllocFn = malloc; - MemFreeFn = free; GetClipboardTextFn = GetClipboardTextFn_DefaultImpl; // Platform dependent default implementations SetClipboardTextFn = SetClipboardTextFn_DefaultImpl; ClipboardUserData = NULL; @@ -2173,14 +2183,14 @@ float ImGui::CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x) void* ImGui::MemAlloc(size_t sz) { - GImGui->IO.MetricsAllocs++; - return GImGui->IO.MemAllocFn(sz); + GImAllocatorActiveCount++; + return GImAllocatorAllocFunc(sz, GImAllocatorUserData); } void ImGui::MemFree(void* ptr) { - if (ptr) GImGui->IO.MetricsAllocs--; - return GImGui->IO.MemFreeFn(ptr); + if (ptr) GImAllocatorActiveCount--; + return GImAllocatorFreeFunc(ptr, GImAllocatorUserData); } const char* ImGui::GetClipboardText() @@ -2215,23 +2225,24 @@ void ImGui::SetCurrentContext(ImGuiContext* ctx) #endif } -ImGuiContext* ImGui::CreateContext(void* (*malloc_fn)(size_t), void (*free_fn)(void*)) +void ImGui::SetMemoryAllocators(void* (*alloc_fn)(size_t sz, void* user_data), void(*free_fn)(void* ptr, void* user_data), void* user_data) +{ + GImAllocatorAllocFunc = alloc_fn; + GImAllocatorFreeFunc = free_fn; + GImAllocatorUserData = user_data; +} + +ImGuiContext* ImGui::CreateContext() { - if (!malloc_fn) malloc_fn = malloc; - ImGuiContext* ctx = (ImGuiContext*)malloc_fn(sizeof(ImGuiContext)); - IM_PLACEMENT_NEW(ctx) ImGuiContext(); - ctx->IO.MemAllocFn = malloc_fn; - ctx->IO.MemFreeFn = free_fn ? free_fn : free; + ImGuiContext* ctx = IM_NEW(ImGuiContext)(); return ctx; } void ImGui::DestroyContext(ImGuiContext* ctx) { - void (*free_fn)(void*) = ctx->IO.MemFreeFn; - ctx->~ImGuiContext(); - free_fn(ctx); if (GImGui == ctx) SetCurrentContext(NULL); + IM_DELETE(ctx); } ImGuiIO& ImGui::GetIO() @@ -11668,7 +11679,7 @@ void ImGui::ShowMetricsWindow(bool* p_open) ImGui::Text("Dear ImGui %s", ImGui::GetVersion()); ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); ImGui::Text("%d vertices, %d indices (%d triangles)", ImGui::GetIO().MetricsRenderVertices, ImGui::GetIO().MetricsRenderIndices, ImGui::GetIO().MetricsRenderIndices / 3); - ImGui::Text("%d allocations", ImGui::GetIO().MetricsAllocs); + ImGui::Text("%d allocations", GImAllocatorActiveCount); static bool show_clip_rects = true; ImGui::Checkbox("Show clipping rectangles when hovering an ImDrawCmd", &show_clip_rects); ImGui::Separator(); diff --git a/imgui.h b/imgui.h index 6d411738..b137ab70 100644 --- a/imgui.h +++ b/imgui.h @@ -509,10 +509,12 @@ namespace ImGui IMGUI_API const char* GetClipboardText(); IMGUI_API void SetClipboardText(const char* text); - // Internal context access - if you want to use multiple context, share context between modules (e.g. DLL). There is a default context created and active by default. + // Context creation and access, if you want to use multiple context, share context between modules (e.g. DLL). There is a default context created and active by default. // All contexts share a same ImFontAtlas by default. If you want different font atlas, you can new() them and overwrite the GetIO().Fonts variable of an ImGui context. + // All those functions are not reliant on the current context. IMGUI_API const char* GetVersion(); - IMGUI_API ImGuiContext* CreateContext(void* (*malloc_fn)(size_t) = NULL, void (*free_fn)(void*) = NULL); + IMGUI_API void SetMemoryAllocators(void* (*alloc_fn)(size_t sz, void* user_data), void(*free_fn)(void* ptr, void* user_data), void* user_data = NULL); + IMGUI_API ImGuiContext* CreateContext(); IMGUI_API void DestroyContext(ImGuiContext* ctx); IMGUI_API ImGuiContext* GetCurrentContext(); IMGUI_API void SetCurrentContext(ImGuiContext* ctx); @@ -914,11 +916,6 @@ struct ImGuiIO void (*SetClipboardTextFn)(void* user_data, const char* text); void* ClipboardUserData; - // Optional: override memory allocations. MemFreeFn() may be called with a NULL pointer. - // (default to posix malloc/free) - void* (*MemAllocFn)(size_t sz); - void (*MemFreeFn)(void* ptr); - // Optional: notify OS Input Method Editor of the screen position of your cursor for text input position (e.g. when using Japanese/Chinese IME in Windows) // (default to use native imm32 api on Windows) void (*ImeSetInputScreenPosFn)(int x, int y); @@ -954,7 +951,6 @@ struct ImGuiIO bool WantTextInput; // Mobile/console: when io.WantTextInput is true, you may display an on-screen keyboard. This is set by ImGui when it wants textual keyboard input to happen (e.g. when a InputText widget is active). bool WantMoveMouse; // [BETA-NAV] MousePos has been altered, back-end should reposition mouse on next frame. Set only when 'NavMovesMouse=true'. float Framerate; // Application framerate estimation, in frame per second. Solely for convenience. Rolling average estimation based on IO.DeltaTime over 120 frames - int MetricsAllocs; // Number of active memory allocations int MetricsRenderVertices; // Vertices output during last call to Render() int MetricsRenderIndices; // Indices output during last call to Render() = number of triangles * 3 int MetricsActiveWindows; // Number of visible root windows (exclude child windows) From e45d7a7060454a9cd80db56772ac5ce0891fa95d Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 21 Jan 2018 18:54:22 +0100 Subject: [PATCH 2/7] Context: Added IMGUI_DISABLE_DEFAULT_ALLOCATORS to disable linking with malloc/free. (#1565, #586, #992, #1007, #1558) --- imgui.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/imgui.cpp b/imgui.cpp index 71e6371d..99839f4c 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -713,8 +713,13 @@ ImGuiContext* GImGui = &GImDefaultContext; // Memory Allocator Functions. Use SetMemoryAllocators() to change them. // If you use DLL hotreloading you might need to call SetMemoryAllocators() after reloading code from this file. // Otherwise, you probably don't want to modify them mid-program, and if you use global/static e.g. ImVector<> instances you may need to keep them accessible during program destruction. +#ifndef IMGUI_DISABLE_DEFAULT_ALLOCATORS static void* MallocWrapper(size_t size, void* user_data) { (void)user_data; return malloc(size); } static void FreeWrapper(void* ptr, void* user_data) { (void)user_data; free(ptr); } +#else +static void* MallocWrapper(size_t size, void* user_data) { (void)user_data; (void)size; IM_ASSERT(0); return NULL; } +static void FreeWrapper(void* ptr, void* user_data) { (void)user_data; (void)ptr; IM_ASSERT(0); } +#endif static void* (*GImAllocatorAllocFunc)(size_t size, void* user_data) = MallocWrapper; static void (*GImAllocatorFreeFunc)(void* ptr, void* user_data) = FreeWrapper; From 7e4d28a49d457ee6dce520bca16453ea8c3e9d49 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 21 Jan 2018 19:44:48 +0100 Subject: [PATCH 3/7] Context: Renamed SetMemoryAllocators() to SetAllocatorFunctions(). Tweaked comments. (#1565, #586, #992, #1007, #1558) --- imgui.cpp | 20 ++++++++++---------- imgui.h | 6 +++--- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 99839f4c..fa6e542d 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -213,7 +213,7 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. - - 2018/01/20 (1.XX) - removed allocator parameters from CreateContext(), they are now setup with SetMemoryAllocators() and shared by all contexts. + - 2018/01/20 (1.XX) - removed allocator parameters from CreateContext(), they are now setup with SetAllocatorFunctions() and shared by all contexts. - 2018/01/11 (1.54) - obsoleted IsAnyWindowHovered() in favor of IsWindowHovered(ImGuiHoveredFlags_AnyWindow). Kept redirection function (will obsolete). - 2018/01/11 (1.54) - obsoleted IsAnyWindowFocused() in favor of IsWindowFocused(ImGuiFocusedFlags_AnyWindow). Kept redirection function (will obsolete). - 2018/01/03 (1.54) - renamed ImGuiSizeConstraintCallback to ImGuiSizeCallback, ImGuiSizeConstraintCallbackData to ImGuiSizeCallbackData. @@ -710,8 +710,8 @@ static ImGuiContext GImDefaultContext; ImGuiContext* GImGui = &GImDefaultContext; #endif -// Memory Allocator Functions. Use SetMemoryAllocators() to change them. -// If you use DLL hotreloading you might need to call SetMemoryAllocators() after reloading code from this file. +// Memory Allocator functions. Use SetAllocatorFunctions() to change them. +// If you use DLL hotreloading you might need to call SetAllocatorFunctions() after reloading code from this file. // Otherwise, you probably don't want to modify them mid-program, and if you use global/static e.g. ImVector<> instances you may need to keep them accessible during program destruction. #ifndef IMGUI_DISABLE_DEFAULT_ALLOCATORS static void* MallocWrapper(size_t size, void* user_data) { (void)user_data; return malloc(size); } @@ -724,7 +724,7 @@ static void FreeWrapper(void* ptr, void* user_data) { (void)user_data; static void* (*GImAllocatorAllocFunc)(size_t size, void* user_data) = MallocWrapper; static void (*GImAllocatorFreeFunc)(void* ptr, void* user_data) = FreeWrapper; static void* GImAllocatorUserData = NULL; -static size_t GImAllocatorActiveCount = 0; +static size_t GImAllocatorActiveAllocationsCount = 0; //----------------------------------------------------------------------------- // User facing structures @@ -2188,13 +2188,13 @@ float ImGui::CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x) void* ImGui::MemAlloc(size_t sz) { - GImAllocatorActiveCount++; + GImAllocatorActiveAllocationsCount++; return GImAllocatorAllocFunc(sz, GImAllocatorUserData); } void ImGui::MemFree(void* ptr) { - if (ptr) GImAllocatorActiveCount--; + if (ptr) GImAllocatorActiveAllocationsCount--; return GImAllocatorFreeFunc(ptr, GImAllocatorUserData); } @@ -2230,10 +2230,10 @@ void ImGui::SetCurrentContext(ImGuiContext* ctx) #endif } -void ImGui::SetMemoryAllocators(void* (*alloc_fn)(size_t sz, void* user_data), void(*free_fn)(void* ptr, void* user_data), void* user_data) +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_fn; - GImAllocatorFreeFunc = free_fn; + GImAllocatorAllocFunc = alloc_func; + GImAllocatorFreeFunc = free_func; GImAllocatorUserData = user_data; } @@ -11684,7 +11684,7 @@ void ImGui::ShowMetricsWindow(bool* p_open) ImGui::Text("Dear ImGui %s", ImGui::GetVersion()); ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); ImGui::Text("%d vertices, %d indices (%d triangles)", ImGui::GetIO().MetricsRenderVertices, ImGui::GetIO().MetricsRenderIndices, ImGui::GetIO().MetricsRenderIndices / 3); - ImGui::Text("%d allocations", GImAllocatorActiveCount); + ImGui::Text("%d allocations", GImAllocatorActiveAllocationsCount); static bool show_clip_rects = true; ImGui::Checkbox("Show clipping rectangles when hovering an ImDrawCmd", &show_clip_rects); ImGui::Separator(); diff --git a/imgui.h b/imgui.h index b137ab70..fff343d0 100644 --- a/imgui.h +++ b/imgui.h @@ -503,8 +503,9 @@ namespace ImGui IMGUI_API void CaptureKeyboardFromApp(bool capture = true); // manually override io.WantCaptureKeyboard flag next frame (said flag is entirely left for your application handle). e.g. force capture keyboard when your widget is being hovered. IMGUI_API void CaptureMouseFromApp(bool capture = true); // manually override io.WantCaptureMouse flag next frame (said flag is entirely left for your application handle). - // Helpers functions to access functions pointers in ImGui::GetIO() - IMGUI_API void* MemAlloc(size_t sz); + // Helpers functions to access memory allocators and clipboard functions. + IMGUI_API void SetAllocatorFunctions(void* (*alloc_func)(size_t sz, void* user_data), void(*free_func)(void* ptr, void* user_data), void* user_data = NULL); + IMGUI_API void* MemAlloc(size_t size); IMGUI_API void MemFree(void* ptr); IMGUI_API const char* GetClipboardText(); IMGUI_API void SetClipboardText(const char* text); @@ -513,7 +514,6 @@ namespace ImGui // All contexts share a same ImFontAtlas by default. If you want different font atlas, you can new() them and overwrite the GetIO().Fonts variable of an ImGui context. // All those functions are not reliant on the current context. IMGUI_API const char* GetVersion(); - IMGUI_API void SetMemoryAllocators(void* (*alloc_fn)(size_t sz, void* user_data), void(*free_fn)(void* ptr, void* user_data), void* user_data = NULL); IMGUI_API ImGuiContext* CreateContext(); IMGUI_API void DestroyContext(ImGuiContext* ctx); IMGUI_API ImGuiContext* GetCurrentContext(); From 5e2aa6185ccacbdd93cc2d79c8e46c7fbc8a0ee3 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 21 Jan 2018 19:58:32 +0100 Subject: [PATCH 4/7] Reorganized context handling to be more explicit, - YOU NOW NEED TO CALL ImGui::CreateContext() AT THE BEGINNING OF YOUR APP, AND CALL ImGui::DestroyContext() AT THE END. - removed Shutdown() function, as DestroyContext() serve this purpose. - you may pass a ImFontAtlas* pointer to CreateContext() to share a font atlas between contexts. Otherwhise CreateContext() will create its own font atlas instance. - removed allocator parameters from CreateContext(), they are now setup with SetAllocatorFunctions(), and shared by all contexts. - removed the default global context and font atlas instance, which were confusing for users of DLL reloading and users of multiple contexts (#1565, #586, #992, #1007, #1558) --- imgui.cpp | 56 +++++++++++++++++++++++++++++------------------- imgui.h | 19 ++++++++-------- imgui_internal.h | 8 +++++-- 3 files changed, 49 insertions(+), 34 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index fa6e542d..8eb17280 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -125,6 +125,7 @@ - A minimal application skeleton may be: // Application init + ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); io.DisplaySize.x = 1920.0f; io.DisplaySize.y = 1280.0f; @@ -162,6 +163,10 @@ SwapBuffers(); } + // Shutdown + ImGui::DestroyContext(); + + - A minimal render function skeleton may be: void void MyRenderFunction(ImDrawData* draw_data)(ImDrawData* draw_data) @@ -213,7 +218,12 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. - - 2018/01/20 (1.XX) - removed allocator parameters from CreateContext(), they are now setup with SetAllocatorFunctions() and shared by all contexts. + - 2018/01/21 (1.XX) - reorganized context handling to be more explicit, + - YOU NOW NEED TO CALL ImGui::CreateContext() AT THE BEGINNING OF YOUR APP, AND CALL ImGui::DestroyContext() AT THE END. + - removed Shutdown() function, as DestroyContext() serve this purpose. + - you may pass a ImFontAtlas* pointer to CreateContext() to share a font atlas between contexts. Otherwhise CreateContext() will create its own font atlas instance. + - removed allocator parameters from CreateContext(), they are now setup with SetAllocatorFunctions(), and shared by all contexts. + - removed the default global context and font atlas instance, which were confusing for users of DLL reloading and users of multiple contexts. - 2018/01/11 (1.54) - obsoleted IsAnyWindowHovered() in favor of IsWindowHovered(ImGuiHoveredFlags_AnyWindow). Kept redirection function (will obsolete). - 2018/01/11 (1.54) - obsoleted IsAnyWindowFocused() in favor of IsWindowFocused(ImGuiFocusedFlags_AnyWindow). Kept redirection function (will obsolete). - 2018/01/03 (1.54) - renamed ImGuiSizeConstraintCallback to ImGuiSizeCallback, ImGuiSizeConstraintCallbackData to ImGuiSizeCallbackData. @@ -695,19 +705,14 @@ static void ImeSetInputScreenPosFn_DefaultImpl(int x, int y); // Context //----------------------------------------------------------------------------- -// Default font atlas storage. -// New contexts always point by default to this font atlas. It can be changed by reassigning the GetIO().Fonts variable. -static ImFontAtlas GImDefaultFontAtlas; - -// Default context storage + current context pointer. -// Implicitely used by all ImGui functions. Always assumed to be != NULL. Change to a different context by calling ImGui::SetCurrentContext() -// If you are hot-reloading this code in a DLL you will lose the static/global variables. Create your own context+font atlas instead of relying on those default (see FAQ entry "How can I preserve my ImGui context across reloading a DLL?"). -// ImGui is currently not thread-safe because of this variable. If you want thread-safety to allow N threads to access N different contexts, you might work around it by: +// Current context pointer. Implicitely used by all ImGui functions. Always assumed to be != NULL. +// CreateContext() will automatically set this pointer if it is NULL. Change to a different context by calling ImGui::SetCurrentContext(). +// If you use DLL hotreloading you might need to call SetCurrentContext() after reloading code from this file. +// ImGui functions are not thread-safe because of this pointer. If you want thread-safety to allow N threads to access N different contexts, you can: +// - Change this variable to use thread local storage. You may #define GImGui in imconfig.h for that purpose. Future development aim to make this context pointer explicit to all calls. Also read https://github.com/ocornut/imgui/issues/586 // - Having multiple instances of the ImGui code compiled inside different namespace (easiest/safest, if you have a finite number of contexts) -// - or: Changing this variable to be TLS. You may #define GImGui in imconfig.h for further custom hackery. Future development aim to make this context pointer explicit to all calls. Also read https://github.com/ocornut/imgui/issues/586 #ifndef GImGui -static ImGuiContext GImDefaultContext; -ImGuiContext* GImGui = &GImDefaultContext; +ImGuiContext* GImGui = NULL; #endif // Memory Allocator functions. Use SetAllocatorFunctions() to change them. @@ -807,7 +812,7 @@ ImGuiIO::ImGuiIO() KeyRepeatRate = 0.050f; UserData = NULL; - Fonts = &GImDefaultFontAtlas; + Fonts = NULL; FontGlobalScale = 1.0f; FontDefault = NULL; FontAllowUserScaling = false; @@ -2237,14 +2242,19 @@ void ImGui::SetAllocatorFunctions(void* (*alloc_func)(size_t sz, void* user_data GImAllocatorUserData = user_data; } -ImGuiContext* ImGui::CreateContext() +ImGuiContext* ImGui::CreateContext(ImFontAtlas* shared_font_atlas) { - ImGuiContext* ctx = IM_NEW(ImGuiContext)(); + ImGuiContext* ctx = IM_NEW(ImGuiContext)(shared_font_atlas); + if (GImGui == NULL) + SetCurrentContext(ctx); return ctx; } void ImGui::DestroyContext(ImGuiContext* ctx) { + if (ctx == NULL) + ctx = GImGui; + Shutdown(ctx); if (GImGui == ctx) SetCurrentContext(NULL); IM_DELETE(ctx); @@ -2252,11 +2262,13 @@ void ImGui::DestroyContext(ImGuiContext* ctx) ImGuiIO& ImGui::GetIO() { + IM_ASSERT(GImGui != NULL && "No current context. Did you call ImGui::CreateContext() or ImGui::SetCurrentContext()?"); return GImGui->IO; } ImGuiStyle& ImGui::GetStyle() { + IM_ASSERT(GImGui != NULL && "No current context. Did you call ImGui::CreateContext() or ImGui::SetCurrentContext()?"); return GImGui->Style; } @@ -2304,7 +2316,7 @@ void ImGui::NewFrame() // Initialize on first frame if (!g.Initialized) - Initialize(); + Initialize(&g); g.Time += g.IO.DeltaTime; g.FrameCount += 1; @@ -2624,9 +2636,9 @@ static void SettingsHandlerWindow_WriteAll(ImGuiContext* imgui_ctx, ImGuiSetting } } -void ImGui::Initialize() +void ImGui::Initialize(ImGuiContext* context) { - ImGuiContext& g = *GImGui; + ImGuiContext& g = *context; g.LogClipboard = IM_NEW(ImGuiTextBuffer)(); // Add .ini handle for ImGuiWindow type @@ -2645,13 +2657,13 @@ void ImGui::Initialize() } // This function is merely here to free heap allocations. -void ImGui::Shutdown() +void ImGui::Shutdown(ImGuiContext* context) { - ImGuiContext& g = *GImGui; + ImGuiContext& g = *context; // The fonts atlas can be used prior to calling NewFrame(), so we clear it even if g.Initialized is FALSE (which would happen if we never called NewFrame) - if (g.IO.Fonts) // Testing for NULL to allow user to NULLify in case of running Shutdown() on multiple contexts. Bit hacky. - g.IO.Fonts->Clear(); + if (g.IO.Fonts && g.FontAtlasOwnedByContext) + IM_DELETE(g.IO.Fonts); // Cleanup of other data are conditional on actually having initialize ImGui. if (!g.Initialized) diff --git a/imgui.h b/imgui.h index fff343d0..ef8b9a37 100644 --- a/imgui.h +++ b/imgui.h @@ -127,6 +127,14 @@ struct ImVec4 // In a namespace so that user can add extra functions in a separate file (e.g. Value() helpers for your vector or common types) namespace ImGui { + // Context creation and access, if you want to use multiple context, share context between modules (e.g. DLL). + // All contexts share a same ImFontAtlas by default. If you want different font atlas, you can new() them and overwrite the GetIO().Fonts variable of an ImGui context. + // All those functions are not reliant on the current context. + IMGUI_API ImGuiContext* CreateContext(ImFontAtlas* shared_font_atlas = NULL); + IMGUI_API void DestroyContext(ImGuiContext* ctx = NULL); // NULL = Destroy current context + IMGUI_API ImGuiContext* GetCurrentContext(); + IMGUI_API void SetCurrentContext(ImGuiContext* ctx); + // Main IMGUI_API ImGuiIO& GetIO(); IMGUI_API ImGuiStyle& GetStyle(); @@ -134,7 +142,6 @@ namespace ImGui IMGUI_API void NewFrame(); // start a new ImGui frame, you can submit any command from this point until Render()/EndFrame(). IMGUI_API void Render(); // ends the ImGui frame, finalize the draw data, then call your io.RenderDrawListsFn() function if set. IMGUI_API void EndFrame(); // ends the ImGui frame. automatically called by Render(), so most likely don't need to ever call that yourself directly. If you don't need to render you may call EndFrame() but you'll have wasted CPU already. If you don't need to render, better to not create any imgui windows instead! - IMGUI_API void Shutdown(); // Demo, Debug, Informations IMGUI_API void ShowDemoWindow(bool* p_open = NULL); // create demo/test window (previously called ShowTestWindow). demonstrate most ImGui features. call this to learn about the library! try to make it always available in your application! @@ -143,6 +150,7 @@ namespace ImGui IMGUI_API bool ShowStyleSelector(const char* label); IMGUI_API void ShowFontSelector(const char* label); IMGUI_API void ShowUserGuide(); // add basic help/info block (not a window): how to manipulate ImGui as a end-user (mouse/keyboard controls). + IMGUI_API const char* GetVersion(); // Window IMGUI_API bool Begin(const char* name, bool* p_open = NULL, ImGuiWindowFlags flags = 0); // push window to the stack and start appending to it. see .cpp for details. return false when window is collapsed (so you can early out in your code) but you always need to call End() regardless. 'bool* p_open' creates a widget on the upper-right to close the window (which sets your bool to false). @@ -510,15 +518,6 @@ namespace ImGui IMGUI_API const char* GetClipboardText(); IMGUI_API void SetClipboardText(const char* text); - // Context creation and access, if you want to use multiple context, share context between modules (e.g. DLL). There is a default context created and active by default. - // All contexts share a same ImFontAtlas by default. If you want different font atlas, you can new() them and overwrite the GetIO().Fonts variable of an ImGui context. - // All those functions are not reliant on the current context. - IMGUI_API const char* GetVersion(); - IMGUI_API ImGuiContext* CreateContext(); - IMGUI_API void DestroyContext(ImGuiContext* ctx); - IMGUI_API ImGuiContext* GetCurrentContext(); - IMGUI_API void SetCurrentContext(ImGuiContext* ctx); - } // namespace ImGui // Flags for ImGui::Begin() diff --git a/imgui_internal.h b/imgui_internal.h index d6d19a42..e6ba0622 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -497,6 +497,7 @@ struct ImGuiNextWindowData struct ImGuiContext { bool Initialized; + bool FontAtlasOwnedByContext; // Io.Fonts-> is owned by the ImGuiContext and will be destructed along with it. ImGuiIO IO; ImGuiStyle Style; ImFont* Font; // (Shortcut) == FontStack.empty() ? IO.Font : FontStack.back() @@ -598,11 +599,13 @@ struct ImGuiContext int WantTextInputNextFrame; char TempBuffer[1024*3+1]; // temporary text buffer - ImGuiContext() : OverlayDrawList(NULL) + ImGuiContext(ImFontAtlas* shared_font_atlas) : OverlayDrawList(NULL) { Initialized = false; Font = NULL; FontSize = FontBaseSize = 0.0f; + FontAtlasOwnedByContext = shared_font_atlas ? false : true; + IO.Fonts = shared_font_atlas ? shared_font_atlas : IM_NEW(ImFontAtlas)(); Time = 0.0f; FrameCount = 0; @@ -864,7 +867,8 @@ namespace ImGui IMGUI_API void BringWindowToBack(ImGuiWindow* window); IMGUI_API bool IsWindowChildOf(ImGuiWindow* window, ImGuiWindow* potential_parent); - IMGUI_API void Initialize(); + IMGUI_API void Initialize(ImGuiContext* context); + IMGUI_API void Shutdown(ImGuiContext* context); // Since 1.54 this is a _private_ function. You can call DestroyContext() to destroy the context created by CreateContext(). IMGUI_API void MarkIniSettingsDirty(); IMGUI_API ImGuiSettingsHandler* FindSettingsHandler(const char* type_name); From d3e826c247378c2b1f26e3d9a62980f3a9e96e11 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 21 Jan 2018 20:09:30 +0100 Subject: [PATCH 5/7] Examples: Updated for reorganized context functions. Calling CreateContext(), DestroyContext() in example code. Removed Shutdown() from binding code. (#1565, #586, #992, #1007, #1558) --- examples/allegro5_example/imgui_impl_a5.cpp | 1 - examples/allegro5_example/main.cpp | 2 ++ examples/directx10_example/imgui_impl_dx10.cpp | 1 - examples/directx10_example/main.cpp | 3 +++ examples/directx11_example/imgui_impl_dx11.cpp | 1 - examples/directx11_example/main.cpp | 3 +++ examples/directx9_example/imgui_impl_dx9.cpp | 1 - examples/directx9_example/main.cpp | 3 +++ examples/marmalade_example/imgui_impl_marmalade.cpp | 4 ---- examples/marmalade_example/main.cpp | 5 +++++ examples/null_example/main.cpp | 5 +++-- examples/opengl2_example/imgui_impl_glfw_gl2.cpp | 1 - examples/opengl2_example/main.cpp | 2 ++ examples/opengl3_example/imgui_impl_glfw_gl3.cpp | 1 - examples/opengl3_example/main.cpp | 2 ++ examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp | 1 - examples/sdl_opengl2_example/main.cpp | 3 +++ examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp | 1 - examples/sdl_opengl3_example/main.cpp | 3 +++ examples/vulkan_example/imgui_impl_glfw_vulkan.cpp | 1 - examples/vulkan_example/main.cpp | 2 ++ 21 files changed, 31 insertions(+), 15 deletions(-) diff --git a/examples/allegro5_example/imgui_impl_a5.cpp b/examples/allegro5_example/imgui_impl_a5.cpp index 62f7af67..dddb4c3a 100644 --- a/examples/allegro5_example/imgui_impl_a5.cpp +++ b/examples/allegro5_example/imgui_impl_a5.cpp @@ -200,7 +200,6 @@ bool ImGui_ImplA5_Init(ALLEGRO_DISPLAY* display) void ImGui_ImplA5_Shutdown() { ImGui_ImplA5_InvalidateDeviceObjects(); - ImGui::Shutdown(); } // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. diff --git a/examples/allegro5_example/main.cpp b/examples/allegro5_example/main.cpp index 3c9c9770..11ec724c 100644 --- a/examples/allegro5_example/main.cpp +++ b/examples/allegro5_example/main.cpp @@ -23,6 +23,7 @@ int main(int, char**) al_register_event_source(queue, al_get_mouse_event_source()); // Setup ImGui binding + ImGui::CreateContext(); ImGui_ImplA5_Init(display); // Setup style @@ -109,6 +110,7 @@ int main(int, char**) // Cleanup ImGui_ImplA5_Shutdown(); + ImGui::DestroyContext(); al_destroy_event_queue(queue); al_destroy_display(display); diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp index 14a47c4a..66b411e4 100644 --- a/examples/directx10_example/imgui_impl_dx10.cpp +++ b/examples/directx10_example/imgui_impl_dx10.cpp @@ -569,7 +569,6 @@ bool ImGui_ImplDX10_Init(void* hwnd, ID3D10Device* device) void ImGui_ImplDX10_Shutdown() { ImGui_ImplDX10_InvalidateDeviceObjects(); - ImGui::Shutdown(); g_pd3dDevice = NULL; g_hWnd = (HWND)0; } diff --git a/examples/directx10_example/main.cpp b/examples/directx10_example/main.cpp index 38f4054e..8b54fabf 100644 --- a/examples/directx10_example/main.cpp +++ b/examples/directx10_example/main.cpp @@ -122,6 +122,7 @@ int main(int, char**) UpdateWindow(hwnd); // Setup ImGui binding + ImGui::CreateContext(); ImGui_ImplDX10_Init(hwnd, g_pd3dDevice); // Setup style @@ -204,6 +205,8 @@ int main(int, char**) } ImGui_ImplDX10_Shutdown(); + ImGui::DestroyContext(); + CleanupDeviceD3D(); UnregisterClass(_T("ImGui Example"), wc.hInstance); diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp index 4963fc12..61860f5c 100644 --- a/examples/directx11_example/imgui_impl_dx11.cpp +++ b/examples/directx11_example/imgui_impl_dx11.cpp @@ -571,7 +571,6 @@ bool ImGui_ImplDX11_Init(void* hwnd, ID3D11Device* device, ID3D11DeviceContex void ImGui_ImplDX11_Shutdown() { ImGui_ImplDX11_InvalidateDeviceObjects(); - ImGui::Shutdown(); g_pd3dDevice = NULL; g_pd3dDeviceContext = NULL; g_hWnd = (HWND)0; diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp index 79e7bb16..84db742d 100644 --- a/examples/directx11_example/main.cpp +++ b/examples/directx11_example/main.cpp @@ -125,6 +125,7 @@ int main(int, char**) UpdateWindow(hwnd); // Setup ImGui binding + ImGui::CreateContext(); ImGui_ImplDX11_Init(hwnd, g_pd3dDevice, g_pd3dDeviceContext); // Setup style @@ -207,6 +208,8 @@ int main(int, char**) } ImGui_ImplDX11_Shutdown(); + ImGui::DestroyContext(); + CleanupDeviceD3D(); UnregisterClass(_T("ImGui Example"), wc.hInstance); diff --git a/examples/directx9_example/imgui_impl_dx9.cpp b/examples/directx9_example/imgui_impl_dx9.cpp index a4e67691..af30fbf4 100644 --- a/examples/directx9_example/imgui_impl_dx9.cpp +++ b/examples/directx9_example/imgui_impl_dx9.cpp @@ -288,7 +288,6 @@ bool ImGui_ImplDX9_Init(void* hwnd, IDirect3DDevice9* device) void ImGui_ImplDX9_Shutdown() { ImGui_ImplDX9_InvalidateDeviceObjects(); - ImGui::Shutdown(); g_pd3dDevice = NULL; g_hWnd = 0; } diff --git a/examples/directx9_example/main.cpp b/examples/directx9_example/main.cpp index 09a109d9..64159b9e 100644 --- a/examples/directx9_example/main.cpp +++ b/examples/directx9_example/main.cpp @@ -75,6 +75,7 @@ int main(int, char**) } // Setup ImGui binding + ImGui::CreateContext(); ImGui_ImplDX9_Init(hwnd, g_pd3dDevice); // Setup style @@ -173,6 +174,8 @@ int main(int, char**) } ImGui_ImplDX9_Shutdown(); + ImGui::DestroyContext(); + if (g_pd3dDevice) g_pd3dDevice->Release(); if (pD3D) pD3D->Release(); UnregisterClass(_T("ImGui Example"), wc.hInstance); diff --git a/examples/marmalade_example/imgui_impl_marmalade.cpp b/examples/marmalade_example/imgui_impl_marmalade.cpp index 36fc8328..0ce0edc4 100644 --- a/examples/marmalade_example/imgui_impl_marmalade.cpp +++ b/examples/marmalade_example/imgui_impl_marmalade.cpp @@ -207,8 +207,6 @@ void ImGui_Marmalade_InvalidateDeviceObjects() bool ImGui_Marmalade_Init(bool install_callbacks) { - IwGxInit(); - ImGuiIO& io = ImGui::GetIO(); io.KeyMap[ImGuiKey_Tab] = s3eKeyTab; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array. io.KeyMap[ImGuiKey_LeftArrow] = s3eKeyLeft; @@ -248,8 +246,6 @@ bool ImGui_Marmalade_Init(bool install_callbacks) void ImGui_Marmalade_Shutdown() { ImGui_Marmalade_InvalidateDeviceObjects(); - ImGui::Shutdown(); - IwGxTerminate(); } void ImGui_Marmalade_NewFrame() diff --git a/examples/marmalade_example/main.cpp b/examples/marmalade_example/main.cpp index 2b5edb77..4ad1fe25 100644 --- a/examples/marmalade_example/main.cpp +++ b/examples/marmalade_example/main.cpp @@ -14,7 +14,10 @@ int main(int, char**) { + IwGxInit(); + // Setup ImGui binding + ImGui::CreateContext(); ImGui_Marmalade_Init(true); // Setup style @@ -95,6 +98,8 @@ int main(int, char**) // Cleanup ImGui_Marmalade_Shutdown(); + ImGui::DestroyContext(); + IwGxTerminate(); return 0; } diff --git a/examples/null_example/main.cpp b/examples/null_example/main.cpp index 04c1bda4..f60b8054 100644 --- a/examples/null_example/main.cpp +++ b/examples/null_example/main.cpp @@ -4,6 +4,7 @@ int main(int, char**) { + ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); // Build atlas @@ -27,7 +28,7 @@ int main(int, char**) ImGui::Render(); } - printf("Shutdown()\n"); - ImGui::Shutdown(); + printf("DestroyContext()\n"); + ImGui::DestroyContext(); return 0; } diff --git a/examples/opengl2_example/imgui_impl_glfw_gl2.cpp b/examples/opengl2_example/imgui_impl_glfw_gl2.cpp index e5fe2f47..4c450ed5 100644 --- a/examples/opengl2_example/imgui_impl_glfw_gl2.cpp +++ b/examples/opengl2_example/imgui_impl_glfw_gl2.cpp @@ -246,7 +246,6 @@ bool ImGui_ImplGlfwGL2_Init(GLFWwindow* window, bool install_callbacks) void ImGui_ImplGlfwGL2_Shutdown() { ImGui_ImplGlfwGL2_InvalidateDeviceObjects(); - ImGui::Shutdown(); } void ImGui_ImplGlfwGL2_NewFrame() diff --git a/examples/opengl2_example/main.cpp b/examples/opengl2_example/main.cpp index 6359f5b6..ef4f876e 100644 --- a/examples/opengl2_example/main.cpp +++ b/examples/opengl2_example/main.cpp @@ -27,6 +27,7 @@ int main(int, char**) glfwSwapInterval(1); // Enable vsync // Setup ImGui binding + ImGui::CreateContext(); ImGui_ImplGlfwGL2_Init(window, true); // Setup style @@ -105,6 +106,7 @@ int main(int, char**) // Cleanup ImGui_ImplGlfwGL2_Shutdown(); + ImGui::DestroyContext(); glfwTerminate(); return 0; diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index a71fc515..3b39e185 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -358,7 +358,6 @@ bool ImGui_ImplGlfwGL3_Init(GLFWwindow* window, bool install_callbacks) void ImGui_ImplGlfwGL3_Shutdown() { ImGui_ImplGlfwGL3_InvalidateDeviceObjects(); - ImGui::Shutdown(); } void ImGui_ImplGlfwGL3_NewFrame() diff --git a/examples/opengl3_example/main.cpp b/examples/opengl3_example/main.cpp index 6beb855d..7c29cb71 100644 --- a/examples/opengl3_example/main.cpp +++ b/examples/opengl3_example/main.cpp @@ -32,6 +32,7 @@ int main(int, char**) gl3wInit(); // Setup ImGui binding + ImGui::CreateContext(); ImGui_ImplGlfwGL3_Init(window, true); // Setup style @@ -109,6 +110,7 @@ int main(int, char**) // Cleanup ImGui_ImplGlfwGL3_Shutdown(); + ImGui::DestroyContext(); glfwTerminate(); return 0; diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp index 76def29c..f937bcca 100644 --- a/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp +++ b/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp @@ -245,7 +245,6 @@ bool ImGui_ImplSdlGL2_Init(SDL_Window* window) void ImGui_ImplSdlGL2_Shutdown() { ImGui_ImplSdlGL2_InvalidateDeviceObjects(); - ImGui::Shutdown(); } void ImGui_ImplSdlGL2_NewFrame(SDL_Window *window) diff --git a/examples/sdl_opengl2_example/main.cpp b/examples/sdl_opengl2_example/main.cpp index 21b567a8..115dfc65 100644 --- a/examples/sdl_opengl2_example/main.cpp +++ b/examples/sdl_opengl2_example/main.cpp @@ -33,6 +33,7 @@ int main(int, char**) SDL_GLContext glcontext = SDL_GL_CreateContext(window); // Setup ImGui binding + ImGui::CreateContext(); ImGui_ImplSdlGL2_Init(window); // Setup style @@ -116,6 +117,8 @@ int main(int, char**) // Cleanup ImGui_ImplSdlGL2_Shutdown(); + ImGui::DestroyContext(); + SDL_GL_DeleteContext(glcontext); SDL_DestroyWindow(window); SDL_Quit(); diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp index 35d9cdde..a8c1363c 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp @@ -356,7 +356,6 @@ bool ImGui_ImplSdlGL3_Init(SDL_Window* window) void ImGui_ImplSdlGL3_Shutdown() { ImGui_ImplSdlGL3_InvalidateDeviceObjects(); - ImGui::Shutdown(); } void ImGui_ImplSdlGL3_NewFrame(SDL_Window* window) diff --git a/examples/sdl_opengl3_example/main.cpp b/examples/sdl_opengl3_example/main.cpp index 7ee60389..3cd07168 100644 --- a/examples/sdl_opengl3_example/main.cpp +++ b/examples/sdl_opengl3_example/main.cpp @@ -33,6 +33,7 @@ int main(int, char**) gl3wInit(); // Setup ImGui binding + ImGui::CreateContext(); ImGui_ImplSdlGL3_Init(window); // Setup style @@ -115,6 +116,8 @@ int main(int, char**) // Cleanup ImGui_ImplSdlGL3_Shutdown(); + ImGui::DestroyContext(); + SDL_GL_DeleteContext(glcontext); SDL_DestroyWindow(window); SDL_Quit(); diff --git a/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp b/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp index b9e6d78f..caf0312c 100644 --- a/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp +++ b/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp @@ -787,7 +787,6 @@ bool ImGui_ImplGlfwVulkan_Init(GLFWwindow* window, bool install_callbacks, Im void ImGui_ImplGlfwVulkan_Shutdown() { ImGui_ImplGlfwVulkan_InvalidateDeviceObjects(); - ImGui::Shutdown(); } void ImGui_ImplGlfwVulkan_NewFrame() diff --git a/examples/vulkan_example/main.cpp b/examples/vulkan_example/main.cpp index 6c4ef33f..b75fdaf0 100644 --- a/examples/vulkan_example/main.cpp +++ b/examples/vulkan_example/main.cpp @@ -615,6 +615,7 @@ int main(int, char**) setup_vulkan(window); // Setup ImGui binding + ImGui::CreateContext(); ImGui_ImplGlfwVulkan_Init_Data init_data = {}; init_data.allocator = g_Allocator; init_data.gpu = g_Gpu; @@ -737,6 +738,7 @@ int main(int, char**) VkResult err = vkDeviceWaitIdle(g_Device); check_vk_result(err); ImGui_ImplGlfwVulkan_Shutdown(); + ImGui::DestroyContext(); cleanup_vulkan(); glfwTerminate(); From dd89c9ea59af9f8b832fc3fc024166e000d40225 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 21 Jan 2018 20:58:50 +0100 Subject: [PATCH 6/7] Examples: Made the Win32 proc handlers not assert if there is no active context yet, to be more flexible with creation order. (#1565) --- examples/directx10_example/imgui_impl_dx10.cpp | 3 +++ examples/directx11_example/imgui_impl_dx11.cpp | 3 +++ examples/directx9_example/imgui_impl_dx9.cpp | 3 +++ 3 files changed, 9 insertions(+) diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp index 66b411e4..2ba65494 100644 --- a/examples/directx10_example/imgui_impl_dx10.cpp +++ b/examples/directx10_example/imgui_impl_dx10.cpp @@ -243,6 +243,9 @@ static bool IsAnyMouseButtonDown() // PS: We treat DBLCLK messages as regular mouse down messages, so this code will work on windows classes that have the CS_DBLCLKS flag set. Our own example app code doesn't set this flag. IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { + if (ImGui::GetCurrentContext() == NULL) + return 0; + ImGuiIO& io = ImGui::GetIO(); switch (msg) { diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp index 61860f5c..1df2e30f 100644 --- a/examples/directx11_example/imgui_impl_dx11.cpp +++ b/examples/directx11_example/imgui_impl_dx11.cpp @@ -250,6 +250,9 @@ static bool IsAnyMouseButtonDown() // PS: We treat DBLCLK messages as regular mouse down messages, so this code will work on windows classes that have the CS_DBLCLKS flag set. Our own example app code doesn't set this flag. IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { + if (ImGui::GetCurrentContext() == NULL) + return 0; + ImGuiIO& io = ImGui::GetIO(); switch (msg) { diff --git a/examples/directx9_example/imgui_impl_dx9.cpp b/examples/directx9_example/imgui_impl_dx9.cpp index af30fbf4..bd42ecad 100644 --- a/examples/directx9_example/imgui_impl_dx9.cpp +++ b/examples/directx9_example/imgui_impl_dx9.cpp @@ -189,6 +189,9 @@ static bool IsAnyMouseButtonDown() // PS: We treat DBLCLK messages as regular mouse down messages, so this code will work on windows classes that have the CS_DBLCLKS flag set. Our own example app code doesn't set this flag. IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { + if (ImGui::GetCurrentContext() == NULL) + return 0; + ImGuiIO& io = ImGui::GetIO(); switch (msg) { From 2026e792cddaa8deba54b82bf93819034b937d78 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 21 Jan 2018 21:12:52 +0100 Subject: [PATCH 7/7] Context: NewFrame() asserts (#1565) --- imgui.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/imgui.cpp b/imgui.cpp index 8eb17280..3a1aaba3 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2300,6 +2300,7 @@ ImDrawListSharedData* ImGui::GetDrawListSharedData() void ImGui::NewFrame() { + IM_ASSERT(GImGui != NULL && "No current context. Did you call ImGui::CreateContext() or ImGui::SetCurrentContext()?"); ImGuiContext& g = *GImGui; // Check user data