diff --git a/bindings/imgui_bundle/demos_cpp/sandbox/demo_error_check_end_frame_recover.cpp b/bindings/imgui_bundle/demos_cpp/sandbox/demo_error_check_end_frame_recover.cpp new file mode 100644 index 00000000..f7d28122 --- /dev/null +++ b/bindings/imgui_bundle/demos_cpp/sandbox/demo_error_check_end_frame_recover.cpp @@ -0,0 +1,67 @@ +// This demo show how we can call ImGui::ErrorCheckEndFrameRecover() +// to recover from errors originating when ImGui::End() is not called (for example when an exception is raised) + +#include "hello_imgui.h" +#include "imgui.h" +#include "imgui_internal.h" + +void SubWindowGui() +{ + ImGui::SetNextWindowSize(ImVec2(600.f, 200.f)); + ImGui::Begin("Sub window"); + ImGui::Text("The button below will raise an exception which lead to imgui.end() not being called"); + + if (ImGui::Button("Raise exception")) { // This button raises an exception that bypasses `ImGui::End()` + throw std::runtime_error("Argh"); + } + ImGui::End(); +} + +void Gui() +{ + try + { + ImGui::Text("Hello"); + SubWindowGui(); + } + catch (const std::runtime_error& e) + { + std::cout << "Ouch, caught an exception: " << e.what() << std::endl; + } +} + +// By default, ImGui::ErrorCheckEndFrameRecover() uses a C-Style callback with va_args, such as below +void MyEndFrameErrorCallback_CStyle(void* user_data, const char* fmt, ...) +{ + printf("MyEndFrameErrorCallback_CStyle ==> "); + + va_list args; + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); + + printf("\n"); +}; + +// ImGui Bundle provides a fork of ImGui where another version of ImGui::ErrorCheckEndFrameRecover() +// can use a simpler C++ style callback, such a below +// (only available if IMGUI_BUNDLE_PYTHON_API is defined) +void MyEndFrameErrorCallback(const std::string& message) +{ + printf("MyEndFrameErrorCallback ==> %s\n", message.c_str()); +}; + + + +int main() +{ + HelloImGui::RunnerParams runnerParams; + runnerParams.callbacks.ShowGui = Gui; + + // you can use either the C style or the C++ style callback + runnerParams.callbacks.BeforeImGuiRender = [](){ ImGui::ErrorCheckEndFrameRecover(MyEndFrameErrorCallback_CStyle); }; + // runnerParams.callbacks.BeforeImGuiRender = [](){ ImGui::ErrorCheckEndFrameRecover(MyEndFrameErrorCallback); }; + + HelloImGui::Run(runnerParams); + return 0; +} diff --git a/bindings/imgui_bundle/demos_python/sandbox/demo_error_check_end_frame_recover.py b/bindings/imgui_bundle/demos_python/sandbox/demo_error_check_end_frame_recover.py new file mode 100644 index 00000000..76a97e4d --- /dev/null +++ b/bindings/imgui_bundle/demos_python/sandbox/demo_error_check_end_frame_recover.py @@ -0,0 +1,42 @@ +# This demo show how we can call ImGui::ErrorCheckEndFrameRecover() +# to recover from errors originating when ImGui::End() is not called (for example when an exception is raised) + +from imgui_bundle import hello_imgui, imgui + + +def sub_window_gui(): + imgui.set_next_window_size((600, 200)) + imgui.begin("Sub window") + imgui.text_wrapped("The button below will raise an exception which lead to imgui.end() not being called") + + if imgui.button("Raise exception"): # This button raises an exception that bypasses `ìmgui.end()` + raise RuntimeError("Argh") + imgui.end() + + +def gui(): + try: + imgui.text("Hello") + sub_window_gui() + except RuntimeError as e: + print(f"Ouch, caught an exception: {e}") + + +# ImGui Bundle provides a fork of ImGui +# where imgui.internal.error_check_end_frame_recover() can use a simple callback, such a below: +def my_end_frame_error_callback(message): + print("my_end_frame_error_callback ==> " + message) + + +def main(): + + runner_params = hello_imgui.RunnerParams() + runner_params.callbacks.show_gui = gui + + runner_params.callbacks.before_imgui_render = lambda: imgui.internal.error_check_end_frame_recover(my_end_frame_error_callback) + + hello_imgui.run(runner_params) + + +if __name__ == "__main__": + main()