diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index a8c5cbb4..3adf1153 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -332,11 +332,11 @@ RD_NameSchemaInfo rd_name_schema_info_table[19] = {str8_lit_comp("memory"), str8_lit_comp("@inherit(tab) x:\n{\n 'size': code_string,\n @default(16) 'num_columns': @range[1, 64] u64,\n @default(1) 'bytes_per_cell': @range[1, 8] u64,\n}\n")}, {str8_lit_comp("bitmap"), str8_lit_comp("@inherit(tab) x:\n{\n @order(0) 'w': u64,\n @order(1) 'h': u64,\n 'fmt': tex2dformat,\n}\n")}, {str8_lit_comp("geo3d"), str8_lit_comp("@inherit(tab) x:\n{\n 'count': code_string,\n 'vtx': code_string,\n 'vtx_size': code_string,\n 'yaw': @range[0, 1] f32,\n 'pitch': @range[-0.5, 0] f32,\n 'zoom': @range[0, 100] f32,\n}\n")}, -{str8_lit_comp("target"), str8_lit_comp("@commands(enable_cfg, launch_and_run, launch_and_step_into, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'environment': query,\n 'debug_subprocesses': bool,\n @no_expand @default(0) 'enabled': bool,\n}\n")}, -{str8_lit_comp("breakpoint"), str8_lit_comp("@commands(enable_cfg, remove_cfg)\n@collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint)\nx:\n{\n 'label': code_string,\n 'condition': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n 'hit_count': u64,\n 'address_range_size': @or(0, 1, 2, 4, 8) u64,\n 'break_on_write': bool,\n 'break_on_read': bool,\n 'break_on_execute': bool,\n @no_expand @default(1) 'enabled': bool,\n}\n")}, -{str8_lit_comp("watch_pin"), str8_lit_comp("@commands(remove_cfg)\n@collection_commands(add_watch_pin)\nx:\n{\n 'expression': code_string,\n 'view_rule': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n}\n")}, -{str8_lit_comp("file_path_map"), str8_lit_comp("@collection_commands(add_file_path_map) @commands(remove_cfg) x:{'source':path, 'dest':path}")}, -{str8_lit_comp("auto_view_rule"), str8_lit_comp("@collection_commands(add_auto_view_rule) @commands(remove_cfg) x:{'type':code_string, 'view_rule':code_string}")}, +{str8_lit_comp("target"), str8_lit_comp("@row_commands(enable_cfg, launch_and_run, launch_and_step_into, remove_cfg)\n@collection_commands(add_target)\nx:\n{\n 'label': code_string,\n 'executable': path,\n 'arguments': string,\n 'working_directory': path,\n 'entry_point': code_string,\n 'stdout_path': path,\n 'stderr_path': path,\n 'stdin_path': path,\n 'environment': query,\n 'debug_subprocesses': bool,\n @no_expand @default(0) 'enabled': bool,\n}\n")}, +{str8_lit_comp("breakpoint"), str8_lit_comp("@row_commands(enable_cfg, remove_cfg)\n@collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint)\nx:\n{\n 'label': code_string,\n 'condition': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n 'hit_count': u64,\n 'address_range_size': @or(0, 1, 2, 4, 8) u64,\n 'break_on_write': bool,\n 'break_on_read': bool,\n 'break_on_execute': bool,\n @no_expand @default(1) 'enabled': bool,\n}\n")}, +{str8_lit_comp("watch_pin"), str8_lit_comp("@row_commands(remove_cfg)\n@collection_commands(add_watch_pin)\nx:\n{\n 'expression': code_string,\n 'view_rule': code_string,\n 'source_location': path_pt,\n 'address_location': code_string,\n}\n")}, +{str8_lit_comp("file_path_map"), str8_lit_comp("@collection_commands(add_file_path_map) @row_commands(remove_cfg) x:{'source':path, 'dest':path}")}, +{str8_lit_comp("auto_view_rule"), str8_lit_comp("@collection_commands(add_auto_view_rule) @row_commands(remove_cfg) x:{'type':code_string, 'view_rule':code_string}")}, {str8_lit_comp("recent_project"), str8_lit_comp("x:{'path':path}")}, {str8_lit_comp("recent_file"), str8_lit_comp("x:{'path':path}")}, {str8_lit_comp("machine"), str8_lit_comp("x:{'label':code_string, @no_expand 'active':bool, 'unattached_processes':query, 'processes':query}")}, diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index f88de859..5af0805d 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -262,7 +262,7 @@ RD_VocabTable: { target, ``` - @commands(enable_cfg, launch_and_run, launch_and_step_into, remove_cfg) + @row_commands(enable_cfg, launch_and_run, launch_and_step_into, remove_cfg) @collection_commands(add_target) x: { @@ -285,7 +285,7 @@ RD_VocabTable: { breakpoint, ``` - @commands(enable_cfg, remove_cfg) + @row_commands(enable_cfg, remove_cfg) @collection_commands(toggle_breakpoint, add_breakpoint, add_address_breakpoint) x: { @@ -307,7 +307,7 @@ RD_VocabTable: { watch_pin, ``` - @commands(remove_cfg) + @row_commands(remove_cfg) @collection_commands(add_watch_pin) x: { @@ -322,13 +322,13 @@ RD_VocabTable: //- rjf: file path maps { file_path_map, - ```@collection_commands(add_file_path_map) @commands(remove_cfg) x:{'source':path, 'dest':path}```, + ```@collection_commands(add_file_path_map) @row_commands(remove_cfg) x:{'source':path, 'dest':path}```, } //- rjf: auto view rules { auto_view_rule, - ```@collection_commands(add_auto_view_rule) @commands(remove_cfg) x:{'type':code_string, 'view_rule':code_string}```, + ```@collection_commands(add_auto_view_rule) @row_commands(remove_cfg) x:{'type':code_string, 'view_rule':code_string}```, } //- rjf: recent projects diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 4c1e8d7b..46baaa77 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2236,6 +2236,23 @@ rd_view_state_from_cfg(RD_Cfg *cfg) return view_state; } +typedef struct RD_WatchRowExtrasDrawData RD_WatchRowExtrasDrawData; +struct RD_WatchRowExtrasDrawData +{ + B32 breaks_from_prev; +}; + +internal UI_BOX_CUSTOM_DRAW(rd_watch_row_extras_custom_draw) +{ + RD_WatchRowExtrasDrawData *draw_data = (RD_WatchRowExtrasDrawData *)user_data; + if(draw_data->breaks_from_prev) DR_ClipScope(intersect_2f32(dr_top_clip(), box->rect)) + { + Vec4F32 shadow_color = ui_color_from_name(str8_lit("drop_shadow")); + R_Rect2DInst *inst = dr_rect(r2f32p(box->rect.x0, box->rect.y0, box->rect.x1, (box->rect.y0+box->rect.y1)/2), shadow_color, 0, 0, 0); + inst->colors[Corner_01] = inst->colors[Corner_11] = v4f32(0, 0, 0, 0); + } +} + internal void rd_view_ui(Rng2F32 rect) { @@ -3946,6 +3963,9 @@ rd_view_ui(Rng2F32 rect) ui_set_next_pref_height(ui_px(row_height_px*row->visual_size, 1.f)); ui_set_next_focus_hot(row_selected ? UI_FocusKind_On : UI_FocusKind_Off); UI_Box *row_box = ui_build_box_from_stringf(row_flags|((!row_node->next)*UI_BoxFlag_DrawSideBottom)|UI_BoxFlag_Clickable, "row_%I64x", row_hash); + RD_WatchRowExtrasDrawData *row_draw_data = push_array(ui_build_arena(), RD_WatchRowExtrasDrawData, 1); + row_draw_data->breaks_from_prev = !row_matches_last_row_topology; + ui_box_equip_custom_draw(row_box, rd_watch_row_extras_custom_draw, row_draw_data); ////////////////////// //- rjf: build row contents diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index 7611a0a2..68201878 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -469,6 +469,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(schema) typedef struct RD_SchemaExpandAccel RD_SchemaExpandAccel; struct RD_SchemaExpandAccel { + String8Array commands; MD_Node **children; U64 children_count; }; @@ -482,6 +483,22 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(schema) // rjf: unpack RD_SchemaIRExt *ext = (RD_SchemaIRExt *)irtree->user_data; + // rjf: gather expansion commands + String8Array commands = {0}; + { + String8List commands_list = {0}; + for(MD_NodePtrNode *n = ext->schemas.first; n != 0; n = n->next) + { + MD_Node *schema = n->v; + MD_Node *tag = md_tag_from_string(schema, str8_lit("expand_commands"), 0); + for MD_EachNode(arg, tag->first) + { + str8_list_push(scratch.arena, &commands_list, arg->string); + } + } + commands = str8_array_from_list(arena, &commands_list); + } + // rjf: gather expansion children typedef struct ExpandChildNode ExpandChildNode; struct ExpandChildNode @@ -523,12 +540,13 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(schema) // rjf: build accelerator for lookups RD_SchemaExpandAccel *accel = push_array(arena, RD_SchemaExpandAccel, 1); + accel->commands = commands; accel->children = children; accel->children_count = child_count; // rjf: fill result result.user_data = accel; - result.expr_count = child_count; + result.expr_count = child_count + commands.count; scratch_end(scratch); } @@ -538,12 +556,25 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(schema) E_TYPE_EXPAND_RANGE_FUNCTION_DEF(schema) { RD_SchemaExpandAccel *accel = (RD_SchemaExpandAccel *)user_data; + Rng1U64 cmds_idx_range = r1u64(0, accel->commands.count); + Rng1U64 chld_idx_range = r1u64(cmds_idx_range.max, cmds_idx_range.max + accel->children_count); U64 out_idx = 0; - for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) + + // rjf: read commands { - if(0 <= idx && idx < accel->children_count) + Rng1U64 read_range = intersect_1u64(idx_range, cmds_idx_range); + for(U64 idx = read_range.min; idx < read_range.max; idx += 1, out_idx += 1) { - MD_Node *child_schema = accel->children[idx]; + exprs_out[out_idx] = e_expr_irext_member_access(arena, expr, irtree, accel->commands.v[idx - cmds_idx_range.min]); + } + } + + // rjf: read children + { + Rng1U64 read_range = intersect_1u64(idx_range, chld_idx_range); + for(U64 idx = read_range.min; idx < read_range.max; idx += 1, out_idx += 1) + { + MD_Node *child_schema = accel->children[idx - chld_idx_range.min]; exprs_out[out_idx] = e_expr_irext_member_access(arena, expr, irtree, child_schema->string); } } diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 01f9afe0..d6fd181d 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1173,7 +1173,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) for(MD_NodePtrNode *n = schemas.first; n != 0; n = n->next) { MD_Node *schema = n->v; - MD_Node *cmds_root = md_tag_from_string(schema, str8_lit("commands"), 0); + MD_Node *cmds_root = md_tag_from_string(schema, str8_lit("row_commands"), 0); for MD_EachNode(cmd, cmds_root->first) { String8 cmd_name = cmd->string;