I'm having a hard time guessing the details of how a GUI that doesn't have an event loop in it would work, so I think a more detailed answer would be very interesting.
This is typically not possible in gui programming, because the underlying display library typically owns the event loop, which fundamentally makes it framework like
I remember in my first real job I wrote a GUI for an RTOS (all the way up starting with the hardware, device driver, ...). Not knowing anything about how GUIs worked, or about events, I had a main loop which redrew the GUI on every action. This article tells me I wasn't completely wrong, these are called "Immediate Mode" GUIs!
The gui equivalent would be right-clicking on a thing. There's probably a lot on what you should put in that menu, and you could probably take some general principles from that.
Maybe I jumped the gun. I’m not an expert on GUI programming. In what case do thousands of GUI callbacks need to be called in one second? I would be interested to know.
"Not possible" is an exaggeration. For a retained mode GUI library, you could, for instance, have the event loop of the library run on a separate thread, and provide functions to modify the widget tree and read events that have occurred since the last time events were read, allowing the user of the library to operate the library without being coupled to the event loop in any way. For an immediate mode GUI library, things are even simpler, because the library doesn't even have an event loop in the first place, placing the responsibility of implementing one on the user of the library.
i think the nature of GUI programming hasn't been well enough characterized, and thus the tools we use for building them aren't adequate. it's a bit like trying to do DB programming before transaction, and relational algebra were invented.
Gui has a lot of conceptually complex properties :
- it has both synchronous and asynchronous behaviors ( drag vs trigger an animation or loading data for the next screen )
- it has i/o (the screen)
- it is interactive (a user can click at any point in time, interrupting the process)
- it has transactional properties (you sometimes want a whole set of changes to be performed atomically, with nothing interrupting it).
-it is working both in diff mode ( change just the color of that button) and in whole state change (load a new screen)
Yes I am especially curious to know how they manage state in desktop GUIs - if it's events and callback based or some other kind of functional architecture
Ah, it was quite a while since I looked at desktop GUI apps... It used to be just like OP described - you define logic, and then run pieces of it in the loop. It makes sense to abstract that away to standardize the process.
The way you can wire up a UI without writing any code is masterfully done.
Really, your GUI should have a clear separation between your logic anyways, so if you can't wire up the GUI without writing a ton of code, something is astray.
The example only goes through the code once and then enters a GUI loop and also uses callbacks, so ... yeah. Doesn't look like immediate mode GUI to me.
The core of a GUI framework is nearly always written as asynchronous events and drawn responses, with the developer at that level responsible for the state machine in the middle and invalidation of the GUI in response.
Coordinating large asynchronous systems by hand is challenging. There can be surprising interactions. For example, tapping a button again in the middle of an animation is an example of something where the complexity often leads to the program getting in a bad state or even crashing.
This is one reason that structured concurrency and asynchronicity primitives have been added to many programming languages - to make reasoning about and managing such state machines easier.
Some modern GUI frameworks attempt to simplify this by instead let you declare the UI and its relationship with your data, the interdependencies there, and may have sophisticated means to monitor data changes. This breaks you from having to maintain most GUI state within your program - you respond to user actions by updating your program state, and the GUI responds to those updates.
It was abstracted out, but I don't know if it qualified as a GUI. I had subroutines for creating the various components and placing them anywhere on the screen. I don't remember how I handled the events. One of my biggest regrets is loosing all my work around that time.
I'm definitely no GUI framework expert, but I didn't necessarily mean to imply an immediate mode architecture. Personally I've been writing a lot of code that way in retained mode frameworks. There's some duplication of data but it's not a huge deal when a widget's state is just single variant, which covers just about all I need.
Check the site. There's a nice example there. It is basically a script-like way of building interfaces. The cool thing is that it is loaded as a resource, so you can edit the LED script after compiling, and as long as you haven't changed any of the identifier names, you can modify the GUI.
I am going to try that this week. Sounds like a nice compromise between the newer 'Immediate-Mode GUIs' and the standard event-based one. I can see it as a way to let the user skin your app within your control of how much they can modify.
reply