From 9504946376aaf94068ddf774460181e7ee5cc47e Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 5 Feb 2024 12:08:50 -0800 Subject: [PATCH] entity view filtering --- src/df/core/df_core.c | 36 +++++++ src/df/core/df_core.h | 21 ++++ src/df/gfx/df_gfx.c | 24 +++-- src/df/gfx/df_gfx.h | 2 +- src/df/gfx/df_gfx.mdesk | 2 +- src/df/gfx/df_views.c | 166 +++++++++++++++++------------ src/df/gfx/generated/df_gfx.meta.h | 2 +- 7 files changed, 171 insertions(+), 82 deletions(-) diff --git a/src/df/core/df_core.c b/src/df/core/df_core.c index 79efd1d2..2ecee728 100644 --- a/src/df/core/df_core.c +++ b/src/df/core/df_core.c @@ -1335,6 +1335,42 @@ df_entity_array_from_list(Arena *arena, DF_EntityList *list) return result; } +//- rjf: entity fuzzy list building + +internal DF_EntityFuzzyItemArray +df_entity_fuzzy_item_array_from_entity_list_needle(Arena *arena, DF_EntityList *list, String8 needle) +{ + Temp scratch = scratch_begin(&arena, 1); + DF_EntityArray array = df_entity_array_from_list(scratch.arena, list); + DF_EntityFuzzyItemArray result = df_entity_fuzzy_item_array_from_entity_array_needle(arena, &array, needle); + return result; +} + +internal DF_EntityFuzzyItemArray +df_entity_fuzzy_item_array_from_entity_array_needle(Arena *arena, DF_EntityArray *array, String8 needle) +{ + Temp scratch = scratch_begin(&arena, 1); + DF_EntityFuzzyItemArray result = {0}; + result.count = array->count; + result.v = push_array(arena, DF_EntityFuzzyItem, result.count); + U64 result_idx = 0; + for(U64 src_idx = 0; src_idx < array->count; src_idx += 1) + { + DF_Entity *entity = array->v[src_idx]; + String8 display_string = df_display_string_from_entity(scratch.arena, entity); + FuzzyMatchRangeList matches = fuzzy_match_find(arena, needle, display_string); + if(matches.count >= matches.needle_part_count) + { + result.v[result_idx].entity = entity; + result.v[result_idx].matches = matches; + result_idx += 1; + } + } + result.count = result_idx; + scratch_end(scratch); + return result; +} + //- rjf: entity -> text info internal TXTI_Handle diff --git a/src/df/core/df_core.h b/src/df/core/df_core.h index d5e38b50..8af91fb3 100644 --- a/src/df/core/df_core.h +++ b/src/df/core/df_core.h @@ -512,6 +512,23 @@ struct DF_EntityRec S32 pop_count; }; +//////////////////////////////// +//~ rjf: Entity Fuzzy Listing Types + +typedef struct DF_EntityFuzzyItem DF_EntityFuzzyItem; +struct DF_EntityFuzzyItem +{ + DF_Entity *entity; + FuzzyMatchRangeList matches; +}; + +typedef struct DF_EntityFuzzyItemArray DF_EntityFuzzyItemArray; +struct DF_EntityFuzzyItemArray +{ + DF_EntityFuzzyItem *v; + U64 count; +}; + //////////////////////////////// //~ rjf: Text Slices (output type from data which can be used to produce readable text) @@ -1361,6 +1378,10 @@ internal void df_entity_list_push(Arena *arena, DF_EntityList *list, DF_Entity * internal DF_EntityArray df_entity_array_from_list(Arena *arena, DF_EntityList *list); #define df_first_entity_from_list(list) ((list)->first != 0 ? (list)->first->entity : &df_g_nil_entity) +//- rjf: entity fuzzy list building +internal DF_EntityFuzzyItemArray df_entity_fuzzy_item_array_from_entity_list_needle(Arena *arena, DF_EntityList *list, String8 needle); +internal DF_EntityFuzzyItemArray df_entity_fuzzy_item_array_from_entity_array_needle(Arena *arena, DF_EntityArray *array, String8 needle); + //- rjf: entity -> text info internal TXTI_Handle df_txti_handle_from_entity(DF_Entity *entity); diff --git a/src/df/gfx/df_gfx.c b/src/df/gfx/df_gfx.c index 938701e7..a3914001 100644 --- a/src/df/gfx/df_gfx.c +++ b/src/df/gfx/df_gfx.c @@ -8746,7 +8746,7 @@ df_entity_tooltips(DF_Entity *entity) } internal void -df_entity_desc_button(DF_Window *ws, DF_Entity *entity) +df_entity_desc_button(DF_Window *ws, DF_Entity *entity, FuzzyMatchRangeList *name_matches) { Temp scratch = scratch_begin(0, 0); if(entity->kind == DF_EntityKind_Thread) @@ -8850,7 +8850,13 @@ df_entity_desc_button(DF_Window *ws, DF_Entity *entity) String8 label = df_display_string_from_entity(scratch.arena, entity); UI_TextColor(entity_color) UI_Font(kind_flags&DF_EntityKindFlag_NameIsCode ? df_font_from_slot(DF_FontSlot_Code) : ui_top_font()) - ui_label(label); + { + UI_Signal label_sig = ui_label(label); + if(name_matches != 0) + { + ui_box_equip_fuzzy_match_ranges(label_sig.box, name_matches); + } + } if(entity->kind == DF_EntityKind_Target) UI_TextColor(df_rgba_from_theme_color(DF_ThemeColor_WeakText)) UI_FontSize(ui_top_font_size()*0.95f) { DF_Entity *args = df_entity_child_from_kind(entity, DF_EntityKind_Arguments); @@ -9294,13 +9300,13 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ ui_set_next_pref_height(ui_pct(1, 0)); ui_set_next_text_color(color); ui_set_next_text_alignment(UI_TextAlign_Center); - UI_Box *thread_box = ui_build_box_from_stringf(UI_BoxFlag_DisableTextTrunc| - UI_BoxFlag_Clickable| - UI_BoxFlag_AnimatePosX| - UI_BoxFlag_DrawText, - "%S##ip_%p", - df_g_icon_kind_text_table[DF_IconKind_RightArrow], - thread); + UI_Key thread_box_key = ui_key_from_stringf(top_container_box->key, "###ip_%p", thread); + UI_Box *thread_box = ui_build_box_from_key(UI_BoxFlag_DisableTextTrunc| + UI_BoxFlag_Clickable| + UI_BoxFlag_AnimatePosX| + UI_BoxFlag_DrawText, + thread_box_key); + ui_box_equip_display_string(thread_box, df_g_icon_kind_text_table[DF_IconKind_RightArrow]); UI_Signal thread_sig = ui_signal_from_box(thread_box); // rjf: custom draw diff --git a/src/df/gfx/df_gfx.h b/src/df/gfx/df_gfx.h index 09a5abb1..75dab278 100644 --- a/src/df/gfx/df_gfx.h +++ b/src/df/gfx/df_gfx.h @@ -1028,7 +1028,7 @@ internal void df_cmd_list_menu_buttons(DF_Window *ws, U64 count, DF_CoreCmdKind internal UI_Signal df_icon_button(DF_IconKind kind, String8 string); internal UI_Signal df_icon_buttonf(DF_IconKind kind, char *fmt, ...); internal void df_entity_tooltips(DF_Entity *entity); -internal void df_entity_desc_button(DF_Window *ws, DF_Entity *entity); +internal void df_entity_desc_button(DF_Window *ws, DF_Entity *entity, FuzzyMatchRangeList *name_matches); internal void df_entity_src_loc_button(DF_Window *ws, DF_Entity *entity, TxtPt point); //////////////////////////////// diff --git a/src/df/gfx/df_gfx.mdesk b/src/df/gfx/df_gfx.mdesk index d60a43fd..6c061b5e 100644 --- a/src/df/gfx/df_gfx.mdesk +++ b/src/df/gfx/df_gfx.mdesk @@ -196,7 +196,7 @@ DF_GfxViewTable: { PendingEntity "pending_entity" "Pending Entity" EntityName FileOutline 1 0 0 0 0 0 "" } { Code "code" "Code" EntityName FileOutline 1 1 1 0 0 0 "" } { Disassembly "disassembly" "Disassembly" Null Glasses 0 1 0 0 0 1 "Displays disassembled instructions in a textual form from the selected thread's containing process virtual address space." } - { Watch "watch" "Watch" Null Binoculars 0 1 0 1 0 1 "The familiar 'watch window' debugger interface. Allows the inputting of a number of expressions. Each expression in the table is evaluated within the context of the selected thread's selected call stack frame. If applicable (depending on visualization rules and the expression's type), these expressions may be hierarchically expanded, which displays children as more rows in the table. The values of these expressions may also be edited, and if possible, can be used to write to registers or memory in attached processes. Also contains a new *view rule* column, not found in other major debuggers, which allows per-row specification of various visualization rules. These view rules may be used to visualize and inspect the evaluation of expressions in a variety of ways. To learn more, read the 'View Rules' section." } + { Watch "watch" "Watch" Null Binoculars 0 1 0 1 1 1 "The familiar 'watch window' debugger interface. Allows the inputting of a number of expressions. Each expression in the table is evaluated within the context of the selected thread's selected call stack frame. If applicable (depending on visualization rules and the expression's type), these expressions may be hierarchically expanded, which displays children as more rows in the table. The values of these expressions may also be edited, and if possible, can be used to write to registers or memory in attached processes. Also contains a new *view rule* column, not found in other major debuggers, which allows per-row specification of various visualization rules. These view rules may be used to visualize and inspect the evaluation of expressions in a variety of ways. To learn more, read the 'View Rules' section." } { Locals "locals" "Locals" Null Binoculars 0 1 0 1 1 1 "Nearly identical to `Watch`, but automatically filled with local variables found within the selected call stack frame of the selected thread, according to the associated debug info. View rules and evaluation values can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table." } { Registers "registers" "Registers" Null Binoculars 0 1 0 1 1 1 "Nearly identical to `Watch`, but automatically filled with all register names according to the selected thread's architecture. View rules and evaluation values can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table." } { Globals "globals" "Globals" Null Binoculars 0 1 0 1 1 1 "Nearly identical to `Watch`, but automatically filled with all global variables within the selected thread's module. View rules and evaluation values can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table." } diff --git a/src/df/gfx/df_views.c b/src/df/gfx/df_views.c index 7ca04a5c..a06576ba 100644 --- a/src/df/gfx/df_views.c +++ b/src/df/gfx/df_views.c @@ -3290,7 +3290,8 @@ DF_VIEW_UI_FUNCTION_DEF(Targets) ProfBeginFunction(); Temp scratch = scratch_begin(0, 0); DF_EntityList targets_list = df_query_cached_entity_list_with_kind(DF_EntityKind_Target); - DF_EntityArray targets = df_entity_array_from_list(scratch.arena, &targets_list); + String8 query = str8(view->query_buffer, view->query_string_size); + DF_EntityFuzzyItemArray targets = df_entity_fuzzy_item_array_from_entity_list_needle(scratch.arena, &targets_list, query); F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); //- rjf: grab state @@ -3313,7 +3314,7 @@ DF_VIEW_UI_FUNCTION_DEF(Targets) DF_Entity *selected_target = df_entity_from_handle(tv->selected_target_handle); for(U64 idx = 0; idx < targets.count; idx += 1) { - if(selected_target == targets.v[idx]) + if(selected_target == targets.v[idx].entity) { cursor.y = (S64)idx+2; break; @@ -3363,7 +3364,7 @@ DF_VIEW_UI_FUNCTION_DEF(Targets) row_idx += 1) UI_Row { - DF_Entity *target = targets.v[row_idx-1]; + DF_Entity *target = targets.v[row_idx-1].entity; B32 row_selected = ((U64)cursor.y == row_idx+1); // rjf: enabled @@ -3388,7 +3389,7 @@ DF_VIEW_UI_FUNCTION_DEF(Targets) // rjf: target name UI_WidthFill UI_FocusHot((row_selected && cursor.x == 1) ? UI_FocusKind_On : UI_FocusKind_Off) { - df_entity_desc_button(ws, target); + df_entity_desc_button(ws, target, &targets.v[row_idx-1].matches); } // rjf: controls @@ -3434,7 +3435,7 @@ DF_VIEW_UI_FUNCTION_DEF(Targets) //- rjf: commit cursor to selection state { tv->selected_column = cursor.x; - tv->selected_target_handle = (1 < cursor.y && cursor.y < targets.count+2) ? df_handle_from_entity(targets.v[cursor.y-2]) : df_handle_zero(); + tv->selected_target_handle = (1 < cursor.y && cursor.y < targets.count+2) ? df_handle_from_entity(targets.v[cursor.y-2].entity) : df_handle_zero(); tv->selected_add = (cursor.y == 1); } @@ -3794,6 +3795,7 @@ DF_VIEW_UI_FUNCTION_DEF(Scheduler) ProfBeginFunction(); Temp scratch = scratch_begin(0, 0); DBGI_Scope *scope = dbgi_scope_open(); + String8 query = str8(view->query_buffer, view->query_string_size); DF_CtrlCtx ctrl_ctx = df_ctrl_ctx_from_view(ws, view); //- rjf: get state @@ -3810,45 +3812,57 @@ DF_VIEW_UI_FUNCTION_DEF(Scheduler) DF_EntityList processes = df_query_cached_entity_list_with_kind(DF_EntityKind_Process); DF_EntityList threads = df_query_cached_entity_list_with_kind(DF_EntityKind_Thread); - //- rjf: build flat array of entities, arranged into row order - DF_EntityArray entities = {0}; + //- rjf: produce list of items; no query -> all entities, in tree; query -> only show threads + DF_EntityFuzzyItemArray items = {0}; + if(query.size == 0) { - entities.count = machines.count+processes.count+threads.count; - entities.v = push_array_no_zero(scratch.arena, DF_Entity *, entities.count); - U64 idx = 0; - for(DF_EntityNode *machine_n = machines.first; machine_n != 0; machine_n = machine_n->next) + //- rjf: build flat array of entities, arranged into row order + DF_EntityArray entities = {0}; { - DF_Entity *machine = machine_n->entity; - entities.v[idx] = machine; - idx += 1; - for(DF_EntityNode *process_n = processes.first; process_n != 0; process_n = process_n->next) + entities.count = machines.count+processes.count+threads.count; + entities.v = push_array_no_zero(scratch.arena, DF_Entity *, entities.count); + U64 idx = 0; + for(DF_EntityNode *machine_n = machines.first; machine_n != 0; machine_n = machine_n->next) { - DF_Entity *process = process_n->entity; - if(df_entity_ancestor_from_kind(process, DF_EntityKind_Machine) != machine) - { - continue; - } - entities.v[idx] = process; + DF_Entity *machine = machine_n->entity; + entities.v[idx] = machine; idx += 1; - for(DF_EntityNode *thread_n = threads.first; thread_n != 0; thread_n = thread_n->next) + for(DF_EntityNode *process_n = processes.first; process_n != 0; process_n = process_n->next) { - DF_Entity *thread = thread_n->entity; - if(df_entity_ancestor_from_kind(thread, DF_EntityKind_Process) != process) + DF_Entity *process = process_n->entity; + if(df_entity_ancestor_from_kind(process, DF_EntityKind_Machine) != machine) { continue; } - entities.v[idx] = thread; + entities.v[idx] = process; idx += 1; + for(DF_EntityNode *thread_n = threads.first; thread_n != 0; thread_n = thread_n->next) + { + DF_Entity *thread = thread_n->entity; + if(df_entity_ancestor_from_kind(thread, DF_EntityKind_Process) != process) + { + continue; + } + entities.v[idx] = thread; + idx += 1; + } } } } + + //- rjf: entities -> fuzzy-filtered entities + items = df_entity_fuzzy_item_array_from_entity_array_needle(scratch.arena, &entities, query); + } + else + { + items = df_entity_fuzzy_item_array_from_entity_list_needle(scratch.arena, &threads, query); } //- rjf: selected column/entity -> selected cursor Vec2S64 cursor = {sv->selected_column}; - for(U64 idx = 0; idx < entities.count; idx += 1) + for(U64 idx = 0; idx < items.count; idx += 1) { - if(entities.v[idx] == df_entity_from_handle(sv->selected_entity)) + if(items.v[idx].entity == df_entity_from_handle(sv->selected_entity)) { cursor.y = (S64)(idx+1); break; @@ -3862,8 +3876,8 @@ DF_VIEW_UI_FUNCTION_DEF(Scheduler) scroll_list_params.flags = UI_ScrollListFlag_All; scroll_list_params.row_height_px = floor_f32(ui_top_font_size()*2.5f); scroll_list_params.dim_px = dim_2f32(rect); - scroll_list_params.cursor_range = r2s64(v2s64(0, 0), v2s64(4, entities.count)); - scroll_list_params.item_range = r1s64(0, entities.count); + scroll_list_params.cursor_range = r2s64(v2s64(0, 0), v2s64(4, items.count)); + scroll_list_params.item_range = r1s64(0, items.count); scroll_list_params.cursor_min_is_empty_selection[Axis2_Y] = 1; } UI_ScrollListSignal scroll_list_sig = {0}; @@ -3874,13 +3888,13 @@ DF_VIEW_UI_FUNCTION_DEF(Scheduler) { Vec2S64 next_cursor = cursor; for(U64 idx = visible_row_range.min; - idx <= visible_row_range.max && idx < entities.count; + idx <= visible_row_range.max && idx < items.count; idx += 1) { - DF_Entity *entity = entities.v[idx]; + DF_Entity *entity = items.v[idx].entity; B32 row_is_selected = (cursor.y == (S64)(idx+1)); F32 depth = 0.f; - switch(entity->kind) + if(query.size == 0) switch(entity->kind) { default:{}break; case DF_EntityKind_Machine:{depth = 0.f;}break; @@ -3930,7 +3944,7 @@ DF_VIEW_UI_FUNCTION_DEF(Scheduler) UI_TableCellSized(ui_pct(1, 0)) UI_FocusHot((row_is_selected && desc_col_rng.min <= cursor.x && cursor.x <= desc_col_rng.max) ? UI_FocusKind_On : UI_FocusKind_Off) { - df_entity_desc_button(ws, entity); + df_entity_desc_button(ws, entity, &items.v[idx].matches); } switch(entity->kind) { @@ -4001,7 +4015,7 @@ DF_VIEW_UI_FUNCTION_DEF(Scheduler) //- rjf: selected num -> selected entity sv->selected_column = cursor.x; - sv->selected_entity = (1 <= cursor.y && cursor.y <= entities.count) ? df_handle_from_entity(entities.v[cursor.y-1]) : df_handle_zero(); + sv->selected_entity = (1 <= cursor.y && cursor.y <= items.count) ? df_handle_from_entity(items.v[cursor.y-1].entity) : df_handle_zero(); dbgi_scope_close(scope); scratch_end(scratch); @@ -4154,7 +4168,7 @@ DF_VIEW_UI_FUNCTION_DEF(CallStack) } else { - df_entity_desc_button(ws, module); + df_entity_desc_button(ws, module, 0); } } @@ -4286,6 +4300,7 @@ DF_VIEW_UI_FUNCTION_DEF(Modules) ProfBeginFunction(); Temp scratch = scratch_begin(0, 0); DBGI_Scope *scope = dbgi_scope_open(); + String8 query = str8(view->query_buffer, view->query_string_size); //- rjf: get state DF_ModulesViewState *mv = df_view_user_state(view, DF_ModulesViewState); @@ -4295,35 +4310,44 @@ DF_VIEW_UI_FUNCTION_DEF(Modules) DF_EntityList processes = df_query_cached_entity_list_with_kind(DF_EntityKind_Process); DF_EntityList modules = df_query_cached_entity_list_with_kind(DF_EntityKind_Module); - //- rjf: build flat array of entities, arranged into row order - DF_EntityArray entities = {0}; + //- rjf: make filtered item array + DF_EntityFuzzyItemArray items = {0}; + if(query.size == 0) { - entities.count = processes.count+modules.count; - entities.v = push_array_no_zero(scratch.arena, DF_Entity *, entities.count); - U64 idx = 0; - for(DF_EntityNode *process_n = processes.first; process_n != 0; process_n = process_n->next) + DF_EntityArray entities = {0}; { - DF_Entity *process = process_n->entity; - entities.v[idx] = process; - idx += 1; - for(DF_EntityNode *module_n = modules.first; module_n != 0; module_n = module_n->next) + entities.count = processes.count+modules.count; + entities.v = push_array_no_zero(scratch.arena, DF_Entity *, entities.count); + U64 idx = 0; + for(DF_EntityNode *process_n = processes.first; process_n != 0; process_n = process_n->next) { - DF_Entity *module = module_n->entity; - if(df_entity_ancestor_from_kind(module, DF_EntityKind_Process) != process) - { - continue; - } - entities.v[idx] = module; + DF_Entity *process = process_n->entity; + entities.v[idx] = process; idx += 1; + for(DF_EntityNode *module_n = modules.first; module_n != 0; module_n = module_n->next) + { + DF_Entity *module = module_n->entity; + if(df_entity_ancestor_from_kind(module, DF_EntityKind_Process) != process) + { + continue; + } + entities.v[idx] = module; + idx += 1; + } } } + items = df_entity_fuzzy_item_array_from_entity_array_needle(scratch.arena, &entities, query); + } + else + { + items = df_entity_fuzzy_item_array_from_entity_list_needle(scratch.arena, &modules, query); } //- rjf: selected column/entity -> selected cursor Vec2S64 cursor = {mv->selected_column}; - for(U64 idx = 0; idx < entities.count; idx += 1) + for(U64 idx = 0; idx < items.count; idx += 1) { - if(entities.v[idx] == df_entity_from_handle(mv->selected_entity)) + if(items.v[idx].entity == df_entity_from_handle(mv->selected_entity)) { cursor.y = (S64)(idx+1); break; @@ -4377,8 +4401,8 @@ DF_VIEW_UI_FUNCTION_DEF(Modules) scroll_list_params.flags = UI_ScrollListFlag_All; scroll_list_params.row_height_px = floor_f32(ui_top_font_size()*2.5f); scroll_list_params.dim_px = dim_2f32(rect); - scroll_list_params.cursor_range = r2s64(v2s64(0, 0), v2s64(3, entities.count)); - scroll_list_params.item_range = r1s64(0, entities.count); + scroll_list_params.cursor_range = r2s64(v2s64(0, 0), v2s64(3, items.count)); + scroll_list_params.item_range = r1s64(0, items.count); scroll_list_params.cursor_min_is_empty_selection[Axis2_Y] = 1; } UI_ScrollListSignal scroll_list_sig = {0}; @@ -4389,9 +4413,9 @@ DF_VIEW_UI_FUNCTION_DEF(Modules) { Vec2S64 next_cursor = cursor; U64 idx_in_process = 0; - for(U64 idx = 0; idx < entities.count; idx += 1) + for(U64 idx = 0; idx < items.count; idx += 1) { - DF_Entity *entity = entities.v[idx]; + DF_Entity *entity = items.v[idx].entity; B32 row_is_selected = (cursor.y == (S64)(idx+1)); idx_in_process += (entity->kind == DF_EntityKind_Module); if(visible_row_range.min <= idx && idx <= visible_row_range.max) @@ -4405,7 +4429,7 @@ DF_VIEW_UI_FUNCTION_DEF(Modules) { UI_TableCellSized(ui_pct(1, 0)) UI_FocusHot((row_is_selected) ? UI_FocusKind_On : UI_FocusKind_Off) { - df_entity_desc_button(ws, entity); + df_entity_desc_button(ws, entity, &items.v[idx].matches); } } idx_in_process = 0; @@ -4419,7 +4443,7 @@ DF_VIEW_UI_FUNCTION_DEF(Modules) } UI_TableCell UI_FocusHot((row_is_selected && cursor.x == 0) ? UI_FocusKind_On : UI_FocusKind_Off) { - df_entity_desc_button(ws, entity); + df_entity_desc_button(ws, entity, &items.v[idx].matches); } UI_TableCell UI_Font(df_font_from_slot(DF_FontSlot_Code)) UI_FocusHot((row_is_selected && cursor.x == 1) ? UI_FocusKind_On : UI_FocusKind_Off) { @@ -4533,7 +4557,7 @@ DF_VIEW_UI_FUNCTION_DEF(Modules) //- rjf: selected num -> selected entity mv->selected_column = cursor.x; - mv->selected_entity = (1 <= cursor.y && cursor.y <= entities.count) ? df_handle_from_entity(entities.v[cursor.y-1]) : df_handle_zero(); + mv->selected_entity = (1 <= cursor.y && cursor.y <= items.count) ? df_handle_from_entity(items.v[cursor.y-1].entity) : df_handle_zero(); dbgi_scope_close(scope); scratch_end(scratch); @@ -8232,6 +8256,7 @@ DF_VIEW_CMD_FUNCTION_DEF(Breakpoints) {} DF_VIEW_UI_FUNCTION_DEF(Breakpoints) { Temp scratch = scratch_begin(0, 0); + String8 query = str8(view->query_buffer, view->query_string_size); //- rjf: get state typedef struct DF_BreakpointsViewState DF_BreakpointsViewState; @@ -8260,13 +8285,13 @@ DF_VIEW_UI_FUNCTION_DEF(Breakpoints) //- rjf: get entities DF_EntityList entities_list = df_query_cached_entity_list_with_kind(DF_EntityKind_Breakpoint); - DF_EntityArray entities = df_entity_array_from_list(scratch.arena, &entities_list); + DF_EntityFuzzyItemArray entities = df_entity_fuzzy_item_array_from_entity_list_needle(scratch.arena, &entities_list, query); //- rjf: selected column/entity -> selected cursor Vec2S64 cursor = {bv->selected_column}; for(U64 idx = 0; idx < entities.count; idx += 1) { - if(entities.v[idx] == df_entity_from_handle(bv->selected_entity)) + if(entities.v[idx].entity == df_entity_from_handle(bv->selected_entity)) { cursor.y = (S64)(idx+1); break; @@ -8301,7 +8326,7 @@ DF_VIEW_UI_FUNCTION_DEF(Breakpoints) Vec2S64 next_cursor = cursor; for(U64 idx = Max(1, visible_row_range.min); idx <= visible_row_range.max && idx <= entities.count; idx += 1) { - DF_Entity *entity = entities.v[idx-1]; + DF_Entity *entity = entities.v[idx-1].entity; B32 row_is_selected = (cursor.y == (S64)(idx)); UI_NamedTableVectorF("breakpoint_%p", entity) { @@ -8314,7 +8339,7 @@ DF_VIEW_UI_FUNCTION_DEF(Breakpoints) } UI_TableCell UI_FocusHot((row_is_selected && cursor.x == 1) ? UI_FocusKind_On : UI_FocusKind_Off) { - df_entity_desc_button(ws, entity); + df_entity_desc_button(ws, entity, &entities.v[idx-1].matches); } UI_TableCell UI_FocusHot((row_is_selected && cursor.x == 2) ? UI_FocusKind_On : UI_FocusKind_Off) { @@ -8391,7 +8416,7 @@ DF_VIEW_UI_FUNCTION_DEF(Breakpoints) //- rjf: selected num -> selected entity bv->selected_column = cursor.x; - bv->selected_entity = (1 <= cursor.y && cursor.y <= entities.count) ? df_handle_from_entity(entities.v[cursor.y-1]) : df_handle_zero(); + bv->selected_entity = (1 <= cursor.y && cursor.y <= entities.count) ? df_handle_from_entity(entities.v[cursor.y-1].entity) : df_handle_zero(); scratch_end(scratch); } @@ -8405,6 +8430,7 @@ DF_VIEW_CMD_FUNCTION_DEF(WatchPins) {} DF_VIEW_UI_FUNCTION_DEF(WatchPins) { Temp scratch = scratch_begin(0, 0); + String8 query = str8(view->query_buffer, view->query_string_size); //- rjf: get state typedef struct DF_WatchPinsViewState DF_WatchPinsViewState; @@ -8429,13 +8455,13 @@ DF_VIEW_UI_FUNCTION_DEF(WatchPins) //- rjf: get entities DF_EntityList entities_list = df_query_cached_entity_list_with_kind(DF_EntityKind_WatchPin); - DF_EntityArray entities = df_entity_array_from_list(scratch.arena, &entities_list); + DF_EntityFuzzyItemArray entities = df_entity_fuzzy_item_array_from_entity_list_needle(scratch.arena, &entities_list, query); //- rjf: selected column/entity -> selected cursor Vec2S64 cursor = {pv->selected_column}; for(U64 idx = 0; idx < entities.count; idx += 1) { - if(entities.v[idx] == df_entity_from_handle(pv->selected_entity)) + if(entities.v[idx].entity == df_entity_from_handle(pv->selected_entity)) { cursor.y = (S64)(idx+1); break; @@ -8468,13 +8494,13 @@ DF_VIEW_UI_FUNCTION_DEF(WatchPins) Vec2S64 next_cursor = cursor; for(U64 idx = Max(1, visible_row_range.min); idx <= visible_row_range.max && idx <= entities.count; idx += 1) { - DF_Entity *entity = entities.v[idx-1]; + DF_Entity *entity = entities.v[idx-1].entity; B32 row_is_selected = (cursor.y == (S64)(idx)); UI_NamedTableVectorF("pin_%p", entity) { UI_TableCell UI_FocusHot((row_is_selected && cursor.x == 0) ? UI_FocusKind_On : UI_FocusKind_Off) { - df_entity_desc_button(ws, entity); + df_entity_desc_button(ws, entity, &entities.v[idx-1].matches); } UI_TableCell UI_FocusHot((row_is_selected && cursor.x == 1) ? UI_FocusKind_On : UI_FocusKind_Off) { @@ -8520,7 +8546,7 @@ DF_VIEW_UI_FUNCTION_DEF(WatchPins) //- rjf: selected num -> selected entity pv->selected_column = cursor.x; - pv->selected_entity = (1 <= cursor.y && cursor.y <= entities.count) ? df_handle_from_entity(entities.v[cursor.y-1]) : df_handle_zero(); + pv->selected_entity = (1 <= cursor.y && cursor.y <= entities.count) ? df_handle_from_entity(entities.v[cursor.y-1].entity) : df_handle_zero(); scratch_end(scratch); } diff --git a/src/df/gfx/generated/df_gfx.meta.h b/src/df/gfx/generated/df_gfx.meta.h index d0e3cac4..55004b9f 100644 --- a/src/df/gfx/generated/df_gfx.meta.h +++ b/src/df/gfx/generated/df_gfx.meta.h @@ -960,7 +960,7 @@ DF_ViewSpecInfo df_g_gfx_view_kind_spec_info_table[] = {(0|1*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("pending_entity"), str8_lit_comp("Pending Entity"), DF_NameKind_EntityName, DF_IconKind_FileOutline, DF_VIEW_SETUP_FUNCTION_NAME(PendingEntity), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(PendingEntity), DF_VIEW_CMD_FUNCTION_NAME(PendingEntity), DF_VIEW_UI_FUNCTION_NAME(PendingEntity)}, {(0|1*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|1*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("code"), str8_lit_comp("Code"), DF_NameKind_EntityName, DF_IconKind_FileOutline, DF_VIEW_SETUP_FUNCTION_NAME(Code), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Code), DF_VIEW_CMD_FUNCTION_NAME(Code), DF_VIEW_UI_FUNCTION_NAME(Code)}, {(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("disassembly"), str8_lit_comp("Disassembly"), DF_NameKind_Null, DF_IconKind_Glasses, DF_VIEW_SETUP_FUNCTION_NAME(Disassembly), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Disassembly), DF_VIEW_CMD_FUNCTION_NAME(Disassembly), DF_VIEW_UI_FUNCTION_NAME(Disassembly)}, -{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("watch"), str8_lit_comp("Watch"), DF_NameKind_Null, DF_IconKind_Binoculars, DF_VIEW_SETUP_FUNCTION_NAME(Watch), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Watch), DF_VIEW_CMD_FUNCTION_NAME(Watch), DF_VIEW_UI_FUNCTION_NAME(Watch)}, +{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("watch"), str8_lit_comp("Watch"), DF_NameKind_Null, DF_IconKind_Binoculars, DF_VIEW_SETUP_FUNCTION_NAME(Watch), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Watch), DF_VIEW_CMD_FUNCTION_NAME(Watch), DF_VIEW_UI_FUNCTION_NAME(Watch)}, {(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("locals"), str8_lit_comp("Locals"), DF_NameKind_Null, DF_IconKind_Binoculars, DF_VIEW_SETUP_FUNCTION_NAME(Locals), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Locals), DF_VIEW_CMD_FUNCTION_NAME(Locals), DF_VIEW_UI_FUNCTION_NAME(Locals)}, {(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("registers"), str8_lit_comp("Registers"), DF_NameKind_Null, DF_IconKind_Binoculars, DF_VIEW_SETUP_FUNCTION_NAME(Registers), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Registers), DF_VIEW_CMD_FUNCTION_NAME(Registers), DF_VIEW_UI_FUNCTION_NAME(Registers)}, {(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("globals"), str8_lit_comp("Globals"), DF_NameKind_Null, DF_IconKind_Binoculars, DF_VIEW_SETUP_FUNCTION_NAME(Globals), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Globals), DF_VIEW_CMD_FUNCTION_NAME(Globals), DF_VIEW_UI_FUNCTION_NAME(Globals)},