Closed west-rynes closed 11 months ago
Hi,
Is this a good minimal reproducible example of what you are trying to solve?
from imgui_bundle import hello_imgui, imgui
def subwindow_gui():
imgui.begin("Sub window")
imgui.text("This is a subwindow that can raise an exception")
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")
subwindow_gui()
except RuntimeError as e:
# We do catch the exception,
print(f"Ouch, caught an exception: {e}")
hello_imgui.run(gui)
If so, I could study a way to call ErrorCheckEndFrameRecover().
For this adding a PreEndFrame
or PreImGuiRender
callback might be useful, in order to be able to call ErrorCheckEndFrameRecover.
At the moment, I, am not sure whether providing a binding for ErrorCheckEndFrameRecover
is a good idea or not: its signature is quite complex, since it uses C-style function pointers:
typedef void (*ImGuiErrorLogCallback)(void* user_data, const char* fmt, ...);
void ImGui::ErrorCheckEndFrameRecover(ImGuiErrorLogCallback log_callback, void* user_data);
I might have to provide an easier signature for python (bypassing void* user_data, and decrypting va_args):
using CallbackWithMessage = std::function<void(const std::string&)>;
void ImGui::ErrorCheckEndFrameRecover2(CallbackWithMessage callback);
Anyhow, I still need to study this more in details.
Ok, I made some changes that address this:
https://github.com/pthom/imgui_bundle/commit/11f505933a0bcbf00fdc2e723d1fa674439bc459: add a BeforeImGuiRender
callback (in python: before_imgui_render
)
https://github.com/pthom/imgui_bundle/commit/40af929455664f5503039e34775fbd0c80a49d15: add bindings for ErrorCheckEndFrameRecover
(I had to write a C++ style adapter for the ImGui callbacks, here (inside the ImGui fork used by ImGui Bundle)
Below is a typical usage with python:
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}")
def my_end_frame_error_callback(message):
print("my_end_frame_error_callback ==> " + message)
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)
I apologize, I should have provided an example. Thanks for being more complete than I was.
I am not an expert at all on Dear ImGui and in most cases I can trap the errors. I think it is just the few legacy begin_xxx
calls that require the end_xxx
call. If an error occurs between the begin and end that is where I notice an issue. I'm not sure if there are more, but the two I'm aware of that require the end call are the begin()
for windows and begin_child()
calls.
I think what you have shown above is perfect. This would solve the issue. I have been able to work around it currently with more error traps within the primary window gui functions and the child functions. But this would help clean up my code a bit to handle unexpected cases.
One question, if I don't re-raise the error in the my_end_frame_error_callback
does that allow the application to continue running. For cases where it is not a critical error I'm hoping to allow things to continue to run.
Thank you so much for looking at this.
One question, if I don't re-raise the error in the my_end_frame_error_callback does that allow the application to continue running. For cases where it is not a critical error I'm hoping to allow things to continue to run.
Yes it does! If you update the package (by pip install -v -e .
from a checkout), you will see that it does continue to run
Thanks. I build the latest version when I get a chance and give it a try. Thanks so much.
I am building a python application and there are some cases where I am trying to trap unhandled exceptions and allow the application to continue to run or save user data before exit.
However, if an error occurs between a
begin_xxx
andend_xxx
statements, ImGui raises an error that theend_xxx
statement was not called in certain cases. This ends up preventing python from being able to trap the exception and the app immediately exits with a console error such asIn this closed issue for ImGui on Exception handling advice https://github.com/ocornut/imgui/issues/5769, the solution mentioned is to
The
ErrorCheckEndFrameRecover()
function appears to be in theinternal
functions of ImGui. However I don't see that wrapped into python inimgui.internal
. I suspect we would likely need to have a runner parameter callback option to turn this on since I don't see where to add function calls right beforeEndFrame()
.Is there a way to call
ErrorCheckEndFrameRecover()
that I missed?Thank for any thoughts on this.