(no title)
wasmperson | 1 month ago
Compare a hypothetical "Immediate Mode" counter:
void render_and_handle_button_click(struct ctx *ctx){
draw_text(ctx, "Count: %d", ctx->count);
if(draw_button(ctx, "Increment")){
ctx->count++;
}
}
To the equivalent "Retained" counter: void render(struct ctx *ctx){
set_textbox_text(ctx->textbox, "Count: %d", ctx->count);
}
void handle_button_click(void *ctx_in){
struct ctx *ctx = ctx_in;
ctx->count++;
render(ctx);
}
void init(struct ctx *ctx){
ctx->textbox = create_textbox(ctx);
ctx->button = create_button(ctx);
set_button_text(ctx->button, "Increment");
set_button_click_handler(ctx->button, ctx, handle_button_click);
render(ctx);
}
The only difference I see here is whether the stateful "cache" of UI components (ctx->textbox and ctx->button) is library-side or application-side.
theamk|1 month ago
- If you have partial redraw request, can you quickly locate _only_ the controls which are covered and only redraw those?
- If you are clicking on something, can you quickly locate which component will receive the click?
- If you are moving mouse, or dragging a selection, can you quickly determine if any components should change the state? Can you avoid running the full event loop on every mouse move event?
- If your application state has updated, do you need to force redraw or not? (Many immediate mode UIs fail badly here, never going to idle even if nothing is happening)
This is all trivial in the old-style UI - efficient redraw / mouse mapping is table stakes in the older GUIs. While all that immediate mode can do is to keep running redraw loop _every_ _single_ _time_ something as trivial as mouse move is happening, just in case this can change highlighted item or something.
(Unless the "immediate mode UI" is just a thin veneer, and library is using good-old OOP based GUI components under the hood... but in this case, it's still faster to cut out the middleman and control components yourself)
And yes, back when I was doing "game development" class in college, around that time, I've used the immediate mode UI for menus. This only makes sense - games run on foreground _anyway_, and they basically consume 100% of CPU anyway. But for regular apps? Please don't.
Example: I just opened https://www.egui.rs/#demo in background tab... The browser's task manager shows this tab never goes idle, consuming between 0.1% and 3%. Considering I often have 40+ tabs open, this can take a significant part of CPU.
Immediate mode GUIs, unless in app which already uses 100% CPU, like game or video player, will always be less efficient than classical event-driven ones.
wasmperson|1 month ago
I'm not a good advocate for IMGUI; there are resources available online which explain it better than I can. I'm just trying to point out that the claim that immediate mode GUIs are some sort of CPU hog isn't really true. That's what I meant by "doesn't necessarily sacrifice performance," not that there is literally zero overhead (although I wouldn't be surprised if that were the case!).
> ...The browser's task manager shows this tab never goes idle...
As far as I can tell, the demo you linked appears to be bugged. You can see from poking around in a profiler (and from the frame timer under the "backend" popout) that the UI code does in fact go idle, but the requestAnimationFrame loop is never disabled for some reason. Regardless, even if this particular GUI library has problems going idle, that's not an inherent problem with the paradigm. I get the impression you understand this already, so I'm not sure why you've brought it up.
kvemkon|1 month ago
ImGui's author deliberately doesn't fix this because this is one of the main issues preventing ImGui to be widely adopted on desktop potentially attracting too many users at once but lacking support for all of them.
https://github.com/ocornut/imgui/issues/7892#issuecomment-22...