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

Most upvoted comments

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.