You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Patrick Jakobsen 12fe6abc25 Updated README 7 months ago
gui Fixed borked font bitmap allocation size 7 months ago
test Introduced a level of indirection for the rdic freelist 7 months ago
.gitignore Added .gitignore 7 months ago Updated README 7 months ago
rdic.h Added inline function for reference validity 7 months ago

RDIC - Retained Data, Immediate Code

Serious GUI programming has long been dominated by retained mode APIs, where a tree of GUI objects that hold function pointers for callbacks is built and a central "do the GUI thing" procedure is called, which takes care of handling all the GUI functionality and calls the callbacks as necessary.

A competitor to retained mode GUIs is the immediate mode GUI paradigm, which prioritizes locality of GUI element definition and its behavior. The specification of GUI elements is done by calling procedures that instantiate them every frame that they should appear on the screen. For instance, a button is achieved by calling some procedure, e.g. gui_button, which would return true if the button was clicked on and false otherwise.

There are tradeoffs in choosing one or the other. Retained mode required you to use inversion of control, which to some is a violation of good programming principles. Immediate mode is in many regards simpler, but has the downside that it forgoes exposing a data structure to the user at all, and has to use clever techniques to identify the same GUI elements across frames.

The RDIC approach combines retained and immediate techniques. In retained mode it is normal to use handles into a behind-the-scenes data structure, which is used to make state changes requests in order to manipulate the GUI. RDIC introduces the use of references into an exposed, retained data structure, where you re-use your references across frames, in an immediate style API. When passing the same, stable reference to e.g. a button call every frame, it is determined that this is in fact the same button across consecutive frames.

RDIC example:

static RDIC_Reference my_button = {0};
if(button(&my_button, "Button Label")) {
    printf("Printed if button is clicked.\n");

The stable data structure in RDIC can be leveraged for features such as accessibility. One example of how this data structure is used in the example GUI in this repository is conditional redrawing. It stores a "dirty" flag with each node, which is used to skip over non-"dirty" nodes when generating draw commands. This is very useful for the implementation, which draws using only the CPU.