imgui: Context recovery / graceful handling of bad state
I’m using vanilla Dear Imgui v1.60 WIP.
I have an app that exposes imgui API to plugins using a scripting language. Now, in my own code I can be sure that I am “well-behaved” - for example, I match calls to ImGui::Begin() with calls to ImGui::End(). But I can’t be sure that plugins will be the same. I also have live reloading of plugin scripts, and sometimes I end up trying to load plugin code that won’t compile (I can keep using the last-known-good version in this case) or worse: plugin code that isn’t well-behaved with respect to imgui API. Consider a plugin that consists entirely of [the scrip equivalent of] the following:
ImGui::Begin("This won't end well.");
I end up hitting this assertion:
IM_ASSERT(g.CurrentWindowStack.Size == 1); // Mismatched Begin()/End() calls
As a feature request, is it possible to consider supporting more graceful failures? I don’t have a solid idea in mind, but you can see my use case above. It could be something like D3D12’s command lists, where the CloseCommandList() function returns a status code indicating whether this was a valid or malformed command list - maybe ImGui::EndFrame() could return a similar value and just drop the frame altogether, or render as much of it as it can [and I realize how this is a fuzzy concept - I’m just thinking out loud here].
Is there some other way to do this that I’m missing? I wouldn’t mind running the plugin code in its own imgui context (multiple context support rocks!), but currently that doesn’t seem to solve the problem I have.
About this issue
- Original URL
- State: open
- Created 6 years ago
- Reactions: 3
- Comments: 35 (18 by maintainers)
Commits related to this issue
- Error recovery: Extraneous/undesired calls to End() are now being caught by an assert in the End() function itself at the call site (instead of being reported in EndFrame). Past the assert, they don't... — committed to ocornut/imgui by ocornut 6 years ago
- Fixes crash/assert bug introduced in d845135 (#1651): would assert when showing the CTRL+Tab list and or fallback "...." tooltip. — committed to ocornut/imgui by ocornut 5 years ago
- Revert "Fixes crash/assert bug introduced in d845135 (#1651): would assert when showing the CTRL+Tab list and or fallback "...." tooltip." This reverts commit 1b0e38df47e7b29932717e695e4a76e0bcbec55b... — committed to ocornut/imgui by ocornut 5 years ago
- Alternative fix for bug introduced in d845135 (#1651), fix CTRL+Tab and fallback tooltip. — committed to ocornut/imgui by ocornut 5 years ago
- TabBar: Added extra mis-usage error recovery. Past the assert, common mis-usage don't lead to hard crashes any more, facilitating integration with scripting languages. (#1651) — committed to ocornut/imgui by ocornut 5 years ago
- Error handling: Assert if user mistakenly calls End() instead of EndChild() on a child window. (#1651) Internals: Moved some error handling code. — committed to ocornut/imgui by ocornut 5 years ago
- Internals: Routing recoverable user errors via IMGUI_USER_ERROR() macro. (#1651) — committed to ocornut/imgui by ocornut 5 years ago
- Internals: added experimental ErrorCheckEndFrameRecover() to unroll/end/pop. (#1651, #3600) — committed to ocornut/imgui by ocornut 4 years ago
- Disabled: Added assert guard for mismatching BeginDisabled()/EndDisabled() blocks. (#211) + Added asserts for missing PopItemFlag() calls. Added both to ErrorCheckEndFrameRecover (#1651) — committed to ocornut/imgui by ocornut 3 years ago
- Misc: extracted ErrorCheckEndWindowRecover() out of ErrorCheckEndFrameRecover(). (#1651) — committed to ocornut/imgui by ocornut 3 years ago
- Better error reporting for PopStyleColor()/PopStyleVar() + easier to recover. (#1651) — committed to ocornut/imgui by ocornut 2 years ago
- Better error reporting for PopStyleColor()/PopStyleVar() + easier to recover. (#1651) — committed to kjblanchard/imgui by ocornut 2 years ago
- Misc: made ErrorCheckEndWindowRecover() handle font stack. (#6431, #1651) — committed to ocornut/imgui by ocornut a year ago
Pushed this in master as 9712bff Note this is technically undocumented/internals api so come with little guarantee and won’t be widely advertised but we’ve been using it in the TestEngine.
We’ve been using that function for a long time in the test engine. It’s not perfect but doesn’t make things worse, and recovers many cases.
The way we’ve been handling stack unrolling on error in Pioneer has been to save a copy of the stack sizes, including the CurrentWindowStackSize, when entering a protected call (
try {} catch-equivalent) and to then handle the necessary End/Pops if an error occurred during the protected call. Looking at ErrorCheckEndFrameRecover, this appears to be very similar to what we are doing; however ImGui’s function unwinds the entire stack instead of supporting mid-frame unrolling.Would you be interested in a pull request that allows unrolling to a “known state” (implemented with
ImGuiStackSizes) mid-frame? It would need a few minutes to detach from Pioneer’s logging system but is otherwise based on the existing ImGui functionality with a few extra variables to enable unrolling to a “mid-window” state.