Skip to content

Commit 4153c56

Browse files
committed
slightly better context cleanup when an exception is thrown
1 parent 022deea commit 4153c56

File tree

1 file changed

+36
-21
lines changed

1 file changed

+36
-21
lines changed

src/polyscope.cpp

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -307,32 +307,47 @@ void pushContext(std::function<void()> callbackFunction, bool drawDefaultUI) {
307307

308308
// Re-enter main loop until the context has been popped
309309
size_t currentContextStackSize = contextStack.size();
310-
while (contextStack.size() >= currentContextStackSize) {
311310

312-
sleepForFramerate();
313-
mainLoopIteration();
314-
315-
// auto-exit if the window is closed
316-
if (render::engine->windowRequestsClose()) {
317-
popContext();
311+
// Helper lambda to perform cleanup of the context
312+
auto cleanupContext = [&]() {
313+
// Restore the previous context, if there was one
314+
if (!contextStack.empty()) {
315+
ImGui::SetCurrentContext(contextStack.back().context);
316+
ImPlot::SetCurrentContext(contextStack.back().plotContext);
317+
render::engine->updateImGuiContext(newContext, &newIO, oldContext, &oldIO);
318+
ImGuizmo::PopContext();
318319
}
319-
}
320320

321-
// Restore the previous context, if there was one
322-
if (!contextStack.empty()) {
323-
ImGui::SetCurrentContext(contextStack.back().context);
324-
ImPlot::SetCurrentContext(contextStack.back().plotContext);
325-
render::engine->updateImGuiContext(newContext, &newIO, oldContext, &oldIO);
326-
ImGuizmo::PopContext();
321+
// WARNING: code duplicated here and in screenshot.cpp
322+
// Workaround overzealous ImGui assertion before destroying any inner context
323+
// https://github.com/ocornut/imgui/pull/7175
324+
newIO.BackendPlatformUserData = nullptr;
325+
newIO.BackendRendererUserData = nullptr;
326+
ImPlot::DestroyContext(newPlotContext);
327+
ImGui::DestroyContext(newContext);
328+
};
329+
330+
try {
331+
while (contextStack.size() >= currentContextStackSize) {
332+
333+
sleepForFramerate();
334+
mainLoopIteration();
335+
336+
// auto-exit if the window is closed
337+
if (render::engine->windowRequestsClose()) {
338+
popContext();
339+
}
340+
}
341+
} catch (...) {
342+
// Ensure cleanup happens even if an exception is thrown
343+
// NOTE: we don't really guarantee exception safety in general, it's likely that things are broken if an excpetion
344+
// was thrown. But this handles a few of the worst and most confusing cases.
345+
popContext();
346+
cleanupContext();
347+
throw; // re-throw the exception after cleanup
327348
}
328349

329-
// WARNING: code duplicated here and in screenshot.cpp
330-
// Workaround overzealous ImGui assertion before destroying any inner context
331-
// https://github.com/ocornut/imgui/pull/7175
332-
newIO.BackendPlatformUserData = nullptr;
333-
newIO.BackendRendererUserData = nullptr;
334-
ImPlot::DestroyContext(newPlotContext);
335-
ImGui::DestroyContext(newContext);
350+
cleanupContext();
336351
}
337352

338353

0 commit comments

Comments
 (0)