From 9c8f585bf4c2ac981e478cd90fd564f0ead100c8 Mon Sep 17 00:00:00 2001 From: jacob Date: Fri, 7 Nov 2025 17:10:10 -0600 Subject: [PATCH] explicit checkpoint push/pop --- src/proto/pp_game.c | 18 ++--- src/proto/pp_widgets.c | 51 +++++++------- src/proto/pp_widgets.h | 17 +++-- src/ui/ui_common.c | 19 +++--- src/ui/ui_core.c | 147 +++++++++++------------------------------ src/ui/ui_core.h | 24 +++---- 6 files changed, 106 insertions(+), 170 deletions(-) diff --git a/src/proto/pp_game.c b/src/proto/pp_game.c index b785b7d0..edba2f7f 100644 --- a/src/proto/pp_game.c +++ b/src/proto/pp_game.c @@ -111,7 +111,7 @@ JobDef(PP_VisWorker, sig, job_id) Struct(VisPersist) { - PP_ListerWidget lister; + PP_CommandsWidget commands_widget; b32 ui_debug; }; VisPersist persist = ZI; @@ -173,36 +173,36 @@ JobDef(PP_VisWorker, sig, job_id) { b32 minimized = 1; - PP_BuildDebugConsoleWidget(minimized); + PP_BuildConsoleWidget(minimized); } ////////////////////////////// - //- Build lister + //- Build commands widget - PP_BeginListerWidget(&persist.lister); + PP_BeginCommandsWidget(&persist.commands_widget); { - if (PP_BuildListerButton(&persist.lister, Lit("Debug UI")).m1_presses > 0) + if (PP_PushItemToCommandsWidget(&persist.commands_widget, Lit("Debug UI")).m1_presses > 0) { persist.ui_debug = !persist.ui_debug; } - if (PP_BuildListerButton(&persist.lister, Lit("Fullscreen")).m1_presses > 0) + if (PP_PushItemToCommandsWidget(&persist.commands_widget, Lit("Fullscreen")).m1_presses > 0) { b32 new = !window_frame.fullscreen; WND_PushCmd(window_frame, .kind = WND_CmdKind_SetFullscreen, .v = new); LogInfoF("Toggled fullscreen: %F", FmtSint(new)); } - if (PP_BuildListerButton(&persist.lister, Lit("Topmost")).m1_presses > 0) + if (PP_PushItemToCommandsWidget(&persist.commands_widget, Lit("Topmost")).m1_presses > 0) { b32 new = !window_frame.forced_top; WND_PushCmd(window_frame, .kind = WND_CmdKind_SetForcedTop, .v = new); LogInfoF("Toggled topmost: %F", FmtSint(new)); } - if (PP_BuildListerButton(&persist.lister, Lit("Spawn")).m1_presses > 0) + if (PP_PushItemToCommandsWidget(&persist.commands_widget, Lit("Spawn")).m1_presses > 0) { LogErrorF("RAAAAH"); } } - PP_EndListerWidget(&persist.lister); + PP_EndCommandsWidget(&persist.commands_widget); ////////////////////////////// //- Submit sim commands diff --git a/src/proto/pp_widgets.c b/src/proto/pp_widgets.c index 5bc2cfd3..9278f557 100644 --- a/src/proto/pp_widgets.c +++ b/src/proto/pp_widgets.c @@ -23,17 +23,19 @@ void PP_PushWidgetThemeStyles(PP_WidgetTheme theme) } //////////////////////////////////////////////////////////// -//~ Lister widgets +//~ Commands widget -void PP_BeginListerWidget(PP_ListerWidget *lister) +void PP_BeginCommandsWidget(PP_CommandsWidget *widget) { + widget->window_cp = UI_PushCP(0); + PP_WidgetTheme theme = PP_GetWidgetTheme(); Vec2 cursor_pos = UI_GetCursorPos(); - lister->num_buttons = 0; + widget->num_items = 0; + UI_Push(Tag, HashF("commands widget")); - UI_Push(Tag, HashF("lister")); - UI_Key titlebar_key = UI_KeyF("lister title bar"); + UI_Key titlebar_key = UI_KeyF("title bar"); Vec4 window_background_color = theme.window_background_color; Vec4 window_border_color = theme.window_border_color; @@ -44,7 +46,7 @@ void PP_BeginListerWidget(PP_ListerWidget *lister) UI_Report rep = UI_ReportFromKey(titlebar_key); if (rep.m1_held) { - lister->pos = SubVec2(cursor_pos, rep.last_m1_offset); + widget->pos = SubVec2(cursor_pos, rep.last_m1_offset); } window_border_color = BlendSrgb(window_border_color, Rgb(0.5, 0.5, 0.5), rep.hot); } @@ -57,9 +59,9 @@ void PP_BeginListerWidget(PP_ListerWidget *lister) UI_Push(Width, UI_PIX(theme.window_width, 0)); UI_Push(Height, UI_FIT(0)); UI_Push(ChildLayoutAxis, Axis_Y); - UI_Push(FloatingPos, lister->pos); + UI_Push(FloatingPos, widget->pos); UI_SetNext(Flags, UI_BoxFlag_Floating); - UI_PushCP(UI_BuildBox(UI_KeyF("lister"))); + UI_PushCP(UI_BuildBox(UI_KeyF("titlebar"))); { /* Title bar */ UI_PushCP(0); @@ -83,16 +85,16 @@ void PP_BeginListerWidget(PP_ListerWidget *lister) UI_SetNext(FontSize, theme.window_title_font_size); UI_SetNext(ChildAlignment, UI_Alignment_Center); UI_SetNext(Width, UI_FIT(1)); - UI_SetNext(Text, Lit("Lister")); + UI_SetNext(Text, Lit("Commands")); UI_SetNext(Flags, UI_BoxFlag_DrawText); UI_BuildBox(UI_NilKey); /* Right title box */ UI_BuildRow(UI_NilKey); } - UI_PopCP(); + UI_PopCP(UI_TopCP()); } - UI_PopCP(); + UI_PopCP(UI_TopCP()); } UI_SetNext(Tint, 0); @@ -110,12 +112,12 @@ void PP_BeginListerWidget(PP_ListerWidget *lister) } } -UI_Report PP_BuildListerButton(PP_ListerWidget *lister, String text) +UI_Report PP_PushItemToCommandsWidget(PP_CommandsWidget *widget, String text) { PP_WidgetTheme theme = PP_GetWidgetTheme(); UI_BuildDivider(UI_PIX(1, 1), theme.divider_color); - UI_Key btn_key = UI_KeyF("btn%F", FmtSint(lister->num_buttons)); + UI_Key btn_key = UI_KeyF("btn%F", FmtSint(widget->num_items)); UI_Report rep = UI_ReportFromKey(btn_key); Vec4 hovered_color = Rgb32(0x103c4c); @@ -149,30 +151,29 @@ UI_Report PP_BuildListerButton(PP_ListerWidget *lister, String text) UI_BuildSpacer(UI_PIX(20, 1)); UI_BuildLabel(text); } - UI_PopCP(); + UI_PopCP(UI_TopCP()); } - UI_PopCP(); + UI_PopCP(UI_TopCP()); - ++lister->num_buttons; + ++widget->num_items; return rep; } -void PP_EndListerWidget(PP_ListerWidget *lister) +void PP_EndCommandsWidget(PP_CommandsWidget *widget) { PP_WidgetTheme theme = PP_GetWidgetTheme(); f32 padding = theme.window_border; UI_BuildSpacer(UI_PIX(padding, 1)); - UI_PopCP(); + UI_PopCP(UI_TopCP()); UI_BuildSpacer(UI_PIX(padding, 1)); - UI_PopCP(); - UI_PopCP(); + UI_PopCP(widget->window_cp); } //////////////////////////////////////////////////////////// -//~ Debug console widgets +//~ Console widget -UI_Box *PP_BuildDebugConsoleWidget(b32 minimized) +UI_Box *PP_BuildConsoleWidget(b32 minimized) { /* TODO: Remove this whole thing */ __prof; @@ -300,13 +301,13 @@ UI_Box *PP_BuildDebugConsoleWidget(b32 minimized) UI_Push(Flags, UI_BoxFlag_DrawText); UI_BuildBox(UI_NilKey); } - UI_PopCP(); + UI_PopCP(UI_TopCP()); } } - UI_PopCP(); + UI_PopCP(UI_TopCP()); } } - UI_PopCP(); + UI_PopCP(UI_TopCP()); } EndScratch(scratch); diff --git a/src/proto/pp_widgets.h b/src/proto/pp_widgets.h index 045e895a..e057212e 100644 --- a/src/proto/pp_widgets.h +++ b/src/proto/pp_widgets.h @@ -16,15 +16,16 @@ Struct(PP_WidgetTheme) }; //////////////////////////////////////////////////////////// -//~ Lister types +//~ Commands widget types -Struct(PP_ListerWidget) +Struct(PP_CommandsWidget) { /* Persistent state */ Vec2 pos; /* Per-build state */ - i64 num_buttons; + UI_Checkpoint window_cp; + i64 num_items; }; //////////////////////////////////////////////////////////// @@ -34,11 +35,13 @@ PP_WidgetTheme PP_GetWidgetThemeStyles(void); void PP_PushWidgetTheme(PP_WidgetTheme theme); //////////////////////////////////////////////////////////// -//~ Lister widgets +//~ Commands widget -/* FIXME */ +void PP_BeginCommandsWidget(PP_CommandsWidget *widget); +UI_Report PP_PushItemToCommandsWidget(PP_CommandsWidget *widget, String text); +void PP_EndCommandsWidget(PP_CommandsWidget *widget); //////////////////////////////////////////////////////////// -//~ Debug console widgets +//~ Console widget -UI_Box *PP_BuildDebugConsoleWidget(b32 minimized); +UI_Box *PP_BuildConsoleWidget(b32 minimized); diff --git a/src/ui/ui_common.c b/src/ui/ui_common.c index 61967177..6e369ca3 100644 --- a/src/ui/ui_common.c +++ b/src/ui/ui_common.c @@ -8,10 +8,11 @@ UI_Box *UI_BuildLabel(String text) Vec4 tint = UI_UseTop(Tint); UI_Box *box = 0; - UI_PushEmptyStack(); + UI_PushCP(0); { + UI_PushDefaults(); + UI_Push(Parent, parent); UI_SetNext(Tint, tint); - UI_SetNext(Parent, parent); UI_SetNext(Font, font); UI_SetNext(FontSize, font_size); UI_SetNext(Width, UI_FIT(0)); @@ -20,7 +21,7 @@ UI_Box *UI_BuildLabel(String text) UI_SetNext(Flags, UI_BoxFlag_DrawText); box = UI_BuildBox(UI_NilKey); } - UI_PopStack(); + UI_PopCP(UI_TopCP()); return box; } @@ -47,15 +48,16 @@ UI_Box *UI_BuildSpacer(UI_Size size) UI_Box *box = 0; UI_Box *parent = UI_UseTop(Parent); Axis axis = parent->child_layout_axis; - UI_PushEmptyStack(); + UI_PushCP(0); { - UI_Push(Tint, 0); + UI_PushDefaults(); UI_Push(Parent, parent); + UI_Push(Tint, 0); UI_Push(AxisSize, UI_FILL(1, 0), .axis = !axis); UI_Push(AxisSize, size, .axis = axis); box = UI_BuildBox(UI_NilKey); } - UI_PopStack(); + UI_PopCP(UI_TopCP()); return box; } @@ -65,8 +67,9 @@ UI_Box *UI_BuildDivider(UI_Size size, Vec4 color) UI_Box *parent = UI_UseTop(Parent); Vec4 tint = UI_UseTop(Tint); Axis axis = parent->child_layout_axis; - UI_PushEmptyStack(); + UI_PushCP(0); { + UI_PushDefaults(); UI_Push(Parent, parent); UI_Push(Tint, tint); UI_Push(BackgroundColor, color); @@ -74,7 +77,7 @@ UI_Box *UI_BuildDivider(UI_Size size, Vec4 color) UI_Push(AxisSize, size, .axis = axis); box = UI_BuildBox(UI_NilKey); } - UI_PopStack(); + UI_PopCP(UI_TopCP()); return box; } diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index 99df4c88..51eeb91b 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -98,41 +98,26 @@ String UI_StringF_(String fmt, ...) //////////////////////////////////////////////////////////// //~ Checkpoint helpers -UI_Box *UI_PushCP(UI_Box *parent) +UI_Checkpoint UI_PushCP(UI_Box *parent) { UI_SharedState *g = &UI_shared_state; UI_Stack *stack = g->top_stack; - UI_Checkpoint *cp = g->first_free_checkpoint; - if (cp) - { - g->first_free_checkpoint = cp->next; - ZeroStruct(cp); - } - else - { - cp = PushStruct(g->build_arena, UI_Checkpoint); - } - cp->next = stack->top_checkpoint; - cp->v = stack->top_checkpoint->v + 1; - stack->top_checkpoint = cp; + stack->top_checkpoint.v += 1; if (parent != 0) { UI_Push(Parent, parent); } - return parent; + return stack->top_checkpoint; } -void UI_PopCP(void) +void UI_PopCP(UI_Checkpoint cp) { UI_SharedState *g = &UI_shared_state; UI_Stack *stack = g->top_stack; - UI_Checkpoint *cp = stack->top_checkpoint; - u64 v = cp->v; - /* Pop styles */ for (UI_StyleKind kind = UI_StyleKind_None; kind < UI_StyleKind_Count; ++kind) { UI_StyleNode *n = stack->style_tops[kind]; - while (n && n->checkpoint >= v) + while (n && n->checkpoint.v >= cp.v) { UI_StyleNode *next = n->next; n->next = g->first_free_style_node; @@ -141,98 +126,44 @@ void UI_PopCP(void) n = next; } } - stack->top_checkpoint = cp->next; - cp->next = g->first_free_checkpoint; - g->first_free_checkpoint = cp; + stack->top_checkpoint.v = cp.v - 1; +} + +UI_Checkpoint UI_TopCP(void) +{ + UI_SharedState *g = &UI_shared_state; + UI_Stack *stack = g->top_stack; + return stack->top_checkpoint; } //////////////////////////////////////////////////////////// //~ Style stack helpers -void UI_PushEmptyStack(void) -{ - UI_SharedState *g = &UI_shared_state; - UI_Stack *stack = PushStruct(g->build_arena, UI_Stack); - - /* Init checkpoint */ - { - UI_Checkpoint *cp = g->first_free_checkpoint; - if (cp) - { - g->first_free_checkpoint = cp->next; - ZeroStruct(cp); - } - else - { - cp = PushStruct(g->build_arena, UI_Checkpoint); - } - stack->top_checkpoint = cp; - } - - /* Init styles */ - { - for (UI_StyleKind kind = UI_StyleKind_None; kind < UI_StyleKind_Count; ++kind) - { - UI_StyleNode *n = g->first_free_style_node; - if (n) - { - g->first_free_style_node = n->next; - ZeroStruct(n); - } - else - { - n = PushStruct(g->build_arena, UI_StyleNode); - } - n->style.kind = kind; - stack->style_tops[kind] = n; - } - stack->style_tops[UI_StyleKind_Parent]->style.Parent = g->root_box; - stack->style_tops[UI_StyleKind_Width]->style.Width = UI_FILL(1, 0); - stack->style_tops[UI_StyleKind_Height]->style.Height = UI_FILL(1, 0); - stack->style_tops[UI_StyleKind_Font]->style.Font = UI_GetDefaultFontResource(); - stack->style_tops[UI_StyleKind_FontSize]->style.FontSize = 16.0f; - stack->style_tops[UI_StyleKind_Tint]->style.Tint = Color_White; - stack->style_tops[UI_StyleKind_Tag]->style.Tag = HashFnv64(Fnv64Basis, Lit("root")); - stack->style_tops[UI_StyleKind_DebugColor]->style.DebugColor = Rgba(1, 0, 1, 0.5); - } - - stack->next = g->top_stack; - g->top_stack = stack; -} - -void UI_PopStack(void) +void UI_PushDefaults(void) { UI_SharedState *g = &UI_shared_state; UI_Stack *stack = g->top_stack; - - /* Free checkpoints */ + UI_Checkpoint checkpoint = stack->top_checkpoint; { - UI_Checkpoint *cp = stack->top_checkpoint; - while (cp) + for (UI_StyleKind kind = UI_StyleKind_None; kind < UI_StyleKind_Count; ++kind) { - UI_Checkpoint *next = cp->next; - cp->next = g->first_free_checkpoint; - g->first_free_checkpoint = cp; - cp = next; + UI_StyleDesc desc = ZI; + desc.style.kind = kind; + switch (kind) + { + default: break; + case UI_StyleKind_Parent: { desc.style.Parent = g->root_box; } break; + case UI_StyleKind_Width: { desc.style.Width = UI_FILL(1, 0); } break; + case UI_StyleKind_Height: { desc.style.Height = UI_FILL(1, 0); } break; + case UI_StyleKind_Font: { desc.style.Font = UI_GetDefaultFontResource(); } break; + case UI_StyleKind_FontSize: { desc.style.FontSize = 16.0f; } break; + case UI_StyleKind_Tint: { desc.style.Tint = Color_White; } break; + case UI_StyleKind_Tag: { desc.style.Tag = HashFnv64(Fnv64Basis, Lit("root")); } break; + case UI_StyleKind_DebugColor: { desc.style.DebugColor = Rgba(1, 0, 1, 0.5); } break; + }; + UI_PushStyle(desc); } } - - /* Free style nodes */ - for (UI_StyleKind kind = UI_StyleKind_None; kind < UI_StyleKind_Count; ++kind) - { - UI_StyleNode *n = stack->style_tops[kind]; - while (n) - { - UI_StyleNode *next = n->next; - n->next = g->first_free_style_node; - g->first_free_style_node = n; - n = next; - } - } - - g->top_stack = stack->next; - stack->next = g->first_free_stack; - g->first_free_stack = stack; } void UI_PushStyle(UI_StyleDesc desc) @@ -313,10 +244,10 @@ void UI_PushStyle(UI_StyleDesc desc) else { UI_StyleNode *n = stack->style_tops[kind]; - if (!n->override) + if (!(n && n->override)) { { - if (n->pop_when_used) + if (n && n->pop_when_used) { UI_StyleNode *next = n->next; ZeroStruct(n); @@ -340,7 +271,7 @@ void UI_PushStyle(UI_StyleDesc desc) n->style = desc.style; n->pop_when_used = desc.pop_when_used; n->override = desc.override; - n->checkpoint = stack->top_checkpoint->v; + n->checkpoint = stack->top_checkpoint; } /* Initialize style data from desc */ @@ -355,7 +286,10 @@ void UI_PushStyle(UI_StyleDesc desc) case UI_StyleKind_Tag: { - n->style.Tag = RandU64FromSeeds(n->next->style.Tag, n->style.Tag); + if (n->next != 0) + { + n->style.Tag = RandU64FromSeeds(n->next->style.Tag, n->style.Tag); + } } break; } } @@ -686,8 +620,6 @@ UI_Frame UI_BeginFrame(UI_FrameFlag frame_flags) ResetArena(g->build_arena); g->boxes_count = 0; g->first_free_style_node = 0; - g->first_free_checkpoint = 0; - g->first_free_stack = 0; g->frame_flags = frame_flags; @@ -711,7 +643,8 @@ UI_Frame UI_BeginFrame(UI_FrameFlag frame_flags) ////////////////////////////// //- Init style stack - UI_PushEmptyStack(); + g->top_stack = PushStruct(g->build_arena, UI_Stack); + UI_PushDefaults(); frame.cursor_pos = g->cursor_pos; return frame; diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index dd50a4e8..2a2d233f 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -71,7 +71,6 @@ Enum(UI_AxisAlignment) Struct(UI_Checkpoint) { - UI_Checkpoint *next; u64 v; }; @@ -157,17 +156,15 @@ Struct(UI_StyleNode) { UI_StyleNode *next; UI_Style style; + UI_Checkpoint checkpoint; b32 pop_when_used; b32 override; - u64 checkpoint; }; Struct(UI_Stack) { - UI_Stack *next; - - UI_Checkpoint *top_checkpoint; UI_StyleNode *style_tops[UI_StyleKind_Count]; + UI_Checkpoint top_checkpoint; }; //////////////////////////////////////////////////////////// @@ -305,8 +302,6 @@ Struct(UI_SharedState) u64 back_boxes_count; UI_Stack *top_stack; - UI_Stack *first_free_stack; - UI_Checkpoint *first_free_checkpoint; UI_StyleNode *first_free_style_node; //- Layout state @@ -353,14 +348,15 @@ String UI_StringF_(String fmt, ...); //////////////////////////////////////////////////////////// //~ Checkpoint helpers -UI_Box *UI_PushCP(UI_Box *parent); -void UI_PopCP(void); +UI_Checkpoint UI_PushCP(UI_Box *parent); +void UI_PopCP(UI_Checkpoint pop_to); + +UI_Checkpoint UI_TopCP(void); //////////////////////////////////////////////////////////// //~ Style stack helpers -void UI_PushEmptyStack(void); -void UI_PopStack(void); +void UI_PushDefaults(void); void UI_PushStyle(UI_StyleDesc desc); UI_Style UI_PopStyle(UI_StyleDesc desc); @@ -369,9 +365,9 @@ UI_Style UI_PopStyle(UI_StyleDesc desc); #define UI_SetNext(name, ...) UI_PushStyle(UI_STYLEDESC(name, .pop_when_used = 1, .style.name = __VA_ARGS__)) #define UI_Push(name, ...) UI_PushStyle(UI_STYLEDESC(name, .style.name = __VA_ARGS__)) -#define UI_ForceNext(name, ...) UI_PushStyle(UI_STYLEDESC(name, .pop_when_used = 1, .forced = 1, .style.name = __VA_ARGS__)) -#define UI_ForcePush(name, ...) UI_PushStyle(UI_STYLEDESC(name, .forced = 1, .style.name = __VA_ARGS__)) -#define UI_Pop(name, ...) UI_PopStyle(UI_STYLEDESC(name, .forced_pop = 1, __VA_ARGS__)).name +#define UI_ForceNext(name, ...) UI_PushStyle(UI_STYLEDESC(name, .pop_when_used = 1, .override = 1, .style.name = __VA_ARGS__)) +#define UI_ForcePush(name, ...) UI_PushStyle(UI_STYLEDESC(name, .override = 1, .style.name = __VA_ARGS__)) +#define UI_Pop(name, ...) UI_PopStyle(UI_STYLEDESC(name, .force_pop = 1, __VA_ARGS__)).name #define UI_PeekTop(name, ...) UI_PopStyle(UI_STYLEDESC(name, __VA_ARGS__)).name #define UI_UseTop(name, ...) UI_PopStyle(UI_STYLEDESC(name, .use = 1, __VA_ARGS__)).name