Compare commits
3
Commits
5e070521bc
..
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
12fe6abc25 | ||
|
|
dd406fe7b4 | ||
|
|
5be35aa3de |
No files matched your search
@@ -1,2 +1,31 @@
|
|||||||
# RDIC
|
# 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:
|
||||||
|
```C
|
||||||
|
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.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
+1
-1
@@ -1 +1 @@
|
|||||||
gcc -g -Wall -Wextra $1 -fsanitize=address,undefined gui.c stb_truetype.o -lX11 -lm
|
gcc -g -Wall -Wextra -Wno-stringop-overflow $1 -fsanitize=address,undefined gui.c stb_truetype.o -lX11 -lm
|
||||||
@@ -610,7 +610,13 @@ GUI_Subtree_Reference gui_get_subtree(
|
|||||||
i = i->sibling)
|
i = i->sibling)
|
||||||
{
|
{
|
||||||
GUI_Subtree *subtree = (GUI_Subtree*)i;
|
GUI_Subtree *subtree = (GUI_Subtree*)i;
|
||||||
|
// NOTE(Zelaven): This line falsely triggers -Wstringop-overflow and the
|
||||||
|
// copy into a temporary variable seemingly fixes it.
|
||||||
|
// For this reason I simply opted to use -Wno-stringop-overflow, as I
|
||||||
|
// don't want to have a broken flag enabled.
|
||||||
rdic_cull_subtrees(&subtree->rdic, subtree->rdic.root);
|
rdic_cull_subtrees(&subtree->rdic, subtree->rdic.root);
|
||||||
|
//RDIC_Context *rdic_context = &subtree->rdic;
|
||||||
|
//rdic_cull_subtrees(rdic_context, subtree->rdic.root);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3841,8 +3847,10 @@ int main(void)
|
|||||||
struct File_Read_Result font_data = read_file__cruddy(font_file);
|
struct File_Read_Result font_data = read_file__cruddy(font_file);
|
||||||
// TODO(Zelaven): How much data do I have to make sure that I read at minimum?
|
// TODO(Zelaven): How much data do I have to make sure that I read at minimum?
|
||||||
assert(font_data.size > 16);
|
assert(font_data.size > 16);
|
||||||
g_font_bitmap = memory_arena_allocate(&font_arena, sizeof(char), _Alignof(char));
|
|
||||||
{
|
{
|
||||||
|
int font_bitmap_size = g_font_bitmap_width * g_font_bitmap_height;
|
||||||
|
g_font_bitmap = memory_arena_allocate(
|
||||||
|
&font_arena, font_bitmap_size, _Alignof(char));
|
||||||
int bake_font_return_value = stbtt_BakeFontBitmap(
|
int bake_font_return_value = stbtt_BakeFontBitmap(
|
||||||
font_data.data, 0,
|
font_data.data, 0,
|
||||||
20.0,
|
20.0,
|
||||||
|
|||||||
Reference in new issue
Block a user