Notes + fix minor typos (in vurtun's blurb, in good faith)

omar 2021-02-15 13:29:53 +01:00
parent 4763490569
commit cb2c4df4c0

@ -50,8 +50,8 @@ What it doesn't stands for:
- IMGUI does not mean it needs a continuous loop nor need to refresh continuously.
- IMGUI does not mean it needs to refresh all-or-nothing.
- IMGUI does not mean that states are polled.
- IMGUI does not mean the UI doesn't look "native".
- IMGUI does not mean that it looks a certain way and cannot animate.
- IMGUI does not mean the UI doesn't look "native" or looks a certain way.
- IMGUI does not mean it cannot animate.
- IMGUI does not mean it needs a GPU to render.
- IMGUI does not mean that layout features are limited.
- IMGUI does not mean that there is a single pass flow.
@ -59,23 +59,25 @@ What it doesn't stands for:
TODO: Each of those points should be explained with a paragraph. We could also describe how common UI libraries (of all types) stand on a given axis. We could also describe less explored paths and envision what new UI libraries could do.
### Vurtun's writeup
It's particularly important we develop this section to dissociate the promise (sometimes unfulfilled) vs current implementation. The full -feature bell-and-whistle promise is more likely to be ever full-filled by a UI libary if people understand that it can.
### Vurtun's write-up
[@vurtun](https://github.com/vurtun) said very eloquently around April 2019:
_"I usually don't like to write about immediate mode UI since there are a lot of preconceived notions about them. Addressing all of them is hard since often that is required since they all are thrown at once. For example a single implementation of a concept does not define a concept (dear imgui is a immediate mode UI not all imgui are like dear imgui)._
_Everything that can be done with "retained" gui can by definition be done by an immdiate mode gui (I hate this whole divide at this point). Then we have state. For some reason like andrew already said I often see confusion that immediate mode means stateless. Immediate mode has nothing to do with how or if state is stored. Immediate mode in guis doesn't remove having two data representation. One on the calling side and one in the library. Even dear imgui and nuklear both have internal state they keep track of. Rather at its core immediate mode is about how this state is updated. In classical gui the state of the application was synchronized to the gui state by modification. On the other hand immediate mode is closer to functional programming. Instead of mutating state, all previous state is immutable and new state can only be generated by taking the previous state and appling new changes. Both in dear imgui and nuklear there is very little previous state and most is build up every "frame"._
_Everything that can be done with "retained" gui can by definition be done by an immediate mode gui (I hate this whole divide at this point). Then we have state. For some reason like andrew already said I often see confusion that immediate mode means stateless. Immediate mode has nothing to do with how or if state is stored. Immediate mode in guis doesn't remove having two data representation. One on the calling side and one in the library. Even dear imgui and nuklear both have internal state they keep track of. Rather at its core immediate mode is about how this state is updated. In classical gui the state of the application was synchronized to the gui state by modification. On the other hand immediate mode is closer to functional programming. Instead of mutating state, all previous state is immutable and new state can only be generated by taking the previous state and applying new changes. Both in dear imgui and nuklear there is very little previous state and most is build up every "frame"._
_Next up handling widget events (press,clicked,...). Immediate mode has nothing to do with events vs polling for input changes. The famously convenient if (button(...)). You can even have retained libraries that use polling instead of events._
_Then we have "immediate mode bundles layouting, input and rendering". Once again only dear imgui and nuklear do this. At this point all my imguis have multiple passes. For example if I cache state for layouting I have (layout, input, render). Any change in the input or render pass will will jump back to layouting. If I don't cache state for layouting I still have two passes (input, render) to prevent glitches. To make sure that performance is not a problem I make sure that only those elements that are actually visible are updated, which is important for datastructures (list, trees). Invisible widgets are not only not rendered but also not layouted or have input handling. In a current implementation they are not even iterated over._
_Another argument I've read is that immediate mode cannot be used with OOP. While I try to stay away from that term since at this point it has taken so many meaning that it is basically worthless, what I hear it in context of is having composability for widgets. Once again just because dear imgui and nuklear don't have does not mean it has to be or even should be that way. For example the imgui we have at work supports composibility and just like retain mode UIs you can put any widget inside any other. Want a slider inside a tab you can just compose them (not that it makes sense in this case)._
_Another argument I've read is that immediate mode cannot be used with OOP. While I try to stay away from that term since at this point it has taken so many meaning that it is basically worthless, what I hear it in context of is having composability for widgets. Once again just because dear imgui and nuklear don't have does not mean it has to be or even should be that way. For example the imgui we have at work supports composability and just like retain mode UIs you can put any widget inside any other. Want a slider inside a tab you can just compose them (not that it makes sense in this case)._
_Getting to game vs. tool ui. Disclaimer: I spend most of my time on tool ui however I played around with game ui or rather the concept behind it in my immediate/retain mode hybrid (https://gist.github.com/vurtun/c5b0374c27d2f5e9905bfbe7431d9dc0)._
_Personally for me tool and game ui are two completley different use cases. Interestingly at work we actually have a single immediate mode core that is used for both game as well as tool ui and it still works. However our advantage is that our UI designer can code. Immediate mode biggest advantage is that state mutation is extremely simple and easy. However in games all UI (including stuff like animations) outside datastructures likes list are know at compile time or loading time. So most advantages of immediate mode doesn't hold up (outside mentioned datastructures). Interestingly for datastructes you can even have an immediate mode API inside a retained state UI. So having the best of both worlds by having a hybrid._
_Personally for me tool and game ui are two completely different use cases. Interestingly at work we actually have a single immediate mode core that is used for both game as well as tool ui and it still works. However our advantage is that our UI designer can code. Immediate mode biggest advantage is that state mutation is extremely simple and easy. However in games all UI (including stuff like animations) outside datastructures likes list are know at compile time or loading time. So most advantages of immediate mode doesn't hold up (outside mentioned datastructures). Interestingly for datastructures you can even have an immediate mode API inside a retained state UI. So having the best of both worlds by having a hybrid._
_Finally state handling. For games this is easier since most state is known beforehand and can be reserved/preallocated. For tool ui it is a bit more complicated. First of it is possible to have state per widget. That is what we currently do at keen core. The state itself is lifetime tracked and freed if not used anymore. However what is actually possible as well is having a concept of an window/view and managing state outside the library. By that I mean a tabbed window with content. Like for example a log view or scene view storing all needed state for the UI and the actually data needed (log entries for the log view). Instead of trying to do state handling on the widget level it makes a lot more sense to have state management inside the view itself, since unlike the actually widgets the view itself has an easy to track lifetime. Just to clarify the view in the library API would just an handle while the actual view implementation would store the state._
@ -87,7 +89,6 @@ _A lot in ui depends on the problem on hand so I feel there is no silver bullet.
- [A presentation by Rickard Gustafsson and Johannes Algelind](http://www.cse.chalmers.se/edu/year/2011/course/TDA361/Advanced%20Computer%20Graphics/IMGUI.pdf), 2011.
- [Jari Komppa's tutorial on building an IMGUI library](http://iki.fi/sol/imgui/), @jarikomppa, 2006.
- [Casey Muratori's original video that popularized the concept](https://mollyrocket.com/861), 2005.
- [Writing an IMGUI](https://www.youtube.com/watch?v=wsJ8Y1HO250), @heroseh, 2021
- [Nicolas Guillemot's CppCon'16 flash-talk about Dear ImGui](https://www.youtube.com/watch?v=LSRJ1jZq90k), 2016.
- [Thierry Excoffier's ZMV (Zero Memory Widget)](http://perso.univ-lyon1.fr/thierry.excoffier/ZMW/), 2004.
- [Unity's IMGUI](https://docs.unity3d.com/Manual/GUIScriptingGuide.html)