From 508d11c8d8c1c980fef0025b8cee7d7c7d9f6ed4 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 23 Sep 2024 16:06:01 -0700 Subject: [PATCH] further progress on targets view replacement; split collection views into several types --- src/raddbg/generated/raddbg.meta.c | 32 ++ src/raddbg/generated/raddbg.meta.h | 14 + src/raddbg/raddbg.mdesk | 35 ++ src/raddbg/raddbg_core.c | 642 +++++++++++++++-------------- src/raddbg/raddbg_core.h | 7 +- src/raddbg/raddbg_views.c | 79 +++- src/raddbg/raddbg_views.h | 1 + 7 files changed, 476 insertions(+), 334 deletions(-) diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index a79d12fe..e5f476ea 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -675,6 +675,38 @@ str8_lit_comp("5"), str8_lit_comp("c"), }; +String8 rd_collection_name_table[12] = +{ +str8_lit_comp("watches"), +str8_lit_comp("targets"), +str8_lit_comp("breakpoints"), +str8_lit_comp("watch_pins"), +str8_lit_comp("threads"), +str8_lit_comp("modules"), +str8_lit_comp("locals"), +str8_lit_comp("registers"), +str8_lit_comp("globals"), +str8_lit_comp("thread_locals"), +str8_lit_comp("types"), +str8_lit_comp("procedures"), +}; + +EV_ViewRuleBlockProdHookFunctionType * rd_collection_block_prod_hook_function_table[12] = +{ +EV_VIEW_RULE_BLOCK_PROD_FUNCTION_NAME(watches), +EV_VIEW_RULE_BLOCK_PROD_FUNCTION_NAME(targets), +EV_VIEW_RULE_BLOCK_PROD_FUNCTION_NAME(breakpoints), +EV_VIEW_RULE_BLOCK_PROD_FUNCTION_NAME(watch_pins), +EV_VIEW_RULE_BLOCK_PROD_FUNCTION_NAME(threads), +EV_VIEW_RULE_BLOCK_PROD_FUNCTION_NAME(modules), +EV_VIEW_RULE_BLOCK_PROD_FUNCTION_NAME(locals), +EV_VIEW_RULE_BLOCK_PROD_FUNCTION_NAME(registers), +EV_VIEW_RULE_BLOCK_PROD_FUNCTION_NAME(globals), +EV_VIEW_RULE_BLOCK_PROD_FUNCTION_NAME(thread_locals), +EV_VIEW_RULE_BLOCK_PROD_FUNCTION_NAME(types), +EV_VIEW_RULE_BLOCK_PROD_FUNCTION_NAME(procedures), +}; + RD_ViewRuleInfo rd_view_rule_kind_info_table[34] = { {{0}, {0}, {0}, {0}, RD_IconKind_Null, 0, 0, RD_VIEW_RULE_UI_FUNCTION_NAME(null)}, diff --git a/src/raddbg/generated/raddbg.meta.h b/src/raddbg/generated/raddbg.meta.h index a5038a56..1a4ebb70 100644 --- a/src/raddbg/generated/raddbg.meta.h +++ b/src/raddbg/generated/raddbg.meta.h @@ -648,6 +648,18 @@ RD_ViewRuleUIFunctionType *ui; .params_tree = rd_regs()->params_tree,\ .os_event = rd_regs()->os_event,\ +EV_VIEW_RULE_BLOCK_PROD_FUNCTION_DEF(watches); +EV_VIEW_RULE_BLOCK_PROD_FUNCTION_DEF(targets); +EV_VIEW_RULE_BLOCK_PROD_FUNCTION_DEF(breakpoints); +EV_VIEW_RULE_BLOCK_PROD_FUNCTION_DEF(watch_pins); +EV_VIEW_RULE_BLOCK_PROD_FUNCTION_DEF(threads); +EV_VIEW_RULE_BLOCK_PROD_FUNCTION_DEF(modules); +EV_VIEW_RULE_BLOCK_PROD_FUNCTION_DEF(locals); +EV_VIEW_RULE_BLOCK_PROD_FUNCTION_DEF(registers); +EV_VIEW_RULE_BLOCK_PROD_FUNCTION_DEF(globals); +EV_VIEW_RULE_BLOCK_PROD_FUNCTION_DEF(thread_locals); +EV_VIEW_RULE_BLOCK_PROD_FUNCTION_DEF(types); +EV_VIEW_RULE_BLOCK_PROD_FUNCTION_DEF(procedures); RD_VIEW_RULE_UI_FUNCTION_DEF(null); EV_VIEW_RULE_BLOCK_PROD_FUNCTION_DEF(text); EV_VIEW_RULE_BLOCK_PROD_FUNCTION_DEF(disasm); @@ -704,6 +716,8 @@ extern RD_StringBindingPair rd_default_binding_table[110]; extern String8 rd_binding_version_remap_old_name_table[7]; extern String8 rd_binding_version_remap_new_name_table[7]; extern String8 rd_icon_kind_text_table[69]; +extern String8 rd_collection_name_table[12]; +extern EV_ViewRuleBlockProdHookFunctionType * rd_collection_block_prod_hook_function_table[12]; extern RD_ViewRuleInfo rd_view_rule_kind_info_table[34]; extern RD_IconKind rd_entity_kind_icon_kind_table[30]; extern String8 rd_theme_preset_display_string_table[9]; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 5395e823..cfab1ad4 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -820,6 +820,41 @@ RD_IconTable: @expand(RD_IconTable a) `str8_lit_comp("$(a.text)")`; } +//////////////////////////////// +//~ rjf: Collections + +@table(name) +RD_CollectionTable: +{ + {watches} + {targets} + {breakpoints} + {watch_pins} + {threads} + {modules} + {locals} + {registers} + {globals} + {thread_locals} + {types} + {procedures} +} + +@gen +{ + @expand(RD_CollectionTable a) `EV_VIEW_RULE_BLOCK_PROD_FUNCTION_DEF($(a.name));` +} + +@data(String8) rd_collection_name_table: +{ + @expand(RD_CollectionTable a) `str8_lit_comp("$(a.name)")` +} + +@data(`EV_ViewRuleBlockProdHookFunctionType *`) rd_collection_block_prod_hook_function_table: +{ + @expand(RD_CollectionTable a) `EV_VIEW_RULE_BLOCK_PROD_FUNCTION_NAME($(a.name))` +} + //////////////////////////////// //~ rjf: View Rules diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 08b40512..423bf665 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1705,6 +1705,35 @@ rd_entity_from_name_and_kind(String8 string, RD_EntityKind kind) return result; } +//////////////////////////////// +//~ rjf: Frontend Entity Info Extraction + +internal DR_FancyStringList +rd_title_fstrs_from_entity(Arena *arena, RD_Entity *entity, Vec4F32 secondary_color, F32 size) +{ + DR_FancyStringList result = {0}; + RD_IconKind icon_kind = rd_entity_kind_icon_kind_table[entity->kind]; + Vec4F32 color = rd_rgba_from_theme_color(RD_ThemeColor_Text); + if(icon_kind != RD_IconKind_Null) + { + dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Icons), size, secondary_color, rd_icon_kind_text_table[icon_kind]); + } + dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(RD_FontSlot_Code), size, secondary_color, str8_lit(" ")); + String8 name = entity->string; + B32 name_is_code = 1; + if(name.size == 0) + { + RD_Entity *exe = rd_entity_child_from_kind(entity, RD_EntityKind_Executable); + if(!rd_entity_is_nil(exe)) + { + name = str8_skip_last_slash(exe->string); + name_is_code = 0; + } + } + dr_fancy_string_list_push_new(arena, &result, rd_font_from_slot(name_is_code ? RD_FontSlot_Code : RD_FontSlot_Main), size, color, name); + return result; +} + //////////////////////////////// //~ rjf: Control Entity Info Extraction @@ -7868,334 +7897,316 @@ rd_window_frame(RD_Window *ws) //////////////////////////////// //~ rjf: Eval Visualization -EV_VIEW_RULE_BLOCK_PROD_FUNCTION_DEF(rd_collection_block_prod) +EV_VIEW_RULE_BLOCK_PROD_FUNCTION_DEF(watches) { - ////////////////////////////// - //- rjf: watches - // - if(str8_match(string, str8_lit("watches"), 0)) + Temp scratch = scratch_begin(&arena, 1); + RD_EntityList watches = rd_query_cached_entity_list_with_kind(RD_EntityKind_Watch); + EV_ViewRuleList *view_rules_inherited = ev_view_rule_list_from_inheritance(arena, view_rules); + for(RD_EntityNode *n = watches.first; n != 0; n = n->next) { - Temp scratch = scratch_begin(&arena, 1); - RD_EntityList watches = rd_query_cached_entity_list_with_kind(RD_EntityKind_Watch); - EV_ViewRuleList *view_rules_inherited = ev_view_rule_list_from_inheritance(arena, view_rules); - for(RD_EntityNode *n = watches.first; n != 0; n = n->next) + RD_Entity *entity = n->entity; + String8 entity_expr_string = entity->string; + EV_Key entity_parent_key = rd_parent_ev_key_from_entity(entity); + EV_Key entity_key = rd_ev_key_from_entity(entity); + EV_BlockList blocks = ev_block_list_from_view_expr_keys(arena, view, filter, view_rules_inherited, entity_expr_string, entity_parent_key, entity_key, depth); + FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, entity_expr_string); + if(blocks.total_semantic_row_count > 1 || matches.count == matches.needle_part_count) { - RD_Entity *entity = n->entity; - String8 entity_expr_string = entity->string; - EV_Key entity_parent_key = rd_parent_ev_key_from_entity(entity); - EV_Key entity_key = rd_ev_key_from_entity(entity); - EV_BlockList blocks = ev_block_list_from_view_expr_keys(arena, view, filter, view_rules_inherited, entity_expr_string, entity_parent_key, entity_key, depth); - FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, entity_expr_string); - if(blocks.total_semantic_row_count > 1 || matches.count == matches.needle_part_count) - { - ev_block_list_concat__in_place(out, &blocks); - } - } - scratch_end(scratch); - } - - ////////////////////////////// - //- rjf: targets - // - else if(str8_match(string, str8_lit("targets"), 0)) - { - Temp scratch = scratch_begin(&arena, 1); - RD_EntityList targets = rd_query_cached_entity_list_with_kind(RD_EntityKind_Target); - EV_ViewRuleList *view_rules_inherited = ev_view_rule_list_from_inheritance(arena, view_rules); - for(RD_EntityNode *n = targets.first; n != 0; n = n->next) - { - RD_Entity *target = n->entity; - String8 target_expr_string = push_str8f(arena, "$%I64u", target->id); - EV_Key target_parent_key = key; - EV_Key target_key = ev_key_make(ev_hash_from_key(target_parent_key), target->id); - EV_BlockList blocks = ev_block_list_from_view_expr_keys(arena, view, str8_zero(), view_rules_inherited, target_expr_string, target_parent_key, target_key, depth); ev_block_list_concat__in_place(out, &blocks); } - scratch_end(scratch); } - - ////////////////////////////// - //- rjf: breakpoints - // - else if(str8_match(string, str8_lit("breakpoints"), 0)) + scratch_end(scratch); +} + +EV_VIEW_RULE_BLOCK_PROD_FUNCTION_DEF(targets) +{ + Temp scratch = scratch_begin(&arena, 1); + RD_EntityList targets = rd_query_cached_entity_list_with_kind(RD_EntityKind_Target); + EV_ViewRuleList *view_rules_inherited = ev_view_rule_list_from_inheritance(arena, view_rules); + for(RD_EntityNode *n = targets.first; n != 0; n = n->next) { - Temp scratch = scratch_begin(&arena, 1); - RD_EntityList bps = rd_query_cached_entity_list_with_kind(RD_EntityKind_Breakpoint); - EV_ViewRuleList *view_rules_inherited = ev_view_rule_list_from_inheritance(arena, view_rules); - for(RD_EntityNode *n = bps.first; n != 0; n = n->next) + RD_Entity *target = n->entity; + String8 target_expr_string = push_str8f(arena, "$%I64u", target->id); + EV_Key target_parent_key = key; + EV_Key target_key = ev_key_make(ev_hash_from_key(target_parent_key), target->id); + EV_BlockList blocks = ev_block_list_from_view_expr_keys(arena, view, str8_zero(), view_rules_inherited, target_expr_string, target_parent_key, target_key, depth); + ev_block_list_concat__in_place(out, &blocks); + } + scratch_end(scratch); +} + +EV_VIEW_RULE_BLOCK_PROD_FUNCTION_DEF(breakpoints) +{ + Temp scratch = scratch_begin(&arena, 1); + RD_EntityList bps = rd_query_cached_entity_list_with_kind(RD_EntityKind_Breakpoint); + EV_ViewRuleList *view_rules_inherited = ev_view_rule_list_from_inheritance(arena, view_rules); + for(RD_EntityNode *n = bps.first; n != 0; n = n->next) + { + RD_Entity *bp = n->entity; + String8 bp_expr_string = push_str8f(arena, "$%I64u", bp->id); + EV_Key bp_parent_key = key; + EV_Key bp_key = ev_key_make(ev_hash_from_key(bp_parent_key), bp->id); + EV_BlockList blocks = ev_block_list_from_view_expr_keys(arena, view, str8_zero(), view_rules_inherited, bp_expr_string, bp_parent_key, bp_key, depth); + ev_block_list_concat__in_place(out, &blocks); + } + scratch_end(scratch); +} + +EV_VIEW_RULE_BLOCK_PROD_FUNCTION_DEF(watch_pins) +{ + Temp scratch = scratch_begin(&arena, 1); + RD_EntityList wps = rd_query_cached_entity_list_with_kind(RD_EntityKind_WatchPin); + EV_ViewRuleList *view_rules_inherited = ev_view_rule_list_from_inheritance(arena, view_rules); + for(RD_EntityNode *n = wps.first; n != 0; n = n->next) + { + RD_Entity *wp = n->entity; + String8 wp_expr_string = push_str8f(arena, "$%I64u", wp->id); + EV_Key wp_parent_key = key; + EV_Key wp_key = ev_key_make(ev_hash_from_key(wp_parent_key), wp->id); + EV_BlockList blocks = ev_block_list_from_view_expr_keys(arena, view, str8_zero(), view_rules_inherited, wp_expr_string, wp_parent_key, wp_key, depth); + ev_block_list_concat__in_place(out, &blocks); + } + scratch_end(scratch); +} + +EV_VIEW_RULE_BLOCK_PROD_FUNCTION_DEF(threads) +{ + Temp scratch = scratch_begin(&arena, 1); + CTRL_EntityList entities = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Thread); + EV_ViewRuleList *view_rules_inherited = ev_view_rule_list_from_inheritance(arena, view_rules); + for(CTRL_EntityNode *n = entities.first; n != 0; n = n->next) + { + CTRL_Entity *entity = n->v; + String8 entity_expr_string = push_str8f(arena, "$_%I64x_%I64x", entity->handle.machine_id, entity->handle.dmn_handle.u64[0]); + EV_Key entity_parent_key = key; + EV_Key entity_key = ev_key_make(ev_hash_from_key(entity_parent_key), d_hash_from_string(entity_expr_string)); + EV_BlockList blocks = ev_block_list_from_view_expr_keys(arena, view, str8_zero(), view_rules_inherited, entity_expr_string, entity_parent_key, entity_key, depth); + ev_block_list_concat__in_place(out, &blocks); + } + scratch_end(scratch); +} + +EV_VIEW_RULE_BLOCK_PROD_FUNCTION_DEF(modules) +{ + Temp scratch = scratch_begin(&arena, 1); + CTRL_EntityList entities = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Module); + EV_ViewRuleList *view_rules_inherited = ev_view_rule_list_from_inheritance(arena, view_rules); + for(CTRL_EntityNode *n = entities.first; n != 0; n = n->next) + { + CTRL_Entity *entity = n->v; + String8 entity_expr_string = push_str8f(arena, "$_%I64x_%I64x", entity->handle.machine_id, entity->handle.dmn_handle.u64[0]); + EV_Key entity_parent_key = key; + EV_Key entity_key = ev_key_make(ev_hash_from_key(entity_parent_key), d_hash_from_string(entity_expr_string)); + EV_BlockList blocks = ev_block_list_from_view_expr_keys(arena, view, str8_zero(), view_rules_inherited, entity_expr_string, entity_parent_key, entity_key, depth); + ev_block_list_concat__in_place(out, &blocks); + } + scratch_end(scratch); +} + +EV_VIEW_RULE_BLOCK_PROD_FUNCTION_DEF(locals) +{ + Temp scratch = scratch_begin(&arena, 1); + E_String2NumMapNodeArray nodes = e_string2num_map_node_array_from_map(scratch.arena, e_parse_ctx->locals_map); + e_string2num_map_node_array_sort__in_place(&nodes); + EV_ViewRuleList *view_rules_inherited = ev_view_rule_list_from_inheritance(arena, view_rules); + for(U64 idx = 0; idx < nodes.count; idx += 1) + { + E_String2NumMapNode *n = nodes.v[idx]; + String8 root_expr_string = n->string; + FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, root_expr_string); + if(matches.count == matches.needle_part_count) { - RD_Entity *bp = n->entity; - String8 bp_expr_string = push_str8f(arena, "$%I64u", bp->id); - EV_Key bp_parent_key = key; - EV_Key bp_key = ev_key_make(ev_hash_from_key(bp_parent_key), bp->id); - EV_BlockList blocks = ev_block_list_from_view_expr_keys(arena, view, str8_zero(), view_rules_inherited, bp_expr_string, bp_parent_key, bp_key, depth); - ev_block_list_concat__in_place(out, &blocks); + EV_Key local_parent_key = key; + EV_Key local_key = ev_key_make(ev_hash_from_key(local_parent_key), idx+1); + EV_BlockList root_blocks = ev_block_list_from_view_expr_keys(arena, view, str8_zero(), view_rules_inherited, root_expr_string, local_parent_key, local_key, depth); + ev_block_list_concat__in_place(out, &root_blocks); } - scratch_end(scratch); } - - ////////////////////////////// - //- rjf: watch_pins - // - else if(str8_match(string, str8_lit("watch_pins"), 0)) + scratch_end(scratch); +} + +EV_VIEW_RULE_BLOCK_PROD_FUNCTION_DEF(registers) +{ + Temp scratch = scratch_begin(&arena, 1); + CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread); + Arch arch = thread->arch; + U64 reg_count = regs_reg_code_count_from_arch(arch); + String8 *reg_strings = regs_reg_code_string_table_from_arch(arch); + U64 alias_count = regs_alias_code_count_from_arch(arch); + String8 *alias_strings = regs_alias_code_string_table_from_arch(arch); + U64 num = 1; + EV_ViewRuleList *view_rules_inherited = ev_view_rule_list_from_inheritance(arena, view_rules); + ev_view_rule_list_push_string(arena, view_rules_inherited, str8_lit("hex")); + for(U64 reg_idx = 1; reg_idx < reg_count; reg_idx += 1, num += 1) { - Temp scratch = scratch_begin(&arena, 1); - RD_EntityList wps = rd_query_cached_entity_list_with_kind(RD_EntityKind_WatchPin); - EV_ViewRuleList *view_rules_inherited = ev_view_rule_list_from_inheritance(arena, view_rules); - for(RD_EntityNode *n = wps.first; n != 0; n = n->next) + String8 root_expr_string = push_str8f(arena, "reg:%S", reg_strings[reg_idx]); + FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, root_expr_string); + if(matches.count == matches.needle_part_count) { - RD_Entity *wp = n->entity; - String8 wp_expr_string = push_str8f(arena, "$%I64u", wp->id); - EV_Key wp_parent_key = key; - EV_Key wp_key = ev_key_make(ev_hash_from_key(wp_parent_key), wp->id); - EV_BlockList blocks = ev_block_list_from_view_expr_keys(arena, view, str8_zero(), view_rules_inherited, wp_expr_string, wp_parent_key, wp_key, depth); - ev_block_list_concat__in_place(out, &blocks); + EV_Key reg_parent_key = key; + EV_Key reg_key = ev_key_make(ev_hash_from_key(reg_parent_key), num); + EV_BlockList root_blocks = ev_block_list_from_view_expr_keys(arena, view, str8_zero(), view_rules_inherited, root_expr_string, reg_parent_key, reg_key, depth); + ev_block_list_concat__in_place(out, &root_blocks); } - scratch_end(scratch); } - - ////////////////////////////// - //- rjf: threads - // - else if(str8_match(string, str8_lit("threads"), 0)) + for(U64 alias_idx = 1; alias_idx < alias_count; alias_idx += 1, num += 1) { - Temp scratch = scratch_begin(&arena, 1); - CTRL_EntityList entities = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Thread); - EV_ViewRuleList *view_rules_inherited = ev_view_rule_list_from_inheritance(arena, view_rules); - for(CTRL_EntityNode *n = entities.first; n != 0; n = n->next) + String8 root_expr_string = push_str8f(arena, "reg:%S", alias_strings[alias_idx]); + FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, root_expr_string); + if(matches.count == matches.needle_part_count) { - CTRL_Entity *entity = n->v; - String8 entity_expr_string = push_str8f(arena, "$_%I64x_%I64x", entity->handle.machine_id, entity->handle.dmn_handle.u64[0]); - EV_Key entity_parent_key = key; - EV_Key entity_key = ev_key_make(ev_hash_from_key(entity_parent_key), d_hash_from_string(entity_expr_string)); - EV_BlockList blocks = ev_block_list_from_view_expr_keys(arena, view, str8_zero(), view_rules_inherited, entity_expr_string, entity_parent_key, entity_key, depth); - ev_block_list_concat__in_place(out, &blocks); + EV_Key reg_parent_key = ev_key_make(5381, 0); + EV_Key reg_key = ev_key_make(ev_hash_from_key(reg_parent_key), num); + EV_BlockList root_blocks = ev_block_list_from_view_expr_keys(arena, view, str8_zero(), view_rules_inherited, root_expr_string, reg_parent_key, reg_key, depth); + ev_block_list_concat__in_place(out, &root_blocks); } - scratch_end(scratch); } - - ////////////////////////////// - //- rjf: modules - // - else if(str8_match(string, str8_lit("modules"), 0)) + scratch_end(scratch); +} + +EV_VIEW_RULE_BLOCK_PROD_FUNCTION_DEF(globals) +{ + rd_ev_view_rule_block_prod_collection_debug_tables(arena, RDI_SectionKind_GlobalVariables, view, filter, parent_key, key, expand_node, string, expr, view_rules, view_params, depth, out); +} + +EV_VIEW_RULE_BLOCK_PROD_FUNCTION_DEF(thread_locals) +{ + rd_ev_view_rule_block_prod_collection_debug_tables(arena, RDI_SectionKind_ThreadVariables, view, filter, parent_key, key, expand_node, string, expr, view_rules, view_params, depth, out); +} + +EV_VIEW_RULE_BLOCK_PROD_FUNCTION_DEF(types) +{ + rd_ev_view_rule_block_prod_collection_debug_tables(arena, RDI_SectionKind_UDTs, view, filter, parent_key, key, expand_node, string, expr, view_rules, view_params, depth, out); +} + +EV_VIEW_RULE_BLOCK_PROD_FUNCTION_DEF(procedures) +{ + rd_ev_view_rule_block_prod_collection_debug_tables(arena, RDI_SectionKind_Procedures, view, filter, parent_key, key, expand_node, string, expr, view_rules, view_params, depth, out); +} + +internal void +rd_ev_view_rule_block_prod_collection_debug_tables(Arena *arena, RDI_SectionKind target, EV_View *view, String8 filter, EV_Key parent_key, EV_Key key, EV_ExpandNode *expand_node, String8 string, E_Expr *expr, EV_ViewRuleList *view_rules, MD_Node *view_params, S32 depth, struct EV_BlockList *out) +{ + Temp scratch = scratch_begin(&arena, 1); + if(target != RDI_SectionKind_NULL) { - Temp scratch = scratch_begin(&arena, 1); - CTRL_EntityList entities = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Module); - EV_ViewRuleList *view_rules_inherited = ev_view_rule_list_from_inheritance(arena, view_rules); - for(CTRL_EntityNode *n = entities.first; n != 0; n = n->next) + U64 endt_us = os_now_microseconds()+200; + + //- rjf: unpack context + DI_KeyList dbgi_keys_list = d_push_active_dbgi_key_list(scratch.arena); + DI_KeyArray dbgi_keys = di_key_array_from_list(scratch.arena, &dbgi_keys_list); + U64 rdis_count = dbgi_keys.count; + RDI_Parsed **rdis = push_array(scratch.arena, RDI_Parsed *, rdis_count); + for(U64 idx = 0; idx < rdis_count; idx += 1) { - CTRL_Entity *entity = n->v; - String8 entity_expr_string = push_str8f(arena, "$_%I64x_%I64x", entity->handle.machine_id, entity->handle.dmn_handle.u64[0]); - EV_Key entity_parent_key = key; - EV_Key entity_key = ev_key_make(ev_hash_from_key(entity_parent_key), d_hash_from_string(entity_expr_string)); - EV_BlockList blocks = ev_block_list_from_view_expr_keys(arena, view, str8_zero(), view_rules_inherited, entity_expr_string, entity_parent_key, entity_key, depth); - ev_block_list_concat__in_place(out, &blocks); + rdis[idx] = di_rdi_from_key(rd_state->frame_di_scope, &dbgi_keys.v[idx], endt_us); } - scratch_end(scratch); - } - - ////////////////////////////// - //- rjf: locals - // - else if(str8_match(string, str8_lit("locals"), 0)) - { - Temp scratch = scratch_begin(&arena, 1); - E_String2NumMapNodeArray nodes = e_string2num_map_node_array_from_map(scratch.arena, e_parse_ctx->locals_map); - e_string2num_map_node_array_sort__in_place(&nodes); - EV_ViewRuleList *view_rules_inherited = ev_view_rule_list_from_inheritance(arena, view_rules); - for(U64 idx = 0; idx < nodes.count; idx += 1) + + //- rjf: calculate top-level keys, expand root-level, grab root expansion node + EV_ExpandNode *root_node = ev_expand_node_from_key(view, key); + + //- rjf: query all filtered items from dbgi searching system + U128 fuzzy_search_key = {rd_regs()->view.u64[0], d_hash_from_seed_string(ev_hash_from_key(key), string)}; + B32 items_stale = 0; + FZY_Params params = {target, dbgi_keys}; + FZY_ItemArray items = fzy_items_from_key_params_query(rd_state->frame_fzy_scope, fuzzy_search_key, ¶ms, filter, endt_us, &items_stale); + if(items_stale) { - E_String2NumMapNode *n = nodes.v[idx]; - String8 root_expr_string = n->string; - FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, root_expr_string); - if(matches.count == matches.needle_part_count) + rd_request_frame(); + } + + //- rjf: gather unsorted child expansion keys + // + // Nodes are sorted in the underlying expansion tree data structure, but + // ONLY by THEIR ORDER IN THE UNDERLYING DEBUG INFO TABLE. This is + // because debug info watch rows use the DEBUG INFO TABLE INDEX to form + // their key - this provides more stable/predictable behavior as rows + // are reordered, filtered, and shuffled around, as the user filters. + // + // When we actually build viz blocks, however, we want to produce viz + // blocks BY THE ORDER OF SUB-EXPANSIONS IN THE FILTERED ITEM ARRAY + // SPACE, so that all of the expansions come out in the right order. + // + EV_Key *sub_expand_keys = 0; + U64 *sub_expand_item_idxs = 0; + U64 sub_expand_keys_count = 0; + { + for(EV_ExpandNode *child = root_node->first; child != 0; child = child->next) { - EV_Key local_parent_key = key; - EV_Key local_key = ev_key_make(ev_hash_from_key(local_parent_key), idx+1); - EV_BlockList root_blocks = ev_block_list_from_view_expr_keys(arena, view, str8_zero(), view_rules_inherited, root_expr_string, local_parent_key, local_key, depth); - ev_block_list_concat__in_place(out, &root_blocks); + sub_expand_keys_count += 1; } - } - scratch_end(scratch); - } - - ////////////////////////////// - //- rjf: registers - // - else if(str8_match(string, str8_lit("registers"), 0)) - { - Temp scratch = scratch_begin(&arena, 1); - CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread); - Arch arch = thread->arch; - U64 reg_count = regs_reg_code_count_from_arch(arch); - String8 *reg_strings = regs_reg_code_string_table_from_arch(arch); - U64 alias_count = regs_alias_code_count_from_arch(arch); - String8 *alias_strings = regs_alias_code_string_table_from_arch(arch); - U64 num = 1; - EV_ViewRuleList *view_rules_inherited = ev_view_rule_list_from_inheritance(arena, view_rules); - ev_view_rule_list_push_string(arena, view_rules_inherited, str8_lit("hex")); - for(U64 reg_idx = 1; reg_idx < reg_count; reg_idx += 1, num += 1) - { - String8 root_expr_string = push_str8f(arena, "reg:%S", reg_strings[reg_idx]); - FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, root_expr_string); - if(matches.count == matches.needle_part_count) + sub_expand_keys = push_array(scratch.arena, EV_Key, sub_expand_keys_count); + sub_expand_item_idxs = push_array(scratch.arena, U64, sub_expand_keys_count); + U64 idx = 0; + for(EV_ExpandNode *child = root_node->first; child != 0; child = child->next) { - EV_Key reg_parent_key = key; - EV_Key reg_key = ev_key_make(ev_hash_from_key(reg_parent_key), num); - EV_BlockList root_blocks = ev_block_list_from_view_expr_keys(arena, view, str8_zero(), view_rules_inherited, root_expr_string, reg_parent_key, reg_key, depth); - ev_block_list_concat__in_place(out, &root_blocks); - } - } - for(U64 alias_idx = 1; alias_idx < alias_count; alias_idx += 1, num += 1) - { - String8 root_expr_string = push_str8f(arena, "reg:%S", alias_strings[alias_idx]); - FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, root_expr_string); - if(matches.count == matches.needle_part_count) - { - EV_Key reg_parent_key = ev_key_make(5381, 0); - EV_Key reg_key = ev_key_make(ev_hash_from_key(reg_parent_key), num); - EV_BlockList root_blocks = ev_block_list_from_view_expr_keys(arena, view, str8_zero(), view_rules_inherited, root_expr_string, reg_parent_key, reg_key, depth); - ev_block_list_concat__in_place(out, &root_blocks); - } - } - scratch_end(scratch); - } - - ////////////////////////////// - //- rjf: debug info tables - // - else if(str8_match(string, str8_lit("globals"), 0) || - str8_match(string, str8_lit("thread_locals"), 0) || - str8_match(string, str8_lit("types"), 0) || - str8_match(string, str8_lit("procedures"), 0)) - { - Temp scratch = scratch_begin(&arena, 1); - RDI_SectionKind fzy_target = (str8_match(string, str8_lit("globals"), 0) ? RDI_SectionKind_GlobalVariables : - str8_match(string, str8_lit("thread_locals"), 0) ? RDI_SectionKind_ThreadVariables : - str8_match(string, str8_lit("types"), 0) ? RDI_SectionKind_UDTs : - str8_match(string, str8_lit("procedures"), 0) ? RDI_SectionKind_Procedures : - RDI_SectionKind_NULL); - if(fzy_target != RDI_SectionKind_NULL) - { - U64 endt_us = os_now_microseconds()+200; - - //- rjf: unpack context - DI_KeyList dbgi_keys_list = d_push_active_dbgi_key_list(scratch.arena); - DI_KeyArray dbgi_keys = di_key_array_from_list(scratch.arena, &dbgi_keys_list); - U64 rdis_count = dbgi_keys.count; - RDI_Parsed **rdis = push_array(scratch.arena, RDI_Parsed *, rdis_count); - for(U64 idx = 0; idx < rdis_count; idx += 1) - { - rdis[idx] = di_rdi_from_key(rd_state->frame_di_scope, &dbgi_keys.v[idx], endt_us); - } - - //- rjf: calculate top-level keys, expand root-level, grab root expansion node - EV_ExpandNode *root_node = ev_expand_node_from_key(view, key); - - //- rjf: query all filtered items from dbgi searching system - U128 fuzzy_search_key = {rd_regs()->view.u64[0], d_hash_from_seed_string(ev_hash_from_key(key), string)}; - B32 items_stale = 0; - FZY_Params params = {fzy_target, dbgi_keys}; - FZY_ItemArray items = fzy_items_from_key_params_query(rd_state->frame_fzy_scope, fuzzy_search_key, ¶ms, filter, endt_us, &items_stale); - if(items_stale) - { - rd_request_frame(); - } - - //- rjf: gather unsorted child expansion keys - // - // Nodes are sorted in the underlying expansion tree data structure, but - // ONLY by THEIR ORDER IN THE UNDERLYING DEBUG INFO TABLE. This is - // because debug info watch rows use the DEBUG INFO TABLE INDEX to form - // their key - this provides more stable/predictable behavior as rows - // are reordered, filtered, and shuffled around, as the user filters. - // - // When we actually build viz blocks, however, we want to produce viz - // blocks BY THE ORDER OF SUB-EXPANSIONS IN THE FILTERED ITEM ARRAY - // SPACE, so that all of the expansions come out in the right order. - // - EV_Key *sub_expand_keys = 0; - U64 *sub_expand_item_idxs = 0; - U64 sub_expand_keys_count = 0; - { - for(EV_ExpandNode *child = root_node->first; child != 0; child = child->next) + U64 item_num = fzy_item_num_from_array_element_idx__linear_search(&items, child->key.child_num); + if(item_num != 0) { - sub_expand_keys_count += 1; + sub_expand_keys[idx] = child->key; + sub_expand_item_idxs[idx] = item_num-1; + idx += 1; } - sub_expand_keys = push_array(scratch.arena, EV_Key, sub_expand_keys_count); - sub_expand_item_idxs = push_array(scratch.arena, U64, sub_expand_keys_count); - U64 idx = 0; - for(EV_ExpandNode *child = root_node->first; child != 0; child = child->next) + else { - U64 item_num = fzy_item_num_from_array_element_idx__linear_search(&items, child->key.child_num); - if(item_num != 0) + sub_expand_keys_count -= 1; + } + } + } + + //- rjf: sort child expansion keys + { + for(U64 idx1 = 0; idx1 < sub_expand_keys_count; idx1 += 1) + { + U64 min_idx2 = 0; + U64 min_item_idx = sub_expand_item_idxs[idx1]; + for(U64 idx2 = idx1+1; idx2 < sub_expand_keys_count; idx2 += 1) + { + if(sub_expand_item_idxs[idx2] < min_item_idx) { - sub_expand_keys[idx] = child->key; - sub_expand_item_idxs[idx] = item_num-1; - idx += 1; - } - else - { - sub_expand_keys_count -= 1; + min_idx2 = idx2; + min_item_idx = sub_expand_item_idxs[idx2]; } } + if(min_idx2 != 0) + { + Swap(EV_Key, sub_expand_keys[idx1], sub_expand_keys[min_idx2]); + Swap(U64, sub_expand_item_idxs[idx1], sub_expand_item_idxs[min_idx2]); + } + } + } + + //- rjf: build blocks for all table items, split by sorted sub-expansions + EV_Block *last_vb = ev_block_begin(arena, EV_BlockKind_DebugInfoTable, key, ev_key_make(ev_hash_from_key(key), 0), depth); + { + last_vb->visual_idx_range = last_vb->semantic_idx_range = r1u64(0, items.count); + last_vb->fzy_target = target; + last_vb->fzy_backing_items = items; + } + for(U64 sub_expand_idx = 0; sub_expand_idx < sub_expand_keys_count; sub_expand_idx += 1) + { + FZY_Item *item = &items.v[sub_expand_item_idxs[sub_expand_idx]]; + E_Expr *child_expr = ev_expr_from_block_index(arena, last_vb, sub_expand_item_idxs[sub_expand_idx]); + + // rjf: form split: truncate & complete last block; begin next block + last_vb = ev_block_split_and_continue(arena, out, last_vb, sub_expand_item_idxs[sub_expand_idx]); + + // rjf: build child view rules + EV_ViewRuleList *child_view_rules = ev_view_rule_list_from_inheritance(arena, view_rules); + { + String8 view_rule_string = ev_view_rule_from_key(view, sub_expand_keys[sub_expand_idx]); + if(view_rule_string.size != 0) + { + ev_view_rule_list_push_string(arena, child_view_rules, view_rule_string); + } } - //- rjf: sort child expansion keys - { - for(U64 idx1 = 0; idx1 < sub_expand_keys_count; idx1 += 1) - { - U64 min_idx2 = 0; - U64 min_item_idx = sub_expand_item_idxs[idx1]; - for(U64 idx2 = idx1+1; idx2 < sub_expand_keys_count; idx2 += 1) - { - if(sub_expand_item_idxs[idx2] < min_item_idx) - { - min_idx2 = idx2; - min_item_idx = sub_expand_item_idxs[idx2]; - } - } - if(min_idx2 != 0) - { - Swap(EV_Key, sub_expand_keys[idx1], sub_expand_keys[min_idx2]); - Swap(U64, sub_expand_item_idxs[idx1], sub_expand_item_idxs[min_idx2]); - } - } - } - - //- rjf: build blocks for all table items, split by sorted sub-expansions - EV_Block *last_vb = ev_block_begin(arena, EV_BlockKind_DebugInfoTable, key, ev_key_make(ev_hash_from_key(key), 0), depth); - { - last_vb->visual_idx_range = last_vb->semantic_idx_range = r1u64(0, items.count); - last_vb->fzy_target = fzy_target; - last_vb->fzy_backing_items = items; - } - for(U64 sub_expand_idx = 0; sub_expand_idx < sub_expand_keys_count; sub_expand_idx += 1) - { - FZY_Item *item = &items.v[sub_expand_item_idxs[sub_expand_idx]]; - E_Expr *child_expr = ev_expr_from_block_index(arena, last_vb, sub_expand_item_idxs[sub_expand_idx]); - - // rjf: form split: truncate & complete last block; begin next block - last_vb = ev_block_split_and_continue(arena, out, last_vb, sub_expand_item_idxs[sub_expand_idx]); - - // rjf: build child view rules - EV_ViewRuleList *child_view_rules = ev_view_rule_list_from_inheritance(arena, view_rules); - { - String8 view_rule_string = ev_view_rule_from_key(view, sub_expand_keys[sub_expand_idx]); - if(view_rule_string.size != 0) - { - ev_view_rule_list_push_string(arena, child_view_rules, view_rule_string); - } - } - - // rjf: recurse for child - ev_append_expr_blocks__rec(arena, view, str8_zero(), key, sub_expand_keys[sub_expand_idx], str8_zero(), child_expr, child_view_rules, depth, out); - } - ev_block_end(out, last_vb); + // rjf: recurse for child + ev_append_expr_blocks__rec(arena, view, str8_zero(), key, sub_expand_keys[sub_expand_idx], str8_zero(), child_expr, child_view_rules, depth, out); } - scratch_end(scratch); + ev_block_end(out, last_vb); } - + scratch_end(scratch); } internal EV_View * @@ -10643,10 +10654,18 @@ rd_frame(void) } e_select_parse_ctx(parse_ctx); + //////////////////////////// + //- rjf: create names/type-info for debugger collections + // + E_TypeKey collection_type_keys[ArrayCount(rd_collection_name_table)] = {0}; + for EachElement(idx, rd_collection_name_table) + { + collection_type_keys[idx] = e_type_key_cons(.kind = E_TypeKind_Collection, .name = rd_collection_name_table[idx]); + } + //////////////////////////// //- rjf: build eval IR context // - E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Collection, .name = str8_lit("collection")); E_TypeKey meta_eval_type_key = e_type_key_cons_base(type(CTRL_MetaEval)); E_IRCtx *ir_ctx = push_array(scratch.arena, E_IRCtx, 1); { @@ -10656,28 +10675,13 @@ rd_frame(void) //- rjf: add macros for collections { - String8 collection_names[] = - { - str8_lit_comp("watches"), - str8_lit_comp("targets"), - str8_lit_comp("breakpoints"), - str8_lit_comp("watch_pins"), - str8_lit_comp("threads"), - str8_lit_comp("modules"), - str8_lit_comp("locals"), - str8_lit_comp("registers"), - str8_lit_comp("globals"), - str8_lit_comp("thread_locals"), - str8_lit_comp("types"), - str8_lit_comp("procedures"), - }; - for EachElement(idx, collection_names) + for EachElement(idx, rd_collection_name_table) { E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); expr->space = e_space_make(RD_EvalSpaceKind_MetaCollection); expr->mode = E_Mode_Null; - expr->type_key = collection_type_key; - e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_names[idx], expr); + expr->type_key = collection_type_keys[idx]; + e_string2expr_map_insert(scratch.arena, ctx->macro_map, rd_collection_name_table[idx], expr); } } @@ -10785,16 +10789,17 @@ rd_frame(void) { ev_view_rule_info_table_push_builtins(scratch.arena, view_rule_info_table); - // rjf: collection view rule + // rjf: collection view rules + for EachElement(idx, rd_collection_name_table) { EV_ViewRuleInfo info = {0}; - info.string = str8_lit("collection"); + info.string = rd_collection_name_table[idx]; info.flags = EV_ViewRuleInfoFlag_Expandable; - info.block_prod = EV_VIEW_RULE_BLOCK_PROD_FUNCTION_NAME(rd_collection_block_prod); + info.block_prod = rd_collection_block_prod_hook_function_table[idx]; ev_view_rule_info_table_push(scratch.arena, view_rule_info_table, &info); } - // rjf: raddbg-layer view rules + // rjf: visualizer view rules for EachEnumVal(RD_ViewRuleKind, k) { RD_ViewRuleInfo *src_info = &rd_view_rule_kind_info_table[k]; @@ -10816,7 +10821,10 @@ rd_frame(void) EV_AutoViewRuleTable *auto_view_rule_table = push_array(scratch.arena, EV_AutoViewRuleTable, 1); { ev_auto_view_rule_table_push_new(scratch.arena, auto_view_rule_table, e_type_key_cons_base(type(CTRL_MetaEvalFrameArray)), str8_lit("slice")); - ev_auto_view_rule_table_push_new(scratch.arena, auto_view_rule_table, collection_type_key, str8_lit("collection")); + for EachElement(idx, rd_collection_name_table) + { + ev_auto_view_rule_table_push_new(scratch.arena, auto_view_rule_table, collection_type_keys[idx], rd_collection_name_table[idx]); + } } ev_select_auto_view_rule_table(auto_view_rule_table); diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 621d0058..a86e1d7d 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -1155,6 +1155,11 @@ internal RD_Entity *rd_entity_from_ctrl_handle(CTRL_Handle handle); internal RD_Entity *rd_entity_from_ctrl_id(CTRL_MachineID machine_id, U32 id); internal RD_Entity *rd_entity_from_name_and_kind(String8 string, RD_EntityKind kind); +//////////////////////////////// +//~ rjf: Frontend Entity Info Extraction + +internal DR_FancyStringList rd_title_fstrs_from_entity(Arena *arena, RD_Entity *entity, Vec4F32 secondary_color, F32 size); + //////////////////////////////// //~ rjf: Control Entity Info Extraction @@ -1275,7 +1280,7 @@ internal void rd_window_frame(RD_Window *ws); //////////////////////////////// //~ rjf: Eval Visualization -EV_VIEW_RULE_BLOCK_PROD_FUNCTION_DEF(rd_collection_block_prod); +internal void rd_ev_view_rule_block_prod_collection_debug_tables(Arena *arena, RDI_SectionKind target, EV_View *view, String8 filter, EV_Key parent_key, EV_Key key, EV_ExpandNode *expand_node, String8 string, E_Expr *expr, EV_ViewRuleList *view_rules, MD_Node *view_params, S32 depth, struct EV_BlockList *out); internal EV_View *rd_ev_view_from_key(U64 key); internal F32 rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 default_radix, FNT_Tag font, F32 font_size, F32 max_size, S32 depth, E_Eval eval, E_Member *member, EV_ViewRuleList *view_rules, String8List *out); internal String8 rd_value_string_from_eval(Arena *arena, EV_StringFlags flags, U32 default_radix, FNT_Tag font, F32 font_size, F32 max_size, E_Eval eval, E_Member *member, EV_ViewRuleList *view_rules); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index ad389225..13e501d6 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -849,9 +849,10 @@ rd_string_from_eval_viz_row_column(Arena *arena, EV_View *ev, EV_Row *row, RD_Wa case RD_WatchViewColumnKind_Module: { E_Eval eval = e_eval_from_expr(arena, row->expr); + E_Eval value_eval = e_value_eval_from_eval(eval); CTRL_Entity *process = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->process); - CTRL_Entity *module = ctrl_module_from_process_vaddr(process, eval.value.u64); - result = push_str8_copy(arena, module->string); + CTRL_Entity *module = ctrl_module_from_process_vaddr(process, value_eval.value.u64); + result = str8_skip_last_slash(module->string); }break; case RD_WatchViewColumnKind_Member: { @@ -2311,12 +2312,15 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo //////////////////////// //- rjf: canvas block row -> build singular row for "escape hatch" ui // - if(row->block_kind == EV_BlockKind_Canvas) + B32 did_row_build = 0; + if(!did_row_build && row->block_kind == EV_BlockKind_Canvas) UI_Parent(row_box) UI_FocusHot(row_selected ? UI_FocusKind_On : UI_FocusKind_Off) { //- rjf: build ui hook row contents if(ui_view_rule_info != &rd_nil_view_rule_info && ui_view_rule_info->ui != 0) { + did_row_build = 1; + //- rjf: unpack RD_WatchViewPoint pt = {0, row->parent_key, row->key}; RD_View *view = rd_view_from_handle(rd_regs()->view); @@ -2412,10 +2416,53 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo } //////////////////////// - //- rjf: build non-canvas row contents + //- rjf: build button row // - if(row->block_kind != EV_BlockKind_Canvas) UI_Parent(row_box) UI_HeightFill + if(!did_row_build && row->depth == 0 && flags & RD_WatchViewFlag_RootButtons) UI_Parent(row_box) UI_HeightFill UI_FocusHot(row_selected ? UI_FocusKind_On : UI_FocusKind_Off) { + did_row_build = 1; + switch(row_eval.space.kind) + { + default:{did_row_build = 0;}break; + case RD_EvalSpaceKind_MetaEntity: + { + RD_Entity *entity = rd_entity_from_eval_space(row_eval.space); + UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clickable|UI_BoxFlag_DrawHotEffects|UI_BoxFlag_DrawActiveEffects, "###entity_%p", entity); + UI_Parent(box) + { + if(row_is_expandable) UI_PrefWidth(ui_em(2.f, 1.f)) UI_Focus(UI_FocusKind_Off) + { + if(ui_pressed(ui_expanderf(next_row_expanded, "###expand_%p", entity))) + { + next_row_expanded ^= 1; + } + } + DR_FancyStringList fstrs = rd_title_fstrs_from_entity(scratch.arena, entity, rd_rgba_from_theme_color(RD_ThemeColor_TextWeak), ui_top_font_size()); + UI_Box *label = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); + ui_box_equip_display_fancy_strings(label, &fstrs); + } + UI_Signal sig = ui_signal_from_box(box); + if(ui_pressed(sig)) + { + RD_WatchViewPoint cell_pt = {0, row->parent_key, row->key}; + ewv->next_cursor = ewv->next_mark = cell_pt; + pressed = 1; + } + }break; + case RD_EvalSpaceKind_MetaCtrlEntity: + { + + }break; + } + } + + //////////////////////// + //- rjf: build regular row contents in all other cases + // + if(!did_row_build) UI_Parent(row_box) UI_HeightFill + { + did_row_build = 1; + ////////////////////// //- rjf: draw start of cache lines in expansions // @@ -2895,14 +2942,14 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo } } } - - ////////////////////// - //- rjf: commit expansion state changes - // - if(next_row_expanded != row_expanded) - { - ev_key_set_expansion(eval_view, row->parent_key, row->key, next_row_expanded); - } + } + + ////////////////////// + //- rjf: commit expansion state changes + // + if(next_row_expanded != row_expanded) + { + ev_key_set_expansion(eval_view, row->parent_key, row->key, next_row_expanded); } } } @@ -5028,9 +5075,9 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(targets) { rd_watch_view_init(wv); rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Expr, 0.30f, .display_string = str8_lit("Expression")); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Value, 0.70f, .display_string = str8_lit("Value"), .dequote_string = 1, .is_non_code = 1); + rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Value, 0.70f, .display_string = str8_lit("Value")); } - rd_watch_view_build(wv, RD_WatchViewFlag_NoHeader, str8_lit("targets"), str8_lit("collection, only:label exe args working_directory entry_point str"), 0, 10, rect); + rd_watch_view_build(wv, RD_WatchViewFlag_NoHeader|RD_WatchViewFlag_RootButtons, str8_lit("targets"), str8_lit("collection, only:label exe args working_directory entry_point str"), 0, 10, rect); ProfEnd(); } @@ -5799,7 +5846,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(call_stack) rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Value, 0.7f); rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Module, 0.25f, .is_non_code = 1); } - rd_watch_view_build(wv, 0, str8_lit("current_thread.callstack.v"), str8_lit("cast:void**, array:current_thread.callstack.count"), 0, 10, rect); + rd_watch_view_build(wv, 0, str8_lit("current_thread.callstack.v"), str8_lit("array:current_thread.callstack.count"), 0, 10, rect); ProfEnd(); } diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index a00ad2b6..9b1a92bc 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -45,6 +45,7 @@ typedef U32 RD_WatchViewFlags; enum { RD_WatchViewFlag_NoHeader = (1<<0), + RD_WatchViewFlag_RootButtons = (1<<1), }; typedef enum RD_WatchViewColumnKind