From 2cc81baffa29bca438fd369d180f54400548e559 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sun, 8 Sep 2024 09:44:39 -0700 Subject: [PATCH] sketch out simplified input types for engine; port over animation cache from reverted changes --- src/dbg_engine/dbg_engine_core.h | 50 +++++++++++++++++++ src/ui/ui_core.c | 86 +++++++++++++++++++++++++++++++- src/ui/ui_core.h | 53 ++++++++++++++++++++ 3 files changed, 187 insertions(+), 2 deletions(-) diff --git a/src/dbg_engine/dbg_engine_core.h b/src/dbg_engine/dbg_engine_core.h index b08c687e..2503d533 100644 --- a/src/dbg_engine/dbg_engine_core.h +++ b/src/dbg_engine/dbg_engine_core.h @@ -4,6 +4,56 @@ #ifndef DBG_ENGINE_CORE_H #define DBG_ENGINE_CORE_H +//////////////////////////////// +//~ rjf: Input State Types + +typedef struct D_PathMap D_PathMap; +struct D_PathMap +{ + String8 src; + String8 dst; +}; + +typedef struct D_PathMapArray D_PathMapArray; +struct D_PathMapArray +{ + D_PathMap *v; + U64 count; +}; + +typedef struct D_Breakpoint D_Breakpoint; +struct D_Breakpoint +{ + String8 file_path; + TxtPt pt; + U64 vaddr; + String8 condition; +}; + +typedef struct D_BreakpointArray D_BreakpointArray; +struct D_BreakpointArray +{ + D_Breakpoint *v; + U64 count; +}; + +typedef struct D_Target D_Target; +struct D_Target +{ + String8 exe; + String8 args; + String8 working_directory; + String8 custom_entry_point_name; + String8List env; +}; + +typedef struct D_TargetArray D_TargetArray; +struct D_TargetArray +{ + D_Target *v; + U64 count; +}; + //////////////////////////////// //~ rjf: Handles diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index 1a067018..ba6953a3 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -430,6 +430,8 @@ ui_state_alloc(void) ui->string_hover_arena = arena_alloc(); ui->box_table_size = 4096; ui->box_table = push_array(arena, UI_BoxHashSlot, ui->box_table_size); + ui->anim_slots_count = 4096; + ui->anim_slots = push_array(arena, UI_AnimSlot, ui->anim_slots_count); UI_InitStackNils(ui); return ui; } @@ -797,6 +799,25 @@ ui_begin_build(OS_Handle window, UI_EventList *events, UI_IconInfo *icon_info, U ui_state->build_box_count = 0; ui_state->tooltip_open = 0; ui_state->ctx_menu_changed = 0; + ui_state->default_animation_rate = 1 - pow_f32(2, (-50.f * ui_state->animation_dt)); + } + + //- rjf: prune unused animation nodes + ProfScope("ui prune unused animation nodes") + { + for(UI_AnimNode *n = ui_state->lru_anim_node, *next = &ui_nil_anim_node; n != &ui_nil_anim_node; n = next) + { + next = n->lru_next; + if(n->last_touched_build_index+1 < ui_state->build_index) + { + DLLRemove_NPZ(&ui_nil_anim_node, ui_state->lru_anim_node, ui_state->mru_anim_node, n, lru_next, lru_prev); + SLLStackPush_N(ui_state->free_anim_node, n, slot_next); + } + else + { + break; + } + } } //- rjf: detect mouse-moves @@ -1255,8 +1276,18 @@ ui_end_build(void) } //- rjf: animate + ProfScope("animate") { - ProfBegin("ui animate"); + for(U64 slot_idx = 0; slot_idx < ui_state->anim_slots_count; slot_idx += 1) + { + for(UI_AnimNode *n = ui_state->anim_slots[slot_idx].first; + n != &ui_nil_anim_node && n != 0; + n = n->slot_next) + { + n->current += (n->params.target - n->current) * n->params.rate; + ui_state->is_animating = (ui_state->is_animating || abs_f32(n->params.target - n->current) > n->params.epsilon); + } + } F32 vast_rate = 1 - pow_f32(2, (-60.f * ui_state->animation_dt)); F32 fast_rate = 1 - pow_f32(2, (-50.f * ui_state->animation_dt)); F32 fish_rate = 1 - pow_f32(2, (-40.f * ui_state->animation_dt)); @@ -1372,7 +1403,6 @@ ui_end_build(void) } } } - ProfEnd(); } //- rjf: animate context menu @@ -2917,6 +2947,58 @@ ui_signal_from_box(UI_Box *box) return sig; } +//////////////////////////////// +//~ rjf: Animation Cache Interaction API + +internal F32 +ui_anim_(UI_Key key, UI_AnimParams *params) +{ + // rjf: get animation cache node + UI_AnimNode *node = &ui_nil_anim_node; + { + U64 slot_idx = key.u64[0]%ui_state->anim_slots_count; + UI_AnimSlot *slot = &ui_state->anim_slots[slot_idx]; + for(UI_AnimNode *n = slot->first; n != &ui_nil_anim_node; n = n->slot_next) + { + if(ui_key_match(n->key, key)) + { + node = n; + break; + } + } + if(node == &ui_nil_anim_node) + { + node = ui_state->free_anim_node; + if(node != 0) + { + SLLStackPop_N(ui_state->free_anim_node, slot_next); + } + else + { + node = push_array(ui_state->arena, UI_AnimNode, 1); + } + node->first_touched_build_index = ui_state->build_index; + node->key = key; + MemoryCopyStruct(&node->params, params); + DLLPushBack_NPZ(&ui_nil_anim_node, slot->first, slot->last, node, slot_next, slot_prev); + } + else + { + DLLRemove_NPZ(&ui_nil_anim_node, ui_state->lru_anim_node, ui_state->mru_anim_node, node, lru_next, lru_prev); + } + } + + // rjf: touch node & update parameters - grab current + node->last_touched_build_index = ui_state->build_index; + DLLPushBack_NPZ(&ui_nil_anim_node, ui_state->lru_anim_node, ui_state->mru_anim_node, node, lru_next, lru_prev); + MemoryCopyStruct(&node->params, params); + if(node->params.epsilon == 0) + { + node->params.epsilon = (node->params.target - node->params.initial) / 10000.f; + } + return node->current;; +} + //////////////////////////////// //~ rjf: Stacks diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index 86486ccf..d9890aac 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -571,6 +571,39 @@ struct UI_Nav Vec2S64 new_p; }; +//////////////////////////////// +//~ rjf: Animation State Types + +typedef struct UI_AnimParams UI_AnimParams; +struct UI_AnimParams +{ + F32 initial; + F32 target; + F32 rate; + F32 epsilon; +}; + +typedef struct UI_AnimNode UI_AnimNode; +struct UI_AnimNode +{ + UI_AnimNode *slot_next; + UI_AnimNode *slot_prev; + UI_AnimNode *lru_next; + UI_AnimNode *lru_prev; + U64 first_touched_build_index; + U64 last_touched_build_index; + UI_Key key; + UI_AnimParams params; + F32 current; +}; + +typedef struct UI_AnimSlot UI_AnimSlot; +struct UI_AnimSlot +{ + UI_AnimNode *first; + UI_AnimNode *last; +}; + //////////////////////////////// //~ rjf: Generated Code @@ -601,6 +634,13 @@ struct UI_State U64 box_table_size; UI_BoxHashSlot *box_table; + //- rjf: anim cache + UI_AnimNode *free_anim_node; + UI_AnimNode *lru_anim_node; + UI_AnimNode *mru_anim_node; + U64 anim_slots_count; + UI_AnimSlot *anim_slots; + //- rjf: build state machine state B32 is_in_open_ctx_menu; @@ -622,6 +662,7 @@ struct UI_State UI_EventList *events; Vec2F32 mouse; F32 animation_dt; + F32 default_animation_rate; //- rjf: user interaction state UI_Key hot_box_key; @@ -852,6 +893,18 @@ internal U64 ui_box_char_pos_from_xy(UI_Box *box, Vec2F32 xy); internal UI_Signal ui_signal_from_box(UI_Box *box); +//////////////////////////////// +//~ rjf: Animation Cache Interaction API + +read_only global UI_AnimNode ui_nil_anim_node = +{ + &ui_nil_anim_node, + &ui_nil_anim_node, +}; + +internal F32 ui_anim_(UI_Key key, UI_AnimParams *params); +#define ui_anim(key, target_val, ...) ui_anim_((key), &(UI_AnimParams){.target = (target_val), __VA_ARGS__, .rate = (ui_state->default_animation_rate)}) + //////////////////////////////// //~ rjf: Stacks