From c2ddffd4243c218b5c15d1a30102c0f1d67e8cb4 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 26 Jun 2024 09:21:51 -0700 Subject: [PATCH] set up interaction register push/pops for windows & views; use to implement top-level cursor-breakpoint operations; more convergence with new unified src view path --- src/df/core/df_core.c | 25 ++- src/df/core/df_core.h | 6 +- src/df/gfx/df_gfx.c | 288 +++++++++++++++++++++-------- src/df/gfx/df_gfx.h | 4 + src/df/gfx/df_gfx.mdesk | 4 + src/df/gfx/df_views.c | 65 ++++--- src/df/gfx/df_views.h | 2 - src/df/gfx/generated/df_gfx.meta.c | 24 ++- src/df/gfx/generated/df_gfx.meta.h | 12 +- src/raddbg/raddbg.c | 6 + 10 files changed, 310 insertions(+), 126 deletions(-) diff --git a/src/df/core/df_core.c b/src/df/core/df_core.c index 208c2e48..38445b33 100644 --- a/src/df/core/df_core.c +++ b/src/df/core/df_core.c @@ -6981,7 +6981,8 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt) df_state->dt = dt; df_state->time_in_seconds += dt; df_state->top_interact_regs = &df_state->base_interact_regs; - MemoryZeroStruct(df_state->top_interact_regs); + df_state->top_interact_regs->v.lines = df_line_list_copy(df_frame_arena(), &df_state->top_interact_regs->v.lines); + df_state->top_interact_regs->v.dbgi_key = di_key_copy(df_frame_arena(), &df_state->top_interact_regs->v.dbgi_key); //- rjf: sync with ctrl thread ProfScope("sync with ctrl thread") @@ -8877,6 +8878,10 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt) case DF_CoreCmdKind_TextBreakpoint: { DF_Entity *entity = df_entity_from_handle(params.entity); + if(df_entity_is_nil(entity)) + { + entity = df_entity_from_path(params.file_path, 0); + } if(!df_entity_is_nil(entity)) { S64 line_num = params.text_point.line; @@ -8952,6 +8957,24 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt) } } }break; + case DF_CoreCmdKind_ToggleBreakpointAtCursor: + { + DF_InteractRegs *regs = df_interact_regs(); + DF_Entity *file = df_entity_from_handle(regs->file); + if(file->kind == DF_EntityKind_File && regs->cursor.line != 0) + { + DF_CmdParams p = df_cmd_params_zero(); + p.entity = df_handle_from_entity(file); + p.text_point = regs->cursor; + df_cmd_list_push(arena, cmds, &p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_TextBreakpoint)); + } + else if(regs->vaddr_range.min != 0) + { + DF_CmdParams p = df_cmd_params_zero(); + p.vaddr = regs->vaddr_range.min; + df_cmd_list_push(arena, cmds, &p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_AddressBreakpoint)); + } + }break; //- rjf: watches case DF_CoreCmdKind_ToggleWatchPin: diff --git a/src/df/core/df_core.h b/src/df/core/df_core.h index 5d4df49e..e10c1f38 100644 --- a/src/df/core/df_core.h +++ b/src/df/core/df_core.h @@ -662,6 +662,8 @@ struct DF_InteractRegs DF_Handle window; DF_Handle panel; DF_Handle view; + DF_Handle module; + DF_Handle process; DF_Handle thread; DF_Handle file; TxtPt cursor; @@ -670,8 +672,10 @@ struct DF_InteractRegs U64 inline_unwind_count; U128 text_key; TXT_LangKind lang_kind; + Rng1U64 vaddr_range; + Rng1U64 voff_range; DF_LineList lines; - U64 vaddr; + DI_Key dbgi_key; }; typedef struct DF_InteractRegsNode DF_InteractRegsNode; diff --git a/src/df/gfx/df_gfx.c b/src/df/gfx/df_gfx.c index 5cd0e511..01b634e3 100644 --- a/src/df/gfx/df_gfx.c +++ b/src/df/gfx/df_gfx.c @@ -3413,6 +3413,13 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) } } + ////////////////////////////// + //- rjf: fill window/panel/view interaction registers + // + df_interact_regs()->window = df_handle_from_window(ws); + df_interact_regs()->panel = df_handle_from_panel(ws->focused_panel); + df_interact_regs()->view = ws->focused_panel->selected_tab_view; + ////////////////////////////// //- rjf: process view-level commands on leaf panels // @@ -3429,8 +3436,14 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) DF_View *view = df_selected_tab_from_panel(panel); if(!df_view_is_nil(view)) { + df_push_interact_regs(); DF_ViewCmdFunctionType *do_view_cmds_function = view->spec->info.cmd_hook; do_view_cmds_function(ws, panel, view, cmds); + DF_InteractRegs *view_regs = df_pop_interact_regs(); + if(panel == ws->focused_panel) + { + MemoryCopyStruct(df_interact_regs(), view_regs); + } } } } @@ -3614,76 +3627,101 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) } } - //- rjf: stats & info + ui_divider(ui_em(1.f, 1.f)); + + //- rjf: draw current interaction regs { - //- rjf: draw per-window stats - for(DF_Window *window = df_gfx_state->first_window; window != 0; window = window->next) + DF_InteractRegs *regs = df_interact_regs(); +#define Handle(name) ui_labelf("%s: [0x%I64x, 0x%I64x]", #name, (regs->name).u64[0], (regs->name).u64[1]) + Handle(window); + Handle(panel); + Handle(view); + Handle(module); + Handle(process); + Handle(thread); + Handle(file); +#undef Handle + ui_labelf("cursor: (L:%I64d, C:%I64d)", regs->cursor.line, regs->cursor.column); + ui_labelf("mark: (L:%I64d, C:%I64d)", regs->mark.line, regs->mark.column); + ui_labelf("unwind_count: %I64u", regs->unwind_count); + ui_labelf("inline_unwind_count: %I64u", regs->inline_unwind_count); + ui_labelf("text_key: [0x%I64x, 0x%I64x]", regs->text_key.u64[0], regs->text_key.u64[1]); + ui_labelf("lang_kind: '%S'", txt_extension_from_lang_kind(regs->lang_kind)); + ui_labelf("vaddr_range: [0x%I64x, 0x%I64x)", regs->vaddr_range.min, regs->vaddr_range.max); + ui_labelf("voff_range: [0x%I64x, 0x%I64x)", regs->voff_range.min, regs->voff_range.max); + } + + ui_divider(ui_em(1.f, 1.f)); + + //- rjf: draw per-window stats + for(DF_Window *window = df_gfx_state->first_window; window != 0; window = window->next) + { + // rjf: calc ui hash chain length + F64 avg_ui_hash_chain_length = 0; { - // rjf: calc ui hash chain length - F64 avg_ui_hash_chain_length = 0; + F64 chain_count = 0; + F64 chain_length_sum = 0; + for(U64 idx = 0; idx < ws->ui->box_table_size; idx += 1) { - F64 chain_count = 0; - F64 chain_length_sum = 0; - for(U64 idx = 0; idx < ws->ui->box_table_size; idx += 1) + F64 chain_length = 0; + for(UI_Box *b = ws->ui->box_table[idx].hash_first; !ui_box_is_nil(b); b = b->hash_next) { - F64 chain_length = 0; - for(UI_Box *b = ws->ui->box_table[idx].hash_first; !ui_box_is_nil(b); b = b->hash_next) - { - chain_length += 1; - } - if(chain_length > 0) - { - chain_length_sum += chain_length; - chain_count += 1; - } + chain_length += 1; + } + if(chain_length > 0) + { + chain_length_sum += chain_length; + chain_count += 1; } - avg_ui_hash_chain_length = chain_length_sum / chain_count; } - ui_labelf("Target Hz: %.2f", 1.f/df_dt()); - ui_labelf("Ctrl Run Index: %I64u", ctrl_run_gen()); - ui_labelf("Ctrl Mem Gen Index: %I64u", ctrl_mem_gen()); - ui_labelf("Window %p", window); - ui_set_next_pref_width(ui_children_sum(1)); - ui_set_next_pref_height(ui_children_sum(1)); - UI_Row + avg_ui_hash_chain_length = chain_length_sum / chain_count; + } + ui_labelf("Target Hz: %.2f", 1.f/df_dt()); + ui_labelf("Ctrl Run Index: %I64u", ctrl_run_gen()); + ui_labelf("Ctrl Mem Gen Index: %I64u", ctrl_mem_gen()); + ui_labelf("Window %p", window); + ui_set_next_pref_width(ui_children_sum(1)); + ui_set_next_pref_height(ui_children_sum(1)); + UI_Row + { + ui_spacer(ui_em(2.f, 1.f)); + ui_labelf("Box Count: %I64u", window->ui->last_build_box_count); + } + ui_set_next_pref_width(ui_children_sum(1)); + ui_set_next_pref_height(ui_children_sum(1)); + UI_Row + { + ui_spacer(ui_em(2.f, 1.f)); + ui_labelf("Average UI Hash Chain Length: %f", avg_ui_hash_chain_length); + } + } + + ui_divider(ui_em(1.f, 1.f)); + + //- rjf: draw entity tree + DF_EntityRec rec = {0}; + S32 indent = 0; + UI_PrefWidth(ui_text_dim(10, 1)) ui_labelf("Entity Tree:"); + for(DF_Entity *e = df_entity_root(); !df_entity_is_nil(e); e = rec.next) + { + ui_set_next_pref_width(ui_children_sum(1)); + ui_set_next_pref_height(ui_children_sum(1)); + UI_Row + { + ui_spacer(ui_em(2.f*indent, 1.f)); + if(e->kind == DF_EntityKind_OverrideFileLink) { - ui_spacer(ui_em(2.f, 1.f)); - ui_labelf("Box Count: %I64u", window->ui->last_build_box_count); + DF_Entity *dst = df_entity_from_handle(e->entity_handle); + ui_labelf("[link] %S -> %S", e->name, dst->name); } - ui_set_next_pref_width(ui_children_sum(1)); - ui_set_next_pref_height(ui_children_sum(1)); - UI_Row + else { - ui_spacer(ui_em(2.f, 1.f)); - ui_labelf("Average UI Hash Chain Length: %f", avg_ui_hash_chain_length); + ui_labelf("%S: %S", df_g_entity_kind_display_string_table[e->kind], e->name); } } - - //- rjf: draw entity tree - DF_EntityRec rec = {0}; - S32 indent = 0; - UI_PrefWidth(ui_text_dim(10, 1)) ui_labelf("Entity Tree:"); - for(DF_Entity *e = df_entity_root(); !df_entity_is_nil(e); e = rec.next) - { - ui_set_next_pref_width(ui_children_sum(1)); - ui_set_next_pref_height(ui_children_sum(1)); - UI_Row - { - ui_spacer(ui_em(2.f*indent, 1.f)); - if(e->kind == DF_EntityKind_OverrideFileLink) - { - DF_Entity *dst = df_entity_from_handle(e->entity_handle); - ui_labelf("[link] %S -> %S", e->name, dst->name); - } - else - { - ui_labelf("%S: %S", df_g_entity_kind_display_string_table[e->kind], e->name); - } - } - rec = df_entity_rec_df_pre(e, df_entity_root()); - indent += rec.push_count; - indent -= rec.pop_count; - } + rec = df_entity_rec_df_pre(e, df_entity_root()); + indent += rec.push_count; + indent -= rec.pop_count; } } } @@ -3724,7 +3762,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) os_set_clipboard_text(copy_data); ui_ctx_menu_close(); } - if(range.min.line == range.max.line && ui_clicked(df_icon_buttonf(DF_IconKind_RightArrow, 0, "Move Thread Here"))) + if(range.min.line == range.max.line && ui_clicked(df_icon_buttonf(DF_IconKind_RightArrow, 0, "Set Next Statement"))) { DF_Entity *thread = df_entity_from_handle(ctrl_ctx.thread); U64 new_rip_vaddr = ws->code_ctx_menu_vaddr; @@ -7121,6 +7159,20 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) UI_Focus(panel_is_focused ? UI_FocusKind_Null : UI_FocusKind_Off) UI_WidthFill { + //- rjf: push interaction registers, fill with per-view states + df_push_interact_regs(); + { + DF_View *view = df_selected_tab_from_panel(panel); + DF_Entity *entity = df_entity_from_handle(view->entity); + df_interact_regs()->cursor = view->cursor; + df_interact_regs()->mark = view->mark; + switch(entity->kind) + { + default:{}break; + case DF_EntityKind_File:{df_interact_regs()->file = view->entity;}break; + } + } + //- rjf: build view container UI_Box *view_container_box = &ui_g_nil_box; UI_FixedWidth(dim_2f32(content_rect).x) @@ -7143,6 +7195,13 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) DF_ViewUIFunctionType *build_view_ui_function = view->spec->info.ui_hook; build_view_ui_function(ws, panel, view, content_rect); } + + //- rjf: pop interaction registers; commit if this is the selected view + DF_InteractRegs *view_regs = df_pop_interact_regs(); + if(panel_is_focused) + { + MemoryCopyStruct(df_interact_regs(), view_regs); + } } ////////////////////////// @@ -10278,7 +10337,15 @@ df_entity_tooltips(DF_Entity *entity) String8 explanation = df_stop_explanation_string_icon_from_ctrl_event(scratch.arena, &stop_event, &icon_kind); if(explanation.size != 0) { - UI_PrefWidth(ui_children_sum(1)) UI_Row DF_Palette(DF_PaletteCode_NegativePopButton) + UI_Palette *palette = ui_top_palette(); + if(stop_event.cause == CTRL_EventCause_Error || + stop_event.cause == CTRL_EventCause_InterruptedByException || + stop_event.cause == CTRL_EventCause_InterruptedByTrap || + stop_event.cause == CTRL_EventCause_UserBreakpoint) + { + palette = ui_build_palette(ui_top_palette(), .text = df_rgba_from_theme_color(DF_ThemeColor_TextNegative)); + } + UI_PrefWidth(ui_children_sum(1)) UI_Row UI_Palette(palette) { UI_PrefWidth(ui_em(1.5f, 1.f)) UI_Font(df_font_from_slot(DF_FontSlot_Icons)) @@ -10655,6 +10722,7 @@ internal UI_BOX_CUSTOM_DRAW(df_thread_box_draw_extensions) DF_ThreadBoxDrawExtData *u = (DF_ThreadBoxDrawExtData *)box->custom_draw_user_data; // rjf: draw line before next-to-execute line + if(df_setting_val_from_code(DF_SettingCode_ThreadLines).s32) { R_Rect2DInst *inst = d_rect(r2f32p(box->parent->parent->parent->rect.x0, box->parent->rect.y0 - box->font_size*0.125f, @@ -10679,7 +10747,7 @@ internal UI_BOX_CUSTOM_DRAW(df_thread_box_draw_extensions) } // rjf: draw slight fill on selected thread - if(u->is_selected) + if(u->is_selected && df_setting_val_from_code(DF_SettingCode_ThreadGlow).s32) { Vec4F32 weak_thread_color = u->thread_color; weak_thread_color.w *= 0.3f; @@ -10719,6 +10787,7 @@ internal UI_BOX_CUSTOM_DRAW(df_bp_box_draw_extensions) DF_BreakpointBoxDrawExtData *u = (DF_BreakpointBoxDrawExtData *)box->custom_draw_user_data; // rjf: draw line before next-to-execute line + if(df_setting_val_from_code(DF_SettingCode_BreakpointLines).s32) { R_Rect2DInst *inst = d_rect(r2f32p(box->parent->parent->parent->rect.x0, box->parent->rect.y0 - box->font_size*0.125f, @@ -10730,6 +10799,7 @@ internal UI_BOX_CUSTOM_DRAW(df_bp_box_draw_extensions) } // rjf: draw slight fill + if(df_setting_val_from_code(DF_SettingCode_BreakpointGlow).s32) { Vec4F32 weak_thread_color = u->color; weak_thread_color.w *= 0.3f; @@ -11294,10 +11364,25 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ } } } + + // rjf: empty margin interaction UI_Signal line_margin_sig = ui_signal_from_box(line_margin_box); if(ui_clicked(line_margin_sig)) { - result.clicked_margin_line_num = line_num; + if(!df_entity_is_nil(code_ctx->file)) + { + TxtPt pt = txt_pt(line_num, 1); + DF_CmdParams p = df_cmd_params_from_window(ws); + p.entity = df_handle_from_entity(code_ctx->file); + p.text_point = pt; + df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_TextBreakpoint)); + } + else if(params->line_vaddrs[line_idx] != 0) + { + DF_CmdParams p = df_cmd_params_from_window(ws); + p.vaddr = params->line_vaddrs[line_idx]; + df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_AddressBreakpoint)); + } } } } @@ -11681,17 +11766,60 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ } //- rjf: drop target is dropped -> process - // TODO(rjf): @src_collapse -#if 0 { DF_DragDropPayload payload = {0}; - if(!df_entity_is_nil(line_drag_entity) && df_drag_drop(&payload)) + if(!df_entity_is_nil(line_drag_entity) && df_drag_drop(&payload) && contains_1s64(params->line_num_range, mouse_pt.line)) { - result.dropped_entity = line_drag_entity; - result.dropped_entity_line_num = mouse_pt.line; + DF_Entity *dropped_entity = line_drag_entity; + S64 line_num = mouse_pt.line; + U64 line_idx = line_num - params->line_num_range.min; + U64 line_vaddr = params->line_vaddrs[line_idx]; + switch(dropped_entity->kind) + { + default:{}break; + case DF_EntityKind_Breakpoint: + case DF_EntityKind_WatchPin: + { + if(!df_entity_is_nil(code_ctx->file)) + { + df_entity_change_parent(0, dropped_entity, dropped_entity->parent, code_ctx->file); + df_entity_equip_txt_pt(dropped_entity, txt_pt(line_num, 1)); + if(dropped_entity->flags & DF_EntityFlag_HasVAddr) + { + dropped_entity->flags &= ~DF_EntityFlag_HasVAddr; + } + } + else if(line_vaddr != 0) + { + df_entity_change_parent(0, dropped_entity, dropped_entity->parent, df_entity_root()); + df_entity_equip_vaddr(dropped_entity, line_vaddr); + } + }break; + case DF_EntityKind_Thread: + { + U64 new_rip_vaddr = line_vaddr; + if(!df_entity_is_nil(code_ctx->file)) + { + DF_LineList *lines = ¶ms->line_infos[line_idx]; + for(DF_LineNode *n = lines->first; n != 0; n = n->next) + { + DF_EntityList modules = df_modules_from_dbgi_key(scratch.arena, &n->v.dbgi_key); + DF_Entity *module = df_module_from_thread_candidates(dropped_entity, &modules); + if(!df_entity_is_nil(module)) + { + new_rip_vaddr = df_vaddr_from_voff(module, n->v.voff_range.min); + break; + } + } + } + DF_CmdParams p = df_cmd_params_from_window(ws); + p.entity = df_handle_from_entity(dropped_entity); + p.vaddr = new_rip_vaddr; + df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_SetThreadIP)); + }break; + } } } -#endif //- rjf: commit text container signal to main output result.base = text_container_sig; @@ -11702,6 +11830,7 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ // TxtRng mouse_expr_rng = {0}; Vec2F32 mouse_expr_baseline_pos = {0}; + String8 mouse_expr = {0}; if(ui_hovering(text_container_sig) && contains_1s64(params->line_num_range, mouse_pt.line)) ProfScope("mouse -> expression range") { TxtRng selected_rng = txt_rng(*cursor, *mark); @@ -11715,6 +11844,7 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ result.mouse_expr_rng = mouse_expr_rng = selected_rng; result.mouse_expr_baseline_pos = mouse_expr_baseline_pos = v2f32(text_container_box->rect.x0+expr_hoff_px, text_container_box->rect.y0+line_slice_idx*params->line_height_px + params->line_height_px*0.85f); + mouse_expr = str8_substr(line_text, r1u64(selected_rng.min.column-1, selected_rng.max.column-1)); } else { @@ -11723,13 +11853,14 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ TXT_TokenArray line_tokens = params->line_tokens[line_slice_idx]; Rng1U64 line_range = params->line_ranges[line_slice_idx]; U64 mouse_pt_off = line_range.min + (mouse_pt.column-1); - Rng1U64 expr_off_rng = txti_expr_range_from_line_off_range_string_tokens(mouse_pt_off, line_range, line_text, &line_tokens); + Rng1U64 expr_off_rng = txt_expr_off_range_from_line_off_range_string_tokens(mouse_pt_off, line_range, line_text, &line_tokens); if(expr_off_rng.max != expr_off_rng.min) { F32 expr_hoff_px = params->line_num_width_px + f_dim_from_tag_size_string(params->font, params->font_size, 0, params->tab_size, str8_prefix(line_text, expr_off_rng.min-line_range.min)).x; result.mouse_expr_rng = mouse_expr_rng = txt_rng(txt_pt(mouse_pt.line, 1+(expr_off_rng.min-line_range.min)), txt_pt(mouse_pt.line, 1+(expr_off_rng.max-line_range.min))); result.mouse_expr_baseline_pos = mouse_expr_baseline_pos = v2f32(text_container_box->rect.x0+expr_hoff_px, text_container_box->rect.y0+line_slice_idx*params->line_height_px + params->line_height_px*0.85f); + mouse_expr = str8_substr(line_text, r1u64(expr_off_rng.min-line_range.min, expr_off_rng.max-line_range.min)); } } } @@ -11756,21 +11887,16 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ ////////////////////////////// //- rjf: hover eval // -#if 0 - if(!ui_dragging(text_container_sig) && sig.mouse_expr_rng.min.line != 0 && sig.base.event_flags == 0) + if(!ui_dragging(text_container_sig) && text_container_sig.event_flags == 0 && mouse_expr.size != 0) { - TxtRng expr_rng = mouse_expr_rng; - String8 expr = txt_string_from_info_data_txt_rng(&text_info, data, expr_rng); - if(expr.size != 0) + DI_Scope *di_scope = di_scope_open(); + DF_Eval eval = df_eval_from_string(scratch.arena, di_scope, ctrl_ctx, parse_ctx, &eval_string2expr_map_nil, mouse_expr); + if(eval.mode != EVAL_EvalMode_NULL) { - DF_Eval eval = df_eval_from_string(scratch.arena, di_scope, &ctrl_ctx, &parse_ctx, &eval_string2expr_map_nil, expr); - if(eval.mode != EVAL_EvalMode_NULL) - { - df_set_hover_eval(ws, mouse_expr_baseline_pos, ctrl_ctx, entity, sig.mouse_pt, 0, expr); - } + df_set_hover_eval(ws, mouse_expr_baseline_pos, *ctrl_ctx, code_ctx->file, mouse_pt, 0, mouse_expr); } + di_scope_close(di_scope); } -#endif ////////////////////////////// //- rjf: dragging entity which applies to lines over this slice -> visualize diff --git a/src/df/gfx/df_gfx.h b/src/df/gfx/df_gfx.h index afe3e7ab..5eb09b77 100644 --- a/src/df/gfx/df_gfx.h +++ b/src/df/gfx/df_gfx.h @@ -199,6 +199,8 @@ struct DF_View // rjf: view state UI_ScrollPt2 scroll_pos; + TxtPt cursor; + TxtPt mark; // rjf: ctrl context overrides DF_CtrlCtx ctrl_ctx_overrides; @@ -836,6 +838,8 @@ read_only global DF_View df_g_nil_view = 0, {0}, {0}, + {0}, + {0}, 0, 0, 0, diff --git a/src/df/gfx/df_gfx.mdesk b/src/df/gfx/df_gfx.mdesk index b86819b8..6c6814b5 100644 --- a/src/df/gfx/df_gfx.mdesk +++ b/src/df/gfx/df_gfx.mdesk @@ -625,6 +625,10 @@ DF_SettingTable: {MenuAnimations menu_animations "Menu Animations" 1 0 1 } {ScrollingAnimations scrolling_animations "Scrolling Animations" 1 0 1 } {BackgroundBlur background_blur "Background Blur" 1 0 1 } + {ThreadLines thread_lines "Thread Lines" 1 0 1 } + {BreakpointLines breakpoint_lines "Breakpoint Lines" 1 0 1 } + {ThreadGlow thread_glow "Thread Glow" 1 0 1 } + {BreakpointGlow breakpoint_glow "Breakpoint Glow" 1 0 1 } {OpaqueBackgrounds opaque_backgrounds "Opaque Backgrounds" 0 0 1 } {TabWidth tab_width "Tab Width" 4 0 32 } } diff --git a/src/df/gfx/df_views.c b/src/df/gfx/df_views.c index 2a7d9eaf..3bc78c32 100644 --- a/src/df/gfx/df_views.c +++ b/src/df/gfx/df_views.c @@ -378,9 +378,9 @@ df_code_view_init(DF_CodeViewState *cv, DF_View *view) if(cv->initialized == 0) { cv->initialized = 1; - cv->cursor = cv->mark = txt_pt(1, 1); cv->preferred_column = 1; cv->find_text_arena = df_view_push_arena_ext(view); + view->cursor = view->mark = txt_pt(1, 1); } df_view_equip_loading_info(view, 1, 0, 0); view->loading_t = view->loading_t_target = 1.f; @@ -436,10 +436,10 @@ df_code_view_cmds(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_CodeViewStat // rjf: determine expression range Rng1U64 expr_range = {0}; { - TxtRng selection_range = txt_rng(cv->cursor, cv->mark); + TxtRng selection_range = txt_rng(view->cursor, view->mark); if(txt_pt_match(selection_range.min, selection_range.max)) { - expr_range = txt_expr_off_range_from_info_data_pt(info, data, cv->cursor); + expr_range = txt_expr_off_range_from_info_data_pt(info, data, view->cursor); } else { @@ -469,10 +469,10 @@ df_code_view_cmds(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_CodeViewStat // rjf: determine expression range Rng1U64 expr_range = {0}; { - TxtRng selection_range = txt_rng(cv->cursor, cv->mark); + TxtRng selection_range = txt_rng(view->cursor, view->mark); if(txt_pt_match(selection_range.min, selection_range.max)) { - expr_range = txt_expr_off_range_from_info_data_pt(info, data, cv->cursor); + expr_range = txt_expr_off_range_from_info_data_pt(info, data, view->cursor); } else { @@ -730,7 +730,7 @@ df_code_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_CodeViewSta Temp scratch = scratch_begin(0, 0); B32 found = 0; B32 first = 1; - S64 line_num_start = cv->cursor.line; + S64 line_num_start = view->cursor.line; S64 line_num_last = (S64)info->lines_count; for(S64 line_num = line_num_start;; first = 0) { @@ -740,18 +740,18 @@ df_code_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_CodeViewSta // rjf: gather line info String8 line_string = str8_substr(data, info->lines_ranges[line_num-1]); U64 search_start = 0; - if(cv->cursor.line == line_num && first) + if(view->cursor.line == line_num && first) { - search_start = cv->cursor.column; + search_start = view->cursor.column; } // rjf: search string U64 needle_pos = str8_find_needle(line_string, search_start, cv->find_text_fwd, StringMatchFlag_CaseInsensitive); if(needle_pos < line_string.size) { - cv->cursor.line = line_num; - cv->cursor.column = needle_pos+1; - cv->mark = cv->cursor; + view->cursor.line = line_num; + view->cursor.column = needle_pos+1; + view->mark = view->cursor; found = 1; break; } @@ -786,7 +786,7 @@ df_code_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_CodeViewSta Temp scratch = scratch_begin(0, 0); B32 found = 0; B32 first = 1; - S64 line_num_start = cv->cursor.line; + S64 line_num_start = view->cursor.line; S64 line_num_last = (S64)info->lines_count; for(S64 line_num = line_num_start;; first = 0) { @@ -795,9 +795,9 @@ df_code_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_CodeViewSta // rjf: gather line info String8 line_string = str8_substr(data, info->lines_ranges[line_num-1]); - if(cv->cursor.line == line_num && first) + if(view->cursor.line == line_num && first) { - line_string = str8_prefix(line_string, cv->cursor.column-1); + line_string = str8_prefix(line_string, view->cursor.column-1); } // rjf: search string @@ -813,9 +813,9 @@ df_code_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_CodeViewSta } if(next_needle_pos < line_string.size) { - cv->cursor.line = line_num; - cv->cursor.column = next_needle_pos+1; - cv->mark = cv->cursor; + view->cursor.line = line_num; + view->cursor.column = next_needle_pos+1; + view->mark = view->cursor; found = 1; break; } @@ -857,7 +857,7 @@ df_code_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_CodeViewSta S64 line_num = cv->goto_line_num; cv->goto_line_num = 0; line_num = Clamp(1, line_num, info->lines_count); - cv->cursor = cv->mark = txt_pt(line_num, 1); + view->cursor = view->mark = txt_pt(line_num, 1); cv->center_cursor = !cv->contain_cursor || (line_num < target_visible_line_num_range.min+4 || target_visible_line_num_range.max-4 < line_num); } @@ -869,7 +869,7 @@ df_code_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_CodeViewSta { if(ui_is_focus_active() && visible_line_num_range.max >= visible_line_num_range.min) { - snap[Axis2_X] = snap[Axis2_Y] = df_do_txt_controls(info, data, ClampBot(num_possible_visible_lines, 10) - 10, &cv->cursor, &cv->mark, &cv->preferred_column); + snap[Axis2_X] = snap[Axis2_Y] = df_do_txt_controls(info, data, ClampBot(num_possible_visible_lines, 10) - 10, &view->cursor, &view->mark, &cv->preferred_column); } } @@ -886,7 +886,7 @@ df_code_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_CodeViewSta DF_CodeSliceSignal sig = {0}; UI_Focus(UI_FocusKind_On) { - sig = df_code_slicef(ws, &ctrl_ctx, &parse_ctx, code_ctx, &code_slice_params, &cv->cursor, &cv->mark, &cv->preferred_column, "txt_view_%p", view); + sig = df_code_slicef(ws, &ctrl_ctx, &parse_ctx, code_ctx, &code_slice_params, &view->cursor, &view->mark, &cv->preferred_column, "txt_view_%p", view); } //- rjf: press code slice? -> focus panel @@ -920,9 +920,9 @@ df_code_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_CodeViewSta } //- rjf: selected text on single line, no query? -> set search text - if(!txt_pt_match(cv->cursor, cv->mark) && cv->cursor.line == cv->mark.line && search_query.size == 0) + if(!txt_pt_match(view->cursor, view->mark) && view->cursor.line == view->mark.line && search_query.size == 0) { - String8 text = txt_string_from_info_data_txt_rng(info, data, txt_rng(cv->cursor, cv->mark)); + String8 text = txt_string_from_info_data_txt_rng(info, data, txt_rng(view->cursor, view->mark)); df_set_search_string(text); } @@ -977,8 +977,8 @@ df_code_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_CodeViewSta if(cv->center_cursor) { cv->center_cursor = 0; - String8 cursor_line = str8_substr(data, info->lines_ranges[cv->cursor.line-1]); - F32 cursor_advance = f_dim_from_tag_size_string(code_font, code_font_size, 0, code_tab_size, str8_prefix(cursor_line, cv->cursor.column-1)).x; + String8 cursor_line = str8_substr(data, info->lines_ranges[view->cursor.line-1]); + F32 cursor_advance = f_dim_from_tag_size_string(code_font, code_font_size, 0, code_tab_size, str8_prefix(cursor_line, view->cursor.column-1)).x; // rjf: scroll x { @@ -990,7 +990,7 @@ df_code_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_CodeViewSta // rjf: scroll y { - S64 new_idx = (cv->cursor.line-1) - num_possible_visible_lines/2 + 2; + S64 new_idx = (view->cursor.line-1) - num_possible_visible_lines/2 + 2; new_idx = Clamp(scroll_idx_rng[Axis2_Y].min, new_idx, scroll_idx_rng[Axis2_Y].max); ui_scroll_pt_target_idx(&view->scroll_pos.y, new_idx); snap[Axis2_Y] = 0; @@ -1000,8 +1000,8 @@ df_code_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_CodeViewSta // rjf: snap in X if(snap[Axis2_X]) { - String8 cursor_line = str8_substr(data, info->lines_ranges[cv->cursor.line-1]); - S64 cursor_off = (S64)(f_dim_from_tag_size_string(code_font, code_font_size, 0, code_tab_size, str8_prefix(cursor_line, cv->cursor.column-1)).x + priority_margin_width_px + catchall_margin_width_px + line_num_width_px); + String8 cursor_line = str8_substr(data, info->lines_ranges[view->cursor.line-1]); + S64 cursor_off = (S64)(f_dim_from_tag_size_string(code_font, code_font_size, 0, code_tab_size, str8_prefix(cursor_line, view->cursor.column-1)).x + priority_margin_width_px + catchall_margin_width_px + line_num_width_px); Rng1S64 visible_pixel_range = { view->scroll_pos.x.idx, @@ -1022,7 +1022,7 @@ df_code_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_CodeViewSta // rjf: snap in Y if(snap[Axis2_Y]) { - Rng1S64 cursor_visibility_range = r1s64(cv->cursor.line-4, cv->cursor.line+4); + Rng1S64 cursor_visibility_range = r1s64(view->cursor.line-4, view->cursor.line+4); cursor_visibility_range.min = ClampBot(0, cursor_visibility_range.min); cursor_visibility_range.max = ClampBot(0, cursor_visibility_range.max); S64 min_delta = Min(0, cursor_visibility_range.min-(target_visible_line_num_range.min)); @@ -6282,8 +6282,8 @@ DF_VIEW_SETUP_FUNCTION_DEF(Code) cursor.column = s64_from_str8(cursor_cfg->first->first->string, 10); if(cursor.line == 0) { cursor.line = 1; } if(cursor.column == 0) { cursor.column = 1; } - cv->cursor = cv->mark = cursor; cv->center_cursor = 1; + view->cursor = view->mark = cursor; } // rjf: default to loading @@ -6293,8 +6293,7 @@ DF_VIEW_SETUP_FUNCTION_DEF(Code) DF_VIEW_STRING_FROM_STATE_FUNCTION_DEF(Code) { - DF_CodeViewState *tvs = df_view_user_state(view, DF_CodeViewState); - String8 string = push_str8f(arena, " cursor:%I64d:%I64d", tvs->cursor.line, tvs->cursor.column); + String8 string = push_str8f(arena, " cursor:%I64d:%I64d", view->cursor.line, view->cursor.column); return string; } @@ -6438,7 +6437,7 @@ DF_VIEW_UI_FUNCTION_DEF(Code) { ui_label(path); ui_spacer(ui_em(1.5f, 1)); - ui_labelf("Line: %I64d, Column: %I64d", cv->cursor.line, cv->cursor.column); + ui_labelf("Line: %I64d, Column: %I64d", view->cursor.line, view->cursor.column); ui_spacer(ui_pct(1, 0)); ui_labelf("(read only)"); ui_labelf("%s", @@ -8648,7 +8647,7 @@ DF_VIEW_UI_FUNCTION_DEF(Output) { ui_labelf("(Debug String Output)"); ui_spacer(ui_em(1.5f, 1)); - ui_labelf("Line: %I64d, Column: %I64d", cv->cursor.line, cv->cursor.column); + ui_labelf("Line: %I64d, Column: %I64d", view->cursor.line, view->cursor.column); ui_spacer(ui_pct(1, 0)); ui_labelf("(read only)"); } diff --git a/src/df/gfx/df_views.h b/src/df/gfx/df_views.h index 90f030a6..65768bad 100644 --- a/src/df/gfx/df_views.h +++ b/src/df/gfx/df_views.h @@ -366,8 +366,6 @@ struct DF_CodeViewState { // rjf: stable state B32 initialized; - TxtPt cursor; - TxtPt mark; S64 preferred_column; B32 drifted_for_search; DF_Handle pick_file_override_target; diff --git a/src/df/gfx/generated/df_gfx.meta.c b/src/df/gfx/generated/df_gfx.meta.c index e32943fc..de598c95 100644 --- a/src/df/gfx/generated/df_gfx.meta.c +++ b/src/df/gfx/generated/df_gfx.meta.c @@ -1201,7 +1201,7 @@ str8_lit_comp("thread_error"), str8_lit_comp("breakpoint"), }; -String8 df_g_setting_code_display_string_table[9] = +String8 df_g_setting_code_display_string_table[13] = { str8_lit_comp("Hover Animations"), str8_lit_comp("Press Animations"), @@ -1210,11 +1210,15 @@ str8_lit_comp("Tooltip Animations"), str8_lit_comp("Menu Animations"), str8_lit_comp("Scrolling Animations"), str8_lit_comp("Background Blur"), +str8_lit_comp("Thread Lines"), +str8_lit_comp("Breakpoint Lines"), +str8_lit_comp("Thread Glow"), +str8_lit_comp("Breakpoint Glow"), str8_lit_comp("Opaque Backgrounds"), str8_lit_comp("Tab Width"), }; -String8 df_g_setting_code_lower_string_table[9] = +String8 df_g_setting_code_lower_string_table[13] = { str8_lit_comp("hover_animations"), str8_lit_comp("press_animations"), @@ -1223,11 +1227,15 @@ str8_lit_comp("tooltip_animations"), str8_lit_comp("menu_animations"), str8_lit_comp("scrolling_animations"), str8_lit_comp("background_blur"), +str8_lit_comp("thread_lines"), +str8_lit_comp("breakpoint_lines"), +str8_lit_comp("thread_glow"), +str8_lit_comp("breakpoint_glow"), str8_lit_comp("opaque_backgrounds"), str8_lit_comp("tab_width"), }; -DF_SettingVal df_g_setting_code_default_val_table[9] = +DF_SettingVal df_g_setting_code_default_val_table[13] = { {1, 1}, {1, 1}, @@ -1236,11 +1244,15 @@ DF_SettingVal df_g_setting_code_default_val_table[9] = {1, 1}, {1, 1}, {1, 1}, +{1, 1}, +{1, 1}, +{1, 1}, +{1, 1}, {1, 0}, {1, 4}, }; -Rng1S32 df_g_setting_code_s32_range_table[9] = +Rng1S32 df_g_setting_code_s32_range_table[13] = { {0, 1}, {0, 1}, @@ -1250,6 +1262,10 @@ Rng1S32 df_g_setting_code_s32_range_table[9] = {0, 1}, {0, 1}, {0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, {0, 32}, }; diff --git a/src/df/gfx/generated/df_gfx.meta.h b/src/df/gfx/generated/df_gfx.meta.h index f0292711..e9b4dd89 100644 --- a/src/df/gfx/generated/df_gfx.meta.h +++ b/src/df/gfx/generated/df_gfx.meta.h @@ -145,6 +145,10 @@ DF_SettingCode_TooltipAnimations, DF_SettingCode_MenuAnimations, DF_SettingCode_ScrollingAnimations, DF_SettingCode_BackgroundBlur, +DF_SettingCode_ThreadLines, +DF_SettingCode_BreakpointLines, +DF_SettingCode_ThreadGlow, +DF_SettingCode_BreakpointGlow, DF_SettingCode_OpaqueBackgrounds, DF_SettingCode_TabWidth, DF_SettingCode_COUNT, @@ -333,10 +337,10 @@ extern Vec4F32 df_g_theme_preset_colors__far_manager[75]; extern Vec4F32* df_g_theme_preset_colors_table[9]; extern String8 df_g_theme_color_display_string_table[75]; extern String8 df_g_theme_color_cfg_string_table[75]; -extern String8 df_g_setting_code_display_string_table[9]; -extern String8 df_g_setting_code_lower_string_table[9]; -extern DF_SettingVal df_g_setting_code_default_val_table[9]; -extern Rng1S32 df_g_setting_code_s32_range_table[9]; +extern String8 df_g_setting_code_display_string_table[13]; +extern String8 df_g_setting_code_lower_string_table[13]; +extern DF_SettingVal df_g_setting_code_default_val_table[13]; +extern Rng1S32 df_g_setting_code_s32_range_table[13]; read_only global U8 df_g_icon_font_bytes__data[] = { 0x00,0x01,0x00,0x00,0x00,0x0f,0x00,0x80,0x00,0x03,0x00,0x70,0x47,0x53,0x55,0x42,0x20,0x8b,0x25,0x7a,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x54,0x4f,0x53,0x2f,0x32,0x56,0x44,0x49,0xa0,0x00,0x00,0x01,0x50,0x00,0x00,0x00,0x60,0x63,0x6d,0x61,0x70,0x2a,0x09,0xe2,0xc2,0x00,0x00,0x01,0xb0,0x00,0x00,0x05,0xec,0x63,0x76,0x74,0x20, diff --git a/src/raddbg/raddbg.c b/src/raddbg/raddbg.c index 2b636d6a..f69d40ed 100644 --- a/src/raddbg/raddbg.c +++ b/src/raddbg/raddbg.c @@ -343,7 +343,13 @@ update_and_render(OS_Handle repaint_window_handle, void *user_data) d_begin_frame(); for(DF_Window *w = df_gfx_state->first_window; w != 0; w = w->next) { + df_push_interact_regs(); df_window_update_and_render(scratch.arena, w, &cmds); + DF_InteractRegs *window_regs = df_pop_interact_regs(); + if(os_window_is_focused(w->os)) + { + MemoryCopyStruct(df_interact_regs(), window_regs); + } } }