From 9349ac9e7225b8c81ff7d543467540e4b92b1512 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 24 May 2024 08:20:10 -0700 Subject: [PATCH 01/39] eliminate weird rollback/re-adjust rules for threads hitting int3s - rollback should only ever happen for temporary traps, e.g. user breakpoints or stepping. the fact that the thread shows *after* the trap later is a visualization issue, not a functionality issue --- src/demon/win32/demon_core_win32.c | 36 +----------------------------- src/demon/win32/demon_core_win32.h | 3 --- src/mule/mule_main.cpp | 19 ++++++++++++++++ src/mule/mule_module.cpp | 1 - 4 files changed, 20 insertions(+), 39 deletions(-) diff --git a/src/demon/win32/demon_core_win32.c b/src/demon/win32/demon_core_win32.c index da0984ae..2d39e0fe 100644 --- a/src/demon/win32/demon_core_win32.c +++ b/src/demon/win32/demon_core_win32.c @@ -1544,32 +1544,6 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) } } - ////////////////////////// - //- rjf: if run threads are marked as having reported an explicit trap - // on their last run, shift their RIPs past that trap instruction, so - // that they may continue - // - for(DMN_W32_EntityNode *n = first_run_thread; n != 0; n = n->next) - { - DMN_W32_Entity *thread = n->v; - if(thread->thread.last_run_reported_trap) - { - Temp temp = temp_begin(scratch.arena); - U64 regs_block_size = regs_block_size_from_architecture(thread->arch); - void *regs_block = push_array(temp.arena, U8, regs_block_size); - B32 good = dmn_w32_thread_read_reg_block(thread->arch, thread->handle, regs_block); - U64 pre_rip = regs_rip_from_arch_block(thread->arch, regs_block); - if(good && pre_rip == thread->thread.last_run_reported_trap_pre_rip) - { - regs_arch_block_write_rip(thread->arch, regs_block, thread->thread.last_run_reported_trap_post_rip); - dmn_w32_thread_write_reg_block(thread->arch, thread->handle, regs_block); - } - temp_end(temp); - thread->thread.last_run_reported_trap = 0; - thread->thread.last_run_reported_trap_post_rip = 0; - } - } - ////////////////////////// //- rjf: choose win32 resume code // @@ -2007,7 +1981,7 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) } //- rjf: determine whether to roll back instruction pointer - B32 should_do_rollback = (is_trap); + B32 should_do_rollback = (hit_user_trap); //- rjf: roll back thread's instruction pointer U64 post_trap_rip = 0; @@ -2044,14 +2018,6 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) e->flags = exception->ExceptionFlags; e->instruction_pointer = (U64)exception->ExceptionAddress; - // rjf: explicit trap -> mark this thread as having reported this trap - if(hit_explicit_trap) - { - thread->thread.last_run_reported_trap = 1; - thread->thread.last_run_reported_trap_pre_rip = instruction_pointer; - thread->thread.last_run_reported_trap_post_rip = post_trap_rip; - } - //- rjf: fill according to exception code switch(exception->ExceptionCode) { diff --git a/src/demon/win32/demon_core_win32.h b/src/demon/win32/demon_core_win32.h index 02dd05d1..285f86be 100644 --- a/src/demon/win32/demon_core_win32.h +++ b/src/demon/win32/demon_core_win32.h @@ -118,9 +118,6 @@ struct DMN_W32_Entity U64 thread_local_base; U64 last_name_hash; U64 name_gather_time_us; - B32 last_run_reported_trap; - U64 last_run_reported_trap_pre_rip; - U64 last_run_reported_trap_post_rip; } thread; struct diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index 4b56abf3..a9647a31 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -2280,6 +2280,10 @@ debug_string_tests(void) static void interrupt_stepping_tests(void) { + __debugbreak(); + __debugbreak(); + __debugbreak(); + __debugbreak(); for(int i = 0; i < 1000; i += 1) { if(i == 999) @@ -2297,6 +2301,19 @@ interrupt_stepping_tests(void) int x = 0; } +//////////////////////////////// +//~ rjf: JIT Stepping Tests + +static void +jit_stepping_tests(void) +{ + OutputDebugString("A\n"); + VOID *code = VirtualAlloc(0, 0x1000, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE); + *((uint32_t*)code) = 0xC39090CC; + ((void (__fastcall *)()) code)(); + OutputDebugString("B\n"); +} + //////////////////////////////// // NOTE(allen): Exception Stepping @@ -2592,6 +2609,8 @@ mule_main(int argc, char** argv){ debug_string_tests(); + jit_stepping_tests(); + interrupt_stepping_tests(); exception_stepping_tests(); diff --git a/src/mule/mule_module.cpp b/src/mule/mule_module.cpp index c7dcec7e..6fd7170f 100644 --- a/src/mule/mule_module.cpp +++ b/src/mule/mule_module.cpp @@ -39,5 +39,4 @@ dll_type_eval_tests(void) Basics basics2 = {4, 5, 6, 7}; int x = 0; (void)x; - *(int *)0 = 0; } From f7ad44a0d7870dba80359a30bb54fb97093f51cd Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 24 May 2024 12:16:30 -0700 Subject: [PATCH 02/39] fix new-file query completion --- src/df/gfx/df_views.c | 2 ++ src/raddbg/raddbg.h | 3 +++ 2 files changed, 5 insertions(+) diff --git a/src/df/gfx/df_views.c b/src/df/gfx/df_views.c index 4483019d..dfa997ce 100644 --- a/src/df/gfx/df_views.c +++ b/src/df/gfx/df_views.c @@ -2684,6 +2684,8 @@ DF_VIEW_UI_FUNCTION_DEF(FileSystem) else { DF_CmdParams params = df_cmd_params_from_view(ws, panel, view); + params.file_path = query; + df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_FilePath); df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_CompleteQuery)); } } diff --git a/src/raddbg/raddbg.h b/src/raddbg/raddbg.h index 927e2393..511c8d3a 100644 --- a/src/raddbg/raddbg.h +++ b/src/raddbg/raddbg.h @@ -4,6 +4,9 @@ //////////////////////////////// //~ rjf: Frontend/UI Pass Tasks // +// [ ] display threads at their last exception address, rather than current +// rip, if applicable +// // [ ] editing multiple bindings for commands // [ ] n-row table selection, in watch window & other UIs, multi-selection // ctrl+C From 15a1f81545187b090318edc841eed95d54566eef Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 24 May 2024 12:35:51 -0700 Subject: [PATCH 03/39] profile -> project --- project.4coder | 2 +- src/df/core/df_core.c | 46 +++++++++---------- src/df/core/df_core.h | 4 +- src/df/core/df_core.mdesk | 12 ++--- src/df/core/generated/df_core.meta.c | 66 ++++++++++++++-------------- src/df/core/generated/df_core.meta.h | 8 ++-- src/df/gfx/df_gfx.c | 28 ++++++------ src/df/gfx/df_gfx.mdesk | 18 ++++---- src/df/gfx/generated/df_gfx.meta.c | 12 +++-- src/df/gfx/generated/df_gfx.meta.h | 4 +- src/raddbg/raddbg.h | 2 +- src/raddbg/raddbg_main.cpp | 4 +- 12 files changed, 106 insertions(+), 100 deletions(-) diff --git a/project.4coder b/project.4coder index 4b6edfe2..9f070887 100644 --- a/project.4coder +++ b/project.4coder @@ -65,7 +65,7 @@ commands = }, .rjf_f3 = { - .win = "pushd build && raddbg.exe --user:local_dev.raddbg_user --profile:local_dev.raddbg_profile && popd", + .win = "pushd build && raddbg.exe --user:local_dev.raddbg_user --project:local_dev.raddbg_project && popd", .linux = "", .out = "*compilation*", .footer_panel = true, diff --git a/src/df/core/df_core.c b/src/df/core/df_core.c index ad1de92e..9900ad9d 100644 --- a/src/df/core/df_core.c +++ b/src/df/core/df_core.c @@ -1687,10 +1687,10 @@ df_entity_notify_mutation(DF_Entity *entity) for(DF_Entity *e = entity; !df_entity_is_nil(e); e = e->parent) { DF_EntityKindFlags flags = df_g_entity_kind_flags_table[entity->kind]; - if(e == entity && flags & DF_EntityKindFlag_LeafMutationProfileConfig) + if(e == entity && flags & DF_EntityKindFlag_LeafMutationProjectConfig) { DF_CmdParams p = {0}; - df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_WriteProfileData)); + df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_WriteProjectData)); } if(e == entity && flags & DF_EntityKindFlag_LeafMutationSoftHalt && df_ctrl_targets_running()) { @@ -5937,11 +5937,11 @@ df_cfg_strings_from_core(Arena *arena, String8 root_path, DF_CfgSrc source) DF_Entity *file = df_entity_ancestor_from_kind(pin, DF_EntityKind_File); if(pin->flags & DF_EntityFlag_HasTextPoint && !df_entity_is_nil(file)) { - String8 profile_path = root_path; + String8 project_path = root_path; String8 pin_file_path = df_full_path_from_entity(arena, file); - profile_path = path_normalized_from_string(arena, profile_path); + project_path = path_normalized_from_string(arena, project_path); pin_file_path = path_normalized_from_string(arena, pin_file_path); - String8 srlized_pin_file_path = path_relative_dst_from_absolute_dst_src(arena, pin_file_path, profile_path); + String8 srlized_pin_file_path = path_relative_dst_from_absolute_dst_src(arena, pin_file_path, project_path); str8_list_pushf(arena, &strs, " line: (\"%S\":%I64d)\n", srlized_pin_file_path, pin->text_point.line); } else if(pin->flags & DF_EntityFlag_HasVAddr) @@ -5959,7 +5959,7 @@ df_cfg_strings_from_core(Arena *arena, String8 root_path, DF_CfgSrc source) } //- rjf: write exception code filters - if(source == DF_CfgSrc_Profile) + if(source == DF_CfgSrc_Project) { str8_list_push(arena, &strs, str8_lit("/// exception code filters ////////////////////////////////////////////////////\n")); str8_list_push(arena, &strs, str8_lit("\n")); @@ -5977,7 +5977,7 @@ df_cfg_strings_from_core(Arena *arena, String8 root_path, DF_CfgSrc source) } //- rjf: write control settings - if(source == DF_CfgSrc_Profile) + if(source == DF_CfgSrc_Project) { str8_list_push(arena, &strs, str8_lit("/// control settings //////////////////////////////////////////////////////////\n")); str8_list_push(arena, &strs, str8_lit("\n")); @@ -5987,7 +5987,7 @@ df_cfg_strings_from_core(Arena *arena, String8 root_path, DF_CfgSrc source) //- rjf: write eval view cache #if 0 - if(source == DF_CfgSrc_Profile) + if(source == DF_CfgSrc_Project) { B32 first = 1; for(U64 eval_view_slot_idx = 0; @@ -6529,7 +6529,7 @@ df_core_init(CmdLine *cmdln, DF_StateDeltaHistory *hist) // rjf: unpack command line arguments String8 user_cfg_path = cmd_line_string(cmdln, str8_lit("user")); - String8 profile_cfg_path = cmd_line_string(cmdln, str8_lit("profile")); + String8 project_cfg_path = cmd_line_string(cmdln, str8_lit("project")); { String8 user_program_data_path = os_string_from_system_path(scratch.arena, OS_SystemPath_UserProgramData); String8 user_data_folder = push_str8f(scratch.arena, "%S/%S", user_program_data_path, str8_lit("raddbg")); @@ -6538,14 +6538,14 @@ df_core_init(CmdLine *cmdln, DF_StateDeltaHistory *hist) { user_cfg_path = push_str8f(scratch.arena, "%S/default.raddbg_user", user_data_folder); } - if(profile_cfg_path.size == 0) + if(project_cfg_path.size == 0) { - profile_cfg_path = push_str8f(scratch.arena, "%S/default.raddbg_profile", user_data_folder); + project_cfg_path = push_str8f(scratch.arena, "%S/default.raddbg_project", user_data_folder); } } // rjf: set up config path state - String8 cfg_src_paths[DF_CfgSrc_COUNT] = {user_cfg_path, profile_cfg_path}; + String8 cfg_src_paths[DF_CfgSrc_COUNT] = {user_cfg_path, project_cfg_path}; for(DF_CfgSrc src = (DF_CfgSrc)0; src < DF_CfgSrc_COUNT; src = (DF_CfgSrc)(src+1)) { df_state->cfg_path_arenas[src] = arena_alloc(); @@ -7089,7 +7089,7 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt) { DF_CmdParams params = df_cmd_params_zero(); df_cmd_list_push(arena, cmds, ¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_WriteUserData)); - df_cmd_list_push(arena, cmds, ¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_WriteProfileData)); + df_cmd_list_push(arena, cmds, ¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_WriteProjectData)); df_state->seconds_til_autosave = 5.f; } } @@ -7630,7 +7630,7 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt) //- rjf: config path saving/loading/applying case DF_CoreCmdKind_OpenUser: - case DF_CoreCmdKind_OpenProfile: + case DF_CoreCmdKind_OpenProject: { B32 load_cfg[DF_CfgSrc_COUNT] = {0}; for(DF_CfgSrc src = (DF_CfgSrc)0; src < DF_CfgSrc_COUNT; src = (DF_CfgSrc)(src+1)) @@ -7781,7 +7781,7 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt) //- rjf: loading/applying stateful config changes case DF_CoreCmdKind_ApplyUserData: - case DF_CoreCmdKind_ApplyProfileData: + case DF_CoreCmdKind_ApplyProjectData: { DF_CfgTable *table = df_cfg_table(); @@ -8162,7 +8162,7 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt) //- rjf: writing config changes case DF_CoreCmdKind_WriteUserData: - case DF_CoreCmdKind_WriteProfileData: + case DF_CoreCmdKind_WriteProjectData: { DF_CfgSrc src = DF_CfgSrc_User; for(DF_CfgSrc s = (DF_CfgSrc)0; s < DF_CfgSrc_COUNT; s = (DF_CfgSrc)(s+1)) @@ -8290,7 +8290,7 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt) if(df_entity_is_nil(map)) { map = df_entity_alloc(df_state_delta_history(), df_entity_root(), DF_EntityKind_AutoViewRule); - df_entity_equip_cfg_src(map, DF_CfgSrc_Profile); + df_entity_equip_cfg_src(map, DF_CfgSrc_Project); } DF_Entity *src = df_entity_child_from_kind(map, DF_EntityKind_Source); if(df_entity_is_nil(src)) @@ -8455,7 +8455,7 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt) DF_Entity *bp = df_entity_alloc(df_state_delta_history(), entity, DF_EntityKind_Breakpoint); df_entity_equip_txt_pt(bp, params.text_point); df_entity_equip_b32(bp, 1); - df_entity_equip_cfg_src(bp, DF_CfgSrc_Profile); + df_entity_equip_cfg_src(bp, DF_CfgSrc_Project); } } }break; @@ -8480,7 +8480,7 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt) bp = df_entity_alloc(df_state_delta_history(), df_entity_root(), DF_EntityKind_Breakpoint); df_entity_equip_vaddr(bp, vaddr); df_entity_equip_b32(bp, 1); - df_entity_equip_cfg_src(bp, DF_CfgSrc_Profile); + df_entity_equip_cfg_src(bp, DF_CfgSrc_Project); } else { @@ -8502,7 +8502,7 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt) DF_Entity *symbol_name_entity = df_entity_alloc(df_state_delta_history(), bp, DF_EntityKind_EntryPointName); df_entity_equip_name(df_state_delta_history(), symbol_name_entity, function_name); df_entity_equip_b32(bp, 1); - df_entity_equip_cfg_src(bp, DF_CfgSrc_Profile); + df_entity_equip_cfg_src(bp, DF_CfgSrc_Project); } else { @@ -8536,7 +8536,7 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt) DF_Entity *watch = df_entity_alloc(df_state_delta_history(), entity, DF_EntityKind_WatchPin); df_entity_equip_txt_pt(watch, params.text_point); df_entity_equip_name(df_state_delta_history(), watch, params.string); - df_entity_equip_cfg_src(watch, DF_CfgSrc_Profile); + df_entity_equip_cfg_src(watch, DF_CfgSrc_Project); } } else if(params.vaddr != 0) @@ -8558,7 +8558,7 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt) DF_Entity *pin = df_entity_alloc(df_state_delta_history(), df_entity_root(), DF_EntityKind_WatchPin); df_entity_equip_vaddr(pin, params.vaddr); df_entity_equip_name(df_state_delta_history(), pin, params.string); - df_entity_equip_cfg_src(pin, DF_CfgSrc_Profile); + df_entity_equip_cfg_src(pin, DF_CfgSrc_Project); } } }break; @@ -8569,7 +8569,7 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt) // rjf: build target df_state_delta_history_push_batch(df_state_delta_history(), 0); DF_Entity *entity = df_entity_alloc(df_state_delta_history(), df_entity_root(), DF_EntityKind_Target); - df_entity_equip_cfg_src(entity, DF_CfgSrc_Profile); + df_entity_equip_cfg_src(entity, DF_CfgSrc_Project); DF_Entity *exe = df_entity_alloc(df_state_delta_history(), entity, DF_EntityKind_Executable); df_entity_equip_name(df_state_delta_history(), exe, params.file_path); String8 working_dir = str8_chop_last_slash(params.file_path); diff --git a/src/df/core/df_core.h b/src/df/core/df_core.h index 406e6795..9eeb8fd4 100644 --- a/src/df/core/df_core.h +++ b/src/df/core/df_core.h @@ -87,8 +87,8 @@ enum { DF_EntityKindFlag_LeafMutationUserConfig = (1<<0), DF_EntityKindFlag_TreeMutationUserConfig = (1<<1), - DF_EntityKindFlag_LeafMutationProfileConfig= (1<<2), - DF_EntityKindFlag_TreeMutationProfileConfig= (1<<3), + DF_EntityKindFlag_LeafMutationProjectConfig= (1<<2), + DF_EntityKindFlag_TreeMutationProjectConfig= (1<<3), DF_EntityKindFlag_LeafMutationSoftHalt = (1<<4), DF_EntityKindFlag_TreeMutationSoftHalt = (1<<5), DF_EntityKindFlag_LeafMutationDebugInfoMap = (1<<6), diff --git a/src/df/core/df_core.mdesk b/src/df/core/df_core.mdesk index c879873c..1fd7b6e2 100644 --- a/src/df/core/df_core.mdesk +++ b/src/df/core/df_core.mdesk @@ -8,7 +8,7 @@ DF_CfgSrcTable: { {"user" User OpenUser WriteUserData ApplyUserData } - {"profile" Profile OpenProfile WriteProfileData ApplyProfileData } + {"project" Project OpenProject WriteProjectData ApplyProjectData } {"command_line" CommandLine Null Null Null } {"transient" Transient Null Null Null } } @@ -236,16 +236,16 @@ DF_CoreCmdTable:// | | | {SetAutoViewRuleViewRule 1 Null Nil 0 0 0 0 0 0 Null "set_auto_view_rule_view_rule""Set Auto View Rule View Rule" "Sets the view rule string for an auto view rule." "" } //- rjf: setting config paths - {OpenUser 0 FilePath Nil 1 0 0 0 0 1 Person "open_user" "Open User" "Opens a user file path, immediately loading it, and begins autosaving to it." "load,user,profile,layout" } - {OpenProfile 0 FilePath Nil 1 0 0 0 0 1 Briefcase "open_profile" "Open Profile" "Opens a profile file path, immediately loading it, and begins autosaving to it." "profile,project,session" } + {OpenUser 0 FilePath Nil 1 0 0 0 0 1 Person "open_user" "Open User" "Opens a user file path, immediately loading it, and begins autosaving to it." "load,user,project,layout" } + {OpenProject 0 FilePath Nil 1 0 0 0 0 1 Briefcase "open_project" "Open Project" "Opens a project file path, immediately loading it, and begins autosaving to it." "project,project,session" } //- rjf: loading/applying stateful config changes {ApplyUserData 1 Null Nil 0 0 0 0 0 0 Null "apply_user_data" "Apply User Data" "Applies user data from the active user file." "" } - {ApplyProfileData 1 Null Nil 0 0 0 0 0 0 Null "apply_profile_data" "Apply Profile Data" "Applies profile data from the active profile file." "" } + {ApplyProjectData 1 Null Nil 0 0 0 0 0 0 Null "apply_project_data" "Apply Project Data" "Applies project data from the active project file." "" } //- rjf: writing config changes {WriteUserData 1 Null Nil 0 0 0 0 0 0 Null "write_user_data" "Write User Data" "Writes user data to the active user file." "" } - {WriteProfileData 1 Null Nil 0 0 0 0 0 0 Null "write_profile_data" "Write Profile Data" "Writes profile data to the active profile file." "" } + {WriteProjectData 1 Null Nil 0 0 0 0 0 0 Null "write_project_data" "Write Project Data" "Writes project data to the active project file." "" } //- rjf: meta controls {Edit 0 Null Nil 0 0 0 0 0 0 Pencil "edit" "Edit" "Edits the current selection." "" } @@ -1777,7 +1777,7 @@ DF_DevToggleTable: @data(DF_EntityKindFlags) df_g_entity_kind_flags_table: { - @expand(DF_EntityKindTable a) `($(a.lf_mut_user_cfg)*DF_EntityKindFlag_LeafMutationUserConfig | $(a.lf_mut_prof_cfg)*DF_EntityKindFlag_LeafMutationProfileConfig | $(a.lf_mut_halt)*DF_EntityKindFlag_LeafMutationSoftHalt | $(a.lf_mut_dbg)*DF_EntityKindFlag_LeafMutationDebugInfoMap | $(a.tr_mut_user_cfg)*DF_EntityKindFlag_TreeMutationUserConfig | $(a.tr_mut_prof_cfg)*DF_EntityKindFlag_TreeMutationProfileConfig | $(a.tr_mut_halt)*DF_EntityKindFlag_TreeMutationSoftHalt | $(a.tr_mut_dbg)*DF_EntityKindFlag_TreeMutationDebugInfoMap | $(a.name_is_code)*DF_EntityKindFlag_NameIsCode | $(a.user_lifetime)*DF_EntityKindFlag_UserDefinedLifetime)`, + @expand(DF_EntityKindTable a) `($(a.lf_mut_user_cfg)*DF_EntityKindFlag_LeafMutationUserConfig | $(a.lf_mut_prof_cfg)*DF_EntityKindFlag_LeafMutationProjectConfig | $(a.lf_mut_halt)*DF_EntityKindFlag_LeafMutationSoftHalt | $(a.lf_mut_dbg)*DF_EntityKindFlag_LeafMutationDebugInfoMap | $(a.tr_mut_user_cfg)*DF_EntityKindFlag_TreeMutationUserConfig | $(a.tr_mut_prof_cfg)*DF_EntityKindFlag_TreeMutationProjectConfig | $(a.tr_mut_halt)*DF_EntityKindFlag_TreeMutationSoftHalt | $(a.tr_mut_dbg)*DF_EntityKindFlag_TreeMutationDebugInfoMap | $(a.name_is_code)*DF_EntityKindFlag_NameIsCode | $(a.user_lifetime)*DF_EntityKindFlag_UserDefinedLifetime)`, } @data(DF_EntityOpFlags) df_g_entity_kind_op_flags_table: diff --git a/src/df/core/generated/df_core.meta.c b/src/df/core/generated/df_core.meta.c index c2c5f704..a95e1ac9 100644 --- a/src/df/core/generated/df_core.meta.c +++ b/src/df/core/generated/df_core.meta.c @@ -119,31 +119,31 @@ str8_lit_comp("Label"), DF_EntityKindFlags df_g_entity_kind_flags_table[25] = { -(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime), -(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime), -(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime), -(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime), -(1*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime), -(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 1*DF_EntityKindFlag_UserDefinedLifetime), -(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime), -(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 1*DF_EntityKindFlag_NameIsCode | 1*DF_EntityKindFlag_UserDefinedLifetime), -(0*DF_EntityKindFlag_LeafMutationUserConfig | 1*DF_EntityKindFlag_LeafMutationProfileConfig | 1*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 1*DF_EntityKindFlag_UserDefinedLifetime), -(0*DF_EntityKindFlag_LeafMutationUserConfig | 1*DF_EntityKindFlag_LeafMutationProfileConfig | 1*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 1*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 1*DF_EntityKindFlag_NameIsCode | 1*DF_EntityKindFlag_UserDefinedLifetime), -(0*DF_EntityKindFlag_LeafMutationUserConfig | 1*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 1*DF_EntityKindFlag_UserDefinedLifetime), -(0*DF_EntityKindFlag_LeafMutationUserConfig | 1*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 1*DF_EntityKindFlag_UserDefinedLifetime), -(0*DF_EntityKindFlag_LeafMutationUserConfig | 1*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 1*DF_EntityKindFlag_UserDefinedLifetime), -(0*DF_EntityKindFlag_LeafMutationUserConfig | 1*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 1*DF_EntityKindFlag_UserDefinedLifetime), -(0*DF_EntityKindFlag_LeafMutationUserConfig | 1*DF_EntityKindFlag_LeafMutationProfileConfig | 1*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 1*DF_EntityKindFlag_UserDefinedLifetime), -(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime), -(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime), -(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime), -(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime), -(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime), -(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime), -(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime), -(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime), -(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime), -(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProfileConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProfileConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime), +(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProjectConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProjectConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime), +(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProjectConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProjectConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime), +(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProjectConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProjectConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime), +(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProjectConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProjectConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime), +(1*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProjectConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProjectConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime), +(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProjectConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProjectConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 1*DF_EntityKindFlag_UserDefinedLifetime), +(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProjectConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProjectConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime), +(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProjectConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProjectConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 1*DF_EntityKindFlag_NameIsCode | 1*DF_EntityKindFlag_UserDefinedLifetime), +(0*DF_EntityKindFlag_LeafMutationUserConfig | 1*DF_EntityKindFlag_LeafMutationProjectConfig | 1*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProjectConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 1*DF_EntityKindFlag_UserDefinedLifetime), +(0*DF_EntityKindFlag_LeafMutationUserConfig | 1*DF_EntityKindFlag_LeafMutationProjectConfig | 1*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 1*DF_EntityKindFlag_TreeMutationProjectConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 1*DF_EntityKindFlag_NameIsCode | 1*DF_EntityKindFlag_UserDefinedLifetime), +(0*DF_EntityKindFlag_LeafMutationUserConfig | 1*DF_EntityKindFlag_LeafMutationProjectConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProjectConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 1*DF_EntityKindFlag_UserDefinedLifetime), +(0*DF_EntityKindFlag_LeafMutationUserConfig | 1*DF_EntityKindFlag_LeafMutationProjectConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProjectConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 1*DF_EntityKindFlag_UserDefinedLifetime), +(0*DF_EntityKindFlag_LeafMutationUserConfig | 1*DF_EntityKindFlag_LeafMutationProjectConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProjectConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 1*DF_EntityKindFlag_UserDefinedLifetime), +(0*DF_EntityKindFlag_LeafMutationUserConfig | 1*DF_EntityKindFlag_LeafMutationProjectConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProjectConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 1*DF_EntityKindFlag_UserDefinedLifetime), +(0*DF_EntityKindFlag_LeafMutationUserConfig | 1*DF_EntityKindFlag_LeafMutationProjectConfig | 1*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProjectConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 1*DF_EntityKindFlag_UserDefinedLifetime), +(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProjectConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProjectConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime), +(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProjectConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProjectConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime), +(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProjectConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProjectConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime), +(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProjectConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProjectConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime), +(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProjectConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProjectConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime), +(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProjectConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProjectConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime), +(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProjectConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProjectConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime), +(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProjectConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProjectConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime), +(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProjectConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProjectConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime), +(0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProjectConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProjectConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime), }; DF_EntityOpFlags df_g_entity_kind_op_flags_table[25] = @@ -178,7 +178,7 @@ DF_EntityOpFlags df_g_entity_kind_op_flags_table[25] = String8 df_g_cfg_src_string_table[4] = { str8_lit_comp("user"), -str8_lit_comp("profile"), +str8_lit_comp("project"), str8_lit_comp("command_line"), str8_lit_comp("transient"), }; @@ -186,7 +186,7 @@ str8_lit_comp("transient"), DF_CoreCmdKind df_g_cfg_src_load_cmd_kind_table[4] = { DF_CoreCmdKind_OpenUser, -DF_CoreCmdKind_OpenProfile, +DF_CoreCmdKind_OpenProject, DF_CoreCmdKind_Null, DF_CoreCmdKind_Null, }; @@ -194,7 +194,7 @@ DF_CoreCmdKind_Null, DF_CoreCmdKind df_g_cfg_src_write_cmd_kind_table[4] = { DF_CoreCmdKind_WriteUserData, -DF_CoreCmdKind_WriteProfileData, +DF_CoreCmdKind_WriteProjectData, DF_CoreCmdKind_Null, DF_CoreCmdKind_Null, }; @@ -202,7 +202,7 @@ DF_CoreCmdKind_Null, DF_CoreCmdKind df_g_cfg_src_apply_cmd_kind_table[4] = { DF_CoreCmdKind_ApplyUserData, -DF_CoreCmdKind_ApplyProfileData, +DF_CoreCmdKind_ApplyProjectData, DF_CoreCmdKind_Null, DF_CoreCmdKind_Null, }; @@ -301,12 +301,12 @@ DF_CmdSpecInfo df_g_core_cmd_kind_spec_info_table[220] = { str8_lit_comp("set_file_replacement_path"), str8_lit_comp("Sets the path which should be used as the replacement for the passed file."), str8_lit_comp(""), str8_lit_comp("Set File Replacement Path"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null}, { str8_lit_comp("set_auto_view_rule_type"), str8_lit_comp("Sets the type for an auto view rule."), str8_lit_comp(""), str8_lit_comp("Set Auto View Rule Type"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null}, { str8_lit_comp("set_auto_view_rule_view_rule"), str8_lit_comp("Sets the view rule string for an auto view rule."), str8_lit_comp(""), str8_lit_comp("Set Auto View Rule View Rule"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null}, -{ str8_lit_comp("open_user"), str8_lit_comp("Opens a user file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("load,user,profile,layout"), str8_lit_comp("Open User"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_FilePath, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*1)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_Person}, -{ str8_lit_comp("open_profile"), str8_lit_comp("Opens a profile file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("profile,project,session"), str8_lit_comp("Open Profile"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_FilePath, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*1)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_Briefcase}, +{ str8_lit_comp("open_user"), str8_lit_comp("Opens a user file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("load,user,project,layout"), str8_lit_comp("Open User"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_FilePath, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*1)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_Person}, +{ str8_lit_comp("open_project"), str8_lit_comp("Opens a project file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("project,project,session"), str8_lit_comp("Open Project"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_FilePath, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*1)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_Briefcase}, { str8_lit_comp("apply_user_data"), str8_lit_comp("Applies user data from the active user file."), str8_lit_comp(""), str8_lit_comp("Apply User Data"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null}, -{ str8_lit_comp("apply_profile_data"), str8_lit_comp("Applies profile data from the active profile file."), str8_lit_comp(""), str8_lit_comp("Apply Profile Data"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null}, +{ str8_lit_comp("apply_project_data"), str8_lit_comp("Applies project data from the active project file."), str8_lit_comp(""), str8_lit_comp("Apply Project Data"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null}, { str8_lit_comp("write_user_data"), str8_lit_comp("Writes user data to the active user file."), str8_lit_comp(""), str8_lit_comp("Write User Data"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null}, -{ str8_lit_comp("write_profile_data"), str8_lit_comp("Writes profile data to the active profile file."), str8_lit_comp(""), str8_lit_comp("Write Profile Data"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null}, +{ str8_lit_comp("write_project_data"), str8_lit_comp("Writes project data to the active project file."), str8_lit_comp(""), str8_lit_comp("Write Project Data"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null}, { str8_lit_comp("edit"), str8_lit_comp("Edits the current selection."), str8_lit_comp(""), str8_lit_comp("Edit"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Pencil}, { str8_lit_comp("accept"), str8_lit_comp("Accepts current changes, or answers prompts in the affirmative."), str8_lit_comp(""), str8_lit_comp("Accept"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_CheckFilled}, { str8_lit_comp("cancel"), str8_lit_comp("Rejects current changes, exits temporary menus, or answers prompts in the negative."), str8_lit_comp(""), str8_lit_comp("Cancel"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_X}, diff --git a/src/df/core/generated/df_core.meta.h b/src/df/core/generated/df_core.meta.h index daf1d7b6..f24ccda9 100644 --- a/src/df/core/generated/df_core.meta.h +++ b/src/df/core/generated/df_core.meta.h @@ -9,7 +9,7 @@ typedef enum DF_CfgSrc { DF_CfgSrc_User, -DF_CfgSrc_Profile, +DF_CfgSrc_Project, DF_CfgSrc_CommandLine, DF_CfgSrc_Transient, DF_CfgSrc_COUNT, @@ -140,11 +140,11 @@ DF_CoreCmdKind_SetFileReplacementPath, DF_CoreCmdKind_SetAutoViewRuleType, DF_CoreCmdKind_SetAutoViewRuleViewRule, DF_CoreCmdKind_OpenUser, -DF_CoreCmdKind_OpenProfile, +DF_CoreCmdKind_OpenProject, DF_CoreCmdKind_ApplyUserData, -DF_CoreCmdKind_ApplyProfileData, +DF_CoreCmdKind_ApplyProjectData, DF_CoreCmdKind_WriteUserData, -DF_CoreCmdKind_WriteProfileData, +DF_CoreCmdKind_WriteProjectData, DF_CoreCmdKind_Edit, DF_CoreCmdKind_Accept, DF_CoreCmdKind_Cancel, diff --git a/src/df/gfx/df_gfx.c b/src/df/gfx/df_gfx.c index 6f1ba709..b4c05bdd 100644 --- a/src/df/gfx/df_gfx.c +++ b/src/df/gfx/df_gfx.c @@ -3731,9 +3731,9 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) } // rjf: is command line only? -> make permanent - if(entity->cfg_src == DF_CfgSrc_CommandLine && ui_clicked(df_icon_buttonf(DF_IconKind_Save, 0, "Save To Profile"))) + if(entity->cfg_src == DF_CfgSrc_CommandLine && ui_clicked(df_icon_buttonf(DF_IconKind_Save, 0, "Save To Project"))) { - df_entity_equip_cfg_src(entity, DF_CfgSrc_Profile); + df_entity_equip_cfg_src(entity, DF_CfgSrc_Project); } // rjf: duplicate @@ -4578,7 +4578,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) { DF_CoreCmdKind_Open, DF_CoreCmdKind_OpenUser, - DF_CoreCmdKind_OpenProfile, + DF_CoreCmdKind_OpenProject, DF_CoreCmdKind_Exit, }; U32 codepoints[] = @@ -5249,7 +5249,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) ui_spacer(ui_em(0.75f, 0)); } - // rjf: loaded profile viz + // rjf: loaded project viz if(do_user_prof) { ui_set_next_background_color(df_rgba_from_theme_color(DF_ThemeColor_Highlight0)); @@ -5261,11 +5261,11 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) UI_BoxFlag_DrawBackground| UI_BoxFlag_DrawHotEffects| UI_BoxFlag_DrawActiveEffects, - "###loaded_profile_button"); + "###loaded_project_button"); os_window_push_custom_title_bar_client_area(ws->os, prof_box->rect); UI_Parent(prof_box) UI_PrefWidth(ui_text_dim(10, 0)) UI_TextAlignment(UI_TextAlign_Center) { - String8 prof_path = df_cfg_path_from_src(DF_CfgSrc_Profile); + String8 prof_path = df_cfg_path_from_src(DF_CfgSrc_Project); prof_path = str8_chop_last_dot(prof_path); UI_Font(ui_icon_font()) ui_label(df_g_icon_kind_text_table[DF_IconKind_Briefcase]); ui_label(str8_skip_last_slash(prof_path)); @@ -5274,7 +5274,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) if(ui_clicked(prof_sig)) { DF_CmdParams p = df_cmd_params_from_window(ws); - p.cmd_spec = df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_OpenProfile); + p.cmd_spec = df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_OpenProject); df_cmd_params_mark_slot(&p, DF_CmdParamSlot_CmdSpec); df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_RunCommand)); } @@ -9366,9 +9366,9 @@ df_cfg_strings_from_gfx(Arena *arena, String8 root_path, DF_CfgSrc source) { if(view_entity->kind == DF_EntityKind_File) { - String8 profile_path = root_path; + String8 project_path = root_path; String8 entity_path = df_full_path_from_entity(arena, view_entity); - String8 entity_path_rel = path_relative_dst_from_absolute_dst_src(arena, entity_path, profile_path); + String8 entity_path_rel = path_relative_dst_from_absolute_dst_src(arena, entity_path, project_path); str8_list_pushf(arena, &strs, "\"%S\"", entity_path_rel); } } @@ -10120,7 +10120,7 @@ df_entity_desc_button(DF_Window *ws, DF_Entity *entity, FuzzyMatchRangeList *nam UI_Signal info_sig = ui_signal_from_box(info_box); if(ui_hovering(info_sig)) UI_Tooltip { - ui_labelf("Specified via command line; not saved in profile."); + ui_labelf("Specified via command line; not saved in project."); } } } @@ -12994,7 +12994,7 @@ df_gfx_begin_frame(Arena *arena, DF_CmdList *cmds) { DF_CmdParams params = df_cmd_params_zero(); df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_WriteUserData)); - df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_WriteProfileData)); + df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_WriteProjectData)); df_gfx_state->last_window_queued_save = 1; } @@ -13064,7 +13064,7 @@ df_gfx_begin_frame(Arena *arena, DF_CmdList *cmds) { DF_CmdParams params = df_cmd_params_zero(); df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_WriteUserData)); - df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_WriteProfileData)); + df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_WriteProjectData)); } df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_CloseWindow)); } @@ -13155,7 +13155,7 @@ df_gfx_begin_frame(Arena *arena, DF_CmdList *cmds) //- rjf: loading/applying stateful config changes case DF_CoreCmdKind_ApplyUserData: - case DF_CoreCmdKind_ApplyProfileData: + case DF_CoreCmdKind_ApplyProjectData: { DF_CfgTable *table = df_cfg_table(); OS_HandleArray monitors = os_push_monitors_array(scratch.arena); @@ -13728,7 +13728,7 @@ df_gfx_begin_frame(Arena *arena, DF_CmdList *cmds) //- rjf: writing config changes case DF_CoreCmdKind_WriteUserData: - case DF_CoreCmdKind_WriteProfileData: + case DF_CoreCmdKind_WriteProjectData: { DF_CfgSrc src = DF_CfgSrc_User; for(DF_CfgSrc s = (DF_CfgSrc)0; s < DF_CfgSrc_COUNT; s = (DF_CfgSrc)(s+1)) diff --git a/src/df/gfx/df_gfx.mdesk b/src/df/gfx/df_gfx.mdesk index 3620c593..2ee85fc7 100644 --- a/src/df/gfx/df_gfx.mdesk +++ b/src/df/gfx/df_gfx.mdesk @@ -87,8 +87,8 @@ DF_DefaultBindingTable: { "switch_to_partner_file" O 0 0 alt } //- rjf: setting config paths - { "load_user" O ctrl shift alt } - { "load_profile" O ctrl 0 alt } + { "open_user" O ctrl shift alt } + { "open_project" O ctrl 0 alt } //- rjf: meta controls { "edit" F2 0 0 0 } @@ -182,6 +182,8 @@ DF_BindingVersionRemapTable: {"commands" "run_command"} {"load_user" "open_user"} {"load_profile" "open_profile"} + {"load_project" "open_project"} + {"open_profile" "open_project"} } //////////////////////////////// @@ -654,7 +656,7 @@ raddbg_readme: { @p "`--help` Displays a help menu which documents the possible command line options."; @p "`--user:` Specifies a path to the user file which the debugger should use instead of the default. The default user file is stored at `%appdata%/raddbg/default.raddbg_user`. For more information on user files, read the 'User & Profile Files' section."; - @p "`--profile:` Specifies a path to the profile file which the debugger should use instead of the default. The default profile file is stored at `%appdata%/raddbg/default.raddbg_profile`. For more information on profile files, read the 'User & Profile Files' section."; + @p "`--project:` Specifies a path to the project file which the debugger should use instead of the default. The default project file is stored at `%appdata%/raddbg/default.raddbg_project`. For more information on project files, read the 'User & Project Files' section."; @p "`--auto_run` Specifies that the debugger should immediately run its selected targets upon launching."; @p "`--auto_step` Specifies that the debugger should immediately step into its selected targets upon launching."; //@p "`--ipc` Specifies that the launched debugger instance is for communicating a command to another instance of the debugger. In this mode, any non-argument command line contents will be used to express a command. For more information on commands, read the 'Commands' section. For more information on driving another debugger instance with this argument, read the 'Driving Another Debugger Instance' section." @@ -693,7 +695,7 @@ raddbg_readme: @subtitle "Targets"; @p "A *target* is one executable and configuration for launching that executable, including command line arguments and working directory (the directory from which the executable is launched). Each target may also have a custom label (replaces the executable path when visualizing the target), and the name of a custom entry point function (when the default entry points - `main`, `WinMain`, etc. - are not desired when stepping into the program upon launch). The debugger can have several targets at once. Each target can also be enabled or disabled. Some operations work on all enabled targets - for instance, the `Run` or `Kill All` commands (standardly bound as F5 or Shift + F5). Enabling and disabling targets allows one to filter which targets are currently being worked with."; @p "To add a target, you can run the `Add Target` command. A target is also created automatically from command line arguments - the rules for how this happens can be found in the `Command-Line Usage` section."; - @p "Targets created through command line usage are temporary, meaning they are not persistently saved across runs of the debugger. To change this, you can right click the command-line-created target in the `Targets` view, and click `Save To Profile`. After doing so, the target will be restored across runs, and will no longer need to be specified on the command-line."; + @p "Targets created through command line usage are temporary, meaning they are not persistently saved across runs of the debugger. To change this, you can right click the command-line-created target in the `Targets` view, and click `Save To Project`. After doing so, the target will be restored across runs, and will no longer need to be specified on the command-line."; @subtitle "View Rules"; @p "*View Rules* are used to transform the way that evaluations in the debugger are visualized. An evaluation is produced by taking an expression string - for instance, the name of a variable - and using debug info and information from an attached process' live runtime (memory, registers, and so on) to interpret it."; @@ -712,11 +714,11 @@ raddbg_readme: @p "Each breakpoint has a hit count. Every time a breakpoint causes execution to stop, this counter is increased."; @p "Processor breakpoints are not currently supported, but planned to be in the future."; - @subtitle "User & Profile Files"; - @p "Applicable state controlling the debugger's appearance, behavior, targets, breakpoints, and other configurations is saved and reloaded across runs of the debugger through both *user files* and *profile files*. These files are auto-saved. These files are written in a textual format which can be hand-edited as necessary, but they're also continuously re-read and re-written by the debugger. By default, the debugger uses `%appdata%/raddbg/default.raddbg_user` for its user file path, and `%appdata%/raddbg/default.raddbg_profile` for its profile file path. These paths can be overridden on the command line (see the 'Command-Line Usage' section)."; + @subtitle "User & Project Files"; + @p "Applicable state controlling the debugger's appearance, behavior, targets, breakpoints, and other configurations is saved and reloaded across runs of the debugger through both *user files* and *project files*. These files are auto-saved. These files are written in a textual format which can be hand-edited as necessary, but they're also continuously re-read and re-written by the debugger. By default, the debugger uses `%appdata%/raddbg/default.raddbg_user` for its user file path, and `%appdata%/raddbg/default.raddbg_project` for its project file path. These paths can be overridden on the command line (see the 'Command-Line Usage' section)."; @p "The *user file* defaultly stores file path maps, windows (including their preferred monitor, placement, and size), each window's panel layout and tabs, keybindings, theme colors, and fonts."; - @p "The *profile file* defaultly stores targets, breakpoints, watch pins, and exception code filters."; - @p "Because both can be hand-edited, however, if you want to store something normally stored in a user file in a profile file, or vice versa, this can be done by hand transferring the textual data from one file to another. There is no path in the debugger's UI to support this transfer, currently, although this is planned."; + @p "The *project file* defaultly stores targets, breakpoints, watch pins, and exception code filters."; + @p "Because both can be hand-edited, however, if you want to store something normally stored in a user file in a project file, or vice versa, this can be done by hand transferring the textual data from one file to another. There is no path in the debugger's UI to support this transfer, currently, although this is planned."; //@subtitle "Driving Another Debugger Instance"; //@p "When the debugger is launched with the `--ipc` command-line argument, it does not launch another instance of the graphical debugger. Instead, it launches, sends a string encoding a command to a running instance of the graphical debugger, and then terminates. The set of commands which can be sent are identical to those which can be run from the debugger's UI itself, but these commands must be encoded textually (through the other command-line arguments). These commands are described in the 'Commands' section."; diff --git a/src/df/gfx/generated/df_gfx.meta.c b/src/df/gfx/generated/df_gfx.meta.c index ca6f9d3d..f7ce135a 100644 --- a/src/df/gfx/generated/df_gfx.meta.c +++ b/src/df/gfx/generated/df_gfx.meta.c @@ -642,8 +642,8 @@ DF_StringBindingPair df_g_default_binding_table[104] = {str8_lit_comp("reload_active"), {OS_Key_R, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift }}, {str8_lit_comp("switch"), {OS_Key_I, 0 |OS_EventFlag_Ctrl }}, {str8_lit_comp("switch_to_partner_file"), {OS_Key_O, 0 |OS_EventFlag_Alt}}, -{str8_lit_comp("load_user"), {OS_Key_O, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift |OS_EventFlag_Alt}}, -{str8_lit_comp("load_profile"), {OS_Key_O, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Alt}}, +{str8_lit_comp("open_user"), {OS_Key_O, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Shift |OS_EventFlag_Alt}}, +{str8_lit_comp("open_project"), {OS_Key_O, 0 |OS_EventFlag_Ctrl |OS_EventFlag_Alt}}, {str8_lit_comp("edit"), {OS_Key_F2, 0 }}, {str8_lit_comp("accept"), {OS_Key_Return, 0 }}, {str8_lit_comp("cancel"), {OS_Key_Esc, 0 }}, @@ -706,18 +706,22 @@ DF_StringBindingPair df_g_default_binding_table[104] = {str8_lit_comp("run_command"), {OS_Key_F1, 0 }}, }; -String8 df_g_binding_version_remap_old_name_table[3] = +String8 df_g_binding_version_remap_old_name_table[5] = { str8_lit_comp("commands"), str8_lit_comp("load_user"), str8_lit_comp("load_profile"), +str8_lit_comp("load_project"), +str8_lit_comp("open_profile"), }; -String8 df_g_binding_version_remap_new_name_table[3] = +String8 df_g_binding_version_remap_new_name_table[5] = { str8_lit_comp("run_command"), str8_lit_comp("open_user"), str8_lit_comp("open_profile"), +str8_lit_comp("open_project"), +str8_lit_comp("open_project"), }; DF_GfxViewRuleSpecInfo df_g_gfx_view_rule_spec_info_table[14] = diff --git a/src/df/gfx/generated/df_gfx.meta.h b/src/df/gfx/generated/df_gfx.meta.h index e8921033..f80263f6 100644 --- a/src/df/gfx/generated/df_gfx.meta.h +++ b/src/df/gfx/generated/df_gfx.meta.h @@ -291,8 +291,8 @@ extern DF_CmdParamSlot df_g_cmd_param_slot_2_view_spec_src_map[7]; extern String8 df_g_cmd_param_slot_2_view_spec_dst_map[7]; extern String8 df_g_cmd_param_slot_2_view_spec_cmd_map[7]; extern DF_StringBindingPair df_g_default_binding_table[104]; -extern String8 df_g_binding_version_remap_old_name_table[3]; -extern String8 df_g_binding_version_remap_new_name_table[3]; +extern String8 df_g_binding_version_remap_old_name_table[5]; +extern String8 df_g_binding_version_remap_new_name_table[5]; extern DF_ViewSpecInfo df_g_gfx_view_kind_spec_info_table[31]; extern String8 df_g_theme_color_display_string_table[54]; extern String8 df_g_theme_color_cfg_string_table[54]; diff --git a/src/raddbg/raddbg.h b/src/raddbg/raddbg.h index 511c8d3a..6b12cd6f 100644 --- a/src/raddbg/raddbg.h +++ b/src/raddbg/raddbg.h @@ -158,7 +158,7 @@ // opens the context window. It seems like maybe menus should be right, // and left should do the default action, more consistently? // -// [ ] It wasn't clear to me how you save a user or profile file. I can see +// [ ] It wasn't clear to me how you save a user or project file. I can see // how to load them, but not how you save them. Obviously I can just copy // the files myself in the shell, but it seemed weird that there was no // "save" option in the menus. diff --git a/src/raddbg/raddbg_main.cpp b/src/raddbg/raddbg_main.cpp index 7f28f917..70c881b6 100644 --- a/src/raddbg/raddbg_main.cpp +++ b/src/raddbg/raddbg_main.cpp @@ -552,8 +552,8 @@ entry_point(CmdLine *cmd_line) str8_lit("The following options may be used when starting the RAD Debugger from the command line:\n\n" "--user:\n" "Use to specify the location of a user file which should be used. User files are used to store settings for users, including window and panel setups, path mapping, and visual settings. If this file does not exist, it will be created as necessary. This file will be autosaved as user-related changes are made.\n\n" - "--profile:\n" - "Use to specify the location of a profile file which should be used. Profile files are used to store settings for users and projects. If this file does not exist, it will be created as necessary. This file will be autosaved as profile-related changes are made.\n\n" + "--project:\n" + "Use to specify the location of a project file which should be used. Project files are used to store settings for users and projects. If this file does not exist, it will be created as necessary. This file will be autosaved as project-related changes are made.\n\n" "--auto_step\n" "This will step into all targets after the debugger initially starts.\n\n" "--auto_run\n" From 9e778b30b68fc42264757e4383f6772c059a7bb2 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 24 May 2024 12:58:54 -0700 Subject: [PATCH 04/39] begin tracking per-tab project info; fix dasm cache request dequeue incorrect cv broadcast --- src/dasm_cache/dasm_cache.c | 2 +- src/df/gfx/df_gfx.c | 33 +++++++++++++++ src/df/gfx/df_gfx.h | 14 ++++--- src/df/gfx/df_gfx.mdesk | 66 +++++++++++++++--------------- src/df/gfx/generated/df_gfx.meta.c | 62 ++++++++++++++-------------- 5 files changed, 106 insertions(+), 71 deletions(-) diff --git a/src/dasm_cache/dasm_cache.c b/src/dasm_cache/dasm_cache.c index ffbea99b..1f8b8967 100644 --- a/src/dasm_cache/dasm_cache.c +++ b/src/dasm_cache/dasm_cache.c @@ -355,7 +355,7 @@ dasm_u2p_dequeue_req(Arena *arena, U128 *hash_out, DASM_Params *params_out) } os_condition_variable_wait(dasm_shared->u2p_ring_cv, dasm_shared->u2p_ring_mutex, max_U64); } - os_condition_variable_broadcast(dasm_shared->u2p_ring_mutex); + os_condition_variable_broadcast(dasm_shared->u2p_ring_cv); } internal void diff --git a/src/df/gfx/df_gfx.c b/src/df/gfx/df_gfx.c index b4c05bdd..f7ff95b2 100644 --- a/src/df/gfx/df_gfx.c +++ b/src/df/gfx/df_gfx.c @@ -796,6 +796,14 @@ df_view_equip_spec(DF_Window *window, DF_View *view, DF_ViewSpec *spec, DF_Entit MemoryZeroStruct(&view->scroll_pos); view->spec = spec; view->entity = df_handle_from_entity(entity); + if(spec->info.flags & DF_ViewSpecFlag_ProjectSpecific) + { + view->project = df_handle_from_entity(df_entity_from_path(df_cfg_path_from_src(DF_CfgSrc_Project), DF_EntityFromPathFlag_OpenMissing|DF_EntityFromPathFlag_OpenAsNeeded)); + } + else + { + MemoryZeroStruct(&view->project); + } view->is_filtering = 0; view->is_filtering_t = 0; view_setup(window, view, cfg_root); @@ -9354,6 +9362,17 @@ df_cfg_strings_from_gfx(Arena *arena, String8 root_path, DF_CfgSrc source) { str8_list_push(arena, &strs, str8_lit("selected ")); } + { + DF_Entity *project = df_entity_from_handle(view->project); + if(!df_entity_is_nil(project)) + { + Temp scratch = scratch_begin(&arena, 1); + String8 project_path_absolute = df_full_path_from_entity(scratch.arena, project); + String8 project_path_relative = path_relative_dst_from_absolute_dst_src(scratch.arena, project_path_absolute, root_path); + str8_list_pushf(arena, &strs, "project:{\"%S\"} ", project_path_relative); + scratch_end(scratch); + } + } if(view->query_string_size != 0 && view->spec->info.flags & DF_ViewSpecFlag_CanSerializeQuery) { Temp scratch = scratch_begin(&arena, 1); @@ -13397,6 +13416,16 @@ df_gfx_begin_frame(Arena *arena, DF_CmdList *cmds) // rjf: check if this view is selected view_is_selected = df_cfg_node_child_from_string(op, str8_lit("selected"), StringMatchFlag_CaseInsensitive) != &df_g_nil_cfg_node; + // rjf: read project path + String8 project_path = str8_lit(""); + { + DF_CfgNode *project_cfg_node = df_cfg_node_child_from_string(op, str8_lit("project"), StringMatchFlag_CaseInsensitive); + if(project_cfg_node != &df_g_nil_cfg_node) + { + project_path = project_cfg_node->first->string; + } + } + // rjf: read view query string String8 view_query = str8_lit(""); if(view_spec_flags & DF_ViewSpecFlag_CanSerializeQuery) @@ -13416,6 +13445,10 @@ df_gfx_begin_frame(Arena *arena, DF_CmdList *cmds) // rjf: set up view df_view_equip_spec(ws, view, view_spec, entity, view_query, op); + if(project_path.size != 0) + { + view->project = df_handle_from_entity(df_entity_from_path(project_path, DF_EntityFromPathFlag_OpenMissing|DF_EntityFromPathFlag_OpenAsNeeded)); + } } // rjf: insert diff --git a/src/df/gfx/df_gfx.h b/src/df/gfx/df_gfx.h index 60e0f83f..50370808 100644 --- a/src/df/gfx/df_gfx.h +++ b/src/df/gfx/df_gfx.h @@ -100,12 +100,13 @@ typedef U32 DF_ViewSpecFlags; enum { DF_ViewSpecFlag_ParameterizedByEntity = (1<<0), - DF_ViewSpecFlag_CanSerialize = (1<<1), - DF_ViewSpecFlag_CanSerializeEntityPath = (1<<2), - DF_ViewSpecFlag_CanSerializeQuery = (1<<3), - DF_ViewSpecFlag_CanFilter = (1<<4), - DF_ViewSpecFlag_FilterIsCode = (1<<5), - DF_ViewSpecFlag_TypingAutomaticallyFilters = (1<<6), + DF_ViewSpecFlag_ProjectSpecific = (1<<1), + DF_ViewSpecFlag_CanSerialize = (1<<2), + DF_ViewSpecFlag_CanSerializeEntityPath = (1<<3), + DF_ViewSpecFlag_CanSerializeQuery = (1<<4), + DF_ViewSpecFlag_CanFilter = (1<<5), + DF_ViewSpecFlag_FilterIsCode = (1<<6), + DF_ViewSpecFlag_TypingAutomaticallyFilters = (1<<7), }; typedef enum DF_NameKind @@ -204,6 +205,7 @@ struct DF_View // rjf: view kind info DF_ViewSpec *spec; DF_Handle entity; + DF_Handle project; // rjf: filter mode B32 is_filtering; diff --git a/src/df/gfx/df_gfx.mdesk b/src/df/gfx/df_gfx.mdesk index 2ee85fc7..111f5388 100644 --- a/src/df/gfx/df_gfx.mdesk +++ b/src/df/gfx/df_gfx.mdesk @@ -189,40 +189,40 @@ DF_BindingVersionRemapTable: //////////////////////////////// //~ rjf: Gfx Layer View Kinds -@table(name, name_lower, display_string, name_kind, icon, parameterized_by_entity, can_serialize, can_serialize_entity_path, can_filter, filter_is_code, typing_automatically_filters, inc_in_docs, docs_desc) +@table(name, name_lower, display_string, name_kind, icon, parameterized_by_entity, project_specific, can_serialize, can_serialize_entity_path, can_filter, filter_is_code, typing_automatically_filters, inc_in_docs, docs_desc) DF_GfxViewTable: { - { Null "null" "" Null Null 0 0 0 0 0 0 0 "" } - { Empty "empty" "" Null Null 0 0 0 0 0 0 0 "" } - { GettingStarted "getting_started" "Getting Started" Null QuestionMark 0 1 0 0 0 0 0 "" } - { Commands "commands" "Commands" Null List 0 0 0 0 0 0 0 "" } - { FileSystem "file_system" "File System" Null FileOutline 0 0 0 0 0 0 0 "" } - { SystemProcesses "system_processes" "System Processes" Null Null 0 0 0 0 0 0 0 "" } - { EntityLister "entity_lister" "Entity List" Null Null 0 0 0 0 0 0 0 "" } - { SymbolLister "symbol_lister" "Symbols" Null Null 0 0 0 0 0 0 0 "" } - { Target "target" "Target" EntityName Target 1 0 0 0 0 0 0 "" } - { Targets "targets" "Targets" Null Target 0 1 0 1 0 1 1 "Displays a list of all targets, as well as controls for enabling, disabling, launching, editing, or deleting each target. For more information on targets, read the `Targets` section." } - { FilePathMap "file_path_map" "File Path Map" Null FileOutline 0 1 0 0 0 0 1 "Displays a table of *path maps*. Each path map is a pair of file or folder paths, one being a 'source' path, and one being a 'destination' path. These pairs are used by the debugger when automatically searching for specific files - for instance, when attempting to snap to a source code location specified by debug info. If debug info refers to a path on the machine on which a target executable was originally built, but that path is not valid on the debugger machine, but some alternative path exists, then path maps may be used to redirect the debugger from the debug info's specified paths to the associated appropriate debugger machine file paths." } - { AutoViewRules "auto_view_rules" "Auto View Rules" Null Binoculars 0 1 0 0 0 0 1 "Displays a table of *auto view rules*. Each *auto view rule* is a pair, with one element being a type, and the other being a view rule, which should be automatically applied to expressions of that type, when possible." } - { Scheduler "scheduler" "Scheduler" Null Scheduler 0 1 0 1 1 1 1 "Displays all processes and threads to which the debugger is currently attached, and contains controls for selecting and freezing threads." } - { CallStack "call_stack" "Call Stack" Null Thread 0 1 0 0 0 0 1 "Displays the call stack of the currently selected thread. Each frame in the call stack contains the associated module, function name, and return address. Allows selection of a particular call stack frame other than the top." } - { Modules "modules" "Modules" Null Module 0 1 0 1 0 1 1 "Displays a table of all modules currently loaded by any process to which the debugger is attached. This table displays each module's name, virtual address range in the containing process' address space, and which debug info file is being used by the debugger for the associated module." } - { PendingEntity "pending_entity" "Pending Entity" EntityName FileOutline 1 0 0 0 0 0 0 "" } - { Code "code" "Code" EntityName FileOutline 1 1 1 0 0 0 0 "" } - { Disassembly "disassembly" "Disassembly" Null Glasses 0 1 0 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 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 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 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 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." } - { ThreadLocals "thread_locals" "Thread Locals" Null Binoculars 0 1 0 1 1 1 1 "Nearly identical to `Watch`, but automatically filled with all thread local 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." } - { Types "types" "Types" Null Binoculars 0 1 0 1 1 1 1 "Nearly identical to `Watch`, but automatically filled with all types within the selected thread's module. View rules can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table." } - { Procedures "procedures" "Procedures" Null Binoculars 0 1 0 1 1 1 1 "Nearly identical to `Watch`, but automatically filled with all procedures within the selected thread's module. View rules can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table." } - { Output "output" "Output" Null List 0 1 0 0 0 0 1 "Displays textual output from the selected thread's containing process." } - { Memory "memory" "Memory" Null Grid 0 1 1 0 0 0 1 "A familiar hex-editor-like interface for viewing memory of attached processes." } - { Breakpoints "breakpoints" "Breakpoints" Null CircleFilled 0 1 0 1 0 1 1 "Displays a table of all breakpoints, containing information about each breakpoint's name, location, and hit count. Also contains per-breakpoint controls for enabling, deleting, or editing each breakpoint. For more information on breakpoints and their features, read the 'Breakpoints' section." } - { WatchPins "watch_pins" "Watch Pins" Null Pin 0 1 0 1 1 1 1 "Displays a table of all watch pins (watched expressions, like those found in `Watch`, but instead of being within a table, being pinned to some source code location, like breakpoints). This table contains each pin's name, location, and controls for editing or deleting each pin." } - { ExceptionFilters "exception_filters" "Exception Filters" Null Gear 0 1 0 1 0 1 1 "An interface which controls whether or not the debugger will halt attached processes upon encountering specific exception codes for the first time." } - { Theme "theme" "Theme" Null Palette 0 1 0 0 0 0 1 "An interface for modifying the colors used in the debugger's UI. Allows selecting a theme preset, loading a theme from a file, and modifying individual colors within a theme." } + { Null "null" "" Null Null 0 0 0 0 0 0 0 0 "" } + { Empty "empty" "" Null Null 0 0 0 0 0 0 0 0 "" } + { GettingStarted "getting_started" "Getting Started" Null QuestionMark 0 0 1 0 0 0 0 0 "" } + { Commands "commands" "Commands" Null List 0 0 0 0 0 0 0 0 "" } + { FileSystem "file_system" "File System" Null FileOutline 0 0 0 0 0 0 0 0 "" } + { SystemProcesses "system_processes" "System Processes" Null Null 0 0 0 0 0 0 0 0 "" } + { EntityLister "entity_lister" "Entity List" Null Null 0 0 0 0 0 0 0 0 "" } + { SymbolLister "symbol_lister" "Symbols" Null Null 0 0 0 0 0 0 0 0 "" } + { Target "target" "Target" EntityName Target 1 0 0 0 0 0 0 0 "" } + { Targets "targets" "Targets" Null Target 0 0 1 0 1 0 1 1 "Displays a list of all targets, as well as controls for enabling, disabling, launching, editing, or deleting each target. For more information on targets, read the `Targets` section." } + { FilePathMap "file_path_map" "File Path Map" Null FileOutline 0 0 1 0 0 0 0 1 "Displays a table of *path maps*. Each path map is a pair of file or folder paths, one being a 'source' path, and one being a 'destination' path. These pairs are used by the debugger when automatically searching for specific files - for instance, when attempting to snap to a source code location specified by debug info. If debug info refers to a path on the machine on which a target executable was originally built, but that path is not valid on the debugger machine, but some alternative path exists, then path maps may be used to redirect the debugger from the debug info's specified paths to the associated appropriate debugger machine file paths." } + { AutoViewRules "auto_view_rules" "Auto View Rules" Null Binoculars 0 0 1 0 0 0 0 1 "Displays a table of *auto view rules*. Each *auto view rule* is a pair, with one element being a type, and the other being a view rule, which should be automatically applied to expressions of that type, when possible." } + { Scheduler "scheduler" "Scheduler" Null Scheduler 0 0 1 0 1 1 1 1 "Displays all processes and threads to which the debugger is currently attached, and contains controls for selecting and freezing threads." } + { CallStack "call_stack" "Call Stack" Null Thread 0 0 1 0 0 0 0 1 "Displays the call stack of the currently selected thread. Each frame in the call stack contains the associated module, function name, and return address. Allows selection of a particular call stack frame other than the top." } + { Modules "modules" "Modules" Null Module 0 0 1 0 1 0 1 1 "Displays a table of all modules currently loaded by any process to which the debugger is attached. This table displays each module's name, virtual address range in the containing process' address space, and which debug info file is being used by the debugger for the associated module." } + { PendingEntity "pending_entity" "Pending Entity" EntityName FileOutline 1 0 0 0 0 0 0 0 "" } + { Code "code" "Code" EntityName FileOutline 1 1 1 1 0 0 0 0 "" } + { Disassembly "disassembly" "Disassembly" Null Glasses 0 0 1 0 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 0 1 0 1 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 0 1 0 1 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 0 1 0 1 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 0 1 0 1 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." } + { ThreadLocals "thread_locals" "Thread Locals" Null Binoculars 0 0 1 0 1 1 1 1 "Nearly identical to `Watch`, but automatically filled with all thread local 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." } + { Types "types" "Types" Null Binoculars 0 0 1 0 1 1 1 1 "Nearly identical to `Watch`, but automatically filled with all types within the selected thread's module. View rules can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table." } + { Procedures "procedures" "Procedures" Null Binoculars 0 0 1 0 1 1 1 1 "Nearly identical to `Watch`, but automatically filled with all procedures within the selected thread's module. View rules can be edited, like in `Watch`, but unlike `Watch`, expressions cannot be edited or added to the table." } + { Output "output" "Output" Null List 0 0 1 0 0 0 0 1 "Displays textual output from the selected thread's containing process." } + { Memory "memory" "Memory" Null Grid 0 0 1 1 0 0 0 1 "A familiar hex-editor-like interface for viewing memory of attached processes." } + { Breakpoints "breakpoints" "Breakpoints" Null CircleFilled 0 0 1 0 1 0 1 1 "Displays a table of all breakpoints, containing information about each breakpoint's name, location, and hit count. Also contains per-breakpoint controls for enabling, deleting, or editing each breakpoint. For more information on breakpoints and their features, read the 'Breakpoints' section." } + { WatchPins "watch_pins" "Watch Pins" Null Pin 0 0 1 0 1 1 1 1 "Displays a table of all watch pins (watched expressions, like those found in `Watch`, but instead of being within a table, being pinned to some source code location, like breakpoints). This table contains each pin's name, location, and controls for editing or deleting each pin." } + { ExceptionFilters "exception_filters" "Exception Filters" Null Gear 0 0 1 0 1 0 1 1 "An interface which controls whether or not the debugger will halt attached processes upon encountering specific exception codes for the first time." } + { Theme "theme" "Theme" Null Palette 0 0 1 0 0 0 0 1 "An interface for modifying the colors used in the debugger's UI. Allows selecting a theme preset, loading a theme from a file, and modifying individual colors within a theme." } } //////////////////////////////// @@ -583,7 +583,7 @@ DF_ThemePresetColorTable: @data(DF_ViewSpecInfo) df_g_gfx_view_kind_spec_info_table: { - @expand(DF_GfxViewTable a) ```{(0|$(a.parameterized_by_entity)*DF_ViewSpecFlag_ParameterizedByEntity|$(a.can_serialize)*DF_ViewSpecFlag_CanSerialize|$(a.can_serialize_entity_path)*DF_ViewSpecFlag_CanSerializeEntityPath|$(a.can_filter)*DF_ViewSpecFlag_CanFilter|$(a.filter_is_code)*DF_ViewSpecFlag_FilterIsCode|$(a.typing_automatically_filters)*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("$(a.name_lower)"), str8_lit_comp("$(a.display_string)"), DF_NameKind_$(a.name_kind), DF_IconKind_$(a.icon), DF_VIEW_SETUP_FUNCTION_NAME($(a.name)), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME($(a.name)), DF_VIEW_CMD_FUNCTION_NAME($(a.name)), DF_VIEW_UI_FUNCTION_NAME($(a.name))}```; + @expand(DF_GfxViewTable a) ```{(0|$(a.parameterized_by_entity)*DF_ViewSpecFlag_ParameterizedByEntity|$(a.project_specific)*DF_ViewSpecFlag_ProjectSpecific|$(a.can_serialize)*DF_ViewSpecFlag_CanSerialize|$(a.can_serialize_entity_path)*DF_ViewSpecFlag_CanSerializeEntityPath|$(a.can_filter)*DF_ViewSpecFlag_CanFilter|$(a.filter_is_code)*DF_ViewSpecFlag_FilterIsCode|$(a.typing_automatically_filters)*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("$(a.name_lower)"), str8_lit_comp("$(a.display_string)"), DF_NameKind_$(a.name_kind), DF_IconKind_$(a.icon), DF_VIEW_SETUP_FUNCTION_NAME($(a.name)), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME($(a.name)), DF_VIEW_CMD_FUNCTION_NAME($(a.name)), DF_VIEW_UI_FUNCTION_NAME($(a.name))}```; } //- rjf: theme color tables diff --git a/src/df/gfx/generated/df_gfx.meta.c b/src/df/gfx/generated/df_gfx.meta.c index f7ce135a..86ac3b2e 100644 --- a/src/df/gfx/generated/df_gfx.meta.c +++ b/src/df/gfx/generated/df_gfx.meta.c @@ -752,37 +752,37 @@ DF_ViewSpecInfo df_g_gfx_view_rule_tab_view_spec_info_table[4] = DF_ViewSpecInfo df_g_gfx_view_kind_spec_info_table[31] = { -{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("null"), str8_lit_comp(""), DF_NameKind_Null, DF_IconKind_Null, DF_VIEW_SETUP_FUNCTION_NAME(Null), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Null), DF_VIEW_CMD_FUNCTION_NAME(Null), DF_VIEW_UI_FUNCTION_NAME(Null)}, -{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("empty"), str8_lit_comp(""), DF_NameKind_Null, DF_IconKind_Null, DF_VIEW_SETUP_FUNCTION_NAME(Empty), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Empty), DF_VIEW_CMD_FUNCTION_NAME(Empty), DF_VIEW_UI_FUNCTION_NAME(Empty)}, -{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("getting_started"), str8_lit_comp("Getting Started"), DF_NameKind_Null, DF_IconKind_QuestionMark, DF_VIEW_SETUP_FUNCTION_NAME(GettingStarted), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(GettingStarted), DF_VIEW_CMD_FUNCTION_NAME(GettingStarted), DF_VIEW_UI_FUNCTION_NAME(GettingStarted)}, -{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("commands"), str8_lit_comp("Commands"), DF_NameKind_Null, DF_IconKind_List, DF_VIEW_SETUP_FUNCTION_NAME(Commands), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Commands), DF_VIEW_CMD_FUNCTION_NAME(Commands), DF_VIEW_UI_FUNCTION_NAME(Commands)}, -{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("file_system"), str8_lit_comp("File System"), DF_NameKind_Null, DF_IconKind_FileOutline, DF_VIEW_SETUP_FUNCTION_NAME(FileSystem), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(FileSystem), DF_VIEW_CMD_FUNCTION_NAME(FileSystem), DF_VIEW_UI_FUNCTION_NAME(FileSystem)}, -{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("system_processes"), str8_lit_comp("System Processes"), DF_NameKind_Null, DF_IconKind_Null, DF_VIEW_SETUP_FUNCTION_NAME(SystemProcesses), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(SystemProcesses), DF_VIEW_CMD_FUNCTION_NAME(SystemProcesses), DF_VIEW_UI_FUNCTION_NAME(SystemProcesses)}, -{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("entity_lister"), str8_lit_comp("Entity List"), DF_NameKind_Null, DF_IconKind_Null, DF_VIEW_SETUP_FUNCTION_NAME(EntityLister), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(EntityLister), DF_VIEW_CMD_FUNCTION_NAME(EntityLister), DF_VIEW_UI_FUNCTION_NAME(EntityLister)}, -{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("symbol_lister"), str8_lit_comp("Symbols"), DF_NameKind_Null, DF_IconKind_Null, DF_VIEW_SETUP_FUNCTION_NAME(SymbolLister), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(SymbolLister), DF_VIEW_CMD_FUNCTION_NAME(SymbolLister), DF_VIEW_UI_FUNCTION_NAME(SymbolLister)}, -{(0|1*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("target"), str8_lit_comp("Target"), DF_NameKind_EntityName, DF_IconKind_Target, DF_VIEW_SETUP_FUNCTION_NAME(Target), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Target), DF_VIEW_CMD_FUNCTION_NAME(Target), DF_VIEW_UI_FUNCTION_NAME(Target)}, -{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("targets"), str8_lit_comp("Targets"), DF_NameKind_Null, DF_IconKind_Target, DF_VIEW_SETUP_FUNCTION_NAME(Targets), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Targets), DF_VIEW_CMD_FUNCTION_NAME(Targets), DF_VIEW_UI_FUNCTION_NAME(Targets)}, -{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("file_path_map"), str8_lit_comp("File Path Map"), DF_NameKind_Null, DF_IconKind_FileOutline, DF_VIEW_SETUP_FUNCTION_NAME(FilePathMap), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(FilePathMap), DF_VIEW_CMD_FUNCTION_NAME(FilePathMap), DF_VIEW_UI_FUNCTION_NAME(FilePathMap)}, -{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rules"), DF_NameKind_Null, DF_IconKind_Binoculars, DF_VIEW_SETUP_FUNCTION_NAME(AutoViewRules), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(AutoViewRules), DF_VIEW_CMD_FUNCTION_NAME(AutoViewRules), DF_VIEW_UI_FUNCTION_NAME(AutoViewRules)}, -{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|1*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("scheduler"), str8_lit_comp("Scheduler"), DF_NameKind_Null, DF_IconKind_Scheduler, DF_VIEW_SETUP_FUNCTION_NAME(Scheduler), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Scheduler), DF_VIEW_CMD_FUNCTION_NAME(Scheduler), DF_VIEW_UI_FUNCTION_NAME(Scheduler)}, -{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("call_stack"), str8_lit_comp("Call Stack"), DF_NameKind_Null, DF_IconKind_Thread, DF_VIEW_SETUP_FUNCTION_NAME(CallStack), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(CallStack), DF_VIEW_CMD_FUNCTION_NAME(CallStack), DF_VIEW_UI_FUNCTION_NAME(CallStack)}, -{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("modules"), str8_lit_comp("Modules"), DF_NameKind_Null, DF_IconKind_Module, DF_VIEW_SETUP_FUNCTION_NAME(Modules), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Modules), DF_VIEW_CMD_FUNCTION_NAME(Modules), DF_VIEW_UI_FUNCTION_NAME(Modules)}, -{(0|1*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|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_FilterIsCode|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_FilterIsCode|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|1*DF_ViewSpecFlag_FilterIsCode|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_FilterIsCode|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_FilterIsCode|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_FilterIsCode|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)}, -{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|1*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("thread_locals"), str8_lit_comp("Thread Locals"), DF_NameKind_Null, DF_IconKind_Binoculars, DF_VIEW_SETUP_FUNCTION_NAME(ThreadLocals), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(ThreadLocals), DF_VIEW_CMD_FUNCTION_NAME(ThreadLocals), DF_VIEW_UI_FUNCTION_NAME(ThreadLocals)}, -{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|1*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("types"), str8_lit_comp("Types"), DF_NameKind_Null, DF_IconKind_Binoculars, DF_VIEW_SETUP_FUNCTION_NAME(Types), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Types), DF_VIEW_CMD_FUNCTION_NAME(Types), DF_VIEW_UI_FUNCTION_NAME(Types)}, -{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|1*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("procedures"), str8_lit_comp("Procedures"), DF_NameKind_Null, DF_IconKind_Binoculars, DF_VIEW_SETUP_FUNCTION_NAME(Procedures), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Procedures), DF_VIEW_CMD_FUNCTION_NAME(Procedures), DF_VIEW_UI_FUNCTION_NAME(Procedures)}, -{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("output"), str8_lit_comp("Output"), DF_NameKind_Null, DF_IconKind_List, DF_VIEW_SETUP_FUNCTION_NAME(Output), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Output), DF_VIEW_CMD_FUNCTION_NAME(Output), DF_VIEW_UI_FUNCTION_NAME(Output)}, -{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|1*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("memory"), str8_lit_comp("Memory"), DF_NameKind_Null, DF_IconKind_Grid, DF_VIEW_SETUP_FUNCTION_NAME(Memory), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Memory), DF_VIEW_CMD_FUNCTION_NAME(Memory), DF_VIEW_UI_FUNCTION_NAME(Memory)}, -{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("breakpoints"), str8_lit_comp("Breakpoints"), DF_NameKind_Null, DF_IconKind_CircleFilled, DF_VIEW_SETUP_FUNCTION_NAME(Breakpoints), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Breakpoints), DF_VIEW_CMD_FUNCTION_NAME(Breakpoints), DF_VIEW_UI_FUNCTION_NAME(Breakpoints)}, -{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|1*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("watch_pins"), str8_lit_comp("Watch Pins"), DF_NameKind_Null, DF_IconKind_Pin, DF_VIEW_SETUP_FUNCTION_NAME(WatchPins), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(WatchPins), DF_VIEW_CMD_FUNCTION_NAME(WatchPins), DF_VIEW_UI_FUNCTION_NAME(WatchPins)}, -{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("exception_filters"), str8_lit_comp("Exception Filters"), DF_NameKind_Null, DF_IconKind_Gear, DF_VIEW_SETUP_FUNCTION_NAME(ExceptionFilters), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(ExceptionFilters), DF_VIEW_CMD_FUNCTION_NAME(ExceptionFilters), DF_VIEW_UI_FUNCTION_NAME(ExceptionFilters)}, -{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("theme"), str8_lit_comp("Theme"), DF_NameKind_Null, DF_IconKind_Palette, DF_VIEW_SETUP_FUNCTION_NAME(Theme), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Theme), DF_VIEW_CMD_FUNCTION_NAME(Theme), DF_VIEW_UI_FUNCTION_NAME(Theme)}, +{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_ProjectSpecific|0*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("null"), str8_lit_comp(""), DF_NameKind_Null, DF_IconKind_Null, DF_VIEW_SETUP_FUNCTION_NAME(Null), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Null), DF_VIEW_CMD_FUNCTION_NAME(Null), DF_VIEW_UI_FUNCTION_NAME(Null)}, +{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_ProjectSpecific|0*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("empty"), str8_lit_comp(""), DF_NameKind_Null, DF_IconKind_Null, DF_VIEW_SETUP_FUNCTION_NAME(Empty), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Empty), DF_VIEW_CMD_FUNCTION_NAME(Empty), DF_VIEW_UI_FUNCTION_NAME(Empty)}, +{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_ProjectSpecific|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("getting_started"), str8_lit_comp("Getting Started"), DF_NameKind_Null, DF_IconKind_QuestionMark, DF_VIEW_SETUP_FUNCTION_NAME(GettingStarted), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(GettingStarted), DF_VIEW_CMD_FUNCTION_NAME(GettingStarted), DF_VIEW_UI_FUNCTION_NAME(GettingStarted)}, +{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_ProjectSpecific|0*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("commands"), str8_lit_comp("Commands"), DF_NameKind_Null, DF_IconKind_List, DF_VIEW_SETUP_FUNCTION_NAME(Commands), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Commands), DF_VIEW_CMD_FUNCTION_NAME(Commands), DF_VIEW_UI_FUNCTION_NAME(Commands)}, +{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_ProjectSpecific|0*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("file_system"), str8_lit_comp("File System"), DF_NameKind_Null, DF_IconKind_FileOutline, DF_VIEW_SETUP_FUNCTION_NAME(FileSystem), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(FileSystem), DF_VIEW_CMD_FUNCTION_NAME(FileSystem), DF_VIEW_UI_FUNCTION_NAME(FileSystem)}, +{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_ProjectSpecific|0*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("system_processes"), str8_lit_comp("System Processes"), DF_NameKind_Null, DF_IconKind_Null, DF_VIEW_SETUP_FUNCTION_NAME(SystemProcesses), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(SystemProcesses), DF_VIEW_CMD_FUNCTION_NAME(SystemProcesses), DF_VIEW_UI_FUNCTION_NAME(SystemProcesses)}, +{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_ProjectSpecific|0*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("entity_lister"), str8_lit_comp("Entity List"), DF_NameKind_Null, DF_IconKind_Null, DF_VIEW_SETUP_FUNCTION_NAME(EntityLister), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(EntityLister), DF_VIEW_CMD_FUNCTION_NAME(EntityLister), DF_VIEW_UI_FUNCTION_NAME(EntityLister)}, +{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_ProjectSpecific|0*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("symbol_lister"), str8_lit_comp("Symbols"), DF_NameKind_Null, DF_IconKind_Null, DF_VIEW_SETUP_FUNCTION_NAME(SymbolLister), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(SymbolLister), DF_VIEW_CMD_FUNCTION_NAME(SymbolLister), DF_VIEW_UI_FUNCTION_NAME(SymbolLister)}, +{(0|1*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_ProjectSpecific|0*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("target"), str8_lit_comp("Target"), DF_NameKind_EntityName, DF_IconKind_Target, DF_VIEW_SETUP_FUNCTION_NAME(Target), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Target), DF_VIEW_CMD_FUNCTION_NAME(Target), DF_VIEW_UI_FUNCTION_NAME(Target)}, +{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_ProjectSpecific|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("targets"), str8_lit_comp("Targets"), DF_NameKind_Null, DF_IconKind_Target, DF_VIEW_SETUP_FUNCTION_NAME(Targets), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Targets), DF_VIEW_CMD_FUNCTION_NAME(Targets), DF_VIEW_UI_FUNCTION_NAME(Targets)}, +{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_ProjectSpecific|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("file_path_map"), str8_lit_comp("File Path Map"), DF_NameKind_Null, DF_IconKind_FileOutline, DF_VIEW_SETUP_FUNCTION_NAME(FilePathMap), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(FilePathMap), DF_VIEW_CMD_FUNCTION_NAME(FilePathMap), DF_VIEW_UI_FUNCTION_NAME(FilePathMap)}, +{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_ProjectSpecific|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("auto_view_rules"), str8_lit_comp("Auto View Rules"), DF_NameKind_Null, DF_IconKind_Binoculars, DF_VIEW_SETUP_FUNCTION_NAME(AutoViewRules), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(AutoViewRules), DF_VIEW_CMD_FUNCTION_NAME(AutoViewRules), DF_VIEW_UI_FUNCTION_NAME(AutoViewRules)}, +{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_ProjectSpecific|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|1*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("scheduler"), str8_lit_comp("Scheduler"), DF_NameKind_Null, DF_IconKind_Scheduler, DF_VIEW_SETUP_FUNCTION_NAME(Scheduler), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Scheduler), DF_VIEW_CMD_FUNCTION_NAME(Scheduler), DF_VIEW_UI_FUNCTION_NAME(Scheduler)}, +{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_ProjectSpecific|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("call_stack"), str8_lit_comp("Call Stack"), DF_NameKind_Null, DF_IconKind_Thread, DF_VIEW_SETUP_FUNCTION_NAME(CallStack), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(CallStack), DF_VIEW_CMD_FUNCTION_NAME(CallStack), DF_VIEW_UI_FUNCTION_NAME(CallStack)}, +{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_ProjectSpecific|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("modules"), str8_lit_comp("Modules"), DF_NameKind_Null, DF_IconKind_Module, DF_VIEW_SETUP_FUNCTION_NAME(Modules), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Modules), DF_VIEW_CMD_FUNCTION_NAME(Modules), DF_VIEW_UI_FUNCTION_NAME(Modules)}, +{(0|1*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_ProjectSpecific|0*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|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_ProjectSpecific|1*DF_ViewSpecFlag_CanSerialize|1*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|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|0*DF_ViewSpecFlag_ProjectSpecific|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|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|0*DF_ViewSpecFlag_ProjectSpecific|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|1*DF_ViewSpecFlag_FilterIsCode|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|0*DF_ViewSpecFlag_ProjectSpecific|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|1*DF_ViewSpecFlag_FilterIsCode|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|0*DF_ViewSpecFlag_ProjectSpecific|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|1*DF_ViewSpecFlag_FilterIsCode|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|0*DF_ViewSpecFlag_ProjectSpecific|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|1*DF_ViewSpecFlag_FilterIsCode|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)}, +{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_ProjectSpecific|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|1*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("thread_locals"), str8_lit_comp("Thread Locals"), DF_NameKind_Null, DF_IconKind_Binoculars, DF_VIEW_SETUP_FUNCTION_NAME(ThreadLocals), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(ThreadLocals), DF_VIEW_CMD_FUNCTION_NAME(ThreadLocals), DF_VIEW_UI_FUNCTION_NAME(ThreadLocals)}, +{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_ProjectSpecific|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|1*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("types"), str8_lit_comp("Types"), DF_NameKind_Null, DF_IconKind_Binoculars, DF_VIEW_SETUP_FUNCTION_NAME(Types), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Types), DF_VIEW_CMD_FUNCTION_NAME(Types), DF_VIEW_UI_FUNCTION_NAME(Types)}, +{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_ProjectSpecific|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|1*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("procedures"), str8_lit_comp("Procedures"), DF_NameKind_Null, DF_IconKind_Binoculars, DF_VIEW_SETUP_FUNCTION_NAME(Procedures), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Procedures), DF_VIEW_CMD_FUNCTION_NAME(Procedures), DF_VIEW_UI_FUNCTION_NAME(Procedures)}, +{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_ProjectSpecific|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("output"), str8_lit_comp("Output"), DF_NameKind_Null, DF_IconKind_List, DF_VIEW_SETUP_FUNCTION_NAME(Output), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Output), DF_VIEW_CMD_FUNCTION_NAME(Output), DF_VIEW_UI_FUNCTION_NAME(Output)}, +{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_ProjectSpecific|1*DF_ViewSpecFlag_CanSerialize|1*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("memory"), str8_lit_comp("Memory"), DF_NameKind_Null, DF_IconKind_Grid, DF_VIEW_SETUP_FUNCTION_NAME(Memory), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Memory), DF_VIEW_CMD_FUNCTION_NAME(Memory), DF_VIEW_UI_FUNCTION_NAME(Memory)}, +{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_ProjectSpecific|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("breakpoints"), str8_lit_comp("Breakpoints"), DF_NameKind_Null, DF_IconKind_CircleFilled, DF_VIEW_SETUP_FUNCTION_NAME(Breakpoints), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Breakpoints), DF_VIEW_CMD_FUNCTION_NAME(Breakpoints), DF_VIEW_UI_FUNCTION_NAME(Breakpoints)}, +{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_ProjectSpecific|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|1*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("watch_pins"), str8_lit_comp("Watch Pins"), DF_NameKind_Null, DF_IconKind_Pin, DF_VIEW_SETUP_FUNCTION_NAME(WatchPins), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(WatchPins), DF_VIEW_CMD_FUNCTION_NAME(WatchPins), DF_VIEW_UI_FUNCTION_NAME(WatchPins)}, +{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_ProjectSpecific|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|1*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|1*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("exception_filters"), str8_lit_comp("Exception Filters"), DF_NameKind_Null, DF_IconKind_Gear, DF_VIEW_SETUP_FUNCTION_NAME(ExceptionFilters), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(ExceptionFilters), DF_VIEW_CMD_FUNCTION_NAME(ExceptionFilters), DF_VIEW_UI_FUNCTION_NAME(ExceptionFilters)}, +{(0|0*DF_ViewSpecFlag_ParameterizedByEntity|0*DF_ViewSpecFlag_ProjectSpecific|1*DF_ViewSpecFlag_CanSerialize|0*DF_ViewSpecFlag_CanSerializeEntityPath|0*DF_ViewSpecFlag_CanFilter|0*DF_ViewSpecFlag_FilterIsCode|0*DF_ViewSpecFlag_TypingAutomaticallyFilters), str8_lit_comp("theme"), str8_lit_comp("Theme"), DF_NameKind_Null, DF_IconKind_Palette, DF_VIEW_SETUP_FUNCTION_NAME(Theme), DF_VIEW_STRING_FROM_STATE_FUNCTION_NAME(Theme), DF_VIEW_CMD_FUNCTION_NAME(Theme), DF_VIEW_UI_FUNCTION_NAME(Theme)}, }; String8 df_g_theme_color_display_string_table[54] = From 5f76fcfb6b6f33587b3c03090c4fb292dc0dccec Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 24 May 2024 13:33:47 -0700 Subject: [PATCH 05/39] filter panel tabs by project, if applicable; move all tab controls & so on to working based on this filtering mechanism --- src/df/core/df_core.c | 4 + src/df/gfx/df_gfx.c | 238 +++++++++++++++++++++++++++++++++--------- src/df/gfx/df_gfx.h | 4 +- 3 files changed, 197 insertions(+), 49 deletions(-) diff --git a/src/df/core/df_core.c b/src/df/core/df_core.c index 9900ad9d..704802c2 100644 --- a/src/df/core/df_core.c +++ b/src/df/core/df_core.c @@ -6530,6 +6530,10 @@ df_core_init(CmdLine *cmdln, DF_StateDeltaHistory *hist) // rjf: unpack command line arguments String8 user_cfg_path = cmd_line_string(cmdln, str8_lit("user")); String8 project_cfg_path = cmd_line_string(cmdln, str8_lit("project")); + if(project_cfg_path.size == 0) + { + project_cfg_path = cmd_line_string(cmdln, str8_lit("profile")); + } { String8 user_program_data_path = os_string_from_system_path(scratch.arena, OS_SystemPath_UserProgramData); String8 user_data_folder = push_str8f(scratch.arena, "%S/%S", user_program_data_path, str8_lit("raddbg")); diff --git a/src/df/gfx/df_gfx.c b/src/df/gfx/df_gfx.c index f7ff95b2..e54a6f30 100644 --- a/src/df/gfx/df_gfx.c +++ b/src/df/gfx/df_gfx.c @@ -74,6 +74,22 @@ df_view_is_nil(DF_View *view) return (view == 0 || view == &df_g_nil_view); } +internal B32 +df_view_is_project_filtered(DF_View *view) +{ + B32 result = 0; + DF_Entity *view_project = df_entity_from_handle(view->project); + if(!df_entity_is_nil(view_project)) + { + DF_Entity *current_project = df_entity_from_path(df_cfg_path_from_src(DF_CfgSrc_Project), 0); + if(current_project != view_project) + { + result = 1; + } + } + return result; +} + internal DF_Handle df_handle_from_view(DF_View *view) { @@ -294,20 +310,56 @@ df_panel_insert_tab_view(DF_Panel *panel, DF_View *prev_view, DF_View *view) { DLLInsert_NPZ(&df_g_nil_view, panel->first_tab_view, panel->last_tab_view, prev_view, view, next, prev); panel->tab_view_count += 1; - panel->selected_tab_view = df_handle_from_view(view); + if(!df_view_is_project_filtered(view)) + { + panel->selected_tab_view = df_handle_from_view(view); + } } internal void df_panel_remove_tab_view(DF_Panel *panel, DF_View *view) { - DLLRemove_NPZ(&df_g_nil_view, panel->first_tab_view, panel->last_tab_view, view, next, prev); if(df_view_from_handle(panel->selected_tab_view) == view) { - panel->selected_tab_view = df_handle_from_view(!df_view_is_nil(view->prev) ? view->prev : view->next); + panel->selected_tab_view = df_handle_zero(); + if(df_handle_match(df_handle_zero(), panel->selected_tab_view)) + { + for(DF_View *v = view->next; !df_view_is_nil(v); v = v->next) + { + if(!df_view_is_project_filtered(v)) + { + panel->selected_tab_view = df_handle_from_view(v); + break; + } + } + } + if(df_handle_match(df_handle_zero(), panel->selected_tab_view)) + { + for(DF_View *v = view->prev; !df_view_is_nil(v); v = v->prev) + { + if(!df_view_is_project_filtered(v)) + { + panel->selected_tab_view = df_handle_from_view(v); + break; + } + } + } } + DLLRemove_NPZ(&df_g_nil_view, panel->first_tab_view, panel->last_tab_view, view, next, prev); panel->tab_view_count -= 1; } +internal DF_View * +df_selected_tab_from_panel(DF_Panel *panel) +{ + DF_View *view = df_view_from_handle(panel->selected_tab_view); + if(df_view_is_project_filtered(view)) + { + view = &df_g_nil_view; + } + return view; +} + //- rjf: icons & display strings internal String8 @@ -417,7 +469,7 @@ df_cmd_params_from_gfx(void) { p.window = df_handle_from_window(window); p.panel = df_handle_from_panel(window->focused_panel); - p.view = window->focused_panel->selected_tab_view; + p.view = df_handle_from_view(df_selected_tab_from_panel(window->focused_panel)); } return p; } @@ -426,7 +478,7 @@ internal B32 df_prefer_dasm_from_window(DF_Window *window) { DF_Panel *panel = window->focused_panel; - DF_View *view = df_view_from_handle(panel->selected_tab_view); + DF_View *view = df_selected_tab_from_panel(panel); DF_GfxViewKind view_kind = df_gfx_view_kind_from_string(view->spec->info.name); B32 result = 0; if(view_kind == DF_GfxViewKind_Disassembly) @@ -443,7 +495,7 @@ df_prefer_dasm_from_window(DF_Window *window) B32 has_dasm = 0; for(DF_Panel *p = window->root_panel; !df_panel_is_nil(p); p = df_panel_rec_df_pre(p).next) { - DF_View *p_view = df_view_from_handle(p->selected_tab_view); + DF_View *p_view = df_selected_tab_from_panel(p); DF_GfxViewKind p_view_kind = df_gfx_view_kind_from_string(p_view->spec->info.name); if(p_view_kind == DF_GfxViewKind_Code) { @@ -464,7 +516,7 @@ internal DF_CmdParams df_cmd_params_from_window(DF_Window *window) { DF_CmdParams p = df_cmd_params_zero(); - DF_CtrlCtx ctrl_ctx = df_ctrl_ctx_from_view(window, df_view_from_handle(window->focused_panel->selected_tab_view)); + DF_CtrlCtx ctrl_ctx = df_ctrl_ctx_from_view(window, df_selected_tab_from_panel(window->focused_panel)); df_cmd_params_mark_slot(&p, DF_CmdParamSlot_Window); df_cmd_params_mark_slot(&p, DF_CmdParamSlot_Panel); df_cmd_params_mark_slot(&p, DF_CmdParamSlot_View); @@ -473,7 +525,7 @@ df_cmd_params_from_window(DF_Window *window) df_cmd_params_mark_slot(&p, DF_CmdParamSlot_Index); p.window = df_handle_from_window(window); p.panel = df_handle_from_panel(window->focused_panel); - p.view = window->focused_panel->selected_tab_view; + p.view = df_handle_from_view(df_selected_tab_from_panel(window->focused_panel)); p.prefer_dasm = df_prefer_dasm_from_window(window); p.entity = ctrl_ctx.thread; p.index = ctrl_ctx.unwind_count; @@ -484,7 +536,7 @@ internal DF_CmdParams df_cmd_params_from_panel(DF_Window *window, DF_Panel *panel) { DF_CmdParams p = df_cmd_params_zero(); - DF_CtrlCtx ctrl_ctx = df_ctrl_ctx_from_view(window, df_view_from_handle(panel->selected_tab_view)); + DF_CtrlCtx ctrl_ctx = df_ctrl_ctx_from_view(window, df_selected_tab_from_panel(panel)); df_cmd_params_mark_slot(&p, DF_CmdParamSlot_Window); df_cmd_params_mark_slot(&p, DF_CmdParamSlot_Panel); df_cmd_params_mark_slot(&p, DF_CmdParamSlot_View); @@ -493,7 +545,7 @@ df_cmd_params_from_panel(DF_Window *window, DF_Panel *panel) df_cmd_params_mark_slot(&p, DF_CmdParamSlot_Index); p.window = df_handle_from_window(window); p.panel = df_handle_from_panel(panel); - p.view = panel->selected_tab_view; + p.view = df_handle_from_view(df_selected_tab_from_panel(panel)); p.prefer_dasm = df_prefer_dasm_from_window(window); p.entity = ctrl_ctx.thread; p.index = ctrl_ctx.unwind_count; @@ -943,6 +995,7 @@ df_panel_release_all_views(DF_Panel *panel) } panel->first_tab_view = panel->last_tab_view = &df_g_nil_view; panel->selected_tab_view = df_handle_zero(); + panel->tab_view_count = 0; } //////////////////////////////// @@ -1204,7 +1257,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) DF_View *view = df_view_from_handle(params.view); if(df_view_is_nil(view) && !df_panel_is_nil(panel)) { - view = df_view_from_handle(panel->selected_tab_view); + view = df_selected_tab_from_panel(panel); } if(!df_view_is_nil(view)) { @@ -1322,7 +1375,16 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) df_panel_remove_tab_view(move_tab_panel, move_tab); df_panel_insert_tab_view(new_panel, new_panel->last_tab_view, move_tab); new_panel->selected_tab_view = df_handle_from_view(move_tab); - if(df_view_is_nil(move_tab_panel->first_tab_view) && move_tab_panel != ws->root_panel && + B32 move_tab_panel_is_empty = 1; + for(DF_View *v = move_tab_panel->first_tab_view; !df_view_is_nil(v); v = v->next) + { + if(!df_view_is_project_filtered(v)) + { + move_tab_panel_is_empty = 0; + break; + } + } + if(move_tab_panel_is_empty && move_tab_panel != ws->root_panel && move_tab_panel != new_panel->prev && move_tab_panel != new_panel->next) { DF_CmdParams p = df_cmd_params_from_panel(ws, move_tab_panel); @@ -1910,30 +1972,40 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) case DF_CoreCmdKind_NextTab: { DF_Panel *panel = df_panel_from_handle(params.panel); - DF_View *view = df_view_from_handle(panel->selected_tab_view); - view = view->next; - if(df_view_is_nil(view)) + DF_View *view = df_selected_tab_from_panel(panel); + DF_View *next_view = view; + for(DF_View *v = view; !df_view_is_nil(v); v = df_view_is_nil(v->next) ? panel->first_tab_view : v->next) { - view = panel->first_tab_view; + if(!df_view_is_project_filtered(v)) + { + next_view = v; + break; + } } + view = next_view; panel->selected_tab_view = df_handle_from_view(view); }break; case DF_CoreCmdKind_PrevTab: { DF_Panel *panel = df_panel_from_handle(params.panel); - DF_View *view = df_view_from_handle(panel->selected_tab_view); - view = view->prev; - if(df_view_is_nil(view)) + DF_View *view = df_selected_tab_from_panel(panel); + DF_View *next_view = view; + for(DF_View *v = view; !df_view_is_nil(v); v = df_view_is_nil(v->prev) ? panel->last_tab_view : v->prev) { - view = panel->last_tab_view; + if(!df_view_is_project_filtered(v)) + { + next_view = v; + break; + } } + view = next_view; panel->selected_tab_view = df_handle_from_view(view); }break; case DF_CoreCmdKind_MoveTabRight: case DF_CoreCmdKind_MoveTabLeft: { DF_Panel *panel = ws->focused_panel; - DF_View *view = df_view_from_handle(panel->selected_tab_view); + DF_View *view = df_selected_tab_from_panel(panel); DF_View *prev_view = core_cmd_kind == DF_CoreCmdKind_MoveTabRight ? view->next : view->prev->prev; if(!df_view_is_nil(prev_view) || core_cmd_kind == DF_CoreCmdKind_MoveTabLeft) { @@ -1986,7 +2058,16 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) df_panel_remove_tab_view(src_panel, view); df_panel_insert_tab_view(dst_panel, prev_view, view); ws->focused_panel = dst_panel; - if(df_view_is_nil(src_panel->first_tab_view) && src_panel != ws->root_panel) + B32 src_panel_is_empty = 1; + for(DF_View *v = src_panel->first_tab_view; !df_view_is_nil(v); v = v->next) + { + if(!df_view_is_project_filtered(v)) + { + src_panel_is_empty = 0; + break; + } + } + if(src_panel_is_empty && src_panel != ws->root_panel) { DF_CmdParams p = df_cmd_params_from_panel(ws, src_panel); df_cmd_list_push(arena, cmds, &p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_ClosePanel)); @@ -2028,7 +2109,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) DF_Entity *file = df_entity_from_handle(params.entity); for(DF_Panel *panel = ws->root_panel; !df_panel_is_nil(panel); panel = df_panel_rec_df_pre(panel).next) { - DF_View *view = df_view_from_handle(panel->selected_tab_view); + DF_View *view = df_selected_tab_from_panel(panel); DF_Entity *view_entity = df_entity_from_handle(view->entity); if(view_entity == file) { @@ -2039,7 +2120,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) case DF_CoreCmdKind_ReloadActive: { DF_Panel *panel = df_panel_from_handle(params.panel); - DF_View *view = df_view_from_handle(panel->selected_tab_view); + DF_View *view = df_selected_tab_from_panel(panel); DF_Entity *entity = df_entity_from_handle(view->entity); if(entity->kind == DF_EntityKind_File) { @@ -2055,6 +2136,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) DF_Panel *panel = df_panel_from_handle(params.panel); for(DF_View *v = panel->first_tab_view; !df_view_is_nil(v); v = v->next) { + if(df_view_is_project_filtered(v)) { continue; } DF_Entity *v_param_entity = df_entity_from_handle(v->entity); if(v_param_entity == df_entity_from_handle(params.entity)) { @@ -2078,7 +2160,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) case DF_CoreCmdKind_SwitchToPartnerFile: { DF_Panel *panel = df_panel_from_handle(params.panel); - DF_View *view = df_view_from_handle(panel->selected_tab_view); + DF_View *view = df_selected_tab_from_panel(panel); DF_Entity *entity = df_entity_from_handle(view->entity); DF_GfxViewKind view_kind = df_gfx_view_kind_from_string(view->spec->info.name); if(view_kind == DF_GfxViewKind_Code && entity->kind == DF_EntityKind_File) @@ -2963,13 +3045,14 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) } for(DF_View *view = panel->first_tab_view; !df_view_is_nil(view); view = view->next) { + if(df_view_is_project_filtered(view)) { continue; } DF_GfxViewKind view_kind = df_gfx_view_kind_from_string(view->spec->info.name); DF_Entity *viewed_entity = df_entity_from_handle(view->entity); if((view_kind == DF_GfxViewKind_Code || view_kind == DF_GfxViewKind_PendingEntity) && viewed_entity == src_code) { panel_w_this_src_code = panel; view_w_this_src_code = view; - if(view == df_view_from_handle(panel->selected_tab_view)) + if(view == df_selected_tab_from_panel(panel)) { break; } @@ -2987,6 +3070,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) } for(DF_View *view = panel->first_tab_view; !df_view_is_nil(view); view = view->next) { + if(df_view_is_project_filtered(view)) { continue; } DF_GfxViewKind view_kind = df_gfx_view_kind_from_string(view->spec->info.name); if(view_kind == DF_GfxViewKind_Code) { @@ -3007,13 +3091,14 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) } for(DF_View *view = panel->first_tab_view; !df_view_is_nil(view); view = view->next) { + if(df_view_is_project_filtered(view)) { continue; } DF_GfxViewKind view_kind = df_gfx_view_kind_from_string(view->spec->info.name); DF_Entity *viewed_entity = df_entity_from_handle(view->entity); if(view_kind == DF_GfxViewKind_Disassembly) { panel_w_disasm = panel; view_w_disasm = view; - if(view == df_view_from_handle(panel->selected_tab_view)) + if(view == df_selected_tab_from_panel(panel)) { break; } @@ -3057,7 +3142,16 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) Rng2F32 panel_rect = df_target_rect_from_panel(root_rect, ws->root_panel, panel); Vec2F32 panel_rect_dim = dim_2f32(panel_rect); F32 area = panel_rect_dim.x * panel_rect_dim.y; - if(df_view_is_nil(panel->first_tab_view) && (best_panel_area == 0 || area > best_panel_area)) + B32 panel_is_empty = 1; + for(DF_View *v = panel->first_tab_view; !df_view_is_nil(v); v = v->next) + { + if(!df_view_is_project_filtered(v)) + { + panel_is_empty = 0; + break; + } + } + if(panel_is_empty && (best_panel_area == 0 || area > best_panel_area)) { best_panel_area = area; biggest_empty_panel = panel; @@ -3091,7 +3185,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) // rjf: determine if we need a contain or center DF_CoreCmdKind cursor_snap_kind = DF_CoreCmdKind_CenterCursor; - if(!df_panel_is_nil(dst_panel) && dst_view == view_w_this_src_code && df_view_from_handle(dst_panel->selected_tab_view) == dst_view) + if(!df_panel_is_nil(dst_panel) && dst_view == view_w_this_src_code && df_selected_tab_from_panel(dst_panel) == dst_view) { cursor_snap_kind = DF_CoreCmdKind_ContainCursor; } @@ -3099,7 +3193,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) // rjf: move cursor & snap-to-cursor if(!df_panel_is_nil(dst_panel)) { - disasm_view_prioritized = (df_view_from_handle(dst_panel->selected_tab_view) == view_w_disasm); + disasm_view_prioritized = (df_selected_tab_from_panel(dst_panel) == view_w_disasm); dst_panel->selected_tab_view = df_handle_from_view(dst_view); DF_CmdParams params = df_cmd_params_from_view(ws, dst_panel, dst_view); params.text_point = point; @@ -3139,7 +3233,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) // rjf: determine if we need a contain or center DF_CoreCmdKind cursor_snap_kind = DF_CoreCmdKind_CenterCursor; - if(dst_view == view_w_disasm && df_view_from_handle(dst_panel->selected_tab_view) == dst_view) + if(dst_view == view_w_disasm && df_selected_tab_from_panel(dst_panel) == dst_view) { cursor_snap_kind = DF_CoreCmdKind_ContainCursor; } @@ -3167,6 +3261,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) B32 view_is_tab = 0; for(DF_View *tab = panel->first_tab_view; !df_view_is_nil(tab); tab = tab->next) { + if(df_view_is_project_filtered(tab)) { continue; } if(tab == view) { view_is_tab = 1; @@ -3258,6 +3353,48 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) scratch_end(scratch); } + ////////////////////////////// + //- rjf: panels with no selected tabs? -> select. + // panels with selected tabs? -> ensure they have active tabs. + // + for(DF_Panel *panel = ws->root_panel; + !df_panel_is_nil(panel); + panel = df_panel_rec_df_pre(panel).next) + { + if(!df_panel_is_nil(panel->first)) + { + continue; + } + DF_View *view = df_selected_tab_from_panel(panel); + if(df_view_is_nil(view)) + { + for(DF_View *tab = panel->first_tab_view; !df_view_is_nil(tab); tab = tab->next) + { + if(!df_view_is_project_filtered(tab)) + { + panel->selected_tab_view = df_handle_from_view(tab); + break; + } + } + } + if(!df_view_is_nil(view)) + { + B32 found = 0; + for(DF_View *tab = panel->first_tab_view; !df_view_is_nil(tab); tab = tab->next) + { + if(df_view_is_project_filtered(tab)) {continue;} + if(tab == view) + { + found = 1; + } + } + if(!found) + { + panel->selected_tab_view = df_handle_zero(); + } + } + } + ////////////////////////////// //- rjf: process view-level commands on leaf panels // @@ -3271,7 +3408,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) { continue; } - DF_View *view = df_view_from_handle(panel->selected_tab_view); + DF_View *view = df_selected_tab_from_panel(panel); if(!df_view_is_nil(view)) { DF_ViewCmdFunctionType *do_view_cmds_function = view->spec->info.cmd_hook; @@ -5702,7 +5839,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) { if(!df_panel_is_nil(panel->first)) { continue; } Rng2F32 panel_rect = df_target_rect_from_panel(content_rect, ws->root_panel, panel); - DF_View *view = df_view_from_handle(panel->selected_tab_view); + DF_View *view = df_selected_tab_from_panel(panel); if(!df_view_is_nil(view) && contains_2f32(panel_rect, ui_mouse()) && (abs_f32(view->scroll_pos.x.off) > 0.01f || @@ -6369,7 +6506,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) content_rect.y1 = panel_rect.y1 - tab_bar_vheight; } { - DF_View *tab = df_view_from_handle(panel->selected_tab_view); + DF_View *tab = df_selected_tab_from_panel(panel); if(tab->is_filtering_t > 0.01f) { filter_rect.x0 = content_rect.x0; @@ -6568,7 +6705,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) //- rjf: build filtering box // { - DF_View *view = df_view_from_handle(panel->selected_tab_view); + DF_View *view = df_selected_tab_from_panel(panel); UI_Focus(UI_FocusKind_On) { if(view->is_filtering && ui_is_focus_active() && ui_slot_press(UI_EventActionSlot_Accept)) @@ -6643,7 +6780,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) // UI_Parent(panel_box) { - DF_View *view = df_view_from_handle(panel->selected_tab_view); + DF_View *view = df_selected_tab_from_panel(panel); if(view->flash_t >= 0.001f) { UI_Box *panel_box = ui_top_parent(); @@ -6666,7 +6803,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) // UI_Parent(panel_box) { - DF_View *view = df_view_from_handle(panel->selected_tab_view); + DF_View *view = df_selected_tab_from_panel(panel); if(view->loading_t >= 0.001f) { // rjf: set up dimensions @@ -6767,15 +6904,15 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) } //- rjf: build empty view - UI_Parent(view_container_box) if(df_view_is_nil(df_view_from_handle(panel->selected_tab_view))) + UI_Parent(view_container_box) if(df_view_is_nil(df_selected_tab_from_panel(panel))) { DF_VIEW_UI_FUNCTION_NAME(Empty)(ws, panel, &df_g_nil_view, content_rect); } //- rjf: build tab view - UI_Parent(view_container_box) if(!df_view_is_nil(df_view_from_handle(panel->selected_tab_view))) + UI_Parent(view_container_box) if(!df_view_is_nil(df_selected_tab_from_panel(panel))) { - DF_View *view = df_view_from_handle(panel->selected_tab_view); + DF_View *view = df_selected_tab_from_panel(panel); DF_ViewUIFunctionType *build_view_ui_function = view->spec->info.ui_hook; build_view_ui_function(ws, panel, view, content_rect); } @@ -6786,7 +6923,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) // UI_Focus(UI_FocusKind_On) { - DF_View *view = df_view_from_handle(panel->selected_tab_view); + DF_View *view = df_selected_tab_from_panel(panel); if(ui_is_focus_active() && view->spec->info.flags & DF_ViewSpecFlag_TypingAutomaticallyFilters && !view->is_filtering) { DF_CmdParams p = df_cmd_params_from_view(ws, panel, view); @@ -6842,7 +6979,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) }; // rjf: prep output data - DF_View *next_selected_tab_view = df_view_from_handle(panel->selected_tab_view); + DF_View *next_selected_tab_view = df_selected_tab_from_panel(panel); UI_Box *tab_bar_box = &ui_g_nil_box; U64 drop_site_count = panel->tab_view_count+1; DropSite *drop_sites = push_array(scratch.arena, DropSite, drop_site_count); @@ -6874,7 +7011,8 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) { for(DF_View *view = panel->first_tab_view; !df_view_is_nil(view); view = view->next) { - B32 view_is_selected = (view == df_view_from_handle(panel->selected_tab_view)); + if(df_view_is_project_filtered(view)) { continue; } + B32 view_is_selected = (view == df_selected_tab_from_panel(panel)); DF_IconKind icon_kind = df_icon_kind_from_view(view); DF_CtrlCtx ctrl_ctx = df_ctrl_ctx_from_view(ws, view); String8 label = df_display_string_from_view(scratch.arena, ctrl_ctx, view); @@ -6935,6 +7073,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) for(DF_View *view = panel->first_tab_view;; view = view->next, view_idx += 1) { temp_end(scratch); + if(df_view_is_project_filtered(view)) { continue; } // rjf: if before this tab is the prev-view of the current tab drag, // draw empty space @@ -6967,7 +7106,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) } // rjf: gather info for this tab - B32 view_is_selected = (view == df_view_from_handle(panel->selected_tab_view)); + B32 view_is_selected = (view == df_selected_tab_from_panel(panel)); DF_IconKind icon_kind = df_icon_kind_from_view(view); DF_CtrlCtx ctrl_ctx = df_ctrl_ctx_from_view(ws, view); String8 label = df_display_string_from_view(scratch.arena, ctrl_ctx, view); @@ -7260,6 +7399,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) B32 view_is_in_panel = 0; for(DF_View *view = panel->first_tab_view; !df_view_is_nil(view); view = view->next) { + if(df_view_is_project_filtered(view)) { continue; } if(view == dragged_view) { view_is_in_panel = 1; @@ -7347,7 +7487,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) { df_gfx_request_frame(); } - if(view->loading_t_target != 0 && view == df_view_from_handle(panel->selected_tab_view)) + if(view->loading_t_target != 0 && view == df_selected_tab_from_panel(panel)) { df_gfx_request_frame(); } @@ -7368,7 +7508,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) { view->is_filtering_t = (F32)!!view->is_filtering; } - if(view == df_view_from_handle(panel->selected_tab_view)) + if(view == df_selected_tab_from_panel(panel)) { view->loading_t_target = 0; } @@ -9358,7 +9498,7 @@ df_cfg_strings_from_gfx(Arena *arena, String8 root_path, DF_CfgSrc source) // rjf: serialize view parameterizations str8_list_push(arena, &strs, str8_lit(": {")); - if(view == df_view_from_handle(p->selected_tab_view)) + if(view == df_selected_tab_from_panel(p)) { str8_list_push(arena, &strs, str8_lit("selected ")); } @@ -13163,7 +13303,7 @@ df_gfx_begin_frame(Arena *arena, DF_CmdList *cmds) DF_CmdParams p = params; p.window = df_handle_from_window(window); p.panel = df_handle_from_panel(window->focused_panel); - p.view = df_handle_from_view(df_view_from_handle(window->focused_panel->selected_tab_view)); + p.view = df_handle_from_view(df_selected_tab_from_panel(window->focused_panel)); df_cmd_params_mark_slot(&p, DF_CmdParamSlot_Window); df_cmd_params_mark_slot(&p, DF_CmdParamSlot_Panel); df_cmd_params_mark_slot(&p, DF_CmdParamSlot_View); @@ -13454,6 +13594,8 @@ df_gfx_begin_frame(Arena *arena, DF_CmdList *cmds) // rjf: insert if(!df_view_is_nil(view)) { + DF_Entity *current_project = df_entity_from_path(df_cfg_path_from_src(DF_CfgSrc_Project), DF_EntityFromPathFlag_OpenMissing|DF_EntityFromPathFlag_OpenAsNeeded); + DF_Entity *view_project = df_entity_from_handle(view->project); df_panel_insert_tab_view(panel, panel->last_tab_view, view); if(view_is_selected) { diff --git a/src/df/gfx/df_gfx.h b/src/df/gfx/df_gfx.h index 50370808..8e17fe14 100644 --- a/src/df/gfx/df_gfx.h +++ b/src/df/gfx/df_gfx.h @@ -245,7 +245,7 @@ struct DF_Panel // rjf: tab params Side tab_side; - // rjf: stable view stacks (tabs) + // rjf: stable views (tabs) DF_View *first_tab_view; DF_View *last_tab_view; U64 tab_view_count; @@ -803,6 +803,7 @@ internal DF_PathQuery df_path_query_from_string(String8 string); //~ rjf: View Type Functions internal B32 df_view_is_nil(DF_View *view); +internal B32 df_view_is_project_filtered(DF_View *view); internal DF_Handle df_handle_from_view(DF_View *view); internal DF_View *df_view_from_handle(DF_Handle handle); @@ -839,6 +840,7 @@ internal Rng2F32 df_target_rect_from_panel(Rng2F32 root_rect, DF_Panel *root, DF //- rjf: view ownership insertion/removal internal void df_panel_insert_tab_view(DF_Panel *panel, DF_View *prev_view, DF_View *view); internal void df_panel_remove_tab_view(DF_Panel *panel, DF_View *view); +internal DF_View *df_selected_tab_from_panel(DF_Panel *panel); //- rjf: icons & display strings internal String8 df_display_string_from_view(Arena *arena, DF_CtrlCtx ctrl_ctx, DF_View *view); From fd7085b69024b40442344c9e8d486c7bfa0e0429 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 24 May 2024 13:37:31 -0700 Subject: [PATCH 06/39] do not settle for empty unwinds --- src/df/core/df_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/df/core/df_core.c b/src/df/core/df_core.c index 704802c2..31765e41 100644 --- a/src/df/core/df_core.c +++ b/src/df/core/df_core.c @@ -6183,7 +6183,7 @@ df_query_cached_unwind_from_thread(DF_Entity *thread) node->memgen != mem_gen) { CTRL_Unwind new_unwind = ctrl_unwind_from_thread(scratch.arena, df_state->ctrl_entity_store, thread->ctrl_machine_id, thread->ctrl_handle, os_now_microseconds()+100); - if(!(new_unwind.flags & (CTRL_UnwindFlag_Error|CTRL_UnwindFlag_Stale))) + if(!(new_unwind.flags & (CTRL_UnwindFlag_Error|CTRL_UnwindFlag_Stale)) && new_unwind.frames.count != 0) { node->unwind = ctrl_unwind_deep_copy(node->arena, thread->arch, &new_unwind); node->reggen = reg_gen; From 7e0611e7f126d383ec6952931a2c601fab93bb65 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 24 May 2024 14:03:07 -0700 Subject: [PATCH 07/39] recent projects history & opener --- src/df/core/df_core.c | 78 ++++++++++++++++++++++++++++ src/df/core/df_core.mdesk | 4 ++ src/df/core/generated/df_core.meta.c | 18 ++++--- src/df/core/generated/df_core.meta.h | 12 +++-- src/df/gfx/df_gfx.c | 6 ++- 5 files changed, 105 insertions(+), 13 deletions(-) diff --git a/src/df/core/df_core.c b/src/df/core/df_core.c index 31765e41..96bb85dd 100644 --- a/src/df/core/df_core.c +++ b/src/df/core/df_core.c @@ -5729,6 +5729,34 @@ df_cfg_strings_from_core(Arena *arena, String8 root_path, DF_CfgSrc source) ProfBeginFunction(); String8List strs = {0}; + //- rjf: write recent projects + { + B32 first = 1; + DF_EntityList recent_projects = df_query_cached_entity_list_with_kind(DF_EntityKind_RecentProject); + for(DF_EntityNode *n = recent_projects.first; n != 0; n = n->next) + { + DF_Entity *rp = n->entity; + if(rp->cfg_src == source) + { + if(first) + { + first = 0; + str8_list_push(arena, &strs, str8_lit("/// recent projects ///////////////////////////////////////////////////////////\n")); + str8_list_push(arena, &strs, str8_lit("\n")); + } + Temp scratch = scratch_begin(&arena, 1); + String8 path_absolute = path_normalized_from_string(scratch.arena, rp->name); + String8 path_relative = path_relative_dst_from_absolute_dst_src(scratch.arena, path_absolute, root_path); + str8_list_pushf(arena, &strs, "recent_project: {\"%S\"}\n", path_relative); + scratch_end(scratch); + } + } + if(!first) + { + str8_list_push(arena, &strs, str8_lit("\n")); + } + } + //- rjf: write targets { B32 first = 1; @@ -7633,6 +7661,16 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt) }break; //- rjf: config path saving/loading/applying + case DF_CoreCmdKind_OpenRecentProject: + { + DF_Entity *entity = df_entity_from_handle(params.entity); + if(entity->kind == DF_EntityKind_RecentProject) + { + DF_CmdParams p = df_cmd_params_zero(); + p.file_path = entity->name; + df_cmd_list_push(arena, cmds, &p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_OpenProject)); + } + }break; case DF_CoreCmdKind_OpenUser: case DF_CoreCmdKind_OpenProject: { @@ -7804,8 +7842,28 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt) String8 cfg_path = df_cfg_path_from_src(src); String8 cfg_folder = str8_chop_last_slash(cfg_path); + //- rjf: keep track of recent projects + if(src == DF_CfgSrc_Project) + { + DF_Entity *recent_project = df_entity_from_name_and_kind(cfg_path, DF_EntityKind_RecentProject); + if(df_entity_is_nil(recent_project)) + { + recent_project = df_entity_alloc(0, df_entity_root(), DF_EntityKind_RecentProject); + df_entity_equip_name(0, recent_project, cfg_path); + df_entity_equip_cfg_src(recent_project, DF_CfgSrc_User); + } + } + //- rjf: eliminate all existing entities { + DF_EntityList rps = df_query_cached_entity_list_with_kind(DF_EntityKind_RecentProject); + for(DF_EntityNode *n = rps.first; n != 0; n = n->next) + { + if(n->entity->cfg_src == src) + { + df_entity_mark_for_deletion(n->entity); + } + } DF_EntityList targets = df_query_cached_entity_list_with_kind(DF_EntityKind_Target); for(DF_EntityNode *n = targets.first; n != 0; n = n->next) { @@ -7840,6 +7898,26 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt) } } + //- rjf: apply recent projects + DF_CfgVal *recent_projects = df_cfg_val_from_string(table, str8_lit("recent_project")); + for(DF_CfgNode *rp = recent_projects->first; + rp != &df_g_nil_cfg_node; + rp = rp->next) + { + if(rp->source == src) + { + String8 path_saved = rp->first->string; + String8 path_absolute = path_absolute_dst_from_relative_dst_src(scratch.arena, path_saved, cfg_folder); + DF_Entity *existing = df_entity_from_name_and_kind(path_absolute, DF_EntityKind_RecentProject); + if(df_entity_is_nil(existing)) + { + DF_Entity *rp_ent = df_entity_alloc(0, df_entity_root(), DF_EntityKind_RecentProject); + df_entity_equip_cfg_src(rp_ent, src); + df_entity_equip_name(0, rp_ent, path_absolute); + } + } + } + //- rjf: apply targets DF_CfgVal *targets = df_cfg_val_from_string(table, str8_lit("target")); { diff --git a/src/df/core/df_core.mdesk b/src/df/core/df_core.mdesk index 1fd7b6e2..3297cce4 100644 --- a/src/df/core/df_core.mdesk +++ b/src/df/core/df_core.mdesk @@ -47,6 +47,9 @@ DF_EntityKindTable: {ExecutionPath execution_path 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 "Execution Path" Null "Execution Path" } {EntryPointName entry_point_name 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 1 "Symbol Name" Null "Entry Point Name" } + //- rjf: recent projects + {RecentProject recent_project 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 "Path" Briefcase "Recent Project" } + //- rjf: src -> dst mapping {Source source 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "Path" Null "Source" } {Dest dest 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "Path" Null "Destination" } @@ -238,6 +241,7 @@ DF_CoreCmdTable:// | | | //- rjf: setting config paths {OpenUser 0 FilePath Nil 1 0 0 0 0 1 Person "open_user" "Open User" "Opens a user file path, immediately loading it, and begins autosaving to it." "load,user,project,layout" } {OpenProject 0 FilePath Nil 1 0 0 0 0 1 Briefcase "open_project" "Open Project" "Opens a project file path, immediately loading it, and begins autosaving to it." "project,project,session" } + {OpenRecentProject 0 Entity RecentProject 0 0 0 0 0 1 Briefcase "open_recent_project" "Open Recent Project" "Opens a recently used project file." "project,project,session" } //- rjf: loading/applying stateful config changes {ApplyUserData 1 Null Nil 0 0 0 0 0 0 Null "apply_user_data" "Apply User Data" "Applies user data from the active user file." "" } diff --git a/src/df/core/generated/df_core.meta.c b/src/df/core/generated/df_core.meta.c index a95e1ac9..88fc1a8d 100644 --- a/src/df/core/generated/df_core.meta.c +++ b/src/df/core/generated/df_core.meta.c @@ -30,7 +30,7 @@ Rng1U64 df_g_cmd_param_slot_range_table[22] = {OffsetOf(DF_CmdParams, dir2), OffsetOf(DF_CmdParams, dir2) + sizeof(Dir2)}, }; -DF_IconKind df_g_entity_kind_icon_kind_table[25] = +DF_IconKind df_g_entity_kind_icon_kind_table[26] = { DF_IconKind_Null, DF_IconKind_Null, @@ -47,6 +47,7 @@ DF_IconKind_Null, DF_IconKind_Null, DF_IconKind_Null, DF_IconKind_Null, +DF_IconKind_Briefcase, DF_IconKind_Null, DF_IconKind_Null, DF_IconKind_Threads, @@ -59,7 +60,7 @@ DF_IconKind_Null, DF_IconKind_Null, }; -String8 df_g_entity_kind_display_string_table[25] = +String8 df_g_entity_kind_display_string_table[26] = { str8_lit_comp("Nil"), str8_lit_comp("Root"), @@ -76,6 +77,7 @@ str8_lit_comp("Executable"), str8_lit_comp("Arguments"), str8_lit_comp("Execution Path"), str8_lit_comp("Entry Point Name"), +str8_lit_comp("Recent Project"), str8_lit_comp("Source"), str8_lit_comp("Destination"), str8_lit_comp("Process"), @@ -88,7 +90,7 @@ str8_lit_comp("Conversion Failure"), str8_lit_comp("EndedProcess"), }; -String8 df_g_entity_kind_name_label_table[25] = +String8 df_g_entity_kind_name_label_table[26] = { str8_lit_comp("Label"), str8_lit_comp("Label"), @@ -107,6 +109,7 @@ str8_lit_comp("Execution Path"), str8_lit_comp("Symbol Name"), str8_lit_comp("Path"), str8_lit_comp("Path"), +str8_lit_comp("Path"), str8_lit_comp("Label"), str8_lit_comp("Label"), str8_lit_comp("Label"), @@ -117,7 +120,7 @@ str8_lit_comp("Label"), str8_lit_comp("Label"), }; -DF_EntityKindFlags df_g_entity_kind_flags_table[25] = +DF_EntityKindFlags df_g_entity_kind_flags_table[26] = { (0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProjectConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProjectConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime), (0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProjectConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProjectConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime), @@ -134,6 +137,7 @@ DF_EntityKindFlags df_g_entity_kind_flags_table[25] = (0*DF_EntityKindFlag_LeafMutationUserConfig | 1*DF_EntityKindFlag_LeafMutationProjectConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProjectConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 1*DF_EntityKindFlag_UserDefinedLifetime), (0*DF_EntityKindFlag_LeafMutationUserConfig | 1*DF_EntityKindFlag_LeafMutationProjectConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProjectConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 1*DF_EntityKindFlag_UserDefinedLifetime), (0*DF_EntityKindFlag_LeafMutationUserConfig | 1*DF_EntityKindFlag_LeafMutationProjectConfig | 1*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProjectConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 1*DF_EntityKindFlag_UserDefinedLifetime), +(1*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProjectConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 1*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProjectConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime), (0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProjectConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProjectConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime), (0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProjectConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProjectConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime), (0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProjectConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProjectConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime), @@ -146,7 +150,7 @@ DF_EntityKindFlags df_g_entity_kind_flags_table[25] = (0*DF_EntityKindFlag_LeafMutationUserConfig | 0*DF_EntityKindFlag_LeafMutationProjectConfig | 0*DF_EntityKindFlag_LeafMutationSoftHalt | 0*DF_EntityKindFlag_LeafMutationDebugInfoMap | 0*DF_EntityKindFlag_TreeMutationUserConfig | 0*DF_EntityKindFlag_TreeMutationProjectConfig | 0*DF_EntityKindFlag_TreeMutationSoftHalt | 0*DF_EntityKindFlag_TreeMutationDebugInfoMap | 0*DF_EntityKindFlag_NameIsCode | 0*DF_EntityKindFlag_UserDefinedLifetime), }; -DF_EntityOpFlags df_g_entity_kind_op_flags_table[25] = +DF_EntityOpFlags df_g_entity_kind_op_flags_table[26] = { (0*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (0*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate), (0*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (0*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate), @@ -165,6 +169,7 @@ DF_EntityOpFlags df_g_entity_kind_op_flags_table[25] = (0*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (0*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate), (0*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (0*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate), (0*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (0*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate), +(0*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (0*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate), (0*DF_EntityOpFlag_Delete) | (1*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (1*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate), (0*DF_EntityOpFlag_Delete) | (1*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (1*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate), (0*DF_EntityOpFlag_Delete) | (0*DF_EntityOpFlag_Freeze) | (0*DF_EntityOpFlag_Edit) | (0*DF_EntityOpFlag_Rename) | (0*DF_EntityOpFlag_Enable) | (0*DF_EntityOpFlag_Condition) | (0*DF_EntityOpFlag_Duplicate), @@ -207,7 +212,7 @@ DF_CoreCmdKind_Null, DF_CoreCmdKind_Null, }; -DF_CmdSpecInfo df_g_core_cmd_kind_spec_info_table[220] = +DF_CmdSpecInfo df_g_core_cmd_kind_spec_info_table[221] = { { str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null}, { str8_lit_comp("exit"), str8_lit_comp("Exits the debugger."), str8_lit_comp("quit,close,abort"), str8_lit_comp("Exit"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_X}, @@ -303,6 +308,7 @@ DF_CmdSpecInfo df_g_core_cmd_kind_spec_info_table[220] = { str8_lit_comp("set_auto_view_rule_view_rule"), str8_lit_comp("Sets the view rule string for an auto view rule."), str8_lit_comp(""), str8_lit_comp("Set Auto View Rule View Rule"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null}, { str8_lit_comp("open_user"), str8_lit_comp("Opens a user file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("load,user,project,layout"), str8_lit_comp("Open User"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_FilePath, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*1)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_Person}, { str8_lit_comp("open_project"), str8_lit_comp("Opens a project file path, immediately loading it, and begins autosaving to it."), str8_lit_comp("project,project,session"), str8_lit_comp("Open Project"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_FilePath, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*1)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_Briefcase}, +{ str8_lit_comp("open_recent_project"), str8_lit_comp("Opens a recently used project file."), str8_lit_comp("project,project,session"), str8_lit_comp("Open Recent Project"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Entity, DF_EntityKind_RecentProject, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_Briefcase}, { str8_lit_comp("apply_user_data"), str8_lit_comp("Applies user data from the active user file."), str8_lit_comp(""), str8_lit_comp("Apply User Data"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null}, { str8_lit_comp("apply_project_data"), str8_lit_comp("Applies project data from the active project file."), str8_lit_comp(""), str8_lit_comp("Apply Project Data"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null}, { str8_lit_comp("write_user_data"), str8_lit_comp("Writes user data to the active user file."), str8_lit_comp(""), str8_lit_comp("Write User Data"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null}, diff --git a/src/df/core/generated/df_core.meta.h b/src/df/core/generated/df_core.meta.h index f24ccda9..1a63c7ef 100644 --- a/src/df/core/generated/df_core.meta.h +++ b/src/df/core/generated/df_core.meta.h @@ -32,6 +32,7 @@ DF_EntityKind_Executable, DF_EntityKind_Arguments, DF_EntityKind_ExecutionPath, DF_EntityKind_EntryPointName, +DF_EntityKind_RecentProject, DF_EntityKind_Source, DF_EntityKind_Dest, DF_EntityKind_Process, @@ -141,6 +142,7 @@ DF_CoreCmdKind_SetAutoViewRuleType, DF_CoreCmdKind_SetAutoViewRuleViewRule, DF_CoreCmdKind_OpenUser, DF_CoreCmdKind_OpenProject, +DF_CoreCmdKind_OpenRecentProject, DF_CoreCmdKind_ApplyUserData, DF_CoreCmdKind_ApplyProjectData, DF_CoreCmdKind_WriteUserData, @@ -1529,11 +1531,11 @@ struct {B32 *value_ptr; String8 name;} DEV_toggle_table[] = }; C_LINKAGE_BEGIN extern Rng1U64 df_g_cmd_param_slot_range_table[22]; -extern DF_IconKind df_g_entity_kind_icon_kind_table[25]; -extern String8 df_g_entity_kind_display_string_table[25]; -extern String8 df_g_entity_kind_name_label_table[25]; -extern DF_EntityKindFlags df_g_entity_kind_flags_table[25]; -extern DF_EntityOpFlags df_g_entity_kind_op_flags_table[25]; +extern DF_IconKind df_g_entity_kind_icon_kind_table[26]; +extern String8 df_g_entity_kind_display_string_table[26]; +extern String8 df_g_entity_kind_name_label_table[26]; +extern DF_EntityKindFlags df_g_entity_kind_flags_table[26]; +extern DF_EntityOpFlags df_g_entity_kind_op_flags_table[26]; extern String8 df_g_cfg_src_string_table[4]; extern DF_CoreCmdKind df_g_cfg_src_load_cmd_kind_table[4]; extern DF_CoreCmdKind df_g_cfg_src_write_cmd_kind_table[4]; diff --git a/src/df/gfx/df_gfx.c b/src/df/gfx/df_gfx.c index e54a6f30..bdf98d9a 100644 --- a/src/df/gfx/df_gfx.c +++ b/src/df/gfx/df_gfx.c @@ -1976,7 +1976,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) DF_View *next_view = view; for(DF_View *v = view; !df_view_is_nil(v); v = df_view_is_nil(v->next) ? panel->first_tab_view : v->next) { - if(!df_view_is_project_filtered(v)) + if(!df_view_is_project_filtered(v) && v != view) { next_view = v; break; @@ -1992,7 +1992,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) DF_View *next_view = view; for(DF_View *v = view; !df_view_is_nil(v); v = df_view_is_nil(v->prev) ? panel->last_tab_view : v->prev) { - if(!df_view_is_project_filtered(v)) + if(!df_view_is_project_filtered(v) && v != view) { next_view = v; break; @@ -4724,6 +4724,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) DF_CoreCmdKind_Open, DF_CoreCmdKind_OpenUser, DF_CoreCmdKind_OpenProject, + DF_CoreCmdKind_OpenRecentProject, DF_CoreCmdKind_Exit, }; U32 codepoints[] = @@ -4731,6 +4732,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) 'o', 'u', 'p', + 'r', 'x', }; Assert(ArrayCount(codepoints) == ArrayCount(cmds)); From fd982d38fc945c2422314db5251890c3eea6760e Mon Sep 17 00:00:00 2001 From: Martins Mozeiko Date: Fri, 24 May 2024 12:17:29 -0700 Subject: [PATCH 08/39] Fixes bad resource usage in rendering D3D11 is quite strict about how resources are supposed to be used - read/write & CPU access. This changes Tex2DKind and BufferKind into one uniform ResourceKind (because it's the same thing really). And it is more strict about usage: 1) Static is not allowed to update, resource is immutable, data provided at creation 2) Dynamic allows CPU to update GPU resource occasionally via UpdateSubresource 3) Stream allows CPU to update GPU resource often via Map/Unmap (currently unused) --- src/df/gfx/df_gfx.c | 2 +- src/font_cache/font_cache.c | 2 +- src/geo_cache/geo_cache.c | 2 +- src/render/d3d11/render_d3d11.cpp | 83 +++++++++++++++--------------- src/render/d3d11/render_d3d11.h | 5 +- src/render/generated/render.meta.c | 5 +- src/render/generated/render.meta.h | 20 +++---- src/render/render_core.h | 6 +-- src/render/render_core.mdesk | 32 ++++++------ src/render/stub/render_stub.c | 8 +-- src/texture_cache/texture_cache.c | 2 +- 11 files changed, 80 insertions(+), 87 deletions(-) diff --git a/src/df/gfx/df_gfx.c b/src/df/gfx/df_gfx.c index bdf98d9a..b6688f78 100644 --- a/src/df/gfx/df_gfx.c +++ b/src/df/gfx/df_gfx.c @@ -13091,7 +13091,7 @@ df_gfx_init(OS_WindowRepaintFunctionType *window_repaint_entry_point, DF_StateDe } // rjf: upload to gpu texture - df_gfx_state->icon_texture = r_tex2d_alloc(R_Tex2DKind_Static, image_dim, R_Tex2DFormat_RGBA8, image_data); + df_gfx_state->icon_texture = r_tex2d_alloc(R_ResourceKind_Static, image_dim, R_Tex2DFormat_RGBA8, image_data); // rjf: release stbi_image_free(image_data); diff --git a/src/font_cache/font_cache.c b/src/font_cache/font_cache.c index b3b8eaa2..cd659722 100644 --- a/src/font_cache/font_cache.c +++ b/src/font_cache/font_cache.c @@ -704,7 +704,7 @@ f_push_run_from_string(Arena *arena, F_Tag tag, F32 size, F_RunFlags flags, Stri atlas->root->max_free_size[Corner_01] = atlas->root->max_free_size[Corner_10] = atlas->root->max_free_size[Corner_11] = v2s16(atlas->root_dim.x/2, atlas->root_dim.y/2); - atlas->texture = r_tex2d_alloc(R_Tex2DKind_Dynamic, v2s32((S32)atlas->root_dim.x, (S32)atlas->root_dim.y), R_Tex2DFormat_RGBA8, 0); + atlas->texture = r_tex2d_alloc(R_ResourceKind_Dynamic, v2s32((S32)atlas->root_dim.x, (S32)atlas->root_dim.y), R_Tex2DFormat_RGBA8, 0); } // rjf: allocate from atlas diff --git a/src/geo_cache/geo_cache.c b/src/geo_cache/geo_cache.c index cec24960..587a76fd 100644 --- a/src/geo_cache/geo_cache.c +++ b/src/geo_cache/geo_cache.c @@ -301,7 +301,7 @@ geo_xfer_thread__entry_point(void *p) R_Handle buffer = {0}; if(got_task && data.size != 0) { - buffer = r_buffer_alloc(R_BufferKind_Static, data.size, data.str); + buffer = r_buffer_alloc(R_ResourceKind_Static, data.size, data.str); } //- rjf: commit results to cache diff --git a/src/render/d3d11/render_d3d11.cpp b/src/render/d3d11/render_d3d11.cpp index eef97d94..20686650 100644 --- a/src/render/d3d11/render_d3d11.cpp +++ b/src/render/d3d11/render_d3d11.cpp @@ -125,6 +125,34 @@ r_d3d11_instance_buffer_from_size(U64 size) return buffer; } +internal +void r_res_kind_to_usage(R_ResourceKind kind, D3D11_USAGE* d3d11_usage, UINT* cpu_access_flags) +{ + //- rjf: kind -> usage * cpu access flags + switch(kind) + { + case R_ResourceKind_Static: + { + *d3d11_usage = D3D11_USAGE_IMMUTABLE; + *cpu_access_flags = 0; + }break; + case R_ResourceKind_Dynamic: + { + *d3d11_usage = D3D11_USAGE_DEFAULT; + *cpu_access_flags = 0; + }break; + case R_ResourceKind_Stream: + { + *d3d11_usage = D3D11_USAGE_DYNAMIC; + *cpu_access_flags = D3D11_CPU_ACCESS_WRITE; + }break; + default: + { + InvalidPath; + } + } +} + //////////////////////////////// //~ rjf: Backend Hook Implementations @@ -428,7 +456,7 @@ r_init(CmdLine *cmdln) 0xff00ffff, 0x330033ff, 0x330033ff, 0xff00ffff, }; - r_d3d11_state->backup_texture = r_tex2d_alloc(R_Tex2DKind_Static, v2s32(2, 2), R_Tex2DFormat_RGBA8, backup_texture_data); + r_d3d11_state->backup_texture = r_tex2d_alloc(R_ResourceKind_Static, v2s32(2, 2), R_Tex2DFormat_RGBA8, backup_texture_data); } //- rjf: initialize buffer flush state @@ -534,7 +562,7 @@ r_window_unequip(OS_Handle handle, R_Handle equip_handle) //- rjf: textures r_hook R_Handle -r_tex2d_alloc(R_Tex2DKind kind, Vec2S32 size, R_Tex2DFormat format, void *data) +r_tex2d_alloc(R_ResourceKind kind, Vec2S32 size, R_Tex2DFormat format, void *data) { ProfBeginFunction(); @@ -557,27 +585,12 @@ r_tex2d_alloc(R_Tex2DKind kind, Vec2S32 size, R_Tex2DFormat format, void *data) texture->generation += 1; } - //- rjf: kind * initial_data -> usage * cpu access flags - D3D11_USAGE d3d11_usage = D3D11_USAGE_IMMUTABLE; + D3D11_USAGE d3d11_usage = D3D11_USAGE_DEFAULT; UINT cpu_access_flags = 0; + r_res_kind_to_usage(kind, &d3d11_usage, &cpu_access_flags); + if (kind == R_ResourceKind_Static) { - switch(kind) - { - default: - case R_Tex2DKind_Static: - { - if(data == 0) - { - d3d11_usage = D3D11_USAGE_DYNAMIC; - cpu_access_flags = D3D11_CPU_ACCESS_WRITE; - } - }break; - case R_Tex2DKind_Dynamic: - { - d3d11_usage = D3D11_USAGE_DEFAULT; - cpu_access_flags = D3D11_CPU_ACCESS_WRITE; - }break; - } + Assert(data != 0 && "static texture must have initial data provided"); } //- rjf: format -> dxgi format @@ -650,7 +663,7 @@ r_tex2d_release(R_Handle handle) ProfEnd(); } -r_hook R_Tex2DKind +r_hook R_ResourceKind r_kind_from_tex2d(R_Handle handle) { R_D3D11_Tex2D *texture = r_d3d11_tex2d_from_handle(handle); @@ -678,6 +691,7 @@ r_fill_tex2d_region(R_Handle handle, Rng2S32 subrect, void *data) OS_MutexScopeW(r_d3d11_state->device_rw_mutex) { R_D3D11_Tex2D *texture = r_d3d11_tex2d_from_handle(handle); + Assert(texture->kind == R_ResourceKind_Dynamic && "only dynamic texture can update region"); U64 bytes_per_pixel = r_tex2d_format_bytes_per_pixel_table[texture->format]; Vec2S32 dim = v2s32(subrect.x1 - subrect.x0, subrect.y1 - subrect.y0); D3D11_BOX dst_box = @@ -693,7 +707,7 @@ r_fill_tex2d_region(R_Handle handle, Rng2S32 subrect, void *data) //- rjf: buffers r_hook R_Handle -r_buffer_alloc(R_BufferKind kind, U64 size, void *data) +r_buffer_alloc(R_ResourceKind kind, U64 size, void *data) { ProfBeginFunction(); @@ -716,27 +730,12 @@ r_buffer_alloc(R_BufferKind kind, U64 size, void *data) buffer->generation += 1; } - //- rjf: kind * initial_data -> usage * cpu access flags - D3D11_USAGE d3d11_usage = D3D11_USAGE_IMMUTABLE; + D3D11_USAGE d3d11_usage = D3D11_USAGE_DEFAULT; UINT cpu_access_flags = 0; + r_res_kind_to_usage(kind, &d3d11_usage, &cpu_access_flags); + if (kind == R_ResourceKind_Static) { - switch(kind) - { - default: - case R_BufferKind_Static: - { - if(data == 0) - { - d3d11_usage = D3D11_USAGE_DYNAMIC; - cpu_access_flags = D3D11_CPU_ACCESS_WRITE; - } - }break; - case R_BufferKind_Dynamic: - { - d3d11_usage = D3D11_USAGE_DEFAULT; - cpu_access_flags = D3D11_CPU_ACCESS_WRITE; - }break; - } + Assert(data != 0 && "static buffer must have initial data provided"); } //- rjf: prep initial data, if passed diff --git a/src/render/d3d11/render_d3d11.h b/src/render/d3d11/render_d3d11.h index 0be2f145..b25b4e4b 100644 --- a/src/render/d3d11/render_d3d11.h +++ b/src/render/d3d11/render_d3d11.h @@ -63,7 +63,7 @@ struct R_D3D11_Tex2D U64 generation; ID3D11Texture2D *texture; ID3D11ShaderResourceView *view; - R_Tex2DKind kind; + R_ResourceKind kind; Vec2S32 size; R_Tex2DFormat format; }; @@ -73,7 +73,7 @@ struct R_D3D11_Buffer R_D3D11_Buffer *next; U64 generation; ID3D11Buffer *buffer; - R_BufferKind kind; + R_ResourceKind kind; U64 size; }; @@ -173,5 +173,6 @@ internal R_Handle r_d3d11_handle_from_tex2d(R_D3D11_Tex2D *texture); internal R_D3D11_Buffer *r_d3d11_buffer_from_handle(R_Handle handle); internal R_Handle r_d3d11_handle_from_buffer(R_D3D11_Buffer *buffer); internal ID3D11Buffer *r_d3d11_instance_buffer_from_size(U64 size); +internal void r_res_kind_to_usage(R_ResourceKind kind, D3D11_USAGE* d3d11_usage, UINT* cpu_access_flags); #endif // RENDER_D3D11_H diff --git a/src/render/generated/render.meta.c b/src/render/generated/render.meta.c index ca405579..55fcceef 100644 --- a/src/render/generated/render.meta.c +++ b/src/render/generated/render.meta.c @@ -30,10 +30,9 @@ U8 r_tex2d_format_bytes_per_pixel_table[9] = 16, }; -String8 r_tex2d_kind_display_string_table[2] = +String8 r_tex2d_kind_display_string_table[1] = { -str8_lit_comp("Static"), -str8_lit_comp("Dynamic"), +str8_lit_comp("$(a.display_string)"), }; String8 r_tex2d_sample_kind_display_string_table[2] = diff --git a/src/render/generated/render.meta.h b/src/render/generated/render.meta.h index 5ab27d47..5c4081e6 100644 --- a/src/render/generated/render.meta.h +++ b/src/render/generated/render.meta.h @@ -20,12 +20,13 @@ R_Tex2DFormat_RGBA32, R_Tex2DFormat_COUNT, } R_Tex2DFormat; -typedef enum R_Tex2DKind +typedef enum R_ResourceKind { -R_Tex2DKind_Static, -R_Tex2DKind_Dynamic, -R_Tex2DKind_COUNT, -} R_Tex2DKind; +R_ResourceKind_Static, +R_ResourceKind_Dynamic, +R_ResourceKind_Stream, +R_ResourceKind_COUNT, +} R_ResourceKind; typedef enum R_Tex2DSampleKind { @@ -43,13 +44,6 @@ R_GeoTopologyKind_TriangleStrip, R_GeoTopologyKind_COUNT, } R_GeoTopologyKind; -typedef enum R_BufferKind -{ -R_BufferKind_Static, -R_BufferKind_Dynamic, -R_BufferKind_COUNT, -} R_BufferKind; - typedef enum R_PassKind { R_PassKind_UI, @@ -61,7 +55,7 @@ R_PassKind_COUNT, C_LINKAGE_BEGIN extern String8 r_tex2d_format_display_string_table[9]; extern U8 r_tex2d_format_bytes_per_pixel_table[9]; -extern String8 r_tex2d_kind_display_string_table[2]; +extern String8 r_tex2d_kind_display_string_table[1]; extern String8 r_tex2d_sample_kind_display_string_table[2]; extern String8 r_pass_kind_display_string_table[3]; extern U8 r_pass_kind_batch_table[3]; diff --git a/src/render/render_core.h b/src/render/render_core.h index e4db1699..d2c130a6 100644 --- a/src/render/render_core.h +++ b/src/render/render_core.h @@ -221,15 +221,15 @@ r_hook R_Handle r_window_equip(OS_Handle window); r_hook void r_window_unequip(OS_Handle window, R_Handle window_equip); //- rjf: textures -r_hook R_Handle r_tex2d_alloc(R_Tex2DKind kind, Vec2S32 size, R_Tex2DFormat format, void *data); +r_hook R_Handle r_tex2d_alloc(R_ResourceKind kind, Vec2S32 size, R_Tex2DFormat format, void *data); r_hook void r_tex2d_release(R_Handle texture); -r_hook R_Tex2DKind r_kind_from_tex2d(R_Handle texture); +r_hook R_ResourceKind r_kind_from_tex2d(R_Handle texture); r_hook Vec2S32 r_size_from_tex2d(R_Handle texture); r_hook R_Tex2DFormat r_format_from_tex2d(R_Handle texture); r_hook void r_fill_tex2d_region(R_Handle texture, Rng2S32 subrect, void *data); //- rjf: buffers -r_hook R_Handle r_buffer_alloc(R_BufferKind kind, U64 size, void *data); +r_hook R_Handle r_buffer_alloc(R_ResourceKind kind, U64 size, void *data); r_hook void r_buffer_release(R_Handle buffer); //- rjf: frame markers diff --git a/src/render/render_core.mdesk b/src/render/render_core.mdesk index ba3eff73..2aea3963 100644 --- a/src/render/render_core.mdesk +++ b/src/render/render_core.mdesk @@ -19,10 +19,23 @@ R_Tex2DFormatTable: } @table(name, display_string) -R_Tex2DKindTable: +R_ResourceKindTable: { + // static resource is immutable + // initial data must be provided at creation time + // GPU can read the resource + // CPU is not allowed to read or write {Static "Static" } + + // dynamic resource allows resource to be modified + // GPU can read & write to it + // CPU can write to it using UpdateSubresource {Dynamic "Dynamic"} + + // stream resource will be often updated fully overwriting previous data + // GPU can only read it + // CPU can update via Map (with WRITE_DISCARD flag) + Unmap + {Stream "Stream "} } @table(name, display_string) @@ -41,13 +54,6 @@ R_GeoTopologyKindTable: {TriangleStrip "Triangle Strip" } } -@table(name, display_string) -R_BufferKindTable: -{ - {Static "Static" } - {Dynamic "Dynamic"} -} - @table(name, batch, display_string) R_PassKindTable: { @@ -65,9 +71,9 @@ R_PassKindTable: COUNT, } -@enum R_Tex2DKind: +@enum R_ResourceKind: { - @expand(R_Tex2DKindTable a) `$(a.name)`, + @expand(R_ResourceKindTable a) `$(a.name)`, COUNT, } @@ -83,12 +89,6 @@ R_PassKindTable: COUNT, } -@enum R_BufferKind: -{ - @expand(R_BufferKindTable a) `$(a.name)`, - COUNT, -} - @enum R_PassKind: { @expand(R_PassKindTable a) `$(a.name)`, diff --git a/src/render/stub/render_stub.c b/src/render/stub/render_stub.c index 721af66c..b64dfa83 100644 --- a/src/render/stub/render_stub.c +++ b/src/render/stub/render_stub.c @@ -26,7 +26,7 @@ r_window_unequip(OS_Handle window, R_Handle window_equip) //- rjf: textures r_hook R_Handle -r_tex2d_alloc(R_Tex2DKind kind, Vec2S32 size, R_Tex2DFormat format, void *data) +r_tex2d_alloc(R_ResourceKind kind, Vec2S32 size, R_Tex2DFormat format, void *data) { R_Handle handle = {0}; handle.u64[0] = 1; @@ -38,10 +38,10 @@ r_tex2d_release(R_Handle texture) { } -r_hook R_Tex2DKind +r_hook R_ResourceKind r_kind_from_tex2d(R_Handle texture) { - return R_Tex2DKind_Static; + return R_ResourceStatic; } r_hook Vec2S32 @@ -64,7 +64,7 @@ r_fill_tex2d_region(R_Handle texture, Rng2S32 subrect, void *data) //- rjf: buffers r_hook R_Handle -r_buffer_alloc(R_BufferKind kind, U64 size, void *data) +r_buffer_alloc(R_ResourceKind kind, U64 size, void *data) { R_Handle handle = {0}; handle.u64[0] = 1; diff --git a/src/texture_cache/texture_cache.c b/src/texture_cache/texture_cache.c index 300eda12..bae57895 100644 --- a/src/texture_cache/texture_cache.c +++ b/src/texture_cache/texture_cache.c @@ -319,7 +319,7 @@ tex_xfer_thread__entry_point(void *p) R_Handle texture = {0}; if(got_task && top.dim.x > 0 && top.dim.y > 0 && data.size >= (U64)top.dim.x*(U64)top.dim.y*(U64)r_tex2d_format_bytes_per_pixel_table[top.fmt]) { - texture = r_tex2d_alloc(R_Tex2DKind_Static, v2s32(top.dim.x, top.dim.y), top.fmt, data.str); + texture = r_tex2d_alloc(R_ResourceKind_Static, v2s32(top.dim.x, top.dim.y), top.fmt, data.str); } //- rjf: commit results to cache From 5074b7f62e53810d79f75322164e9a10fd173627 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 24 May 2024 14:40:07 -0700 Subject: [PATCH 09/39] expand f_push_run_from_... to basing its tab-advance logic on what base column it is starting at - currently assume this is 0, basically doing the most naive tab alignment version that will work for leading spaces but for nothing else, and also assume 4-space tab width for now --- src/df/gfx/df_views.c | 6 +++--- src/font_cache/font_cache.c | 11 ++++++++++- src/render/d3d11/render_d3d11.cpp | 21 ++++++++++----------- src/render/d3d11/render_d3d11.h | 2 +- 4 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/df/gfx/df_views.c b/src/df/gfx/df_views.c index dfa997ce..e2704bb2 100644 --- a/src/df/gfx/df_views.c +++ b/src/df/gfx/df_views.c @@ -6534,7 +6534,7 @@ DF_VIEW_UI_FUNCTION_DEF(Code) { ui_label(full_path); ui_spacer(ui_em(1.5f, 1)); - ui_labelf("Line: %I64d, Col: %I64d", tv->cursor.line, tv->cursor.column); + ui_labelf("Line: %I64d, Column: %I64d", tv->cursor.line, tv->cursor.column); ui_spacer(ui_pct(1, 0)); ui_labelf("(read only)"); ui_labelf("%s", @@ -7386,7 +7386,7 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly) U64 cursor_vaddr = (1 <= dv->cursor.line && dv->cursor.line <= dasm_info.insts.count) ? (dasm_vaddr_range.min+dasm_info.insts.v[dv->cursor.line-1].code_off) : 0; ui_labelf("%S", path_normalized_from_string(scratch.arena, module->name)); ui_spacer(ui_em(1.5f, 1)); - ui_labelf("Address: 0x%I64x, Line: %I64d, Col: %I64d", cursor_vaddr, dv->cursor.line, dv->cursor.column); + ui_labelf("Address: 0x%I64x, Line: %I64d, Column: %I64d", cursor_vaddr, dv->cursor.line, dv->cursor.column); ui_spacer(ui_pct(1, 0)); ui_labelf("(read only)"); ui_labelf("bin"); @@ -8180,7 +8180,7 @@ DF_VIEW_UI_FUNCTION_DEF(Output) UI_TextColor(df_rgba_from_theme_color(DF_ThemeColor_WeakText)) UI_Font(code_font) { - ui_labelf("Line: %I64d, Col: %I64d", tv->cursor.line, tv->cursor.column); + ui_labelf("Line: %I64d, Column: %I64d", tv->cursor.line, tv->cursor.column); ui_spacer(ui_pct(1, 0)); ui_labelf("(read only)"); } diff --git a/src/font_cache/font_cache.c b/src/font_cache/font_cache.c index cd659722..63312654 100644 --- a/src/font_cache/font_cache.c +++ b/src/font_cache/font_cache.c @@ -568,6 +568,7 @@ internal F_Run f_push_run_from_string(Arena *arena, F_Tag tag, F32 size, F_RunFlags flags, String8 string) { ProfBeginFunction(); + F32 base_column = 0.f; //- rjf: map tag/size to style node F_Hash2StyleRasterCacheNode *hash2style_node = f_hash2style_from_tag_size(tag, size); @@ -788,6 +789,14 @@ f_push_run_from_string(Arena *arena, F_Tag tag, F32 size, F_RunFlags flags, Stri } } + // rjf: on tabs -> expand advance + F32 advance = info->advance; + if(is_tab) + { + F32 tab_width = 4.f; + advance *= tab_width - mod_f32(base_column, tab_width); + } + // rjf: push piece { F_Piece *piece = f_piece_chunk_list_push_new(arena, &piece_chunks, string.size); @@ -797,7 +806,7 @@ f_push_run_from_string(Arena *arena, F_Tag tag, F32 size, F_RunFlags flags, Stri info->subrect.y0, info->subrect.x0 + info->raster_dim.x, info->subrect.y0 + info->raster_dim.y); - piece->advance = info->advance; + piece->advance = advance; piece->decode_size = piece_substring.size; piece->offset = v2s16(0, -hash2style_node->ascent - 4); } diff --git a/src/render/d3d11/render_d3d11.cpp b/src/render/d3d11/render_d3d11.cpp index 20686650..708d1a59 100644 --- a/src/render/d3d11/render_d3d11.cpp +++ b/src/render/d3d11/render_d3d11.cpp @@ -125,26 +125,25 @@ r_d3d11_instance_buffer_from_size(U64 size) return buffer; } -internal -void r_res_kind_to_usage(R_ResourceKind kind, D3D11_USAGE* d3d11_usage, UINT* cpu_access_flags) +internal void +r_usage_access_flags_from_resource_kind(R_ResourceKind kind, D3D11_USAGE *out_d3d11_usage, UINT *out_cpu_access_flags) { - //- rjf: kind -> usage * cpu access flags switch(kind) { case R_ResourceKind_Static: { - *d3d11_usage = D3D11_USAGE_IMMUTABLE; - *cpu_access_flags = 0; + *out_d3d11_usage = D3D11_USAGE_IMMUTABLE; + *out_cpu_access_flags = 0; }break; case R_ResourceKind_Dynamic: { - *d3d11_usage = D3D11_USAGE_DEFAULT; - *cpu_access_flags = 0; + *out_d3d11_usage = D3D11_USAGE_DEFAULT; + *out_cpu_access_flags = 0; }break; case R_ResourceKind_Stream: { - *d3d11_usage = D3D11_USAGE_DYNAMIC; - *cpu_access_flags = D3D11_CPU_ACCESS_WRITE; + *out_d3d11_usage = D3D11_USAGE_DYNAMIC; + *out_cpu_access_flags = D3D11_CPU_ACCESS_WRITE; }break; default: { @@ -587,7 +586,7 @@ r_tex2d_alloc(R_ResourceKind kind, Vec2S32 size, R_Tex2DFormat format, void *dat D3D11_USAGE d3d11_usage = D3D11_USAGE_DEFAULT; UINT cpu_access_flags = 0; - r_res_kind_to_usage(kind, &d3d11_usage, &cpu_access_flags); + r_usage_access_flags_from_resource_kind(kind, &d3d11_usage, &cpu_access_flags); if (kind == R_ResourceKind_Static) { Assert(data != 0 && "static texture must have initial data provided"); @@ -732,7 +731,7 @@ r_buffer_alloc(R_ResourceKind kind, U64 size, void *data) D3D11_USAGE d3d11_usage = D3D11_USAGE_DEFAULT; UINT cpu_access_flags = 0; - r_res_kind_to_usage(kind, &d3d11_usage, &cpu_access_flags); + r_usage_access_flags_from_resource_kind(kind, &d3d11_usage, &cpu_access_flags); if (kind == R_ResourceKind_Static) { Assert(data != 0 && "static buffer must have initial data provided"); diff --git a/src/render/d3d11/render_d3d11.h b/src/render/d3d11/render_d3d11.h index b25b4e4b..47d14d93 100644 --- a/src/render/d3d11/render_d3d11.h +++ b/src/render/d3d11/render_d3d11.h @@ -173,6 +173,6 @@ internal R_Handle r_d3d11_handle_from_tex2d(R_D3D11_Tex2D *texture); internal R_D3D11_Buffer *r_d3d11_buffer_from_handle(R_Handle handle); internal R_Handle r_d3d11_handle_from_buffer(R_D3D11_Buffer *buffer); internal ID3D11Buffer *r_d3d11_instance_buffer_from_size(U64 size); -internal void r_res_kind_to_usage(R_ResourceKind kind, D3D11_USAGE* d3d11_usage, UINT* cpu_access_flags); +internal void r_usage_access_flags_from_resource_kind(R_ResourceKind kind, D3D11_USAGE *out_d3d11_usage, UINT *out_cpu_access_flags); #endif // RENDER_D3D11_H From d716159faf093da9db7ca6d4521fc643627a2f4a Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 24 May 2024 15:12:40 -0700 Subject: [PATCH 10/39] feed base column & tab width through all font rendering paths; use temporary constants --- src/df/gfx/df_gfx.c | 106 +++++++++++++++++++++--------------- src/df/gfx/df_views.c | 24 ++++---- src/draw/draw.c | 22 ++++---- src/draw/draw.h | 10 ++-- src/font_cache/font_cache.c | 20 +++---- src/font_cache/font_cache.h | 10 ++-- src/ui/ui_basic_widgets.c | 10 ++-- src/ui/ui_core.c | 10 ++-- src/ui/ui_core.h | 4 ++ 9 files changed, 117 insertions(+), 99 deletions(-) diff --git a/src/df/gfx/df_gfx.c b/src/df/gfx/df_gfx.c index b6688f78..a4be7d9a 100644 --- a/src/df/gfx/df_gfx.c +++ b/src/df/gfx/df_gfx.c @@ -1045,11 +1045,17 @@ df_window_open(Vec2F32 size, OS_Handle preferred_monitor, DF_CfgSrc cfg_src) { Temp scratch = scratch_begin(0, 0); DF_FontSlot slot = english_font_slots[idx]; + String8 sample_text = str8_lit("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890~!@#$%^&*()-_+=[{]}\\|;:'\",<.>/?"); f_push_run_from_string(scratch.arena, df_font_from_slot(slot), - df_font_size_from_slot(window, slot), - 0, - str8_lit("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890~!@#$%^&*()-_+=[{]}\\|;:'\",<.>/?")); + df_font_size_from_slot(window, DF_FontSlot_Code), + 0, 0, 0, + sample_text); + f_push_run_from_string(scratch.arena, + df_font_from_slot(slot), + df_font_size_from_slot(window, DF_FontSlot_Main), + 0, 0, 0, + sample_text); scratch_end(scratch); } for(DF_IconKind icon_kind = DF_IconKind_Null; icon_kind < DF_IconKind_COUNT; icon_kind = (DF_IconKind)(icon_kind+1)) @@ -1058,7 +1064,17 @@ df_window_open(Vec2F32 size, OS_Handle preferred_monitor, DF_CfgSrc cfg_src) f_push_run_from_string(scratch.arena, df_font_from_slot(icon_font_slot), df_font_size_from_slot(window, icon_font_slot), - 0, + 0, 0, 0, + df_g_icon_kind_text_table[icon_kind]); + f_push_run_from_string(scratch.arena, + df_font_from_slot(icon_font_slot), + df_font_size_from_slot(window, DF_FontSlot_Main), + 0, 0, 0, + df_g_icon_kind_text_table[icon_kind]); + f_push_run_from_string(scratch.arena, + df_font_from_slot(icon_font_slot), + df_font_size_from_slot(window, DF_FontSlot_Code), + 0, 0, 0, df_g_icon_kind_text_table[icon_kind]); scratch_end(scratch); } @@ -5976,7 +5992,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) //- rjf: calculate width of exp row if(row == viz_rows.first) { - expr_column_width_px = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), row->display_expr).x + ui_top_font_size()*0.5f; + expr_column_width_px = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, UI_TEMP_TAB_WIDTH, row->display_expr).x + ui_top_font_size()*0.5f; expr_column_width_px = Max(expr_column_width_px, ui_top_font_size()*10.f); } @@ -7814,7 +7830,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) if(!(box->flags & UI_BoxFlag_DisableTextTrunc)) { max_x = (box->rect.x1-text_position.x); - ellipses_run = f_push_run_from_string(scratch.arena, box->font, box->font_size, 0, str8_lit("...")); + ellipses_run = f_push_run_from_string(scratch.arena, box->font, box->font_size, 0, UI_TEMP_TAB_WIDTH, 0, str8_lit("...")); } d_truncated_fancy_run_list(text_position, &box->display_string_runs, max_x, ellipses_run); if(box->flags & UI_BoxFlag_HasFuzzyMatchRanges) @@ -8083,8 +8099,8 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) d_fancy_string_list_push(scratch.arena, &strs, &str2); D_FancyString str3 = {df_font_from_slot(DF_FontSlot_Code), str8_lit("very fancy text!"), v4f32(1, 0.8f, 0.4f, 1), 18.f, 4.f, 4.f}; d_fancy_string_list_push(scratch.arena, &strs, &str3); - D_FancyRunList runs = d_fancy_run_list_from_fancy_string_list(scratch.arena, &strs); - F_Run trailer_run = f_push_run_from_string(scratch.arena, df_font_from_slot(DF_FontSlot_Main), 16.f, 0, str8_lit("...")); + D_FancyRunList runs = d_fancy_run_list_from_fancy_string_list(scratch.arena, UI_TEMP_TAB_WIDTH, &strs); + F_Run trailer_run = f_push_run_from_string(scratch.arena, df_font_from_slot(DF_FontSlot_Main), 16.f, 0, UI_TEMP_TAB_WIDTH, 0, str8_lit("...")); F32 limit = 500.f + sin_f32(df_time_in_seconds()/10.f)*200.f; d_truncated_fancy_run_list(p, &runs, limit, trailer_run); d_rect(r2f32p(p.x+limit, 0, p.x+limit+2.f, 1000), v4f32(1, 0, 0, 1), 0, 0, 0); @@ -8202,7 +8218,7 @@ df_single_line_eval_value_strings_from_eval(Arena *arena, DF_EvalVizStringFlags { DF_Eval value_eval = df_value_mode_eval_from_eval(graph, rdi, ctrl_ctx, eval); String8 string = df_string_from_simple_typed_eval(arena, graph, rdi, flags, radix, value_eval); - space_taken += f_dim_from_tag_size_string(font, font_size, string).x; + space_taken += f_dim_from_tag_size_string(font, font_size, 0, 0, string).x; str8_list_push(arena, &list, string); }break; @@ -8242,7 +8258,7 @@ df_single_line_eval_value_strings_from_eval(Arena *arena, DF_EvalVizStringFlags { did_ptr_value = 1; String8 string = df_string_from_simple_typed_eval(arena, graph, rdi, flags, radix, value_eval); - space_taken += f_dim_from_tag_size_string(font, font_size, string).x; + space_taken += f_dim_from_tag_size_string(font, font_size, 0, 0, string).x; str8_list_push(arena, &list, string); } @@ -8251,7 +8267,7 @@ df_single_line_eval_value_strings_from_eval(Arena *arena, DF_EvalVizStringFlags { String8 arrow = str8_lit(" -> "); str8_list_push(arena, &list, arrow); - space_taken += f_dim_from_tag_size_string(font, font_size, arrow).x; + space_taken += f_dim_from_tag_size_string(font, font_size, 0, 0, arrow).x; } // rjf: special-case: strings @@ -8268,8 +8284,8 @@ df_single_line_eval_value_strings_from_eval(Arena *arena, DF_EvalVizStringFlags case 4: {raw_text = str8_from_32(arena, str32((U32 *)text_slice.data.str, text_slice.data.size/sizeof(U32)));}break; } String8 text = df_eval_escaped_from_raw_string(arena, raw_text); - space_taken += f_dim_from_tag_size_string(font, font_size, text).x; - space_taken += 2*f_dim_from_tag_size_string(font, font_size, str8_lit("\"")).x; + space_taken += f_dim_from_tag_size_string(font, font_size, 0, 0, text).x; + space_taken += 2*f_dim_from_tag_size_string(font, font_size, 0, 0, str8_lit("\"")).x; str8_list_push(arena, &list, str8_lit("\"")); str8_list_push(arena, &list, text); str8_list_push(arena, &list, str8_lit("\"")); @@ -8282,7 +8298,7 @@ df_single_line_eval_value_strings_from_eval(Arena *arena, DF_EvalVizStringFlags direct_type_kind == TG_Kind_Void)) { str8_list_push(arena, &list, symbol_name); - space_taken += f_dim_from_tag_size_string(font, font_size, symbol_name).x; + space_taken += f_dim_from_tag_size_string(font, font_size, 0, 0, symbol_name).x; } // rjf: descend to pointed-at thing @@ -8299,11 +8315,11 @@ df_single_line_eval_value_strings_from_eval(Arena *arena, DF_EvalVizStringFlags { String8 unknown = str8_lit("???"); str8_list_push(arena, &list, unknown); - space_taken += f_dim_from_tag_size_string(font, font_size, unknown).x; + space_taken += f_dim_from_tag_size_string(font, font_size, 0, 0, unknown).x; } else { - space_taken += f_dim_from_tag_size_string_list(font, font_size, pted_strs).x; + space_taken += f_dim_from_tag_size_string_list(font, font_size, 0, 0, pted_strs).x; str8_list_concat_in_place(&list, &pted_strs); } } @@ -8311,7 +8327,7 @@ df_single_line_eval_value_strings_from_eval(Arena *arena, DF_EvalVizStringFlags { String8 ellipses = str8_lit("..."); str8_list_push(arena, &list, ellipses); - space_taken += f_dim_from_tag_size_string(font, font_size, ellipses).x; + space_taken += f_dim_from_tag_size_string(font, font_size, 0, 0, ellipses).x; } } }break; @@ -8352,8 +8368,8 @@ df_single_line_eval_value_strings_from_eval(Arena *arena, DF_EvalVizStringFlags case 4: {raw_text = str8_from_32(arena, str32((U32 *)text_slice.data.str, text_slice.data.size/sizeof(U32)));}break; } String8 text = df_eval_escaped_from_raw_string(arena, raw_text); - space_taken += f_dim_from_tag_size_string(font, font_size, text).x; - space_taken += 2*f_dim_from_tag_size_string(font, font_size, str8_lit("\"")).x; + space_taken += f_dim_from_tag_size_string(font, font_size, 0, 0, text).x; + space_taken += 2*f_dim_from_tag_size_string(font, font_size, 0, 0, str8_lit("\"")).x; str8_list_push(arena, &list, str8_lit("\"")); str8_list_push(arena, &list, text); str8_list_push(arena, &list, str8_lit("\"")); @@ -8364,7 +8380,7 @@ df_single_line_eval_value_strings_from_eval(Arena *arena, DF_EvalVizStringFlags { String8 brace = str8_lit("["); str8_list_push(arena, &list, brace); - space_taken += f_dim_from_tag_size_string(font, font_size, brace).x; + space_taken += f_dim_from_tag_size_string(font, font_size, 0, 0, brace).x; } // rjf: content @@ -8381,12 +8397,12 @@ df_single_line_eval_value_strings_from_eval(Arena *arena, DF_EvalVizStringFlags element_eval.offset = eval.offset + direct_type_byte_size*idx; MemoryCopyArray(element_eval.imm_u128, eval.imm_u128); String8List element_strs = df_single_line_eval_value_strings_from_eval(arena, flags, graph, rdi, ctrl_ctx, default_radix, font, font_size, max_size-space_taken, depth+1, element_eval, opt_member, cfg_table); - space_taken += f_dim_from_tag_size_string_list(font, font_size, element_strs).x; + space_taken += f_dim_from_tag_size_string_list(font, font_size, 0, 0, element_strs).x; str8_list_concat_in_place(&list, &element_strs); if(idx+1 < array_count) { String8 comma = str8_lit(", "); - space_taken += f_dim_from_tag_size_string(font, font_size, comma).x; + space_taken += f_dim_from_tag_size_string(font, font_size, 0, 0, comma).x; str8_list_push(arena, &list, comma); } } @@ -8395,7 +8411,7 @@ df_single_line_eval_value_strings_from_eval(Arena *arena, DF_EvalVizStringFlags { String8 ellipses = str8_lit("..."); str8_list_push(arena, &list, ellipses); - space_taken += f_dim_from_tag_size_string(font, font_size, ellipses).x; + space_taken += f_dim_from_tag_size_string(font, font_size, 0, 0, ellipses).x; } } @@ -8404,7 +8420,7 @@ df_single_line_eval_value_strings_from_eval(Arena *arena, DF_EvalVizStringFlags { String8 brace = str8_lit("]"); str8_list_push(arena, &list, brace); - space_taken += f_dim_from_tag_size_string(font, font_size, brace).x; + space_taken += f_dim_from_tag_size_string(font, font_size, 0, 0, brace).x; } scratch_end(scratch); }break; @@ -8421,7 +8437,7 @@ df_single_line_eval_value_strings_from_eval(Arena *arena, DF_EvalVizStringFlags { String8 brace = str8_lit("{"); str8_list_push(arena, &list, brace); - space_taken += f_dim_from_tag_size_string(font, font_size, brace).x; + space_taken += f_dim_from_tag_size_string(font, font_size, 0, 0, brace).x; } // rjf: content @@ -8439,12 +8455,12 @@ df_single_line_eval_value_strings_from_eval(Arena *arena, DF_EvalVizStringFlags member_eval.offset = eval.offset + mem->off; MemoryCopyArray(member_eval.imm_u128, eval.imm_u128); String8List member_strs = df_single_line_eval_value_strings_from_eval(arena, flags, graph, rdi, ctrl_ctx, default_radix, font, font_size, max_size-space_taken, depth+1, member_eval, opt_member, cfg_table); - space_taken += f_dim_from_tag_size_string_list(font, font_size, member_strs).x; + space_taken += f_dim_from_tag_size_string_list(font, font_size, 0, 0, member_strs).x; str8_list_concat_in_place(&list, &member_strs); if(member_idx+1 < filtered_data_members.count) { String8 comma = str8_lit(", "); - space_taken += f_dim_from_tag_size_string(font, font_size, comma).x; + space_taken += f_dim_from_tag_size_string(font, font_size, 0, 0, comma).x; str8_list_push(arena, &list, comma); } } @@ -8454,14 +8470,14 @@ df_single_line_eval_value_strings_from_eval(Arena *arena, DF_EvalVizStringFlags { String8 ellipses = str8_lit("..."); str8_list_push(arena, &list, ellipses); - space_taken += f_dim_from_tag_size_string(font, font_size, ellipses).x; + space_taken += f_dim_from_tag_size_string(font, font_size, 0, 0, ellipses).x; } // rjf: close brace { String8 brace = str8_lit("}"); str8_list_push(arena, &list, brace); - space_taken += f_dim_from_tag_size_string(font, font_size, brace).x; + space_taken += f_dim_from_tag_size_string(font, font_size, 0, 0, brace).x; } }break; @@ -10512,7 +10528,7 @@ internal UI_BOX_CUSTOM_DRAW(df_thread_box_draw_extensions) lock_icon_color.y += (1 - lock_icon_color.y) * 0.3f; lock_icon_color.z += (1 - lock_icon_color.z) * 0.3f; d_text(ui_icon_font(), - box->font_size, + box->font_size, 0, 0, v2f32((box->rect.x0 + box->rect.x1)/2 + lock_icon_off/2, box->rect.y0 + lock_icon_off/2), lock_icon_color, @@ -10560,7 +10576,7 @@ internal UI_BOX_CUSTOM_DRAW(df_bp_box_draw_extensions) if(u->remap_px_delta != 0) { F32 remap_px_delta = u->remap_px_delta; - F32 circle_advance = f_dim_from_tag_size_string(box->font, box->font_size, df_g_icon_kind_text_table[DF_IconKind_CircleFilled]).x; + F32 circle_advance = f_dim_from_tag_size_string(box->font, box->font_size, 0, 0, df_g_icon_kind_text_table[DF_IconKind_CircleFilled]).x; Vec2F32 bp_text_pos = ui_box_text_position(box); Vec2F32 bp_center = v2f32(bp_text_pos.x + circle_advance/2 + circle_advance/8.f, bp_text_pos.y); F_Metrics icon_font_metrics = f_metrics_from_tag_size(box->font, box->font_size); @@ -10573,7 +10589,7 @@ internal UI_BOX_CUSTOM_DRAW(df_bp_box_draw_extensions) bp_center.x + remap_bar_thickness, bp_center.y + ClampBot(remap_px_delta, 0) + remap_bar_thickness), remap_color, 2.f, 0, 1.f); - d_text(box->font, box->font_size, + d_text(box->font, box->font_size, 0, 0, v2f32(bp_text_pos.x, bp_center.y + remap_px_delta), remap_color, @@ -11073,7 +11089,7 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ line_num += 1, line_idx += 1) { String8 line_text = params->line_text[line_idx]; - F32 line_text_dim = f_dim_from_tag_size_string(params->font, params->font_size, line_text).x + params->line_num_width_px; + F32 line_text_dim = f_dim_from_tag_size_string(params->font, params->font_size, 0, UI_TEMP_TAB_WIDTH, line_text).x + params->line_num_width_px; line_extras_off[line_idx] = Max(line_text_dim, params->font_size*50); } } @@ -11227,7 +11243,7 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ String8 line_string = (params->line_num_range.min <= line_num && line_num <= params->line_num_range.max) ? (params->line_text[mouse_y_line_idx]) : str8_zero(); // rjf: mouse x * string => column - S64 column = f_char_pos_from_tag_size_string_p(params->font, params->font_size, line_string, mouse.x-text_container_box->rect.x0-params->line_num_width_px)+1; + S64 column = f_char_pos_from_tag_size_string_p(params->font, params->font_size, 0, UI_TEMP_TAB_WIDTH, line_string, mouse.x-text_container_box->rect.x0-params->line_num_width_px)+1; // rjf: bundle mouse_pt = txt_pt(line_num, column); @@ -11404,7 +11420,7 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ { U64 line_slice_idx = mouse_pt.line-params->line_num_range.min; String8 line_text = params->line_text[line_slice_idx]; - F32 expr_hoff_px = params->line_num_width_px + f_dim_from_tag_size_string(params->font, params->font_size, str8_prefix(line_text, selected_rng.min.column-1)).x; + F32 expr_hoff_px = params->line_num_width_px + f_dim_from_tag_size_string(params->font, params->font_size, UI_TEMP_BASE_COLUMN_TODO, UI_TEMP_TAB_WIDTH, str8_prefix(line_text, selected_rng.min.column-1)).x; result.mouse_expr_rng = selected_rng; result.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); @@ -11419,7 +11435,7 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ Rng1U64 expr_off_rng = txti_expr_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, str8_prefix(line_text, expr_off_rng.min-line_range.min)).x; + F32 expr_hoff_px = params->line_num_width_px + f_dim_from_tag_size_string(params->font, params->font_size, UI_TEMP_BASE_COLUMN_TODO, UI_TEMP_TAB_WIDTH, str8_prefix(line_text, expr_off_rng.min-line_range.min)).x; result.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 = 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); @@ -11774,8 +11790,8 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ Rng1U64 match_range = r1u64(needle_pos, needle_pos+params->search_query.size); Rng1F32 match_column_pixel_off_range = { - f_dim_from_tag_size_string(line_box->font, line_box->font_size, str8_prefix(line_string, match_range.min)).x, - f_dim_from_tag_size_string(line_box->font, line_box->font_size, str8_prefix(line_string, match_range.max)).x, + f_dim_from_tag_size_string(line_box->font, line_box->font_size, UI_TEMP_BASE_COLUMN_TODO, UI_TEMP_TAB_WIDTH, str8_prefix(line_string, match_range.min)).x, + f_dim_from_tag_size_string(line_box->font, line_box->font_size, UI_TEMP_BASE_COLUMN_TODO, UI_TEMP_TAB_WIDTH, str8_prefix(line_string, match_range.max)).x, }; Rng2F32 match_rect = { @@ -11830,8 +11846,8 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ }; Rng1F32 select_column_pixel_off_range = { - f_dim_from_tag_size_string(line_box->font, line_box->font_size, str8_prefix(line_string, select_column_range_in_line.min-1)).x, - f_dim_from_tag_size_string(line_box->font, line_box->font_size, str8_prefix(line_string, select_column_range_in_line.max-1)).x, + f_dim_from_tag_size_string(line_box->font, line_box->font_size, UI_TEMP_BASE_COLUMN_TODO, UI_TEMP_TAB_WIDTH, str8_prefix(line_string, select_column_range_in_line.min-1)).x, + f_dim_from_tag_size_string(line_box->font, line_box->font_size, UI_TEMP_BASE_COLUMN_TODO, UI_TEMP_TAB_WIDTH, str8_prefix(line_string, select_column_range_in_line.max-1)).x, }; Rng2F32 select_rect = { @@ -11859,7 +11875,7 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ if(cursor->line == line_num) { S64 column = cursor->column; - Vec2F32 advance = f_dim_from_tag_size_string(line_box->font, line_box->font_size, str8_prefix(line_string, column-1)); + Vec2F32 advance = f_dim_from_tag_size_string(line_box->font, line_box->font_size, UI_TEMP_BASE_COLUMN_TODO, UI_TEMP_TAB_WIDTH, str8_prefix(line_string, column-1)); F32 cursor_off_pixels = advance.x; F32 cursor_thickness = ClampBot(4.f, line_box->font_size/6.f); Rng2F32 cursor_rect = @@ -12801,7 +12817,7 @@ df_line_edit(DF_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx { String8 edit_string = str8(edit_buffer, edit_string_size_out[0]); Temp scratch = scratch_begin(0, 0); - F32 total_text_width = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), edit_string).x; + F32 total_text_width = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, UI_TEMP_TAB_WIDTH, edit_string).x; F32 total_editstr_width = total_text_width - !!(flags & (DF_LineEditFlag_Expander|DF_LineEditFlag_ExpanderSpace|DF_LineEditFlag_ExpanderPlaceholder)) * expander_size_px; ui_set_next_pref_width(ui_px(total_editstr_width+ui_top_font_size()*2, 0.f)); UI_Box *editstr_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText|UI_BoxFlag_DisableTextTrunc, "###editstr"); @@ -12879,13 +12895,13 @@ df_line_edit(DF_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx draw_data->select_color = ui_top_text_select_color(); ui_box_equip_custom_draw(editstr_box, ui_line_edit_draw, draw_data); mouse_pt = txt_pt(1, 1+ui_box_char_pos_from_xy(editstr_box, ui_mouse())); - cursor_off = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), str8_prefix(edit_string, cursor->column-1)).x; + cursor_off = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), UI_TEMP_BASE_COLUMN_TODO, UI_TEMP_TAB_WIDTH, str8_prefix(edit_string, cursor->column-1)).x; scratch_end(scratch); } else if((is_focus_active || is_focus_active_disabled) && !(flags & DF_LineEditFlag_CodeContents)) { String8 edit_string = str8(edit_buffer, edit_string_size_out[0]); - F32 total_text_width = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), edit_string).x; + F32 total_text_width = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, UI_TEMP_TAB_WIDTH, edit_string).x; F32 total_editstr_width = total_text_width - !!(flags & (DF_LineEditFlag_Expander|DF_LineEditFlag_ExpanderSpace|DF_LineEditFlag_ExpanderPlaceholder)) * expander_size_px; ui_set_next_pref_width(ui_px(total_editstr_width+ui_top_font_size()*2, 0.f)); UI_Box *editstr_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText|UI_BoxFlag_DisableTextTrunc, "###editstr"); @@ -12898,7 +12914,7 @@ df_line_edit(DF_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx ui_box_equip_display_string(editstr_box, edit_string); ui_box_equip_custom_draw(editstr_box, ui_line_edit_draw, draw_data); mouse_pt = txt_pt(1, 1+ui_box_char_pos_from_xy(editstr_box, ui_mouse())); - cursor_off = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), str8_prefix(edit_string, cursor->column-1)).x; + cursor_off = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), UI_TEMP_BASE_COLUMN_TODO, UI_TEMP_TAB_WIDTH, str8_prefix(edit_string, cursor->column-1)).x; } } diff --git a/src/df/gfx/df_views.c b/src/df/gfx/df_views.c index e2704bb2..5c2dc0cf 100644 --- a/src/df/gfx/df_views.c +++ b/src/df/gfx/df_views.c @@ -5746,7 +5746,7 @@ DF_VIEW_UI_FUNCTION_DEF(Code) F32 code_font_size = df_font_size_from_slot(ws, DF_FontSlot_Code); F_Metrics code_font_metrics = f_metrics_from_tag_size(code_font, code_font_size); F32 code_line_height = ceil_f32(f_line_height_from_metrics(&code_font_metrics) * 1.5f); - F32 big_glyph_advance = f_dim_from_tag_size_string(code_font, code_font_size, str8_lit("H")).x; + F32 big_glyph_advance = f_dim_from_tag_size_string(code_font, code_font_size, 0, 0, str8_lit("H")).x; Vec2F32 panel_box_dim = dim_2f32(rect); Vec2F32 bottom_bar_dim = {panel_box_dim.x, ui_em(1.8f, 0).value}; F32 scroll_bar_dim = floor_f32(ui_top_font_size()*1.5f); @@ -6357,7 +6357,7 @@ DF_VIEW_UI_FUNCTION_DEF(Code) { tv->center_cursor = 0; String8 cursor_line = str8_substr(data, text_info.lines_ranges[tv->cursor.line-1]); - F32 cursor_advance = f_dim_from_tag_size_string(code_font, code_font_size, str8_prefix(cursor_line, tv->cursor.column-1)).x; + F32 cursor_advance = f_dim_from_tag_size_string(code_font, code_font_size, UI_TEMP_BASE_COLUMN_TODO, UI_TEMP_TAB_WIDTH, str8_prefix(cursor_line, tv->cursor.column-1)).x; // rjf: scroll x { @@ -6380,7 +6380,7 @@ DF_VIEW_UI_FUNCTION_DEF(Code) if(snap[Axis2_X]) { String8 cursor_line = str8_substr(data, text_info.lines_ranges[tv->cursor.line-1]); - S64 cursor_off = (S64)(f_dim_from_tag_size_string(code_font, code_font_size, str8_prefix(cursor_line, tv->cursor.column-1)).x + margin_width_px + line_num_width_px); + S64 cursor_off = (S64)(f_dim_from_tag_size_string(code_font, code_font_size, UI_TEMP_BASE_COLUMN_TODO, UI_TEMP_TAB_WIDTH, str8_prefix(cursor_line, tv->cursor.column-1)).x + margin_width_px + line_num_width_px); Rng1S64 visible_pixel_range = { view->scroll_pos.x.idx, @@ -6810,7 +6810,7 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly) F32 code_font_size = df_font_size_from_slot(ws, DF_FontSlot_Code); F_Metrics code_font_metrics = f_metrics_from_tag_size(code_font, code_font_size); F32 code_line_height = ceil_f32(f_line_height_from_metrics(&code_font_metrics) * 1.5f); - F32 big_glyph_advance = f_dim_from_tag_size_string(code_font, code_font_size, str8_lit("H")).x; + F32 big_glyph_advance = f_dim_from_tag_size_string(code_font, code_font_size, 0, 0, str8_lit("H")).x; Vec2F32 panel_box_dim = dim_2f32(rect); Vec2F32 bottom_bar_dim = {panel_box_dim.x, ui_top_font_size()*1.8f}; F32 scroll_bar_dim = floor_f32(ui_top_font_size()*1.5f); @@ -7677,7 +7677,7 @@ DF_VIEW_UI_FUNCTION_DEF(Output) F32 code_font_size = df_font_size_from_slot(ws, DF_FontSlot_Code); F_Metrics code_font_metrics = f_metrics_from_tag_size(code_font, code_font_size); F32 code_line_height = ceil_f32(f_line_height_from_metrics(&code_font_metrics) * 1.5f); - F32 big_glyph_advance = f_dim_from_tag_size_string(code_font, code_font_size, str8_lit("H")).x; + F32 big_glyph_advance = f_dim_from_tag_size_string(code_font, code_font_size, 0, 0, str8_lit("H")).x; Vec2F32 panel_box_dim = dim_2f32(rect); Vec2F32 bottom_bar_dim = {panel_box_dim.x, ui_top_font_size()*1.8f}; F32 scroll_bar_dim = floor_f32(ui_top_font_size()*1.5f); @@ -8050,7 +8050,7 @@ DF_VIEW_UI_FUNCTION_DEF(Output) { tv->center_cursor = 0; String8 cursor_line = txti_string_from_handle_line_num(scratch.arena, txti_handle, tv->cursor.line); - F32 cursor_advance = f_dim_from_tag_size_string(code_font, code_font_size, str8_prefix(cursor_line, tv->cursor.column-1)).x; + F32 cursor_advance = f_dim_from_tag_size_string(code_font, code_font_size, UI_TEMP_BASE_COLUMN_TODO, UI_TEMP_TAB_WIDTH, str8_prefix(cursor_line, tv->cursor.column-1)).x; // rjf: scroll x { @@ -8073,7 +8073,7 @@ DF_VIEW_UI_FUNCTION_DEF(Output) if(snap[Axis2_X]) { String8 cursor_line = txti_string_from_handle_line_num(scratch.arena, txti_handle, tv->cursor.line); - S64 cursor_off = (S64)(f_dim_from_tag_size_string(code_font, code_font_size, str8_prefix(cursor_line, tv->cursor.column-1)).x + margin_width_px + line_num_width_px); + S64 cursor_off = (S64)(f_dim_from_tag_size_string(code_font, code_font_size, UI_TEMP_BASE_COLUMN_TODO, UI_TEMP_TAB_WIDTH, str8_prefix(cursor_line, tv->cursor.column-1)).x + margin_width_px + line_num_width_px); Rng1S64 visible_pixel_range = { view->scroll_pos.x.idx, @@ -8282,7 +8282,7 @@ DF_VIEW_UI_FUNCTION_DEF(Memory) // F_Tag font = df_font_from_slot(DF_FontSlot_Code); F32 font_size = df_font_size_from_slot(ws, DF_FontSlot_Code); - F32 big_glyph_advance = f_dim_from_tag_size_string(font, font_size, str8_lit("H")).x; + F32 big_glyph_advance = f_dim_from_tag_size_string(font, font_size, 0, 0, str8_lit("H")).x; F32 row_height_px = floor_f32(font_size*2.f); F32 cell_width_px = floor_f32(font_size*2.f * mv->bytes_per_cell); F32 scroll_bar_dim = floor_f32(ui_top_font_size()*1.5f); @@ -8964,9 +8964,9 @@ DF_VIEW_UI_FUNCTION_DEF(Memory) D_BucketScope(bucket) { Vec2F32 text_pos = ui_box_text_position(ascii_box); - d_rect(r2f32p(text_pos.x + f_dim_from_tag_size_string(font, font_size, str8_prefix(ascii_text, selection_in_row.min+0-row_range_bytes.min)).x - font_size/8.f, + d_rect(r2f32p(text_pos.x + f_dim_from_tag_size_string(font, font_size, 0, 0, str8_prefix(ascii_text, selection_in_row.min+0-row_range_bytes.min)).x - font_size/8.f, ascii_box->rect.y0, - text_pos.x + f_dim_from_tag_size_string(font, font_size, str8_prefix(ascii_text, selection_in_row.max+1-row_range_bytes.min)).x + font_size/4.f, + text_pos.x + f_dim_from_tag_size_string(font, font_size, 0, 0, str8_prefix(ascii_text, selection_in_row.max+1-row_range_bytes.min)).x + font_size/4.f, ascii_box->rect.y1), df_rgba_from_theme_color(DF_ThemeColor_TextSelection), 0, 0, 1.f); @@ -8980,9 +8980,9 @@ DF_VIEW_UI_FUNCTION_DEF(Memory) { Vec2F32 text_pos = ui_box_text_position(ascii_box); Vec4F32 color = df_rgba_from_theme_color(DF_ThemeColor_Highlight0); - d_rect(r2f32p(text_pos.x + f_dim_from_tag_size_string(font, font_size, str8_prefix(ascii_text, mouse_hover_byte_num-1-row_range_bytes.min)).x - font_size/8.f, + d_rect(r2f32p(text_pos.x + f_dim_from_tag_size_string(font, font_size, 0, 0, str8_prefix(ascii_text, mouse_hover_byte_num-1-row_range_bytes.min)).x - font_size/8.f, ascii_box->rect.y0, - text_pos.x + f_dim_from_tag_size_string(font, font_size, str8_prefix(ascii_text, mouse_hover_byte_num+0-row_range_bytes.min)).x + font_size/4.f, + text_pos.x + f_dim_from_tag_size_string(font, font_size, 0, 0, str8_prefix(ascii_text, mouse_hover_byte_num+0-row_range_bytes.min)).x + font_size/4.f, ascii_box->rect.y1), color, 1.f, 3.f, 1.f); diff --git a/src/draw/draw.c b/src/draw/draw.c index c0174c43..9e3f9f37 100644 --- a/src/draw/draw.c +++ b/src/draw/draw.c @@ -70,14 +70,14 @@ d_string_from_fancy_string_list(Arena *arena, D_FancyStringList *list) } internal D_FancyRunList -d_fancy_run_list_from_fancy_string_list(Arena *arena, D_FancyStringList *strs) +d_fancy_run_list_from_fancy_string_list(Arena *arena, F32 tab_width, D_FancyStringList *strs) { ProfBeginFunction(); D_FancyRunList run_list = {0}; for(D_FancyStringNode *n = strs->first; n != 0; n = n->next) { D_FancyRunNode *dst_n = push_array(arena, D_FancyRunNode, 1); - dst_n->v.run = f_push_run_from_string(arena, n->v.font, n->v.size, 0, n->v.string); + dst_n->v.run = f_push_run_from_string(arena, n->v.font, n->v.size, 0, tab_width, 0, n->v.string); dst_n->v.color = n->v.color; dst_n->v.underline_thickness = n->v.underline_thickness; dst_n->v.strikethrough_thickness = n->v.strikethrough_thickness; @@ -703,44 +703,44 @@ d_truncated_text_run(Vec2F32 p, Vec4F32 color, F32 max_x, F_Run text_run, F_Run } internal void -d_text(F_Tag font, F32 size, Vec2F32 p, Vec4F32 color, String8 string) +d_text(F_Tag font, F32 size, F32 base_column, F32 tab_width, Vec2F32 p, Vec4F32 color, String8 string) { Temp scratch = scratch_begin(0, 0); - F_Run run = f_push_run_from_string(scratch.arena, font, size, 0, string); + F_Run run = f_push_run_from_string(scratch.arena, font, size, base_column, tab_width, 0, string); d_text_run(p, color, run); scratch_end(scratch); } internal void -d_textf(F_Tag font, F32 size, Vec2F32 p, Vec4F32 color, char *fmt, ...) +d_textf(F_Tag font, F32 size, F32 base_column, F32 tab_width, Vec2F32 p, Vec4F32 color, char *fmt, ...) { Temp scratch = scratch_begin(0, 0); va_list args; va_start(args, fmt); String8 string = push_str8fv(scratch.arena, fmt, args); va_end(args); - d_text(font, size, p, color, string); + d_text(font, size, base_column, tab_width, p, color, string); scratch_end(scratch); } internal void -d_truncated_text(F_Tag font, F32 size, Vec2F32 p, Vec4F32 color, F32 max_x, String8 string) +d_truncated_text(F_Tag font, F32 size, F32 base_column, F32 tab_width, Vec2F32 p, Vec4F32 color, F32 max_x, String8 string) { Temp scratch = scratch_begin(0, 0); - F_Run run = f_push_run_from_string(scratch.arena, font, size, 0, string); - F_Run ellipses_run = f_push_run_from_string(scratch.arena, font, size, 0, str8_lit("...")); + F_Run run = f_push_run_from_string(scratch.arena, font, size, base_column, tab_width, 0, string); + F_Run ellipses_run = f_push_run_from_string(scratch.arena, font, size, base_column, tab_width, 0, str8_lit("...")); d_truncated_text_run(p, color, max_x, run, ellipses_run); scratch_end(scratch); } internal void -d_truncated_textf(F_Tag font, F32 size, Vec2F32 p, Vec4F32 color, F32 max_x, char *fmt, ...) +d_truncated_textf(F_Tag font, F32 size, F32 base_column, F32 tab_width, Vec2F32 p, Vec4F32 color, F32 max_x, char *fmt, ...) { Temp scratch = scratch_begin(0, 0); va_list args; va_start(args, fmt); String8 string = push_str8f(scratch.arena, fmt, args); - d_truncated_text(font, size, p, color, max_x, string); + d_truncated_text(font, size, base_column, tab_width, p, color, max_x, string); va_end(args); scratch_end(scratch); } diff --git a/src/draw/draw.h b/src/draw/draw.h index 7f94af9e..1cb6d2bc 100644 --- a/src/draw/draw.h +++ b/src/draw/draw.h @@ -110,7 +110,7 @@ internal U64 d_hash_from_string(String8 string); internal void d_fancy_string_list_push(Arena *arena, D_FancyStringList *list, D_FancyString *str); internal String8 d_string_from_fancy_string_list(Arena *arena, D_FancyStringList *list); -internal D_FancyRunList d_fancy_run_list_from_fancy_string_list(Arena *arena, D_FancyStringList *strs); +internal D_FancyRunList d_fancy_run_list_from_fancy_string_list(Arena *arena, F32 tab_width, D_FancyStringList *strs); internal D_FancyRunList d_fancy_run_list_copy(Arena *arena, D_FancyRunList *src); //////////////////////////////// @@ -186,9 +186,9 @@ internal void d_truncated_fancy_run_list(Vec2F32 p, D_FancyRunList *list, F32 ma internal void d_truncated_fancy_run_fuzzy_matches(Vec2F32 p, D_FancyRunList *list, F32 max_x, FuzzyMatchRangeList *ranges, Vec4F32 color); internal void d_text_run(Vec2F32 p, Vec4F32 color, F_Run run); internal void d_truncated_text_run(Vec2F32 p, Vec4F32 color, F32 max_x, F_Run text_run, F_Run trailer_run); -internal void d_text(F_Tag font, F32 size, Vec2F32 p, Vec4F32 color, String8 string); -internal void d_textf(F_Tag font, F32 size, Vec2F32 p, Vec4F32 color, char *fmt, ...); -internal void d_truncated_text(F_Tag font, F32 size, Vec2F32 p, Vec4F32 color, F32 max_x, String8 string); -internal void d_truncated_textf(F_Tag font, F32 size, Vec2F32 p, Vec4F32 color, F32 max_x, char *fmt, ...); +internal void d_text(F_Tag font, F32 size, F32 base_column, F32 tab_width, Vec2F32 p, Vec4F32 color, String8 string); +internal void d_textf(F_Tag font, F32 size, F32 base_column, F32 tab_width, Vec2F32 p, Vec4F32 color, char *fmt, ...); +internal void d_truncated_text(F_Tag font, F32 size, F32 base_column, F32 tab_width, Vec2F32 p, Vec4F32 color, F32 max_x, String8 string); +internal void d_truncated_textf(F_Tag font, F32 size, F32 base_column, F32 tab_width, Vec2F32 p, Vec4F32 color, F32 max_x, char *fmt, ...); #endif // DRAW_H diff --git a/src/font_cache/font_cache.c b/src/font_cache/font_cache.c index 63312654..e2ac283c 100644 --- a/src/font_cache/font_cache.c +++ b/src/font_cache/font_cache.c @@ -565,10 +565,9 @@ f_hash2style_from_tag_size(F_Tag tag, F32 size) } internal F_Run -f_push_run_from_string(Arena *arena, F_Tag tag, F32 size, F_RunFlags flags, String8 string) +f_push_run_from_string(Arena *arena, F_Tag tag, F32 size, F32 base_column, F32 tab_width, F_RunFlags flags, String8 string) { ProfBeginFunction(); - F32 base_column = 0.f; //- rjf: map tag/size to style node F_Hash2StyleRasterCacheNode *hash2style_node = f_hash2style_from_tag_size(tag, size); @@ -793,7 +792,6 @@ f_push_run_from_string(Arena *arena, F_Tag tag, F32 size, F_RunFlags flags, Stri F32 advance = info->advance; if(is_tab) { - F32 tab_width = 4.f; advance *= tab_width - mod_f32(base_column, tab_width); } @@ -838,12 +836,12 @@ f_push_run_from_string(Arena *arena, F_Tag tag, F32 size, F_RunFlags flags, Stri } internal String8List -f_wrapped_string_lines_from_font_size_string_max(Arena *arena, F_Tag font, F32 size, String8 string, F32 max) +f_wrapped_string_lines_from_font_size_string_max(Arena *arena, F_Tag font, F32 size, F32 base_column, F32 tab_width, String8 string, F32 max) { String8List list = {0}; { Temp scratch = scratch_begin(&arena, 1); - F_Run run = f_push_run_from_string(scratch.arena, font, size, 0, string); + F_Run run = f_push_run_from_string(scratch.arena, font, size, base_column, tab_width, 0, string); F32 off_px = 0; U64 off_bytes = 0; U64 line_start_off_bytes = 0; @@ -951,12 +949,12 @@ f_wrapped_string_lines_from_font_size_string_max(Arena *arena, F_Tag font, F32 s } internal Vec2F32 -f_dim_from_tag_size_string(F_Tag tag, F32 size, String8 string) +f_dim_from_tag_size_string(F_Tag tag, F32 size, F32 base_column, F32 tab_width, String8 string) { ProfBeginFunction(); Temp scratch = scratch_begin(0, 0); Vec2F32 result = {0}; - F_Run run = f_push_run_from_string(scratch.arena, tag, size, 0, string); + F_Run run = f_push_run_from_string(scratch.arena, tag, size, base_column, tab_width, 0, string); result = run.dim; scratch_end(scratch); ProfEnd(); @@ -964,13 +962,13 @@ f_dim_from_tag_size_string(F_Tag tag, F32 size, String8 string) } internal Vec2F32 -f_dim_from_tag_size_string_list(F_Tag tag, F32 size, String8List list) +f_dim_from_tag_size_string_list(F_Tag tag, F32 size, F32 base_column, F32 tab_width, String8List list) { ProfBeginFunction(); Vec2F32 sum = {0}; for(String8Node *n = list.first; n != 0; n = n->next) { - Vec2F32 str_dim = f_dim_from_tag_size_string(tag, size, n->string); + Vec2F32 str_dim = f_dim_from_tag_size_string(tag, size, base_column, tab_width, n->string); sum.x += str_dim.x; sum.y = Max(sum.y, str_dim.y); } @@ -979,7 +977,7 @@ f_dim_from_tag_size_string_list(F_Tag tag, F32 size, String8List list) } internal U64 -f_char_pos_from_tag_size_string_p(F_Tag tag, F32 size, String8 string, F32 p) +f_char_pos_from_tag_size_string_p(F_Tag tag, F32 size, F32 base_column, F32 tab_width, String8 string, F32 p) { ProfBeginFunction(); Temp scratch = scratch_begin(0, 0); @@ -997,7 +995,7 @@ f_char_pos_from_tag_size_string_p(F_Tag tag, F32 size, String8 string, F32 p) } if(char_idx < string.size) { - x += f_dim_from_tag_size_string(tag, size, str8_substr(string, r1u64(char_idx, char_idx+1))).x; + x += f_dim_from_tag_size_string(tag, size, base_column, tab_width, str8_substr(string, r1u64(char_idx, char_idx+1))).x; } } result = best_offset; diff --git a/src/font_cache/font_cache.h b/src/font_cache/font_cache.h index f0de383f..72061b2e 100644 --- a/src/font_cache/font_cache.h +++ b/src/font_cache/font_cache.h @@ -247,11 +247,11 @@ internal F_PieceArray f_piece_array_copy(Arena *arena, F_PieceArray *src); //~ rjf: Rasterization Cache internal F_Hash2StyleRasterCacheNode *f_hash2style_from_tag_size(F_Tag tag, F32 size); -internal F_Run f_push_run_from_string(Arena *arena, F_Tag tag, F32 size, F_RunFlags flags, String8 string); -internal String8List f_wrapped_string_lines_from_font_size_string_max(Arena *arena, F_Tag font, F32 size, String8 string, F32 max); -internal Vec2F32 f_dim_from_tag_size_string(F_Tag tag, F32 size, String8 string); -internal Vec2F32 f_dim_from_tag_size_string_list(F_Tag tag, F32 size, String8List list); -internal U64 f_char_pos_from_tag_size_string_p(F_Tag tag, F32 size, String8 string, F32 p); +internal F_Run f_push_run_from_string(Arena *arena, F_Tag tag, F32 size, F32 base_column, F32 tab_width, F_RunFlags flags, String8 string); +internal String8List f_wrapped_string_lines_from_font_size_string_max(Arena *arena, F_Tag font, F32 size, F32 base_column, F32 tab_width, String8 string, F32 max); +internal Vec2F32 f_dim_from_tag_size_string(F_Tag tag, F32 size, F32 base_column, F32 tab_width, String8 string); +internal Vec2F32 f_dim_from_tag_size_string_list(F_Tag tag, F32 size, F32 base_column, F32 tab_width, String8List list); +internal U64 f_char_pos_from_tag_size_string_p(F_Tag tag, F32 size, F32 base_column, F32 tab_width, String8 string, F32 p); //////////////////////////////// //~ rjf: Metrics diff --git a/src/ui/ui_basic_widgets.c b/src/ui/ui_basic_widgets.c index c1fa8983..ac0beee4 100644 --- a/src/ui/ui_basic_widgets.c +++ b/src/ui/ui_basic_widgets.c @@ -43,7 +43,7 @@ ui_label_multiline(F32 max, String8 string) ui_set_next_child_layout_axis(Axis2_Y); ui_set_next_pref_height(ui_children_sum(1)); UI_Box *box = ui_build_box_from_key(0, ui_key_zero()); - String8List lines = f_wrapped_string_lines_from_font_size_string_max(scratch.arena, ui_top_font(), ui_top_font_size(), string, max); + String8List lines = f_wrapped_string_lines_from_font_size_string_max(scratch.arena, ui_top_font(), ui_top_font_size(), 0, UI_TEMP_TAB_WIDTH, string, max); for(String8Node *n = lines.first; n != 0; n = n->next) { ui_label(n->string); @@ -139,8 +139,8 @@ internal UI_BOX_CUSTOM_DRAW(ui_line_edit_draw) String8 edited_string = draw_data->edited_string; TxtPt cursor = draw_data->cursor; TxtPt mark = draw_data->mark; - F32 cursor_pixel_off = f_dim_from_tag_size_string(font, font_size, str8_prefix(edited_string, cursor.column-1)).x + font_size/8.f; - F32 mark_pixel_off = f_dim_from_tag_size_string(font, font_size, str8_prefix(edited_string, mark.column-1)).x + font_size/8.f; + F32 cursor_pixel_off = f_dim_from_tag_size_string(font, font_size, 0, UI_TEMP_TAB_WIDTH, str8_prefix(edited_string, cursor.column-1)).x + font_size/8.f; + F32 mark_pixel_off = f_dim_from_tag_size_string(font, font_size, 0, UI_TEMP_TAB_WIDTH, str8_prefix(edited_string, mark.column-1)).x + font_size/8.f; F32 cursor_thickness = ClampBot(4.f, font_size/6.f); Rng2F32 cursor_rect = { @@ -253,7 +253,7 @@ ui_line_edit(TxtPt *cursor, TxtPt *mark, U8 *edit_buffer, U64 edit_buffer_size, } else { - F32 total_text_width = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), edit_string).x; + F32 total_text_width = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, UI_TEMP_TAB_WIDTH, edit_string).x; ui_set_next_pref_width(ui_px(total_text_width+ui_top_font_size()*5, 1.f)); UI_Box *editstr_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText|UI_BoxFlag_DisableTextTrunc, "###editstr"); UI_LineEditDrawData *draw_data = push_array(ui_build_arena(), UI_LineEditDrawData, 1); @@ -265,7 +265,7 @@ ui_line_edit(TxtPt *cursor, TxtPt *mark, U8 *edit_buffer, U64 edit_buffer_size, ui_box_equip_display_string(editstr_box, edit_string); ui_box_equip_custom_draw(editstr_box, ui_line_edit_draw, draw_data); mouse_pt = txt_pt(1, 1+ui_box_char_pos_from_xy(editstr_box, ui_mouse())); - cursor_off = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), str8_prefix(edit_string, cursor->column-1)).x; + cursor_off = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, UI_TEMP_TAB_WIDTH, str8_prefix(edit_string, cursor->column-1)).x; } } diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index cd68bcae..d276bbd5 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -2258,7 +2258,7 @@ ui_box_equip_display_string(UI_Box *box, String8 string) String8 display_string = ui_box_display_string(box); D_FancyStringNode fancy_string_n = {0, {box->font, display_string, box->text_color, box->font_size, 0, 0}}; D_FancyStringList fancy_strings = {&fancy_string_n, &fancy_string_n, 1}; - box->display_string_runs = d_fancy_run_list_from_fancy_string_list(ui_build_arena(), &fancy_strings); + box->display_string_runs = d_fancy_run_list_from_fancy_string_list(ui_build_arena(), UI_TEMP_TAB_WIDTH, &fancy_strings); } else if(box->flags & UI_BoxFlag_DrawText && box->flags & UI_BoxFlag_DrawTextFastpathCodepoint && box->fastpath_codepoint != 0) { @@ -2273,13 +2273,13 @@ ui_box_equip_display_string(UI_Box *box, String8 string) D_FancyStringNode cdp_fancy_string_n = {&pst_fancy_string_n, {box->font, str8_substr(display_string, r1u64(fpcp_pos, fpcp_pos+fpcp.size)), box->text_color, box->font_size, 4.f, 0}}; D_FancyStringNode pre_fancy_string_n = {&cdp_fancy_string_n, {box->font, str8_prefix(display_string, fpcp_pos), box->text_color, box->font_size, 0, 0}}; D_FancyStringList fancy_strings = {&pre_fancy_string_n, &pst_fancy_string_n, 3}; - box->display_string_runs = d_fancy_run_list_from_fancy_string_list(ui_build_arena(), &fancy_strings); + box->display_string_runs = d_fancy_run_list_from_fancy_string_list(ui_build_arena(), UI_TEMP_TAB_WIDTH, &fancy_strings); } else { D_FancyStringNode fancy_string_n = {0, {box->font, display_string, box->text_color, box->font_size, 0, 0}}; D_FancyStringList fancy_strings = {&fancy_string_n, &fancy_string_n, 1}; - box->display_string_runs = d_fancy_run_list_from_fancy_string_list(ui_build_arena(), &fancy_strings); + box->display_string_runs = d_fancy_run_list_from_fancy_string_list(ui_build_arena(), UI_TEMP_TAB_WIDTH, &fancy_strings); } scratch_end(scratch); } @@ -2291,7 +2291,7 @@ ui_box_equip_display_fancy_strings(UI_Box *box, D_FancyStringList *strings) { box->flags |= UI_BoxFlag_HasDisplayString; box->string = d_string_from_fancy_string_list(ui_build_arena(), strings); - box->display_string_runs = d_fancy_run_list_from_fancy_string_list(ui_build_arena(), strings); + box->display_string_runs = d_fancy_run_list_from_fancy_string_list(ui_build_arena(), UI_TEMP_TAB_WIDTH, strings); } internal inline void @@ -2381,7 +2381,7 @@ ui_box_char_pos_from_xy(UI_Box *box, Vec2F32 xy) F_Tag font = box->font; F32 font_size = box->font_size; String8 line = ui_box_display_string(box); - U64 result = f_char_pos_from_tag_size_string_p(font, font_size, line, xy.x - ui_box_text_position(box).x); + U64 result = f_char_pos_from_tag_size_string_p(font, font_size, 0, UI_TEMP_TAB_WIDTH, line, xy.x - ui_box_text_position(box).x); return result; } diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index 6b24be53..81d9d406 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -4,6 +4,10 @@ #ifndef UI_H #define UI_H +// TODO(rjf): @tab_layout +#define UI_TEMP_TAB_WIDTH 4.f +#define UI_TEMP_BASE_COLUMN_TODO 0.f + //////////////////////////////// //~ rjf: Icon Info From f214b7d5f2c8b4cdb8be58a23f97dfd78393f9e7 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 24 May 2024 15:17:36 -0700 Subject: [PATCH 11/39] eliminate tab picker ui --- src/df/gfx/df_gfx.c | 59 --------------------------------------------- 1 file changed, 59 deletions(-) diff --git a/src/df/gfx/df_gfx.c b/src/df/gfx/df_gfx.c index a4be7d9a..217eb2b5 100644 --- a/src/df/gfx/df_gfx.c +++ b/src/df/gfx/df_gfx.c @@ -7023,65 +7023,6 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) F32 corner_radius = ui_em(0.6f, 1.f).value; ui_spacer(ui_px(1.f, 1.f)); - // rjf: build tab list ctx menu - UI_Key tab_list_ctx_menu_key = ui_key_from_stringf(ui_key_zero(), "###tab_list_ctx_menu_%p", panel); - UI_CtxMenu(tab_list_ctx_menu_key) UI_PrefWidth(ui_em(22.f, 1.f)) UI_PrefHeight(ui_em(2.25f, 1.f)) - { - for(DF_View *view = panel->first_tab_view; !df_view_is_nil(view); view = view->next) - { - if(df_view_is_project_filtered(view)) { continue; } - B32 view_is_selected = (view == df_selected_tab_from_panel(panel)); - DF_IconKind icon_kind = df_icon_kind_from_view(view); - DF_CtrlCtx ctrl_ctx = df_ctrl_ctx_from_view(ws, view); - String8 label = df_display_string_from_view(scratch.arena, ctrl_ctx, view); - if(view_is_selected) - { - ui_set_next_background_color(df_rgba_from_theme_color(DF_ThemeColor_TabActive)); - } - ui_set_next_hover_cursor(OS_Cursor_HandPoint); - UI_Box *tab_list_item_box = ui_build_box_from_stringf(UI_BoxFlag_DrawHotEffects| - UI_BoxFlag_DrawActiveEffects| - UI_BoxFlag_DrawBorder| - UI_BoxFlag_DrawBackground| - UI_BoxFlag_Clickable, - "###tab_list_item_box_%p", view); - UI_Parent(tab_list_item_box) - { - UI_TextColor(df_rgba_from_theme_color(DF_ThemeColor_WeakText)) - UI_Font(df_font_from_slot(DF_FontSlot_Icons)) - UI_PrefWidth(ui_em(3.f, 1.f)) - UI_TextAlignment(UI_TextAlign_Center) - ui_label(df_g_icon_kind_text_table[icon_kind]); - UI_PrefWidth(ui_text_dim(10.f, 1.f)) - ui_label(label); - } - UI_Signal sig = ui_signal_from_box(tab_list_item_box); - if(ui_clicked(sig)) - { - next_selected_tab_view = view; - DF_CmdParams p = df_cmd_params_from_panel(ws, panel); - df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_FocusPanel)); - } - } - } - - // rjf: build tab list button - if(panel->tab_view_count > 5) UI_PrefWidth(ui_em(2.25f, 1.f)) UI_PrefHeight(ui_px(tab_bar_vheight, 1)) - { - UI_Signal sig = df_icon_buttonf(DF_IconKind_List, 0, "###tab_list_%p", panel); - if(ui_clicked(sig)) - { - if(ui_ctx_menu_is_open(tab_list_ctx_menu_key)) - { - ui_ctx_menu_close(); - } - else - { - ui_ctx_menu_open(tab_list_ctx_menu_key, sig.box->key, v2f32(0, dim_2f32(sig.box->rect).y)); - } - } - } - // rjf: build tabs UI_PrefWidth(ui_em(18.f, 0.5f)) UI_CornerRadius00(panel->tab_side == Side_Min ? corner_radius : 0) From f83515807155708e0b6d69cca5c20a10ce136eab Mon Sep 17 00:00:00 2001 From: Casey Muratori Date: Fri, 24 May 2024 15:53:46 -0700 Subject: [PATCH 12/39] Added call to the build.bat so that rc can be redirected as a batch file --- build.bat | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.bat b/build.bat index dd11f047..6a59fcd2 100644 --- a/build.bat +++ b/build.bat @@ -60,8 +60,8 @@ if "%msvc%"=="1" set EHsc=/EHsc if "%clang%"=="1" set EHsc= if "%msvc%"=="1" set no_aslr=/DYNAMICBASE:NO if "%clang%"=="1" set no_aslr= -if "%msvc%"=="1" set rc=rc.exe -if "%clang%"=="1" set rc=llvm-rc.exe +if "%msvc%"=="1" set rc=call rc +if "%clang%"=="1" set rc=call llvm-rc :: --- Choose Compile/Link Lines ---------------------------------------------- if "%msvc%"=="1" set compile_debug=%cl_debug% From 320a307e9000b7d97044d11bcfd4e85cae8cec10 Mon Sep 17 00:00:00 2001 From: Casey Muratori Date: Fri, 24 May 2024 15:56:29 -0700 Subject: [PATCH 13/39] Dynamically linked SetThreadDescription to avoid requiring latest SDK/kernel version on Windows --- src/os/core/win32/os_core_win32.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/os/core/win32/os_core_win32.c b/src/os/core/win32/os_core_win32.c index b131287f..e4b523c8 100644 --- a/src/os/core/win32/os_core_win32.c +++ b/src/os/core/win32/os_core_win32.c @@ -41,10 +41,14 @@ typedef PVOID W32_MapViewOfFile3_Type(HANDLE FileMapping, ULONG PageProtection, void* ExtendedParameters, ULONG ParameterCount); +typedef HRESULT W32_SetThreadDescription_Type(HANDLE hThread, + PCWSTR lpThreadDescription); global W32_VirtualAlloc2_Type *w32_VirtualAlloc2_func = 0; global W32_MapViewOfFile3_Type *w32_MapViewOfFile3_func = 0; +global W32_SetThreadDescription_Type *w32_SetThreadDescription_func = 0; + //////////////////////////////// //~ rjf: Globals @@ -597,9 +601,10 @@ os_set_thread_name(String8 name) Temp scratch = scratch_begin(0, 0); // rjf: windows 10 style + if(w32_SetThreadDescription_func) { String16 name16 = str16_from_8(scratch.arena, name); - HRESULT hr = SetThreadDescription(GetCurrentThread(), (WCHAR*)name16.str); + HRESULT hr = w32_SetThreadDescription_func(GetCurrentThread(), (WCHAR*)name16.str); } // rjf: raise-exception style From 1161c4adbb828263197b3761cb5b3a1a94ec9905 Mon Sep 17 00:00:00 2001 From: Casey Muratori Date: Fri, 24 May 2024 16:03:20 -0700 Subject: [PATCH 14/39] Added line that got left out when I tried to commit this the first time. --- src/os/core/win32/os_core_win32.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/os/core/win32/os_core_win32.c b/src/os/core/win32/os_core_win32.c index e4b523c8..b6c33613 100644 --- a/src/os/core/win32/os_core_win32.c +++ b/src/os/core/win32/os_core_win32.c @@ -197,6 +197,8 @@ os_init(void) if (module != 0){ w32_VirtualAlloc2_func = (W32_VirtualAlloc2_Type*)GetProcAddress(module, "VirtualAlloc2"); w32_MapViewOfFile3_func = (W32_MapViewOfFile3_Type*)GetProcAddress(module, "MapViewOfFile3"); + w32_SetThreadDescription_func = (W32_SetThreadDescription_Type*)GetProcAddress(module, "SetThreadDescription"); + FreeLibrary(module); } } From 1dbbd351d775598380591a62f3fd5f889f7a454f Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 24 May 2024 16:33:30 -0700 Subject: [PATCH 15/39] formalize tab size in all ui codepaths, per-box; pick 4*columnsize by default in text views --- src/df/gfx/df_gfx.c | 42 ++++++++++++++++++------------------- src/df/gfx/df_gfx.h | 1 + src/df/gfx/df_view_rules.c | 4 +++- src/df/gfx/df_views.c | 16 +++++++++----- src/draw/draw.c | 24 +++++++++++---------- src/draw/draw.h | 10 ++++----- src/font_cache/font_cache.c | 30 ++++++++++++++++---------- src/font_cache/font_cache.h | 12 ++++++----- src/ui/generated/ui.meta.c | 6 ++++++ src/ui/generated/ui.meta.h | 11 ++++++++++ src/ui/ui.mdesk | 1 + src/ui/ui_basic_widgets.c | 11 +++++----- src/ui/ui_core.c | 13 ++++++------ src/ui/ui_core.h | 8 +++---- 14 files changed, 114 insertions(+), 75 deletions(-) diff --git a/src/df/gfx/df_gfx.c b/src/df/gfx/df_gfx.c index 217eb2b5..36e994a8 100644 --- a/src/df/gfx/df_gfx.c +++ b/src/df/gfx/df_gfx.c @@ -5992,7 +5992,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) //- rjf: calculate width of exp row if(row == viz_rows.first) { - expr_column_width_px = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, UI_TEMP_TAB_WIDTH, row->display_expr).x + ui_top_font_size()*0.5f; + expr_column_width_px = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), row->display_expr).x + ui_top_font_size()*0.5f; expr_column_width_px = Max(expr_column_width_px, ui_top_font_size()*10.f); } @@ -7153,7 +7153,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) d_fancy_string_list_push(scratch.arena, &fstrs, &query); } UI_Box *box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_fancy_strings(box, &fstrs); + ui_box_equip_display_fancy_strings(box, ui_top_tab_size(), &fstrs); scratch_end(scratch); } } @@ -7771,7 +7771,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) if(!(box->flags & UI_BoxFlag_DisableTextTrunc)) { max_x = (box->rect.x1-text_position.x); - ellipses_run = f_push_run_from_string(scratch.arena, box->font, box->font_size, 0, UI_TEMP_TAB_WIDTH, 0, str8_lit("...")); + ellipses_run = f_push_run_from_string(scratch.arena, box->font, box->font_size, 0, box->tab_size, 0, str8_lit("...")); } d_truncated_fancy_run_list(text_position, &box->display_string_runs, max_x, ellipses_run); if(box->flags & UI_BoxFlag_HasFuzzyMatchRanges) @@ -8040,8 +8040,8 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) d_fancy_string_list_push(scratch.arena, &strs, &str2); D_FancyString str3 = {df_font_from_slot(DF_FontSlot_Code), str8_lit("very fancy text!"), v4f32(1, 0.8f, 0.4f, 1), 18.f, 4.f, 4.f}; d_fancy_string_list_push(scratch.arena, &strs, &str3); - D_FancyRunList runs = d_fancy_run_list_from_fancy_string_list(scratch.arena, UI_TEMP_TAB_WIDTH, &strs); - F_Run trailer_run = f_push_run_from_string(scratch.arena, df_font_from_slot(DF_FontSlot_Main), 16.f, 0, UI_TEMP_TAB_WIDTH, 0, str8_lit("...")); + D_FancyRunList runs = d_fancy_run_list_from_fancy_string_list(scratch.arena, 0, &strs); + F_Run trailer_run = f_push_run_from_string(scratch.arena, df_font_from_slot(DF_FontSlot_Main), 16.f, 0, 0, 0, str8_lit("...")); F32 limit = 500.f + sin_f32(df_time_in_seconds()/10.f)*200.f; d_truncated_fancy_run_list(p, &runs, limit, trailer_run); d_rect(r2f32p(p.x+limit, 0, p.x+limit+2.f, 1000), v4f32(1, 0, 0, 1), 0, 0, 0); @@ -11030,7 +11030,7 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ line_num += 1, line_idx += 1) { String8 line_text = params->line_text[line_idx]; - F32 line_text_dim = f_dim_from_tag_size_string(params->font, params->font_size, 0, UI_TEMP_TAB_WIDTH, line_text).x + params->line_num_width_px; + F32 line_text_dim = f_dim_from_tag_size_string(params->font, params->font_size, 0, params->tab_size, line_text).x + params->line_num_width_px; line_extras_off[line_idx] = Max(line_text_dim, params->font_size*50); } } @@ -11184,7 +11184,7 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ String8 line_string = (params->line_num_range.min <= line_num && line_num <= params->line_num_range.max) ? (params->line_text[mouse_y_line_idx]) : str8_zero(); // rjf: mouse x * string => column - S64 column = f_char_pos_from_tag_size_string_p(params->font, params->font_size, 0, UI_TEMP_TAB_WIDTH, line_string, mouse.x-text_container_box->rect.x0-params->line_num_width_px)+1; + S64 column = f_char_pos_from_tag_size_string_p(params->font, params->font_size, 0, params->tab_size, line_string, mouse.x-text_container_box->rect.x0-params->line_num_width_px)+1; // rjf: bundle mouse_pt = txt_pt(line_num, column); @@ -11361,7 +11361,7 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ { U64 line_slice_idx = mouse_pt.line-params->line_num_range.min; String8 line_text = params->line_text[line_slice_idx]; - F32 expr_hoff_px = params->line_num_width_px + f_dim_from_tag_size_string(params->font, params->font_size, UI_TEMP_BASE_COLUMN_TODO, UI_TEMP_TAB_WIDTH, str8_prefix(line_text, selected_rng.min.column-1)).x; + 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, selected_rng.min.column-1)).x; result.mouse_expr_rng = selected_rng; result.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); @@ -11376,7 +11376,7 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ Rng1U64 expr_off_rng = txti_expr_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, UI_TEMP_BASE_COLUMN_TODO, UI_TEMP_TAB_WIDTH, str8_prefix(line_text, expr_off_rng.min-line_range.min)).x; + 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 = 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 = 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); @@ -11718,7 +11718,7 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ } // rjf: equip fancy strings to line box - ui_box_equip_display_fancy_strings(line_box, &line_fancy_strings); + ui_box_equip_display_fancy_strings(line_box, params->tab_size, &line_fancy_strings); // rjf: extra rendering for strings that are currently being searched for if(params->search_query.size != 0) @@ -11731,8 +11731,8 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ Rng1U64 match_range = r1u64(needle_pos, needle_pos+params->search_query.size); Rng1F32 match_column_pixel_off_range = { - f_dim_from_tag_size_string(line_box->font, line_box->font_size, UI_TEMP_BASE_COLUMN_TODO, UI_TEMP_TAB_WIDTH, str8_prefix(line_string, match_range.min)).x, - f_dim_from_tag_size_string(line_box->font, line_box->font_size, UI_TEMP_BASE_COLUMN_TODO, UI_TEMP_TAB_WIDTH, str8_prefix(line_string, match_range.max)).x, + f_dim_from_tag_size_string(line_box->font, line_box->font_size, 0, params->tab_size, str8_prefix(line_string, match_range.min)).x, + f_dim_from_tag_size_string(line_box->font, line_box->font_size, 0, params->tab_size, str8_prefix(line_string, match_range.max)).x, }; Rng2F32 match_rect = { @@ -11787,8 +11787,8 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ }; Rng1F32 select_column_pixel_off_range = { - f_dim_from_tag_size_string(line_box->font, line_box->font_size, UI_TEMP_BASE_COLUMN_TODO, UI_TEMP_TAB_WIDTH, str8_prefix(line_string, select_column_range_in_line.min-1)).x, - f_dim_from_tag_size_string(line_box->font, line_box->font_size, UI_TEMP_BASE_COLUMN_TODO, UI_TEMP_TAB_WIDTH, str8_prefix(line_string, select_column_range_in_line.max-1)).x, + f_dim_from_tag_size_string(line_box->font, line_box->font_size, 0, params->tab_size, str8_prefix(line_string, select_column_range_in_line.min-1)).x, + f_dim_from_tag_size_string(line_box->font, line_box->font_size, 0, params->tab_size, str8_prefix(line_string, select_column_range_in_line.max-1)).x, }; Rng2F32 select_rect = { @@ -11816,7 +11816,7 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ if(cursor->line == line_num) { S64 column = cursor->column; - Vec2F32 advance = f_dim_from_tag_size_string(line_box->font, line_box->font_size, UI_TEMP_BASE_COLUMN_TODO, UI_TEMP_TAB_WIDTH, str8_prefix(line_string, column-1)); + Vec2F32 advance = f_dim_from_tag_size_string(line_box->font, line_box->font_size, 0, params->tab_size, str8_prefix(line_string, column-1)); F32 cursor_off_pixels = advance.x; F32 cursor_thickness = ClampBot(4.f, line_box->font_size/6.f); Rng2F32 cursor_rect = @@ -12472,7 +12472,7 @@ df_code_label(F32 alpha, B32 indirection_size_change, Vec4F32 base_color, String Temp scratch = scratch_begin(0, 0); D_FancyStringList fancy_strings = df_fancy_string_list_from_code_string(scratch.arena, alpha, indirection_size_change, base_color, string); UI_Box *box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_fancy_strings(box, &fancy_strings); + ui_box_equip_display_fancy_strings(box, ui_top_tab_size(), &fancy_strings); scratch_end(scratch); return box; } @@ -12758,7 +12758,7 @@ df_line_edit(DF_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx { String8 edit_string = str8(edit_buffer, edit_string_size_out[0]); Temp scratch = scratch_begin(0, 0); - F32 total_text_width = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, UI_TEMP_TAB_WIDTH, edit_string).x; + F32 total_text_width = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), edit_string).x; F32 total_editstr_width = total_text_width - !!(flags & (DF_LineEditFlag_Expander|DF_LineEditFlag_ExpanderSpace|DF_LineEditFlag_ExpanderPlaceholder)) * expander_size_px; ui_set_next_pref_width(ui_px(total_editstr_width+ui_top_font_size()*2, 0.f)); UI_Box *editstr_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText|UI_BoxFlag_DisableTextTrunc, "###editstr"); @@ -12827,7 +12827,7 @@ df_line_edit(DF_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx } } } - ui_box_equip_display_fancy_strings(editstr_box, &code_fancy_strings); + ui_box_equip_display_fancy_strings(editstr_box, ui_top_tab_size(), &code_fancy_strings); UI_LineEditDrawData *draw_data = push_array(ui_build_arena(), UI_LineEditDrawData, 1); draw_data->edited_string = push_str8_copy(ui_build_arena(), edit_string); draw_data->cursor = *cursor; @@ -12836,13 +12836,13 @@ df_line_edit(DF_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx draw_data->select_color = ui_top_text_select_color(); ui_box_equip_custom_draw(editstr_box, ui_line_edit_draw, draw_data); mouse_pt = txt_pt(1, 1+ui_box_char_pos_from_xy(editstr_box, ui_mouse())); - cursor_off = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), UI_TEMP_BASE_COLUMN_TODO, UI_TEMP_TAB_WIDTH, str8_prefix(edit_string, cursor->column-1)).x; + cursor_off = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), str8_prefix(edit_string, cursor->column-1)).x; scratch_end(scratch); } else if((is_focus_active || is_focus_active_disabled) && !(flags & DF_LineEditFlag_CodeContents)) { String8 edit_string = str8(edit_buffer, edit_string_size_out[0]); - F32 total_text_width = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, UI_TEMP_TAB_WIDTH, edit_string).x; + F32 total_text_width = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), edit_string).x; F32 total_editstr_width = total_text_width - !!(flags & (DF_LineEditFlag_Expander|DF_LineEditFlag_ExpanderSpace|DF_LineEditFlag_ExpanderPlaceholder)) * expander_size_px; ui_set_next_pref_width(ui_px(total_editstr_width+ui_top_font_size()*2, 0.f)); UI_Box *editstr_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText|UI_BoxFlag_DisableTextTrunc, "###editstr"); @@ -12855,7 +12855,7 @@ df_line_edit(DF_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx ui_box_equip_display_string(editstr_box, edit_string); ui_box_equip_custom_draw(editstr_box, ui_line_edit_draw, draw_data); mouse_pt = txt_pt(1, 1+ui_box_char_pos_from_xy(editstr_box, ui_mouse())); - cursor_off = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), UI_TEMP_BASE_COLUMN_TODO, UI_TEMP_TAB_WIDTH, str8_prefix(edit_string, cursor->column-1)).x; + cursor_off = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), str8_prefix(edit_string, cursor->column-1)).x; } } diff --git a/src/df/gfx/df_gfx.h b/src/df/gfx/df_gfx.h index 8e17fe14..3c317042 100644 --- a/src/df/gfx/df_gfx.h +++ b/src/df/gfx/df_gfx.h @@ -412,6 +412,7 @@ struct DF_CodeSliceParams // rjf: visual parameters F_Tag font; F32 font_size; + F32 tab_size; String8 search_query; F32 line_height_px; F32 margin_width_px; diff --git a/src/df/gfx/df_view_rules.c b/src/df/gfx/df_view_rules.c index 3a8c889a..3a992047 100644 --- a/src/df/gfx/df_view_rules.c +++ b/src/df/gfx/df_view_rules.c @@ -357,7 +357,7 @@ DF_GFX_VIEW_RULE_ROW_UI_FUNCTION_DEF(rgba) d_fancy_string_list_push(scratch.arena, &fancy_strings, &a_fstr); d_fancy_string_list_push(scratch.arena, &fancy_strings, &clse_paren); } - ui_box_equip_display_fancy_strings(text_box, &fancy_strings); + ui_box_equip_display_fancy_strings(text_box, 0, &fancy_strings); } //- rjf: build color box @@ -568,6 +568,7 @@ DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(text) } code_slice_params.font = df_font_from_slot(DF_FontSlot_Code); code_slice_params.font_size = ui_top_font_size(); + code_slice_params.tab_size = f_column_size_from_tag_size(code_slice_params.font, code_slice_params.font_size)*4.f; code_slice_params.line_height_px = ui_top_font_size()*1.5f; code_slice_params.margin_width_px = 0; code_slice_params.line_num_width_px = ui_top_font_size()*5.f; @@ -728,6 +729,7 @@ DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(disasm) } code_slice_params.font = df_font_from_slot(DF_FontSlot_Code); code_slice_params.font_size = ui_top_font_size(); + code_slice_params.tab_size = f_column_size_from_tag_size(code_slice_params.font, code_slice_params.font_size)*4.f; code_slice_params.line_height_px = ui_top_font_size()*1.5f; code_slice_params.margin_width_px = 0; code_slice_params.line_num_width_px = ui_top_font_size()*5.f; diff --git a/src/df/gfx/df_views.c b/src/df/gfx/df_views.c index 5c2dc0cf..946ef6c6 100644 --- a/src/df/gfx/df_views.c +++ b/src/df/gfx/df_views.c @@ -5744,6 +5744,7 @@ DF_VIEW_UI_FUNCTION_DEF(Code) DF_CtrlCtx ctrl_ctx = df_ctrl_ctx_from_view(ws, view); F_Tag code_font = df_font_from_slot(DF_FontSlot_Code); F32 code_font_size = df_font_size_from_slot(ws, DF_FontSlot_Code); + F32 code_tab_size = f_column_size_from_tag_size(code_font, code_font_size)*4.f; F_Metrics code_font_metrics = f_metrics_from_tag_size(code_font, code_font_size); F32 code_line_height = ceil_f32(f_line_height_from_metrics(&code_font_metrics) * 1.5f); F32 big_glyph_advance = f_dim_from_tag_size_string(code_font, code_font_size, 0, 0, str8_lit("H")).x; @@ -5858,6 +5859,7 @@ DF_VIEW_UI_FUNCTION_DEF(Code) code_slice_params.line_src2dasm = push_array(scratch.arena, DF_TextLineSrc2DasmInfoList, visible_line_count); code_slice_params.font = code_font; code_slice_params.font_size = code_font_size; + code_slice_params.tab_size = code_tab_size; code_slice_params.line_height_px = code_line_height; code_slice_params.search_query = search_query; code_slice_params.margin_width_px = margin_width_px; @@ -6357,7 +6359,7 @@ DF_VIEW_UI_FUNCTION_DEF(Code) { tv->center_cursor = 0; String8 cursor_line = str8_substr(data, text_info.lines_ranges[tv->cursor.line-1]); - F32 cursor_advance = f_dim_from_tag_size_string(code_font, code_font_size, UI_TEMP_BASE_COLUMN_TODO, UI_TEMP_TAB_WIDTH, str8_prefix(cursor_line, tv->cursor.column-1)).x; + F32 cursor_advance = f_dim_from_tag_size_string(code_font, code_font_size, 0, code_tab_size, str8_prefix(cursor_line, tv->cursor.column-1)).x; // rjf: scroll x { @@ -6380,7 +6382,7 @@ DF_VIEW_UI_FUNCTION_DEF(Code) if(snap[Axis2_X]) { String8 cursor_line = str8_substr(data, text_info.lines_ranges[tv->cursor.line-1]); - S64 cursor_off = (S64)(f_dim_from_tag_size_string(code_font, code_font_size, UI_TEMP_BASE_COLUMN_TODO, UI_TEMP_TAB_WIDTH, str8_prefix(cursor_line, tv->cursor.column-1)).x + margin_width_px + line_num_width_px); + S64 cursor_off = (S64)(f_dim_from_tag_size_string(code_font, code_font_size, 0, code_tab_size, str8_prefix(cursor_line, tv->cursor.column-1)).x + margin_width_px + line_num_width_px); Rng1S64 visible_pixel_range = { view->scroll_pos.x.idx, @@ -6808,6 +6810,7 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly) DF_CtrlCtx ctrl_ctx = df_ctrl_ctx_from_view(ws, view); F_Tag code_font = df_font_from_slot(DF_FontSlot_Code); F32 code_font_size = df_font_size_from_slot(ws, DF_FontSlot_Code); + F32 code_tab_size = f_column_size_from_tag_size(code_font, code_font_size)*4.f; F_Metrics code_font_metrics = f_metrics_from_tag_size(code_font, code_font_size); F32 code_line_height = ceil_f32(f_line_height_from_metrics(&code_font_metrics) * 1.5f); F32 big_glyph_advance = f_dim_from_tag_size_string(code_font, code_font_size, 0, 0, str8_lit("H")).x; @@ -6945,6 +6948,7 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly) code_slice_params.line_src2dasm = push_array(scratch.arena, DF_TextLineSrc2DasmInfoList, visible_line_count); code_slice_params.font = code_font; code_slice_params.font_size = code_font_size; + code_slice_params.tab_size = code_tab_size; code_slice_params.line_height_px = code_line_height; code_slice_params.search_query = search_query; code_slice_params.margin_width_px = margin_width_px; @@ -7675,6 +7679,7 @@ DF_VIEW_UI_FUNCTION_DEF(Output) DF_CtrlCtx ctrl_ctx = df_ctrl_ctx_from_view(ws, view); F_Tag code_font = df_font_from_slot(DF_FontSlot_Code); F32 code_font_size = df_font_size_from_slot(ws, DF_FontSlot_Code); + F32 code_tab_size = f_column_size_from_tag_size(code_font, code_font_size)*4.f; F_Metrics code_font_metrics = f_metrics_from_tag_size(code_font, code_font_size); F32 code_line_height = ceil_f32(f_line_height_from_metrics(&code_font_metrics) * 1.5f); F32 big_glyph_advance = f_dim_from_tag_size_string(code_font, code_font_size, 0, 0, str8_lit("H")).x; @@ -7785,6 +7790,7 @@ DF_VIEW_UI_FUNCTION_DEF(Output) code_slice_params.line_src2dasm = push_array(scratch.arena, DF_TextLineSrc2DasmInfoList, slice.line_count); code_slice_params.font = code_font; code_slice_params.font_size = code_font_size; + code_slice_params.tab_size = code_tab_size; code_slice_params.line_height_px = code_line_height; code_slice_params.search_query = search_query; code_slice_params.margin_width_px = margin_width_px; @@ -8050,7 +8056,7 @@ DF_VIEW_UI_FUNCTION_DEF(Output) { tv->center_cursor = 0; String8 cursor_line = txti_string_from_handle_line_num(scratch.arena, txti_handle, tv->cursor.line); - F32 cursor_advance = f_dim_from_tag_size_string(code_font, code_font_size, UI_TEMP_BASE_COLUMN_TODO, UI_TEMP_TAB_WIDTH, str8_prefix(cursor_line, tv->cursor.column-1)).x; + F32 cursor_advance = f_dim_from_tag_size_string(code_font, code_font_size, 0, code_tab_size, str8_prefix(cursor_line, tv->cursor.column-1)).x; // rjf: scroll x { @@ -8073,7 +8079,7 @@ DF_VIEW_UI_FUNCTION_DEF(Output) if(snap[Axis2_X]) { String8 cursor_line = txti_string_from_handle_line_num(scratch.arena, txti_handle, tv->cursor.line); - S64 cursor_off = (S64)(f_dim_from_tag_size_string(code_font, code_font_size, UI_TEMP_BASE_COLUMN_TODO, UI_TEMP_TAB_WIDTH, str8_prefix(cursor_line, tv->cursor.column-1)).x + margin_width_px + line_num_width_px); + S64 cursor_off = (S64)(f_dim_from_tag_size_string(code_font, code_font_size, 0, code_tab_size, str8_prefix(cursor_line, tv->cursor.column-1)).x + margin_width_px + line_num_width_px); Rng1S64 visible_pixel_range = { view->scroll_pos.x.idx, @@ -8899,7 +8905,7 @@ DF_VIEW_UI_FUNCTION_DEF(Memory) ui_set_next_background_color(cell_bg_rgba); } UI_Box *cell_box = ui_build_box_from_key(UI_BoxFlag_DrawText|cell_flags, ui_key_zero()); - ui_box_equip_display_fancy_strings(cell_box, &byte_fancy_strings[byte_value]); + ui_box_equip_display_fancy_strings(cell_box, 0, &byte_fancy_strings[byte_value]); { F32 off = 0; for(Annotation *a = annotation; a != 0; a = a->next) diff --git a/src/draw/draw.c b/src/draw/draw.c index 9e3f9f37..b8a2c94b 100644 --- a/src/draw/draw.c +++ b/src/draw/draw.c @@ -70,14 +70,15 @@ d_string_from_fancy_string_list(Arena *arena, D_FancyStringList *list) } internal D_FancyRunList -d_fancy_run_list_from_fancy_string_list(Arena *arena, F32 tab_width, D_FancyStringList *strs) +d_fancy_run_list_from_fancy_string_list(Arena *arena, F32 tab_size_px, D_FancyStringList *strs) { ProfBeginFunction(); D_FancyRunList run_list = {0}; + F32 base_align_px = 0; for(D_FancyStringNode *n = strs->first; n != 0; n = n->next) { D_FancyRunNode *dst_n = push_array(arena, D_FancyRunNode, 1); - dst_n->v.run = f_push_run_from_string(arena, n->v.font, n->v.size, 0, tab_width, 0, n->v.string); + dst_n->v.run = f_push_run_from_string(arena, n->v.font, n->v.size, base_align_px, tab_size_px, 0, n->v.string); dst_n->v.color = n->v.color; dst_n->v.underline_thickness = n->v.underline_thickness; dst_n->v.strikethrough_thickness = n->v.strikethrough_thickness; @@ -85,6 +86,7 @@ d_fancy_run_list_from_fancy_string_list(Arena *arena, F32 tab_width, D_FancyStri run_list.node_count += 1; run_list.dim.x += dst_n->v.run.dim.x; run_list.dim.y = Max(run_list.dim.y, dst_n->v.run.dim.y); + base_align_px += dst_n->v.run.dim.x; } ProfEnd(); return run_list; @@ -703,44 +705,44 @@ d_truncated_text_run(Vec2F32 p, Vec4F32 color, F32 max_x, F_Run text_run, F_Run } internal void -d_text(F_Tag font, F32 size, F32 base_column, F32 tab_width, Vec2F32 p, Vec4F32 color, String8 string) +d_text(F_Tag font, F32 size, F32 base_align_px, F32 tab_size_px, Vec2F32 p, Vec4F32 color, String8 string) { Temp scratch = scratch_begin(0, 0); - F_Run run = f_push_run_from_string(scratch.arena, font, size, base_column, tab_width, 0, string); + F_Run run = f_push_run_from_string(scratch.arena, font, size, base_align_px, tab_size_px, 0, string); d_text_run(p, color, run); scratch_end(scratch); } internal void -d_textf(F_Tag font, F32 size, F32 base_column, F32 tab_width, Vec2F32 p, Vec4F32 color, char *fmt, ...) +d_textf(F_Tag font, F32 size, F32 base_align_px, F32 tab_size_px, Vec2F32 p, Vec4F32 color, char *fmt, ...) { Temp scratch = scratch_begin(0, 0); va_list args; va_start(args, fmt); String8 string = push_str8fv(scratch.arena, fmt, args); va_end(args); - d_text(font, size, base_column, tab_width, p, color, string); + d_text(font, size, base_align_px, tab_size_px, p, color, string); scratch_end(scratch); } internal void -d_truncated_text(F_Tag font, F32 size, F32 base_column, F32 tab_width, Vec2F32 p, Vec4F32 color, F32 max_x, String8 string) +d_truncated_text(F_Tag font, F32 size, F32 base_align_px, F32 tab_size_px, Vec2F32 p, Vec4F32 color, F32 max_x, String8 string) { Temp scratch = scratch_begin(0, 0); - F_Run run = f_push_run_from_string(scratch.arena, font, size, base_column, tab_width, 0, string); - F_Run ellipses_run = f_push_run_from_string(scratch.arena, font, size, base_column, tab_width, 0, str8_lit("...")); + F_Run run = f_push_run_from_string(scratch.arena, font, size, base_align_px, tab_size_px, 0, string); + F_Run ellipses_run = f_push_run_from_string(scratch.arena, font, size, base_align_px, tab_size_px, 0, str8_lit("...")); d_truncated_text_run(p, color, max_x, run, ellipses_run); scratch_end(scratch); } internal void -d_truncated_textf(F_Tag font, F32 size, F32 base_column, F32 tab_width, Vec2F32 p, Vec4F32 color, F32 max_x, char *fmt, ...) +d_truncated_textf(F_Tag font, F32 size, F32 base_align_px, F32 tab_size_px, Vec2F32 p, Vec4F32 color, F32 max_x, char *fmt, ...) { Temp scratch = scratch_begin(0, 0); va_list args; va_start(args, fmt); String8 string = push_str8f(scratch.arena, fmt, args); - d_truncated_text(font, size, base_column, tab_width, p, color, max_x, string); + d_truncated_text(font, size, base_align_px, tab_size_px, p, color, max_x, string); va_end(args); scratch_end(scratch); } diff --git a/src/draw/draw.h b/src/draw/draw.h index 1cb6d2bc..2764605d 100644 --- a/src/draw/draw.h +++ b/src/draw/draw.h @@ -110,7 +110,7 @@ internal U64 d_hash_from_string(String8 string); internal void d_fancy_string_list_push(Arena *arena, D_FancyStringList *list, D_FancyString *str); internal String8 d_string_from_fancy_string_list(Arena *arena, D_FancyStringList *list); -internal D_FancyRunList d_fancy_run_list_from_fancy_string_list(Arena *arena, F32 tab_width, D_FancyStringList *strs); +internal D_FancyRunList d_fancy_run_list_from_fancy_string_list(Arena *arena, F32 tab_size_px, D_FancyStringList *strs); internal D_FancyRunList d_fancy_run_list_copy(Arena *arena, D_FancyRunList *src); //////////////////////////////// @@ -186,9 +186,9 @@ internal void d_truncated_fancy_run_list(Vec2F32 p, D_FancyRunList *list, F32 ma internal void d_truncated_fancy_run_fuzzy_matches(Vec2F32 p, D_FancyRunList *list, F32 max_x, FuzzyMatchRangeList *ranges, Vec4F32 color); internal void d_text_run(Vec2F32 p, Vec4F32 color, F_Run run); internal void d_truncated_text_run(Vec2F32 p, Vec4F32 color, F32 max_x, F_Run text_run, F_Run trailer_run); -internal void d_text(F_Tag font, F32 size, F32 base_column, F32 tab_width, Vec2F32 p, Vec4F32 color, String8 string); -internal void d_textf(F_Tag font, F32 size, F32 base_column, F32 tab_width, Vec2F32 p, Vec4F32 color, char *fmt, ...); -internal void d_truncated_text(F_Tag font, F32 size, F32 base_column, F32 tab_width, Vec2F32 p, Vec4F32 color, F32 max_x, String8 string); -internal void d_truncated_textf(F_Tag font, F32 size, F32 base_column, F32 tab_width, Vec2F32 p, Vec4F32 color, F32 max_x, char *fmt, ...); +internal void d_text(F_Tag font, F32 size, F32 base_align_px, F32 tab_size_px, Vec2F32 p, Vec4F32 color, String8 string); +internal void d_textf(F_Tag font, F32 size, F32 base_align_px, F32 tab_size_px, Vec2F32 p, Vec4F32 color, char *fmt, ...); +internal void d_truncated_text(F_Tag font, F32 size, F32 base_align_px, F32 tab_size_px, Vec2F32 p, Vec4F32 color, F32 max_x, String8 string); +internal void d_truncated_textf(F_Tag font, F32 size, F32 base_align_px, F32 tab_size_px, Vec2F32 p, Vec4F32 color, F32 max_x, char *fmt, ...); #endif // DRAW_H diff --git a/src/font_cache/font_cache.c b/src/font_cache/font_cache.c index e2ac283c..4e05a24f 100644 --- a/src/font_cache/font_cache.c +++ b/src/font_cache/font_cache.c @@ -565,7 +565,7 @@ f_hash2style_from_tag_size(F_Tag tag, F32 size) } internal F_Run -f_push_run_from_string(Arena *arena, F_Tag tag, F32 size, F32 base_column, F32 tab_width, F_RunFlags flags, String8 string) +f_push_run_from_string(Arena *arena, F_Tag tag, F32 size, F32 base_align_px, F32 tab_size_px, F_RunFlags flags, String8 string) { ProfBeginFunction(); @@ -792,7 +792,7 @@ f_push_run_from_string(Arena *arena, F_Tag tag, F32 size, F32 base_column, F32 t F32 advance = info->advance; if(is_tab) { - advance *= tab_width - mod_f32(base_column, tab_width); + advance = tab_size_px - mod_f32(base_align_px, tab_size_px); } // rjf: push piece @@ -808,6 +808,7 @@ f_push_run_from_string(Arena *arena, F_Tag tag, F32 size, F32 base_column, F32 t piece->decode_size = piece_substring.size; piece->offset = v2s16(0, -hash2style_node->ascent - 4); } + base_align_px += advance; dim.x += piece->advance; dim.y = Max(dim.y, dim_2s16(piece->subrect).y); } @@ -836,12 +837,12 @@ f_push_run_from_string(Arena *arena, F_Tag tag, F32 size, F32 base_column, F32 t } internal String8List -f_wrapped_string_lines_from_font_size_string_max(Arena *arena, F_Tag font, F32 size, F32 base_column, F32 tab_width, String8 string, F32 max) +f_wrapped_string_lines_from_font_size_string_max(Arena *arena, F_Tag font, F32 size, F32 base_align_px, F32 tab_size_px, String8 string, F32 max) { String8List list = {0}; { Temp scratch = scratch_begin(&arena, 1); - F_Run run = f_push_run_from_string(scratch.arena, font, size, base_column, tab_width, 0, string); + F_Run run = f_push_run_from_string(scratch.arena, font, size, base_align_px, tab_size_px, 0, string); F32 off_px = 0; U64 off_bytes = 0; U64 line_start_off_bytes = 0; @@ -949,12 +950,12 @@ f_wrapped_string_lines_from_font_size_string_max(Arena *arena, F_Tag font, F32 s } internal Vec2F32 -f_dim_from_tag_size_string(F_Tag tag, F32 size, F32 base_column, F32 tab_width, String8 string) +f_dim_from_tag_size_string(F_Tag tag, F32 size, F32 base_align_px, F32 tab_size_px, String8 string) { ProfBeginFunction(); Temp scratch = scratch_begin(0, 0); Vec2F32 result = {0}; - F_Run run = f_push_run_from_string(scratch.arena, tag, size, base_column, tab_width, 0, string); + F_Run run = f_push_run_from_string(scratch.arena, tag, size, base_align_px, tab_size_px, 0, string); result = run.dim; scratch_end(scratch); ProfEnd(); @@ -962,13 +963,13 @@ f_dim_from_tag_size_string(F_Tag tag, F32 size, F32 base_column, F32 tab_width, } internal Vec2F32 -f_dim_from_tag_size_string_list(F_Tag tag, F32 size, F32 base_column, F32 tab_width, String8List list) +f_dim_from_tag_size_string_list(F_Tag tag, F32 size, F32 base_align_px, F32 tab_size_px, String8List list) { ProfBeginFunction(); Vec2F32 sum = {0}; for(String8Node *n = list.first; n != 0; n = n->next) { - Vec2F32 str_dim = f_dim_from_tag_size_string(tag, size, base_column, tab_width, n->string); + Vec2F32 str_dim = f_dim_from_tag_size_string(tag, size, base_align_px, tab_size_px, n->string); sum.x += str_dim.x; sum.y = Max(sum.y, str_dim.y); } @@ -976,8 +977,15 @@ f_dim_from_tag_size_string_list(F_Tag tag, F32 size, F32 base_column, F32 tab_wi return sum; } +internal F32 +f_column_size_from_tag_size(F_Tag tag, F32 size) +{ + F32 result = f_dim_from_tag_size_string(tag, size, 0, 0, str8_lit("H")).x; + return result; +} + internal U64 -f_char_pos_from_tag_size_string_p(F_Tag tag, F32 size, F32 base_column, F32 tab_width, String8 string, F32 p) +f_char_pos_from_tag_size_string_p(F_Tag tag, F32 size, F32 base_align_px, F32 tab_size_px, String8 string, F32 p) { ProfBeginFunction(); Temp scratch = scratch_begin(0, 0); @@ -987,7 +995,7 @@ f_char_pos_from_tag_size_string_p(F_Tag tag, F32 size, F32 base_column, F32 tab_ F32 x = 0; for(U64 char_idx = 0; char_idx <= string.size; char_idx += 1) { - F32 this_char_distance = fabsf(p - x); + F32 this_char_distance = abs_f32(p - x); if(this_char_distance < best_distance || best_distance < 0.f) { best_offset = char_idx; @@ -995,7 +1003,7 @@ f_char_pos_from_tag_size_string_p(F_Tag tag, F32 size, F32 base_column, F32 tab_ } if(char_idx < string.size) { - x += f_dim_from_tag_size_string(tag, size, base_column, tab_width, str8_substr(string, r1u64(char_idx, char_idx+1))).x; + x += f_dim_from_tag_size_string(tag, size, base_align_px, tab_size_px, str8_substr(string, r1u64(char_idx, char_idx+1))).x; } } result = best_offset; diff --git a/src/font_cache/font_cache.h b/src/font_cache/font_cache.h index 72061b2e..0e4ab173 100644 --- a/src/font_cache/font_cache.h +++ b/src/font_cache/font_cache.h @@ -131,6 +131,7 @@ struct F_Hash2StyleRasterCacheNode U64 style_hash; F32 ascent; F32 descent; + F32 column_width; F_RasterCacheInfo *utf8_class1_direct_map; U64 utf8_class1_direct_map_mask[4]; U64 hash2info_slots_count; @@ -247,11 +248,12 @@ internal F_PieceArray f_piece_array_copy(Arena *arena, F_PieceArray *src); //~ rjf: Rasterization Cache internal F_Hash2StyleRasterCacheNode *f_hash2style_from_tag_size(F_Tag tag, F32 size); -internal F_Run f_push_run_from_string(Arena *arena, F_Tag tag, F32 size, F32 base_column, F32 tab_width, F_RunFlags flags, String8 string); -internal String8List f_wrapped_string_lines_from_font_size_string_max(Arena *arena, F_Tag font, F32 size, F32 base_column, F32 tab_width, String8 string, F32 max); -internal Vec2F32 f_dim_from_tag_size_string(F_Tag tag, F32 size, F32 base_column, F32 tab_width, String8 string); -internal Vec2F32 f_dim_from_tag_size_string_list(F_Tag tag, F32 size, F32 base_column, F32 tab_width, String8List list); -internal U64 f_char_pos_from_tag_size_string_p(F_Tag tag, F32 size, F32 base_column, F32 tab_width, String8 string, F32 p); +internal F_Run f_push_run_from_string(Arena *arena, F_Tag tag, F32 size, F32 base_align_px, F32 tab_size_px, F_RunFlags flags, String8 string); +internal String8List f_wrapped_string_lines_from_font_size_string_max(Arena *arena, F_Tag font, F32 size, F32 base_align_px, F32 tab_size_px, String8 string, F32 max); +internal Vec2F32 f_dim_from_tag_size_string(F_Tag tag, F32 size, F32 base_align_px, F32 tab_size_px, String8 string); +internal Vec2F32 f_dim_from_tag_size_string_list(F_Tag tag, F32 size, F32 base_align_px, F32 tab_size_px, String8List list); +internal F32 f_column_size_from_tag_size(F_Tag tag, F32 size); +internal U64 f_char_pos_from_tag_size_string_p(F_Tag tag, F32 size, F32 base_align_px, F32 tab_size_px, String8 string, F32 p); //////////////////////////////// //~ rjf: Metrics diff --git a/src/ui/generated/ui.meta.c b/src/ui/generated/ui.meta.c index cb7ca0aa..ad2a8149 100644 --- a/src/ui/generated/ui.meta.c +++ b/src/ui/generated/ui.meta.c @@ -27,6 +27,7 @@ #define UI_HoverCursor(v) DeferLoop(ui_push_hover_cursor(v), ui_pop_hover_cursor()) #define UI_Font(v) DeferLoop(ui_push_font(v), ui_pop_font()) #define UI_FontSize(v) DeferLoop(ui_push_font_size(v), ui_pop_font_size()) +#define UI_TabSize(v) DeferLoop(ui_push_tab_size(v), ui_pop_tab_size()) #define UI_CornerRadius00(v) DeferLoop(ui_push_corner_radius_00(v), ui_pop_corner_radius_00()) #define UI_CornerRadius01(v) DeferLoop(ui_push_corner_radius_01(v), ui_pop_corner_radius_01()) #define UI_CornerRadius10(v) DeferLoop(ui_push_corner_radius_10(v), ui_pop_corner_radius_10()) @@ -58,6 +59,7 @@ internal F32 ui_top_squish(void) { UI_StackTopImpl(ui_state, Squish, squish) } internal OS_Cursor ui_top_hover_cursor(void) { UI_StackTopImpl(ui_state, HoverCursor, hover_cursor) } internal F_Tag ui_top_font(void) { UI_StackTopImpl(ui_state, Font, font) } internal F32 ui_top_font_size(void) { UI_StackTopImpl(ui_state, FontSize, font_size) } +internal F32 ui_top_tab_size(void) { UI_StackTopImpl(ui_state, TabSize, tab_size) } internal F32 ui_top_corner_radius_00(void) { UI_StackTopImpl(ui_state, CornerRadius00, corner_radius_00) } internal F32 ui_top_corner_radius_01(void) { UI_StackTopImpl(ui_state, CornerRadius01, corner_radius_01) } internal F32 ui_top_corner_radius_10(void) { UI_StackTopImpl(ui_state, CornerRadius10, corner_radius_10) } @@ -88,6 +90,7 @@ internal F32 ui_bottom_squish(void) { UI_StackBottomImpl(ui_state, Squish, squis internal OS_Cursor ui_bottom_hover_cursor(void) { UI_StackBottomImpl(ui_state, HoverCursor, hover_cursor) } internal F_Tag ui_bottom_font(void) { UI_StackBottomImpl(ui_state, Font, font) } internal F32 ui_bottom_font_size(void) { UI_StackBottomImpl(ui_state, FontSize, font_size) } +internal F32 ui_bottom_tab_size(void) { UI_StackBottomImpl(ui_state, TabSize, tab_size) } internal F32 ui_bottom_corner_radius_00(void) { UI_StackBottomImpl(ui_state, CornerRadius00, corner_radius_00) } internal F32 ui_bottom_corner_radius_01(void) { UI_StackBottomImpl(ui_state, CornerRadius01, corner_radius_01) } internal F32 ui_bottom_corner_radius_10(void) { UI_StackBottomImpl(ui_state, CornerRadius10, corner_radius_10) } @@ -118,6 +121,7 @@ internal F32 ui_push_squish(F32 v) { UI_StackPushImpl(ui_state, Squish, squish, internal OS_Cursor ui_push_hover_cursor(OS_Cursor v) { UI_StackPushImpl(ui_state, HoverCursor, hover_cursor, OS_Cursor, v) } internal F_Tag ui_push_font(F_Tag v) { UI_StackPushImpl(ui_state, Font, font, F_Tag, v) } internal F32 ui_push_font_size(F32 v) { UI_StackPushImpl(ui_state, FontSize, font_size, F32, v) } +internal F32 ui_push_tab_size(F32 v) { UI_StackPushImpl(ui_state, TabSize, tab_size, F32, v) } internal F32 ui_push_corner_radius_00(F32 v) { UI_StackPushImpl(ui_state, CornerRadius00, corner_radius_00, F32, v) } internal F32 ui_push_corner_radius_01(F32 v) { UI_StackPushImpl(ui_state, CornerRadius01, corner_radius_01, F32, v) } internal F32 ui_push_corner_radius_10(F32 v) { UI_StackPushImpl(ui_state, CornerRadius10, corner_radius_10, F32, v) } @@ -148,6 +152,7 @@ internal F32 ui_pop_squish(void) { UI_StackPopImpl(ui_state, Squish, squish) } internal OS_Cursor ui_pop_hover_cursor(void) { UI_StackPopImpl(ui_state, HoverCursor, hover_cursor) } internal F_Tag ui_pop_font(void) { UI_StackPopImpl(ui_state, Font, font) } internal F32 ui_pop_font_size(void) { UI_StackPopImpl(ui_state, FontSize, font_size) } +internal F32 ui_pop_tab_size(void) { UI_StackPopImpl(ui_state, TabSize, tab_size) } internal F32 ui_pop_corner_radius_00(void) { UI_StackPopImpl(ui_state, CornerRadius00, corner_radius_00) } internal F32 ui_pop_corner_radius_01(void) { UI_StackPopImpl(ui_state, CornerRadius01, corner_radius_01) } internal F32 ui_pop_corner_radius_10(void) { UI_StackPopImpl(ui_state, CornerRadius10, corner_radius_10) } @@ -178,6 +183,7 @@ internal F32 ui_set_next_squish(F32 v) { UI_StackSetNextImpl(ui_state, Squish, s internal OS_Cursor ui_set_next_hover_cursor(OS_Cursor v) { UI_StackSetNextImpl(ui_state, HoverCursor, hover_cursor, OS_Cursor, v) } internal F_Tag ui_set_next_font(F_Tag v) { UI_StackSetNextImpl(ui_state, Font, font, F_Tag, v) } internal F32 ui_set_next_font_size(F32 v) { UI_StackSetNextImpl(ui_state, FontSize, font_size, F32, v) } +internal F32 ui_set_next_tab_size(F32 v) { UI_StackSetNextImpl(ui_state, TabSize, tab_size, F32, v) } internal F32 ui_set_next_corner_radius_00(F32 v) { UI_StackSetNextImpl(ui_state, CornerRadius00, corner_radius_00, F32, v) } internal F32 ui_set_next_corner_radius_01(F32 v) { UI_StackSetNextImpl(ui_state, CornerRadius01, corner_radius_01, F32, v) } internal F32 ui_set_next_corner_radius_10(F32 v) { UI_StackSetNextImpl(ui_state, CornerRadius10, corner_radius_10, F32, v) } diff --git a/src/ui/generated/ui.meta.h b/src/ui/generated/ui.meta.h index bd3a2bc4..e60de2bc 100644 --- a/src/ui/generated/ui.meta.h +++ b/src/ui/generated/ui.meta.h @@ -29,6 +29,7 @@ typedef struct UI_SquishNode UI_SquishNode; struct UI_SquishNode{UI_SquishNode * typedef struct UI_HoverCursorNode UI_HoverCursorNode; struct UI_HoverCursorNode{UI_HoverCursorNode *next; OS_Cursor v;}; typedef struct UI_FontNode UI_FontNode; struct UI_FontNode{UI_FontNode *next; F_Tag v;}; typedef struct UI_FontSizeNode UI_FontSizeNode; struct UI_FontSizeNode{UI_FontSizeNode *next; F32 v;}; +typedef struct UI_TabSizeNode UI_TabSizeNode; struct UI_TabSizeNode{UI_TabSizeNode *next; F32 v;}; typedef struct UI_CornerRadius00Node UI_CornerRadius00Node; struct UI_CornerRadius00Node{UI_CornerRadius00Node *next; F32 v;}; typedef struct UI_CornerRadius01Node UI_CornerRadius01Node; struct UI_CornerRadius01Node{UI_CornerRadius01Node *next; F32 v;}; typedef struct UI_CornerRadius10Node UI_CornerRadius10Node; struct UI_CornerRadius10Node{UI_CornerRadius10Node *next; F32 v;}; @@ -62,6 +63,7 @@ UI_SquishNode squish_nil_stack_top;\ UI_HoverCursorNode hover_cursor_nil_stack_top;\ UI_FontNode font_nil_stack_top;\ UI_FontSizeNode font_size_nil_stack_top;\ +UI_TabSizeNode tab_size_nil_stack_top;\ UI_CornerRadius00Node corner_radius_00_nil_stack_top;\ UI_CornerRadius01Node corner_radius_01_nil_stack_top;\ UI_CornerRadius10Node corner_radius_10_nil_stack_top;\ @@ -94,6 +96,7 @@ state->squish_nil_stack_top.v = 0;\ state->hover_cursor_nil_stack_top.v = OS_Cursor_Pointer;\ state->font_nil_stack_top.v = f_tag_zero();\ state->font_size_nil_stack_top.v = 24.f;\ +state->tab_size_nil_stack_top.v = 24.f*4.f;\ state->corner_radius_00_nil_stack_top.v = 0;\ state->corner_radius_01_nil_stack_top.v = 0;\ state->corner_radius_10_nil_stack_top.v = 0;\ @@ -128,6 +131,7 @@ struct { UI_SquishNode *top; F32 bottom_val; UI_SquishNode *free; B32 auto_pop; struct { UI_HoverCursorNode *top; OS_Cursor bottom_val; UI_HoverCursorNode *free; B32 auto_pop; } hover_cursor_stack;\ struct { UI_FontNode *top; F_Tag bottom_val; UI_FontNode *free; B32 auto_pop; } font_stack;\ struct { UI_FontSizeNode *top; F32 bottom_val; UI_FontSizeNode *free; B32 auto_pop; } font_size_stack;\ +struct { UI_TabSizeNode *top; F32 bottom_val; UI_TabSizeNode *free; B32 auto_pop; } tab_size_stack;\ struct { UI_CornerRadius00Node *top; F32 bottom_val; UI_CornerRadius00Node *free; B32 auto_pop; } corner_radius_00_stack;\ struct { UI_CornerRadius01Node *top; F32 bottom_val; UI_CornerRadius01Node *free; B32 auto_pop; } corner_radius_01_stack;\ struct { UI_CornerRadius10Node *top; F32 bottom_val; UI_CornerRadius10Node *free; B32 auto_pop; } corner_radius_10_stack;\ @@ -160,6 +164,7 @@ state->squish_stack.top = &state->squish_nil_stack_top; state->squish_stack.bott state->hover_cursor_stack.top = &state->hover_cursor_nil_stack_top; state->hover_cursor_stack.bottom_val = OS_Cursor_Pointer; state->hover_cursor_stack.free = 0; state->hover_cursor_stack.auto_pop = 0;\ state->font_stack.top = &state->font_nil_stack_top; state->font_stack.bottom_val = f_tag_zero(); state->font_stack.free = 0; state->font_stack.auto_pop = 0;\ state->font_size_stack.top = &state->font_size_nil_stack_top; state->font_size_stack.bottom_val = 24.f; state->font_size_stack.free = 0; state->font_size_stack.auto_pop = 0;\ +state->tab_size_stack.top = &state->tab_size_nil_stack_top; state->tab_size_stack.bottom_val = 24.f*4.f; state->tab_size_stack.free = 0; state->tab_size_stack.auto_pop = 0;\ state->corner_radius_00_stack.top = &state->corner_radius_00_nil_stack_top; state->corner_radius_00_stack.bottom_val = 0; state->corner_radius_00_stack.free = 0; state->corner_radius_00_stack.auto_pop = 0;\ state->corner_radius_01_stack.top = &state->corner_radius_01_nil_stack_top; state->corner_radius_01_stack.bottom_val = 0; state->corner_radius_01_stack.free = 0; state->corner_radius_01_stack.auto_pop = 0;\ state->corner_radius_10_stack.top = &state->corner_radius_10_nil_stack_top; state->corner_radius_10_stack.bottom_val = 0; state->corner_radius_10_stack.free = 0; state->corner_radius_10_stack.auto_pop = 0;\ @@ -192,6 +197,7 @@ if(state->squish_stack.auto_pop) { ui_pop_squish(); state->squish_stack.auto_pop if(state->hover_cursor_stack.auto_pop) { ui_pop_hover_cursor(); state->hover_cursor_stack.auto_pop = 0; }\ if(state->font_stack.auto_pop) { ui_pop_font(); state->font_stack.auto_pop = 0; }\ if(state->font_size_stack.auto_pop) { ui_pop_font_size(); state->font_size_stack.auto_pop = 0; }\ +if(state->tab_size_stack.auto_pop) { ui_pop_tab_size(); state->tab_size_stack.auto_pop = 0; }\ if(state->corner_radius_00_stack.auto_pop) { ui_pop_corner_radius_00(); state->corner_radius_00_stack.auto_pop = 0; }\ if(state->corner_radius_01_stack.auto_pop) { ui_pop_corner_radius_01(); state->corner_radius_01_stack.auto_pop = 0; }\ if(state->corner_radius_10_stack.auto_pop) { ui_pop_corner_radius_10(); state->corner_radius_10_stack.auto_pop = 0; }\ @@ -223,6 +229,7 @@ internal F32 ui_top_squish(void); internal OS_Cursor ui_top_hover_cursor(void); internal F_Tag ui_top_font(void); internal F32 ui_top_font_size(void); +internal F32 ui_top_tab_size(void); internal F32 ui_top_corner_radius_00(void); internal F32 ui_top_corner_radius_01(void); internal F32 ui_top_corner_radius_10(void); @@ -253,6 +260,7 @@ internal F32 ui_bottom_squish(void); internal OS_Cursor ui_bottom_hover_cursor(void); internal F_Tag ui_bottom_font(void); internal F32 ui_bottom_font_size(void); +internal F32 ui_bottom_tab_size(void); internal F32 ui_bottom_corner_radius_00(void); internal F32 ui_bottom_corner_radius_01(void); internal F32 ui_bottom_corner_radius_10(void); @@ -283,6 +291,7 @@ internal F32 ui_push_squish(F32 v); internal OS_Cursor ui_push_hover_cursor(OS_Cursor v); internal F_Tag ui_push_font(F_Tag v); internal F32 ui_push_font_size(F32 v); +internal F32 ui_push_tab_size(F32 v); internal F32 ui_push_corner_radius_00(F32 v); internal F32 ui_push_corner_radius_01(F32 v); internal F32 ui_push_corner_radius_10(F32 v); @@ -313,6 +322,7 @@ internal F32 ui_pop_squish(void); internal OS_Cursor ui_pop_hover_cursor(void); internal F_Tag ui_pop_font(void); internal F32 ui_pop_font_size(void); +internal F32 ui_pop_tab_size(void); internal F32 ui_pop_corner_radius_00(void); internal F32 ui_pop_corner_radius_01(void); internal F32 ui_pop_corner_radius_10(void); @@ -343,6 +353,7 @@ internal F32 ui_set_next_squish(F32 v); internal OS_Cursor ui_set_next_hover_cursor(OS_Cursor v); internal F_Tag ui_set_next_font(F_Tag v); internal F32 ui_set_next_font_size(F32 v); +internal F32 ui_set_next_tab_size(F32 v); internal F32 ui_set_next_corner_radius_00(F32 v); internal F32 ui_set_next_corner_radius_01(F32 v); internal F32 ui_set_next_corner_radius_10(F32 v); diff --git a/src/ui/ui.mdesk b/src/ui/ui.mdesk index f94bfdaf..1eb36228 100644 --- a/src/ui/ui.mdesk +++ b/src/ui/ui.mdesk @@ -46,6 +46,7 @@ UI_StackTable: //- rjf: font { Font font F_Tag `f_tag_zero()` } { FontSize font_size F32 24.f } + { TabSize tab_size F32 `24.f*4.f` } //- rjf: corner radii { CornerRadius00 corner_radius_00 F32 0 } diff --git a/src/ui/ui_basic_widgets.c b/src/ui/ui_basic_widgets.c index ac0beee4..aea53327 100644 --- a/src/ui/ui_basic_widgets.c +++ b/src/ui/ui_basic_widgets.c @@ -43,7 +43,7 @@ ui_label_multiline(F32 max, String8 string) ui_set_next_child_layout_axis(Axis2_Y); ui_set_next_pref_height(ui_children_sum(1)); UI_Box *box = ui_build_box_from_key(0, ui_key_zero()); - String8List lines = f_wrapped_string_lines_from_font_size_string_max(scratch.arena, ui_top_font(), ui_top_font_size(), 0, UI_TEMP_TAB_WIDTH, string, max); + String8List lines = f_wrapped_string_lines_from_font_size_string_max(scratch.arena, ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), string, max); for(String8Node *n = lines.first; n != 0; n = n->next) { ui_label(n->string); @@ -131,6 +131,7 @@ internal UI_BOX_CUSTOM_DRAW(ui_line_edit_draw) UI_LineEditDrawData *draw_data = (UI_LineEditDrawData *)user_data; F_Tag font = box->font; F32 font_size = box->font_size; + F32 tab_size = box->tab_size; Vec4F32 cursor_color = draw_data->cursor_color; cursor_color.w *= box->parent->parent->focus_active_t; Vec4F32 select_color = draw_data->select_color; @@ -139,8 +140,8 @@ internal UI_BOX_CUSTOM_DRAW(ui_line_edit_draw) String8 edited_string = draw_data->edited_string; TxtPt cursor = draw_data->cursor; TxtPt mark = draw_data->mark; - F32 cursor_pixel_off = f_dim_from_tag_size_string(font, font_size, 0, UI_TEMP_TAB_WIDTH, str8_prefix(edited_string, cursor.column-1)).x + font_size/8.f; - F32 mark_pixel_off = f_dim_from_tag_size_string(font, font_size, 0, UI_TEMP_TAB_WIDTH, str8_prefix(edited_string, mark.column-1)).x + font_size/8.f; + F32 cursor_pixel_off = f_dim_from_tag_size_string(font, font_size, 0, tab_size, str8_prefix(edited_string, cursor.column-1)).x + font_size/8.f; + F32 mark_pixel_off = f_dim_from_tag_size_string(font, font_size, 0, tab_size, str8_prefix(edited_string, mark.column-1)).x + font_size/8.f; F32 cursor_thickness = ClampBot(4.f, font_size/6.f); Rng2F32 cursor_rect = { @@ -253,7 +254,7 @@ ui_line_edit(TxtPt *cursor, TxtPt *mark, U8 *edit_buffer, U64 edit_buffer_size, } else { - F32 total_text_width = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, UI_TEMP_TAB_WIDTH, edit_string).x; + F32 total_text_width = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), edit_string).x; ui_set_next_pref_width(ui_px(total_text_width+ui_top_font_size()*5, 1.f)); UI_Box *editstr_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText|UI_BoxFlag_DisableTextTrunc, "###editstr"); UI_LineEditDrawData *draw_data = push_array(ui_build_arena(), UI_LineEditDrawData, 1); @@ -265,7 +266,7 @@ ui_line_edit(TxtPt *cursor, TxtPt *mark, U8 *edit_buffer, U64 edit_buffer_size, ui_box_equip_display_string(editstr_box, edit_string); ui_box_equip_custom_draw(editstr_box, ui_line_edit_draw, draw_data); mouse_pt = txt_pt(1, 1+ui_box_char_pos_from_xy(editstr_box, ui_mouse())); - cursor_off = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, UI_TEMP_TAB_WIDTH, str8_prefix(edit_string, cursor->column-1)).x; + cursor_off = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), str8_prefix(edit_string, cursor->column-1)).x; } } diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index d276bbd5..a0e32ef0 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -2170,6 +2170,7 @@ ui_build_box_from_key(UI_BoxFlags flags, UI_Key key) box->overlay_color = ui_state->overlay_color_stack.top->v; box->font = ui_state->font_stack.top->v; box->font_size = ui_state->font_size_stack.top->v; + box->tab_size = ui_state->tab_size_stack.top->v; box->corner_radii[Corner_00] = ui_state->corner_radius_00_stack.top->v; box->corner_radii[Corner_01] = ui_state->corner_radius_01_stack.top->v; box->corner_radii[Corner_10] = ui_state->corner_radius_10_stack.top->v; @@ -2258,7 +2259,7 @@ ui_box_equip_display_string(UI_Box *box, String8 string) String8 display_string = ui_box_display_string(box); D_FancyStringNode fancy_string_n = {0, {box->font, display_string, box->text_color, box->font_size, 0, 0}}; D_FancyStringList fancy_strings = {&fancy_string_n, &fancy_string_n, 1}; - box->display_string_runs = d_fancy_run_list_from_fancy_string_list(ui_build_arena(), UI_TEMP_TAB_WIDTH, &fancy_strings); + box->display_string_runs = d_fancy_run_list_from_fancy_string_list(ui_build_arena(), box->tab_size, &fancy_strings); } else if(box->flags & UI_BoxFlag_DrawText && box->flags & UI_BoxFlag_DrawTextFastpathCodepoint && box->fastpath_codepoint != 0) { @@ -2273,13 +2274,13 @@ ui_box_equip_display_string(UI_Box *box, String8 string) D_FancyStringNode cdp_fancy_string_n = {&pst_fancy_string_n, {box->font, str8_substr(display_string, r1u64(fpcp_pos, fpcp_pos+fpcp.size)), box->text_color, box->font_size, 4.f, 0}}; D_FancyStringNode pre_fancy_string_n = {&cdp_fancy_string_n, {box->font, str8_prefix(display_string, fpcp_pos), box->text_color, box->font_size, 0, 0}}; D_FancyStringList fancy_strings = {&pre_fancy_string_n, &pst_fancy_string_n, 3}; - box->display_string_runs = d_fancy_run_list_from_fancy_string_list(ui_build_arena(), UI_TEMP_TAB_WIDTH, &fancy_strings); + box->display_string_runs = d_fancy_run_list_from_fancy_string_list(ui_build_arena(), box->tab_size, &fancy_strings); } else { D_FancyStringNode fancy_string_n = {0, {box->font, display_string, box->text_color, box->font_size, 0, 0}}; D_FancyStringList fancy_strings = {&fancy_string_n, &fancy_string_n, 1}; - box->display_string_runs = d_fancy_run_list_from_fancy_string_list(ui_build_arena(), UI_TEMP_TAB_WIDTH, &fancy_strings); + box->display_string_runs = d_fancy_run_list_from_fancy_string_list(ui_build_arena(), box->tab_size, &fancy_strings); } scratch_end(scratch); } @@ -2287,11 +2288,11 @@ ui_box_equip_display_string(UI_Box *box, String8 string) } internal void -ui_box_equip_display_fancy_strings(UI_Box *box, D_FancyStringList *strings) +ui_box_equip_display_fancy_strings(UI_Box *box, F32 tab_size, D_FancyStringList *strings) { box->flags |= UI_BoxFlag_HasDisplayString; box->string = d_string_from_fancy_string_list(ui_build_arena(), strings); - box->display_string_runs = d_fancy_run_list_from_fancy_string_list(ui_build_arena(), UI_TEMP_TAB_WIDTH, strings); + box->display_string_runs = d_fancy_run_list_from_fancy_string_list(ui_build_arena(), tab_size, strings); } internal inline void @@ -2381,7 +2382,7 @@ ui_box_char_pos_from_xy(UI_Box *box, Vec2F32 xy) F_Tag font = box->font; F32 font_size = box->font_size; String8 line = ui_box_display_string(box); - U64 result = f_char_pos_from_tag_size_string_p(font, font_size, 0, UI_TEMP_TAB_WIDTH, line, xy.x - ui_box_text_position(box).x); + U64 result = f_char_pos_from_tag_size_string_p(font, font_size, 0, box->tab_size, line, xy.x - ui_box_text_position(box).x); return result; } diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index 81d9d406..8f69313d 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -4,10 +4,6 @@ #ifndef UI_H #define UI_H -// TODO(rjf): @tab_layout -#define UI_TEMP_TAB_WIDTH 4.f -#define UI_TEMP_BASE_COLUMN_TODO 0.f - //////////////////////////////// //~ rjf: Icon Info @@ -340,6 +336,7 @@ struct UI_Box Vec4F32 overlay_color; F_Tag font; F32 font_size; + F32 tab_size; F32 corner_radii[Corner_COUNT]; F32 blur_size; F32 transparency; @@ -731,7 +728,7 @@ internal UI_Box * ui_build_box_from_stringf(UI_BoxFlags flags, char *fm //- rjf: box node equipment internal inline void ui_box_equip_display_string(UI_Box *box, String8 string); -internal inline void ui_box_equip_display_fancy_strings(UI_Box *box, D_FancyStringList *strings); +internal inline void ui_box_equip_display_fancy_strings(UI_Box *box, F32 tab_size, D_FancyStringList *strings); internal inline void ui_box_equip_display_string_fancy_runs(UI_Box *box, String8 string, D_FancyRunList *runs); internal inline void ui_box_equip_fuzzy_match_ranges(UI_Box *box, FuzzyMatchRangeList *matches); internal inline void ui_box_equip_draw_bucket(UI_Box *box, D_Bucket *bucket); @@ -942,6 +939,7 @@ internal void ui_pop_corner_radius(void); #define UI_HoverCursor(v) DeferLoop(ui_push_hover_cursor(v), ui_pop_hover_cursor()) #define UI_Font(v) DeferLoop(ui_push_font(v), ui_pop_font()) #define UI_FontSize(v) DeferLoop(ui_push_font_size(v), ui_pop_font_size()) +#define UI_TabSize(v) DeferLoop(ui_push_tab_size(v), ui_pop_tab_size()) #define UI_CornerRadius00(v) DeferLoop(ui_push_corner_radius_00(v), ui_pop_corner_radius_00()) #define UI_CornerRadius01(v) DeferLoop(ui_push_corner_radius_01(v), ui_pop_corner_radius_01()) #define UI_CornerRadius10(v) DeferLoop(ui_push_corner_radius_10(v), ui_pop_corner_radius_10()) From 50d401e4ce32012e62f7f6ed829f4f5a7b90ab12 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 24 May 2024 16:33:30 -0700 Subject: [PATCH 16/39] formalize tab size in all ui codepaths, per-box; pick 4*columnsize by default in text views --- src/df/gfx/df_gfx.c | 42 ++++++++++++++++++------------------- src/df/gfx/df_gfx.h | 1 + src/df/gfx/df_view_rules.c | 4 +++- src/df/gfx/df_views.c | 16 +++++++++----- src/draw/draw.c | 24 +++++++++++---------- src/draw/draw.h | 10 ++++----- src/font_cache/font_cache.c | 30 ++++++++++++++++---------- src/font_cache/font_cache.h | 12 ++++++----- src/ui/generated/ui.meta.c | 6 ++++++ src/ui/generated/ui.meta.h | 11 ++++++++++ src/ui/ui.mdesk | 1 + src/ui/ui_basic_widgets.c | 11 +++++----- src/ui/ui_core.c | 13 ++++++------ src/ui/ui_core.h | 8 +++---- 14 files changed, 114 insertions(+), 75 deletions(-) diff --git a/src/df/gfx/df_gfx.c b/src/df/gfx/df_gfx.c index 217eb2b5..36e994a8 100644 --- a/src/df/gfx/df_gfx.c +++ b/src/df/gfx/df_gfx.c @@ -5992,7 +5992,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) //- rjf: calculate width of exp row if(row == viz_rows.first) { - expr_column_width_px = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, UI_TEMP_TAB_WIDTH, row->display_expr).x + ui_top_font_size()*0.5f; + expr_column_width_px = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), row->display_expr).x + ui_top_font_size()*0.5f; expr_column_width_px = Max(expr_column_width_px, ui_top_font_size()*10.f); } @@ -7153,7 +7153,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) d_fancy_string_list_push(scratch.arena, &fstrs, &query); } UI_Box *box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_fancy_strings(box, &fstrs); + ui_box_equip_display_fancy_strings(box, ui_top_tab_size(), &fstrs); scratch_end(scratch); } } @@ -7771,7 +7771,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) if(!(box->flags & UI_BoxFlag_DisableTextTrunc)) { max_x = (box->rect.x1-text_position.x); - ellipses_run = f_push_run_from_string(scratch.arena, box->font, box->font_size, 0, UI_TEMP_TAB_WIDTH, 0, str8_lit("...")); + ellipses_run = f_push_run_from_string(scratch.arena, box->font, box->font_size, 0, box->tab_size, 0, str8_lit("...")); } d_truncated_fancy_run_list(text_position, &box->display_string_runs, max_x, ellipses_run); if(box->flags & UI_BoxFlag_HasFuzzyMatchRanges) @@ -8040,8 +8040,8 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) d_fancy_string_list_push(scratch.arena, &strs, &str2); D_FancyString str3 = {df_font_from_slot(DF_FontSlot_Code), str8_lit("very fancy text!"), v4f32(1, 0.8f, 0.4f, 1), 18.f, 4.f, 4.f}; d_fancy_string_list_push(scratch.arena, &strs, &str3); - D_FancyRunList runs = d_fancy_run_list_from_fancy_string_list(scratch.arena, UI_TEMP_TAB_WIDTH, &strs); - F_Run trailer_run = f_push_run_from_string(scratch.arena, df_font_from_slot(DF_FontSlot_Main), 16.f, 0, UI_TEMP_TAB_WIDTH, 0, str8_lit("...")); + D_FancyRunList runs = d_fancy_run_list_from_fancy_string_list(scratch.arena, 0, &strs); + F_Run trailer_run = f_push_run_from_string(scratch.arena, df_font_from_slot(DF_FontSlot_Main), 16.f, 0, 0, 0, str8_lit("...")); F32 limit = 500.f + sin_f32(df_time_in_seconds()/10.f)*200.f; d_truncated_fancy_run_list(p, &runs, limit, trailer_run); d_rect(r2f32p(p.x+limit, 0, p.x+limit+2.f, 1000), v4f32(1, 0, 0, 1), 0, 0, 0); @@ -11030,7 +11030,7 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ line_num += 1, line_idx += 1) { String8 line_text = params->line_text[line_idx]; - F32 line_text_dim = f_dim_from_tag_size_string(params->font, params->font_size, 0, UI_TEMP_TAB_WIDTH, line_text).x + params->line_num_width_px; + F32 line_text_dim = f_dim_from_tag_size_string(params->font, params->font_size, 0, params->tab_size, line_text).x + params->line_num_width_px; line_extras_off[line_idx] = Max(line_text_dim, params->font_size*50); } } @@ -11184,7 +11184,7 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ String8 line_string = (params->line_num_range.min <= line_num && line_num <= params->line_num_range.max) ? (params->line_text[mouse_y_line_idx]) : str8_zero(); // rjf: mouse x * string => column - S64 column = f_char_pos_from_tag_size_string_p(params->font, params->font_size, 0, UI_TEMP_TAB_WIDTH, line_string, mouse.x-text_container_box->rect.x0-params->line_num_width_px)+1; + S64 column = f_char_pos_from_tag_size_string_p(params->font, params->font_size, 0, params->tab_size, line_string, mouse.x-text_container_box->rect.x0-params->line_num_width_px)+1; // rjf: bundle mouse_pt = txt_pt(line_num, column); @@ -11361,7 +11361,7 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ { U64 line_slice_idx = mouse_pt.line-params->line_num_range.min; String8 line_text = params->line_text[line_slice_idx]; - F32 expr_hoff_px = params->line_num_width_px + f_dim_from_tag_size_string(params->font, params->font_size, UI_TEMP_BASE_COLUMN_TODO, UI_TEMP_TAB_WIDTH, str8_prefix(line_text, selected_rng.min.column-1)).x; + 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, selected_rng.min.column-1)).x; result.mouse_expr_rng = selected_rng; result.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); @@ -11376,7 +11376,7 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ Rng1U64 expr_off_rng = txti_expr_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, UI_TEMP_BASE_COLUMN_TODO, UI_TEMP_TAB_WIDTH, str8_prefix(line_text, expr_off_rng.min-line_range.min)).x; + 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 = 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 = 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); @@ -11718,7 +11718,7 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ } // rjf: equip fancy strings to line box - ui_box_equip_display_fancy_strings(line_box, &line_fancy_strings); + ui_box_equip_display_fancy_strings(line_box, params->tab_size, &line_fancy_strings); // rjf: extra rendering for strings that are currently being searched for if(params->search_query.size != 0) @@ -11731,8 +11731,8 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ Rng1U64 match_range = r1u64(needle_pos, needle_pos+params->search_query.size); Rng1F32 match_column_pixel_off_range = { - f_dim_from_tag_size_string(line_box->font, line_box->font_size, UI_TEMP_BASE_COLUMN_TODO, UI_TEMP_TAB_WIDTH, str8_prefix(line_string, match_range.min)).x, - f_dim_from_tag_size_string(line_box->font, line_box->font_size, UI_TEMP_BASE_COLUMN_TODO, UI_TEMP_TAB_WIDTH, str8_prefix(line_string, match_range.max)).x, + f_dim_from_tag_size_string(line_box->font, line_box->font_size, 0, params->tab_size, str8_prefix(line_string, match_range.min)).x, + f_dim_from_tag_size_string(line_box->font, line_box->font_size, 0, params->tab_size, str8_prefix(line_string, match_range.max)).x, }; Rng2F32 match_rect = { @@ -11787,8 +11787,8 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ }; Rng1F32 select_column_pixel_off_range = { - f_dim_from_tag_size_string(line_box->font, line_box->font_size, UI_TEMP_BASE_COLUMN_TODO, UI_TEMP_TAB_WIDTH, str8_prefix(line_string, select_column_range_in_line.min-1)).x, - f_dim_from_tag_size_string(line_box->font, line_box->font_size, UI_TEMP_BASE_COLUMN_TODO, UI_TEMP_TAB_WIDTH, str8_prefix(line_string, select_column_range_in_line.max-1)).x, + f_dim_from_tag_size_string(line_box->font, line_box->font_size, 0, params->tab_size, str8_prefix(line_string, select_column_range_in_line.min-1)).x, + f_dim_from_tag_size_string(line_box->font, line_box->font_size, 0, params->tab_size, str8_prefix(line_string, select_column_range_in_line.max-1)).x, }; Rng2F32 select_rect = { @@ -11816,7 +11816,7 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ if(cursor->line == line_num) { S64 column = cursor->column; - Vec2F32 advance = f_dim_from_tag_size_string(line_box->font, line_box->font_size, UI_TEMP_BASE_COLUMN_TODO, UI_TEMP_TAB_WIDTH, str8_prefix(line_string, column-1)); + Vec2F32 advance = f_dim_from_tag_size_string(line_box->font, line_box->font_size, 0, params->tab_size, str8_prefix(line_string, column-1)); F32 cursor_off_pixels = advance.x; F32 cursor_thickness = ClampBot(4.f, line_box->font_size/6.f); Rng2F32 cursor_rect = @@ -12472,7 +12472,7 @@ df_code_label(F32 alpha, B32 indirection_size_change, Vec4F32 base_color, String Temp scratch = scratch_begin(0, 0); D_FancyStringList fancy_strings = df_fancy_string_list_from_code_string(scratch.arena, alpha, indirection_size_change, base_color, string); UI_Box *box = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); - ui_box_equip_display_fancy_strings(box, &fancy_strings); + ui_box_equip_display_fancy_strings(box, ui_top_tab_size(), &fancy_strings); scratch_end(scratch); return box; } @@ -12758,7 +12758,7 @@ df_line_edit(DF_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx { String8 edit_string = str8(edit_buffer, edit_string_size_out[0]); Temp scratch = scratch_begin(0, 0); - F32 total_text_width = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, UI_TEMP_TAB_WIDTH, edit_string).x; + F32 total_text_width = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), edit_string).x; F32 total_editstr_width = total_text_width - !!(flags & (DF_LineEditFlag_Expander|DF_LineEditFlag_ExpanderSpace|DF_LineEditFlag_ExpanderPlaceholder)) * expander_size_px; ui_set_next_pref_width(ui_px(total_editstr_width+ui_top_font_size()*2, 0.f)); UI_Box *editstr_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText|UI_BoxFlag_DisableTextTrunc, "###editstr"); @@ -12827,7 +12827,7 @@ df_line_edit(DF_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx } } } - ui_box_equip_display_fancy_strings(editstr_box, &code_fancy_strings); + ui_box_equip_display_fancy_strings(editstr_box, ui_top_tab_size(), &code_fancy_strings); UI_LineEditDrawData *draw_data = push_array(ui_build_arena(), UI_LineEditDrawData, 1); draw_data->edited_string = push_str8_copy(ui_build_arena(), edit_string); draw_data->cursor = *cursor; @@ -12836,13 +12836,13 @@ df_line_edit(DF_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx draw_data->select_color = ui_top_text_select_color(); ui_box_equip_custom_draw(editstr_box, ui_line_edit_draw, draw_data); mouse_pt = txt_pt(1, 1+ui_box_char_pos_from_xy(editstr_box, ui_mouse())); - cursor_off = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), UI_TEMP_BASE_COLUMN_TODO, UI_TEMP_TAB_WIDTH, str8_prefix(edit_string, cursor->column-1)).x; + cursor_off = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), str8_prefix(edit_string, cursor->column-1)).x; scratch_end(scratch); } else if((is_focus_active || is_focus_active_disabled) && !(flags & DF_LineEditFlag_CodeContents)) { String8 edit_string = str8(edit_buffer, edit_string_size_out[0]); - F32 total_text_width = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, UI_TEMP_TAB_WIDTH, edit_string).x; + F32 total_text_width = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), edit_string).x; F32 total_editstr_width = total_text_width - !!(flags & (DF_LineEditFlag_Expander|DF_LineEditFlag_ExpanderSpace|DF_LineEditFlag_ExpanderPlaceholder)) * expander_size_px; ui_set_next_pref_width(ui_px(total_editstr_width+ui_top_font_size()*2, 0.f)); UI_Box *editstr_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText|UI_BoxFlag_DisableTextTrunc, "###editstr"); @@ -12855,7 +12855,7 @@ df_line_edit(DF_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx ui_box_equip_display_string(editstr_box, edit_string); ui_box_equip_custom_draw(editstr_box, ui_line_edit_draw, draw_data); mouse_pt = txt_pt(1, 1+ui_box_char_pos_from_xy(editstr_box, ui_mouse())); - cursor_off = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), UI_TEMP_BASE_COLUMN_TODO, UI_TEMP_TAB_WIDTH, str8_prefix(edit_string, cursor->column-1)).x; + cursor_off = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), str8_prefix(edit_string, cursor->column-1)).x; } } diff --git a/src/df/gfx/df_gfx.h b/src/df/gfx/df_gfx.h index 8e17fe14..3c317042 100644 --- a/src/df/gfx/df_gfx.h +++ b/src/df/gfx/df_gfx.h @@ -412,6 +412,7 @@ struct DF_CodeSliceParams // rjf: visual parameters F_Tag font; F32 font_size; + F32 tab_size; String8 search_query; F32 line_height_px; F32 margin_width_px; diff --git a/src/df/gfx/df_view_rules.c b/src/df/gfx/df_view_rules.c index 3a8c889a..3a992047 100644 --- a/src/df/gfx/df_view_rules.c +++ b/src/df/gfx/df_view_rules.c @@ -357,7 +357,7 @@ DF_GFX_VIEW_RULE_ROW_UI_FUNCTION_DEF(rgba) d_fancy_string_list_push(scratch.arena, &fancy_strings, &a_fstr); d_fancy_string_list_push(scratch.arena, &fancy_strings, &clse_paren); } - ui_box_equip_display_fancy_strings(text_box, &fancy_strings); + ui_box_equip_display_fancy_strings(text_box, 0, &fancy_strings); } //- rjf: build color box @@ -568,6 +568,7 @@ DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(text) } code_slice_params.font = df_font_from_slot(DF_FontSlot_Code); code_slice_params.font_size = ui_top_font_size(); + code_slice_params.tab_size = f_column_size_from_tag_size(code_slice_params.font, code_slice_params.font_size)*4.f; code_slice_params.line_height_px = ui_top_font_size()*1.5f; code_slice_params.margin_width_px = 0; code_slice_params.line_num_width_px = ui_top_font_size()*5.f; @@ -728,6 +729,7 @@ DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(disasm) } code_slice_params.font = df_font_from_slot(DF_FontSlot_Code); code_slice_params.font_size = ui_top_font_size(); + code_slice_params.tab_size = f_column_size_from_tag_size(code_slice_params.font, code_slice_params.font_size)*4.f; code_slice_params.line_height_px = ui_top_font_size()*1.5f; code_slice_params.margin_width_px = 0; code_slice_params.line_num_width_px = ui_top_font_size()*5.f; diff --git a/src/df/gfx/df_views.c b/src/df/gfx/df_views.c index 5c2dc0cf..946ef6c6 100644 --- a/src/df/gfx/df_views.c +++ b/src/df/gfx/df_views.c @@ -5744,6 +5744,7 @@ DF_VIEW_UI_FUNCTION_DEF(Code) DF_CtrlCtx ctrl_ctx = df_ctrl_ctx_from_view(ws, view); F_Tag code_font = df_font_from_slot(DF_FontSlot_Code); F32 code_font_size = df_font_size_from_slot(ws, DF_FontSlot_Code); + F32 code_tab_size = f_column_size_from_tag_size(code_font, code_font_size)*4.f; F_Metrics code_font_metrics = f_metrics_from_tag_size(code_font, code_font_size); F32 code_line_height = ceil_f32(f_line_height_from_metrics(&code_font_metrics) * 1.5f); F32 big_glyph_advance = f_dim_from_tag_size_string(code_font, code_font_size, 0, 0, str8_lit("H")).x; @@ -5858,6 +5859,7 @@ DF_VIEW_UI_FUNCTION_DEF(Code) code_slice_params.line_src2dasm = push_array(scratch.arena, DF_TextLineSrc2DasmInfoList, visible_line_count); code_slice_params.font = code_font; code_slice_params.font_size = code_font_size; + code_slice_params.tab_size = code_tab_size; code_slice_params.line_height_px = code_line_height; code_slice_params.search_query = search_query; code_slice_params.margin_width_px = margin_width_px; @@ -6357,7 +6359,7 @@ DF_VIEW_UI_FUNCTION_DEF(Code) { tv->center_cursor = 0; String8 cursor_line = str8_substr(data, text_info.lines_ranges[tv->cursor.line-1]); - F32 cursor_advance = f_dim_from_tag_size_string(code_font, code_font_size, UI_TEMP_BASE_COLUMN_TODO, UI_TEMP_TAB_WIDTH, str8_prefix(cursor_line, tv->cursor.column-1)).x; + F32 cursor_advance = f_dim_from_tag_size_string(code_font, code_font_size, 0, code_tab_size, str8_prefix(cursor_line, tv->cursor.column-1)).x; // rjf: scroll x { @@ -6380,7 +6382,7 @@ DF_VIEW_UI_FUNCTION_DEF(Code) if(snap[Axis2_X]) { String8 cursor_line = str8_substr(data, text_info.lines_ranges[tv->cursor.line-1]); - S64 cursor_off = (S64)(f_dim_from_tag_size_string(code_font, code_font_size, UI_TEMP_BASE_COLUMN_TODO, UI_TEMP_TAB_WIDTH, str8_prefix(cursor_line, tv->cursor.column-1)).x + margin_width_px + line_num_width_px); + S64 cursor_off = (S64)(f_dim_from_tag_size_string(code_font, code_font_size, 0, code_tab_size, str8_prefix(cursor_line, tv->cursor.column-1)).x + margin_width_px + line_num_width_px); Rng1S64 visible_pixel_range = { view->scroll_pos.x.idx, @@ -6808,6 +6810,7 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly) DF_CtrlCtx ctrl_ctx = df_ctrl_ctx_from_view(ws, view); F_Tag code_font = df_font_from_slot(DF_FontSlot_Code); F32 code_font_size = df_font_size_from_slot(ws, DF_FontSlot_Code); + F32 code_tab_size = f_column_size_from_tag_size(code_font, code_font_size)*4.f; F_Metrics code_font_metrics = f_metrics_from_tag_size(code_font, code_font_size); F32 code_line_height = ceil_f32(f_line_height_from_metrics(&code_font_metrics) * 1.5f); F32 big_glyph_advance = f_dim_from_tag_size_string(code_font, code_font_size, 0, 0, str8_lit("H")).x; @@ -6945,6 +6948,7 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly) code_slice_params.line_src2dasm = push_array(scratch.arena, DF_TextLineSrc2DasmInfoList, visible_line_count); code_slice_params.font = code_font; code_slice_params.font_size = code_font_size; + code_slice_params.tab_size = code_tab_size; code_slice_params.line_height_px = code_line_height; code_slice_params.search_query = search_query; code_slice_params.margin_width_px = margin_width_px; @@ -7675,6 +7679,7 @@ DF_VIEW_UI_FUNCTION_DEF(Output) DF_CtrlCtx ctrl_ctx = df_ctrl_ctx_from_view(ws, view); F_Tag code_font = df_font_from_slot(DF_FontSlot_Code); F32 code_font_size = df_font_size_from_slot(ws, DF_FontSlot_Code); + F32 code_tab_size = f_column_size_from_tag_size(code_font, code_font_size)*4.f; F_Metrics code_font_metrics = f_metrics_from_tag_size(code_font, code_font_size); F32 code_line_height = ceil_f32(f_line_height_from_metrics(&code_font_metrics) * 1.5f); F32 big_glyph_advance = f_dim_from_tag_size_string(code_font, code_font_size, 0, 0, str8_lit("H")).x; @@ -7785,6 +7790,7 @@ DF_VIEW_UI_FUNCTION_DEF(Output) code_slice_params.line_src2dasm = push_array(scratch.arena, DF_TextLineSrc2DasmInfoList, slice.line_count); code_slice_params.font = code_font; code_slice_params.font_size = code_font_size; + code_slice_params.tab_size = code_tab_size; code_slice_params.line_height_px = code_line_height; code_slice_params.search_query = search_query; code_slice_params.margin_width_px = margin_width_px; @@ -8050,7 +8056,7 @@ DF_VIEW_UI_FUNCTION_DEF(Output) { tv->center_cursor = 0; String8 cursor_line = txti_string_from_handle_line_num(scratch.arena, txti_handle, tv->cursor.line); - F32 cursor_advance = f_dim_from_tag_size_string(code_font, code_font_size, UI_TEMP_BASE_COLUMN_TODO, UI_TEMP_TAB_WIDTH, str8_prefix(cursor_line, tv->cursor.column-1)).x; + F32 cursor_advance = f_dim_from_tag_size_string(code_font, code_font_size, 0, code_tab_size, str8_prefix(cursor_line, tv->cursor.column-1)).x; // rjf: scroll x { @@ -8073,7 +8079,7 @@ DF_VIEW_UI_FUNCTION_DEF(Output) if(snap[Axis2_X]) { String8 cursor_line = txti_string_from_handle_line_num(scratch.arena, txti_handle, tv->cursor.line); - S64 cursor_off = (S64)(f_dim_from_tag_size_string(code_font, code_font_size, UI_TEMP_BASE_COLUMN_TODO, UI_TEMP_TAB_WIDTH, str8_prefix(cursor_line, tv->cursor.column-1)).x + margin_width_px + line_num_width_px); + S64 cursor_off = (S64)(f_dim_from_tag_size_string(code_font, code_font_size, 0, code_tab_size, str8_prefix(cursor_line, tv->cursor.column-1)).x + margin_width_px + line_num_width_px); Rng1S64 visible_pixel_range = { view->scroll_pos.x.idx, @@ -8899,7 +8905,7 @@ DF_VIEW_UI_FUNCTION_DEF(Memory) ui_set_next_background_color(cell_bg_rgba); } UI_Box *cell_box = ui_build_box_from_key(UI_BoxFlag_DrawText|cell_flags, ui_key_zero()); - ui_box_equip_display_fancy_strings(cell_box, &byte_fancy_strings[byte_value]); + ui_box_equip_display_fancy_strings(cell_box, 0, &byte_fancy_strings[byte_value]); { F32 off = 0; for(Annotation *a = annotation; a != 0; a = a->next) diff --git a/src/draw/draw.c b/src/draw/draw.c index 9e3f9f37..b8a2c94b 100644 --- a/src/draw/draw.c +++ b/src/draw/draw.c @@ -70,14 +70,15 @@ d_string_from_fancy_string_list(Arena *arena, D_FancyStringList *list) } internal D_FancyRunList -d_fancy_run_list_from_fancy_string_list(Arena *arena, F32 tab_width, D_FancyStringList *strs) +d_fancy_run_list_from_fancy_string_list(Arena *arena, F32 tab_size_px, D_FancyStringList *strs) { ProfBeginFunction(); D_FancyRunList run_list = {0}; + F32 base_align_px = 0; for(D_FancyStringNode *n = strs->first; n != 0; n = n->next) { D_FancyRunNode *dst_n = push_array(arena, D_FancyRunNode, 1); - dst_n->v.run = f_push_run_from_string(arena, n->v.font, n->v.size, 0, tab_width, 0, n->v.string); + dst_n->v.run = f_push_run_from_string(arena, n->v.font, n->v.size, base_align_px, tab_size_px, 0, n->v.string); dst_n->v.color = n->v.color; dst_n->v.underline_thickness = n->v.underline_thickness; dst_n->v.strikethrough_thickness = n->v.strikethrough_thickness; @@ -85,6 +86,7 @@ d_fancy_run_list_from_fancy_string_list(Arena *arena, F32 tab_width, D_FancyStri run_list.node_count += 1; run_list.dim.x += dst_n->v.run.dim.x; run_list.dim.y = Max(run_list.dim.y, dst_n->v.run.dim.y); + base_align_px += dst_n->v.run.dim.x; } ProfEnd(); return run_list; @@ -703,44 +705,44 @@ d_truncated_text_run(Vec2F32 p, Vec4F32 color, F32 max_x, F_Run text_run, F_Run } internal void -d_text(F_Tag font, F32 size, F32 base_column, F32 tab_width, Vec2F32 p, Vec4F32 color, String8 string) +d_text(F_Tag font, F32 size, F32 base_align_px, F32 tab_size_px, Vec2F32 p, Vec4F32 color, String8 string) { Temp scratch = scratch_begin(0, 0); - F_Run run = f_push_run_from_string(scratch.arena, font, size, base_column, tab_width, 0, string); + F_Run run = f_push_run_from_string(scratch.arena, font, size, base_align_px, tab_size_px, 0, string); d_text_run(p, color, run); scratch_end(scratch); } internal void -d_textf(F_Tag font, F32 size, F32 base_column, F32 tab_width, Vec2F32 p, Vec4F32 color, char *fmt, ...) +d_textf(F_Tag font, F32 size, F32 base_align_px, F32 tab_size_px, Vec2F32 p, Vec4F32 color, char *fmt, ...) { Temp scratch = scratch_begin(0, 0); va_list args; va_start(args, fmt); String8 string = push_str8fv(scratch.arena, fmt, args); va_end(args); - d_text(font, size, base_column, tab_width, p, color, string); + d_text(font, size, base_align_px, tab_size_px, p, color, string); scratch_end(scratch); } internal void -d_truncated_text(F_Tag font, F32 size, F32 base_column, F32 tab_width, Vec2F32 p, Vec4F32 color, F32 max_x, String8 string) +d_truncated_text(F_Tag font, F32 size, F32 base_align_px, F32 tab_size_px, Vec2F32 p, Vec4F32 color, F32 max_x, String8 string) { Temp scratch = scratch_begin(0, 0); - F_Run run = f_push_run_from_string(scratch.arena, font, size, base_column, tab_width, 0, string); - F_Run ellipses_run = f_push_run_from_string(scratch.arena, font, size, base_column, tab_width, 0, str8_lit("...")); + F_Run run = f_push_run_from_string(scratch.arena, font, size, base_align_px, tab_size_px, 0, string); + F_Run ellipses_run = f_push_run_from_string(scratch.arena, font, size, base_align_px, tab_size_px, 0, str8_lit("...")); d_truncated_text_run(p, color, max_x, run, ellipses_run); scratch_end(scratch); } internal void -d_truncated_textf(F_Tag font, F32 size, F32 base_column, F32 tab_width, Vec2F32 p, Vec4F32 color, F32 max_x, char *fmt, ...) +d_truncated_textf(F_Tag font, F32 size, F32 base_align_px, F32 tab_size_px, Vec2F32 p, Vec4F32 color, F32 max_x, char *fmt, ...) { Temp scratch = scratch_begin(0, 0); va_list args; va_start(args, fmt); String8 string = push_str8f(scratch.arena, fmt, args); - d_truncated_text(font, size, base_column, tab_width, p, color, max_x, string); + d_truncated_text(font, size, base_align_px, tab_size_px, p, color, max_x, string); va_end(args); scratch_end(scratch); } diff --git a/src/draw/draw.h b/src/draw/draw.h index 1cb6d2bc..2764605d 100644 --- a/src/draw/draw.h +++ b/src/draw/draw.h @@ -110,7 +110,7 @@ internal U64 d_hash_from_string(String8 string); internal void d_fancy_string_list_push(Arena *arena, D_FancyStringList *list, D_FancyString *str); internal String8 d_string_from_fancy_string_list(Arena *arena, D_FancyStringList *list); -internal D_FancyRunList d_fancy_run_list_from_fancy_string_list(Arena *arena, F32 tab_width, D_FancyStringList *strs); +internal D_FancyRunList d_fancy_run_list_from_fancy_string_list(Arena *arena, F32 tab_size_px, D_FancyStringList *strs); internal D_FancyRunList d_fancy_run_list_copy(Arena *arena, D_FancyRunList *src); //////////////////////////////// @@ -186,9 +186,9 @@ internal void d_truncated_fancy_run_list(Vec2F32 p, D_FancyRunList *list, F32 ma internal void d_truncated_fancy_run_fuzzy_matches(Vec2F32 p, D_FancyRunList *list, F32 max_x, FuzzyMatchRangeList *ranges, Vec4F32 color); internal void d_text_run(Vec2F32 p, Vec4F32 color, F_Run run); internal void d_truncated_text_run(Vec2F32 p, Vec4F32 color, F32 max_x, F_Run text_run, F_Run trailer_run); -internal void d_text(F_Tag font, F32 size, F32 base_column, F32 tab_width, Vec2F32 p, Vec4F32 color, String8 string); -internal void d_textf(F_Tag font, F32 size, F32 base_column, F32 tab_width, Vec2F32 p, Vec4F32 color, char *fmt, ...); -internal void d_truncated_text(F_Tag font, F32 size, F32 base_column, F32 tab_width, Vec2F32 p, Vec4F32 color, F32 max_x, String8 string); -internal void d_truncated_textf(F_Tag font, F32 size, F32 base_column, F32 tab_width, Vec2F32 p, Vec4F32 color, F32 max_x, char *fmt, ...); +internal void d_text(F_Tag font, F32 size, F32 base_align_px, F32 tab_size_px, Vec2F32 p, Vec4F32 color, String8 string); +internal void d_textf(F_Tag font, F32 size, F32 base_align_px, F32 tab_size_px, Vec2F32 p, Vec4F32 color, char *fmt, ...); +internal void d_truncated_text(F_Tag font, F32 size, F32 base_align_px, F32 tab_size_px, Vec2F32 p, Vec4F32 color, F32 max_x, String8 string); +internal void d_truncated_textf(F_Tag font, F32 size, F32 base_align_px, F32 tab_size_px, Vec2F32 p, Vec4F32 color, F32 max_x, char *fmt, ...); #endif // DRAW_H diff --git a/src/font_cache/font_cache.c b/src/font_cache/font_cache.c index e2ac283c..4e05a24f 100644 --- a/src/font_cache/font_cache.c +++ b/src/font_cache/font_cache.c @@ -565,7 +565,7 @@ f_hash2style_from_tag_size(F_Tag tag, F32 size) } internal F_Run -f_push_run_from_string(Arena *arena, F_Tag tag, F32 size, F32 base_column, F32 tab_width, F_RunFlags flags, String8 string) +f_push_run_from_string(Arena *arena, F_Tag tag, F32 size, F32 base_align_px, F32 tab_size_px, F_RunFlags flags, String8 string) { ProfBeginFunction(); @@ -792,7 +792,7 @@ f_push_run_from_string(Arena *arena, F_Tag tag, F32 size, F32 base_column, F32 t F32 advance = info->advance; if(is_tab) { - advance *= tab_width - mod_f32(base_column, tab_width); + advance = tab_size_px - mod_f32(base_align_px, tab_size_px); } // rjf: push piece @@ -808,6 +808,7 @@ f_push_run_from_string(Arena *arena, F_Tag tag, F32 size, F32 base_column, F32 t piece->decode_size = piece_substring.size; piece->offset = v2s16(0, -hash2style_node->ascent - 4); } + base_align_px += advance; dim.x += piece->advance; dim.y = Max(dim.y, dim_2s16(piece->subrect).y); } @@ -836,12 +837,12 @@ f_push_run_from_string(Arena *arena, F_Tag tag, F32 size, F32 base_column, F32 t } internal String8List -f_wrapped_string_lines_from_font_size_string_max(Arena *arena, F_Tag font, F32 size, F32 base_column, F32 tab_width, String8 string, F32 max) +f_wrapped_string_lines_from_font_size_string_max(Arena *arena, F_Tag font, F32 size, F32 base_align_px, F32 tab_size_px, String8 string, F32 max) { String8List list = {0}; { Temp scratch = scratch_begin(&arena, 1); - F_Run run = f_push_run_from_string(scratch.arena, font, size, base_column, tab_width, 0, string); + F_Run run = f_push_run_from_string(scratch.arena, font, size, base_align_px, tab_size_px, 0, string); F32 off_px = 0; U64 off_bytes = 0; U64 line_start_off_bytes = 0; @@ -949,12 +950,12 @@ f_wrapped_string_lines_from_font_size_string_max(Arena *arena, F_Tag font, F32 s } internal Vec2F32 -f_dim_from_tag_size_string(F_Tag tag, F32 size, F32 base_column, F32 tab_width, String8 string) +f_dim_from_tag_size_string(F_Tag tag, F32 size, F32 base_align_px, F32 tab_size_px, String8 string) { ProfBeginFunction(); Temp scratch = scratch_begin(0, 0); Vec2F32 result = {0}; - F_Run run = f_push_run_from_string(scratch.arena, tag, size, base_column, tab_width, 0, string); + F_Run run = f_push_run_from_string(scratch.arena, tag, size, base_align_px, tab_size_px, 0, string); result = run.dim; scratch_end(scratch); ProfEnd(); @@ -962,13 +963,13 @@ f_dim_from_tag_size_string(F_Tag tag, F32 size, F32 base_column, F32 tab_width, } internal Vec2F32 -f_dim_from_tag_size_string_list(F_Tag tag, F32 size, F32 base_column, F32 tab_width, String8List list) +f_dim_from_tag_size_string_list(F_Tag tag, F32 size, F32 base_align_px, F32 tab_size_px, String8List list) { ProfBeginFunction(); Vec2F32 sum = {0}; for(String8Node *n = list.first; n != 0; n = n->next) { - Vec2F32 str_dim = f_dim_from_tag_size_string(tag, size, base_column, tab_width, n->string); + Vec2F32 str_dim = f_dim_from_tag_size_string(tag, size, base_align_px, tab_size_px, n->string); sum.x += str_dim.x; sum.y = Max(sum.y, str_dim.y); } @@ -976,8 +977,15 @@ f_dim_from_tag_size_string_list(F_Tag tag, F32 size, F32 base_column, F32 tab_wi return sum; } +internal F32 +f_column_size_from_tag_size(F_Tag tag, F32 size) +{ + F32 result = f_dim_from_tag_size_string(tag, size, 0, 0, str8_lit("H")).x; + return result; +} + internal U64 -f_char_pos_from_tag_size_string_p(F_Tag tag, F32 size, F32 base_column, F32 tab_width, String8 string, F32 p) +f_char_pos_from_tag_size_string_p(F_Tag tag, F32 size, F32 base_align_px, F32 tab_size_px, String8 string, F32 p) { ProfBeginFunction(); Temp scratch = scratch_begin(0, 0); @@ -987,7 +995,7 @@ f_char_pos_from_tag_size_string_p(F_Tag tag, F32 size, F32 base_column, F32 tab_ F32 x = 0; for(U64 char_idx = 0; char_idx <= string.size; char_idx += 1) { - F32 this_char_distance = fabsf(p - x); + F32 this_char_distance = abs_f32(p - x); if(this_char_distance < best_distance || best_distance < 0.f) { best_offset = char_idx; @@ -995,7 +1003,7 @@ f_char_pos_from_tag_size_string_p(F_Tag tag, F32 size, F32 base_column, F32 tab_ } if(char_idx < string.size) { - x += f_dim_from_tag_size_string(tag, size, base_column, tab_width, str8_substr(string, r1u64(char_idx, char_idx+1))).x; + x += f_dim_from_tag_size_string(tag, size, base_align_px, tab_size_px, str8_substr(string, r1u64(char_idx, char_idx+1))).x; } } result = best_offset; diff --git a/src/font_cache/font_cache.h b/src/font_cache/font_cache.h index 72061b2e..0e4ab173 100644 --- a/src/font_cache/font_cache.h +++ b/src/font_cache/font_cache.h @@ -131,6 +131,7 @@ struct F_Hash2StyleRasterCacheNode U64 style_hash; F32 ascent; F32 descent; + F32 column_width; F_RasterCacheInfo *utf8_class1_direct_map; U64 utf8_class1_direct_map_mask[4]; U64 hash2info_slots_count; @@ -247,11 +248,12 @@ internal F_PieceArray f_piece_array_copy(Arena *arena, F_PieceArray *src); //~ rjf: Rasterization Cache internal F_Hash2StyleRasterCacheNode *f_hash2style_from_tag_size(F_Tag tag, F32 size); -internal F_Run f_push_run_from_string(Arena *arena, F_Tag tag, F32 size, F32 base_column, F32 tab_width, F_RunFlags flags, String8 string); -internal String8List f_wrapped_string_lines_from_font_size_string_max(Arena *arena, F_Tag font, F32 size, F32 base_column, F32 tab_width, String8 string, F32 max); -internal Vec2F32 f_dim_from_tag_size_string(F_Tag tag, F32 size, F32 base_column, F32 tab_width, String8 string); -internal Vec2F32 f_dim_from_tag_size_string_list(F_Tag tag, F32 size, F32 base_column, F32 tab_width, String8List list); -internal U64 f_char_pos_from_tag_size_string_p(F_Tag tag, F32 size, F32 base_column, F32 tab_width, String8 string, F32 p); +internal F_Run f_push_run_from_string(Arena *arena, F_Tag tag, F32 size, F32 base_align_px, F32 tab_size_px, F_RunFlags flags, String8 string); +internal String8List f_wrapped_string_lines_from_font_size_string_max(Arena *arena, F_Tag font, F32 size, F32 base_align_px, F32 tab_size_px, String8 string, F32 max); +internal Vec2F32 f_dim_from_tag_size_string(F_Tag tag, F32 size, F32 base_align_px, F32 tab_size_px, String8 string); +internal Vec2F32 f_dim_from_tag_size_string_list(F_Tag tag, F32 size, F32 base_align_px, F32 tab_size_px, String8List list); +internal F32 f_column_size_from_tag_size(F_Tag tag, F32 size); +internal U64 f_char_pos_from_tag_size_string_p(F_Tag tag, F32 size, F32 base_align_px, F32 tab_size_px, String8 string, F32 p); //////////////////////////////// //~ rjf: Metrics diff --git a/src/ui/generated/ui.meta.c b/src/ui/generated/ui.meta.c index cb7ca0aa..ad2a8149 100644 --- a/src/ui/generated/ui.meta.c +++ b/src/ui/generated/ui.meta.c @@ -27,6 +27,7 @@ #define UI_HoverCursor(v) DeferLoop(ui_push_hover_cursor(v), ui_pop_hover_cursor()) #define UI_Font(v) DeferLoop(ui_push_font(v), ui_pop_font()) #define UI_FontSize(v) DeferLoop(ui_push_font_size(v), ui_pop_font_size()) +#define UI_TabSize(v) DeferLoop(ui_push_tab_size(v), ui_pop_tab_size()) #define UI_CornerRadius00(v) DeferLoop(ui_push_corner_radius_00(v), ui_pop_corner_radius_00()) #define UI_CornerRadius01(v) DeferLoop(ui_push_corner_radius_01(v), ui_pop_corner_radius_01()) #define UI_CornerRadius10(v) DeferLoop(ui_push_corner_radius_10(v), ui_pop_corner_radius_10()) @@ -58,6 +59,7 @@ internal F32 ui_top_squish(void) { UI_StackTopImpl(ui_state, Squish, squish) } internal OS_Cursor ui_top_hover_cursor(void) { UI_StackTopImpl(ui_state, HoverCursor, hover_cursor) } internal F_Tag ui_top_font(void) { UI_StackTopImpl(ui_state, Font, font) } internal F32 ui_top_font_size(void) { UI_StackTopImpl(ui_state, FontSize, font_size) } +internal F32 ui_top_tab_size(void) { UI_StackTopImpl(ui_state, TabSize, tab_size) } internal F32 ui_top_corner_radius_00(void) { UI_StackTopImpl(ui_state, CornerRadius00, corner_radius_00) } internal F32 ui_top_corner_radius_01(void) { UI_StackTopImpl(ui_state, CornerRadius01, corner_radius_01) } internal F32 ui_top_corner_radius_10(void) { UI_StackTopImpl(ui_state, CornerRadius10, corner_radius_10) } @@ -88,6 +90,7 @@ internal F32 ui_bottom_squish(void) { UI_StackBottomImpl(ui_state, Squish, squis internal OS_Cursor ui_bottom_hover_cursor(void) { UI_StackBottomImpl(ui_state, HoverCursor, hover_cursor) } internal F_Tag ui_bottom_font(void) { UI_StackBottomImpl(ui_state, Font, font) } internal F32 ui_bottom_font_size(void) { UI_StackBottomImpl(ui_state, FontSize, font_size) } +internal F32 ui_bottom_tab_size(void) { UI_StackBottomImpl(ui_state, TabSize, tab_size) } internal F32 ui_bottom_corner_radius_00(void) { UI_StackBottomImpl(ui_state, CornerRadius00, corner_radius_00) } internal F32 ui_bottom_corner_radius_01(void) { UI_StackBottomImpl(ui_state, CornerRadius01, corner_radius_01) } internal F32 ui_bottom_corner_radius_10(void) { UI_StackBottomImpl(ui_state, CornerRadius10, corner_radius_10) } @@ -118,6 +121,7 @@ internal F32 ui_push_squish(F32 v) { UI_StackPushImpl(ui_state, Squish, squish, internal OS_Cursor ui_push_hover_cursor(OS_Cursor v) { UI_StackPushImpl(ui_state, HoverCursor, hover_cursor, OS_Cursor, v) } internal F_Tag ui_push_font(F_Tag v) { UI_StackPushImpl(ui_state, Font, font, F_Tag, v) } internal F32 ui_push_font_size(F32 v) { UI_StackPushImpl(ui_state, FontSize, font_size, F32, v) } +internal F32 ui_push_tab_size(F32 v) { UI_StackPushImpl(ui_state, TabSize, tab_size, F32, v) } internal F32 ui_push_corner_radius_00(F32 v) { UI_StackPushImpl(ui_state, CornerRadius00, corner_radius_00, F32, v) } internal F32 ui_push_corner_radius_01(F32 v) { UI_StackPushImpl(ui_state, CornerRadius01, corner_radius_01, F32, v) } internal F32 ui_push_corner_radius_10(F32 v) { UI_StackPushImpl(ui_state, CornerRadius10, corner_radius_10, F32, v) } @@ -148,6 +152,7 @@ internal F32 ui_pop_squish(void) { UI_StackPopImpl(ui_state, Squish, squish) } internal OS_Cursor ui_pop_hover_cursor(void) { UI_StackPopImpl(ui_state, HoverCursor, hover_cursor) } internal F_Tag ui_pop_font(void) { UI_StackPopImpl(ui_state, Font, font) } internal F32 ui_pop_font_size(void) { UI_StackPopImpl(ui_state, FontSize, font_size) } +internal F32 ui_pop_tab_size(void) { UI_StackPopImpl(ui_state, TabSize, tab_size) } internal F32 ui_pop_corner_radius_00(void) { UI_StackPopImpl(ui_state, CornerRadius00, corner_radius_00) } internal F32 ui_pop_corner_radius_01(void) { UI_StackPopImpl(ui_state, CornerRadius01, corner_radius_01) } internal F32 ui_pop_corner_radius_10(void) { UI_StackPopImpl(ui_state, CornerRadius10, corner_radius_10) } @@ -178,6 +183,7 @@ internal F32 ui_set_next_squish(F32 v) { UI_StackSetNextImpl(ui_state, Squish, s internal OS_Cursor ui_set_next_hover_cursor(OS_Cursor v) { UI_StackSetNextImpl(ui_state, HoverCursor, hover_cursor, OS_Cursor, v) } internal F_Tag ui_set_next_font(F_Tag v) { UI_StackSetNextImpl(ui_state, Font, font, F_Tag, v) } internal F32 ui_set_next_font_size(F32 v) { UI_StackSetNextImpl(ui_state, FontSize, font_size, F32, v) } +internal F32 ui_set_next_tab_size(F32 v) { UI_StackSetNextImpl(ui_state, TabSize, tab_size, F32, v) } internal F32 ui_set_next_corner_radius_00(F32 v) { UI_StackSetNextImpl(ui_state, CornerRadius00, corner_radius_00, F32, v) } internal F32 ui_set_next_corner_radius_01(F32 v) { UI_StackSetNextImpl(ui_state, CornerRadius01, corner_radius_01, F32, v) } internal F32 ui_set_next_corner_radius_10(F32 v) { UI_StackSetNextImpl(ui_state, CornerRadius10, corner_radius_10, F32, v) } diff --git a/src/ui/generated/ui.meta.h b/src/ui/generated/ui.meta.h index bd3a2bc4..e60de2bc 100644 --- a/src/ui/generated/ui.meta.h +++ b/src/ui/generated/ui.meta.h @@ -29,6 +29,7 @@ typedef struct UI_SquishNode UI_SquishNode; struct UI_SquishNode{UI_SquishNode * typedef struct UI_HoverCursorNode UI_HoverCursorNode; struct UI_HoverCursorNode{UI_HoverCursorNode *next; OS_Cursor v;}; typedef struct UI_FontNode UI_FontNode; struct UI_FontNode{UI_FontNode *next; F_Tag v;}; typedef struct UI_FontSizeNode UI_FontSizeNode; struct UI_FontSizeNode{UI_FontSizeNode *next; F32 v;}; +typedef struct UI_TabSizeNode UI_TabSizeNode; struct UI_TabSizeNode{UI_TabSizeNode *next; F32 v;}; typedef struct UI_CornerRadius00Node UI_CornerRadius00Node; struct UI_CornerRadius00Node{UI_CornerRadius00Node *next; F32 v;}; typedef struct UI_CornerRadius01Node UI_CornerRadius01Node; struct UI_CornerRadius01Node{UI_CornerRadius01Node *next; F32 v;}; typedef struct UI_CornerRadius10Node UI_CornerRadius10Node; struct UI_CornerRadius10Node{UI_CornerRadius10Node *next; F32 v;}; @@ -62,6 +63,7 @@ UI_SquishNode squish_nil_stack_top;\ UI_HoverCursorNode hover_cursor_nil_stack_top;\ UI_FontNode font_nil_stack_top;\ UI_FontSizeNode font_size_nil_stack_top;\ +UI_TabSizeNode tab_size_nil_stack_top;\ UI_CornerRadius00Node corner_radius_00_nil_stack_top;\ UI_CornerRadius01Node corner_radius_01_nil_stack_top;\ UI_CornerRadius10Node corner_radius_10_nil_stack_top;\ @@ -94,6 +96,7 @@ state->squish_nil_stack_top.v = 0;\ state->hover_cursor_nil_stack_top.v = OS_Cursor_Pointer;\ state->font_nil_stack_top.v = f_tag_zero();\ state->font_size_nil_stack_top.v = 24.f;\ +state->tab_size_nil_stack_top.v = 24.f*4.f;\ state->corner_radius_00_nil_stack_top.v = 0;\ state->corner_radius_01_nil_stack_top.v = 0;\ state->corner_radius_10_nil_stack_top.v = 0;\ @@ -128,6 +131,7 @@ struct { UI_SquishNode *top; F32 bottom_val; UI_SquishNode *free; B32 auto_pop; struct { UI_HoverCursorNode *top; OS_Cursor bottom_val; UI_HoverCursorNode *free; B32 auto_pop; } hover_cursor_stack;\ struct { UI_FontNode *top; F_Tag bottom_val; UI_FontNode *free; B32 auto_pop; } font_stack;\ struct { UI_FontSizeNode *top; F32 bottom_val; UI_FontSizeNode *free; B32 auto_pop; } font_size_stack;\ +struct { UI_TabSizeNode *top; F32 bottom_val; UI_TabSizeNode *free; B32 auto_pop; } tab_size_stack;\ struct { UI_CornerRadius00Node *top; F32 bottom_val; UI_CornerRadius00Node *free; B32 auto_pop; } corner_radius_00_stack;\ struct { UI_CornerRadius01Node *top; F32 bottom_val; UI_CornerRadius01Node *free; B32 auto_pop; } corner_radius_01_stack;\ struct { UI_CornerRadius10Node *top; F32 bottom_val; UI_CornerRadius10Node *free; B32 auto_pop; } corner_radius_10_stack;\ @@ -160,6 +164,7 @@ state->squish_stack.top = &state->squish_nil_stack_top; state->squish_stack.bott state->hover_cursor_stack.top = &state->hover_cursor_nil_stack_top; state->hover_cursor_stack.bottom_val = OS_Cursor_Pointer; state->hover_cursor_stack.free = 0; state->hover_cursor_stack.auto_pop = 0;\ state->font_stack.top = &state->font_nil_stack_top; state->font_stack.bottom_val = f_tag_zero(); state->font_stack.free = 0; state->font_stack.auto_pop = 0;\ state->font_size_stack.top = &state->font_size_nil_stack_top; state->font_size_stack.bottom_val = 24.f; state->font_size_stack.free = 0; state->font_size_stack.auto_pop = 0;\ +state->tab_size_stack.top = &state->tab_size_nil_stack_top; state->tab_size_stack.bottom_val = 24.f*4.f; state->tab_size_stack.free = 0; state->tab_size_stack.auto_pop = 0;\ state->corner_radius_00_stack.top = &state->corner_radius_00_nil_stack_top; state->corner_radius_00_stack.bottom_val = 0; state->corner_radius_00_stack.free = 0; state->corner_radius_00_stack.auto_pop = 0;\ state->corner_radius_01_stack.top = &state->corner_radius_01_nil_stack_top; state->corner_radius_01_stack.bottom_val = 0; state->corner_radius_01_stack.free = 0; state->corner_radius_01_stack.auto_pop = 0;\ state->corner_radius_10_stack.top = &state->corner_radius_10_nil_stack_top; state->corner_radius_10_stack.bottom_val = 0; state->corner_radius_10_stack.free = 0; state->corner_radius_10_stack.auto_pop = 0;\ @@ -192,6 +197,7 @@ if(state->squish_stack.auto_pop) { ui_pop_squish(); state->squish_stack.auto_pop if(state->hover_cursor_stack.auto_pop) { ui_pop_hover_cursor(); state->hover_cursor_stack.auto_pop = 0; }\ if(state->font_stack.auto_pop) { ui_pop_font(); state->font_stack.auto_pop = 0; }\ if(state->font_size_stack.auto_pop) { ui_pop_font_size(); state->font_size_stack.auto_pop = 0; }\ +if(state->tab_size_stack.auto_pop) { ui_pop_tab_size(); state->tab_size_stack.auto_pop = 0; }\ if(state->corner_radius_00_stack.auto_pop) { ui_pop_corner_radius_00(); state->corner_radius_00_stack.auto_pop = 0; }\ if(state->corner_radius_01_stack.auto_pop) { ui_pop_corner_radius_01(); state->corner_radius_01_stack.auto_pop = 0; }\ if(state->corner_radius_10_stack.auto_pop) { ui_pop_corner_radius_10(); state->corner_radius_10_stack.auto_pop = 0; }\ @@ -223,6 +229,7 @@ internal F32 ui_top_squish(void); internal OS_Cursor ui_top_hover_cursor(void); internal F_Tag ui_top_font(void); internal F32 ui_top_font_size(void); +internal F32 ui_top_tab_size(void); internal F32 ui_top_corner_radius_00(void); internal F32 ui_top_corner_radius_01(void); internal F32 ui_top_corner_radius_10(void); @@ -253,6 +260,7 @@ internal F32 ui_bottom_squish(void); internal OS_Cursor ui_bottom_hover_cursor(void); internal F_Tag ui_bottom_font(void); internal F32 ui_bottom_font_size(void); +internal F32 ui_bottom_tab_size(void); internal F32 ui_bottom_corner_radius_00(void); internal F32 ui_bottom_corner_radius_01(void); internal F32 ui_bottom_corner_radius_10(void); @@ -283,6 +291,7 @@ internal F32 ui_push_squish(F32 v); internal OS_Cursor ui_push_hover_cursor(OS_Cursor v); internal F_Tag ui_push_font(F_Tag v); internal F32 ui_push_font_size(F32 v); +internal F32 ui_push_tab_size(F32 v); internal F32 ui_push_corner_radius_00(F32 v); internal F32 ui_push_corner_radius_01(F32 v); internal F32 ui_push_corner_radius_10(F32 v); @@ -313,6 +322,7 @@ internal F32 ui_pop_squish(void); internal OS_Cursor ui_pop_hover_cursor(void); internal F_Tag ui_pop_font(void); internal F32 ui_pop_font_size(void); +internal F32 ui_pop_tab_size(void); internal F32 ui_pop_corner_radius_00(void); internal F32 ui_pop_corner_radius_01(void); internal F32 ui_pop_corner_radius_10(void); @@ -343,6 +353,7 @@ internal F32 ui_set_next_squish(F32 v); internal OS_Cursor ui_set_next_hover_cursor(OS_Cursor v); internal F_Tag ui_set_next_font(F_Tag v); internal F32 ui_set_next_font_size(F32 v); +internal F32 ui_set_next_tab_size(F32 v); internal F32 ui_set_next_corner_radius_00(F32 v); internal F32 ui_set_next_corner_radius_01(F32 v); internal F32 ui_set_next_corner_radius_10(F32 v); diff --git a/src/ui/ui.mdesk b/src/ui/ui.mdesk index f94bfdaf..1eb36228 100644 --- a/src/ui/ui.mdesk +++ b/src/ui/ui.mdesk @@ -46,6 +46,7 @@ UI_StackTable: //- rjf: font { Font font F_Tag `f_tag_zero()` } { FontSize font_size F32 24.f } + { TabSize tab_size F32 `24.f*4.f` } //- rjf: corner radii { CornerRadius00 corner_radius_00 F32 0 } diff --git a/src/ui/ui_basic_widgets.c b/src/ui/ui_basic_widgets.c index ac0beee4..aea53327 100644 --- a/src/ui/ui_basic_widgets.c +++ b/src/ui/ui_basic_widgets.c @@ -43,7 +43,7 @@ ui_label_multiline(F32 max, String8 string) ui_set_next_child_layout_axis(Axis2_Y); ui_set_next_pref_height(ui_children_sum(1)); UI_Box *box = ui_build_box_from_key(0, ui_key_zero()); - String8List lines = f_wrapped_string_lines_from_font_size_string_max(scratch.arena, ui_top_font(), ui_top_font_size(), 0, UI_TEMP_TAB_WIDTH, string, max); + String8List lines = f_wrapped_string_lines_from_font_size_string_max(scratch.arena, ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), string, max); for(String8Node *n = lines.first; n != 0; n = n->next) { ui_label(n->string); @@ -131,6 +131,7 @@ internal UI_BOX_CUSTOM_DRAW(ui_line_edit_draw) UI_LineEditDrawData *draw_data = (UI_LineEditDrawData *)user_data; F_Tag font = box->font; F32 font_size = box->font_size; + F32 tab_size = box->tab_size; Vec4F32 cursor_color = draw_data->cursor_color; cursor_color.w *= box->parent->parent->focus_active_t; Vec4F32 select_color = draw_data->select_color; @@ -139,8 +140,8 @@ internal UI_BOX_CUSTOM_DRAW(ui_line_edit_draw) String8 edited_string = draw_data->edited_string; TxtPt cursor = draw_data->cursor; TxtPt mark = draw_data->mark; - F32 cursor_pixel_off = f_dim_from_tag_size_string(font, font_size, 0, UI_TEMP_TAB_WIDTH, str8_prefix(edited_string, cursor.column-1)).x + font_size/8.f; - F32 mark_pixel_off = f_dim_from_tag_size_string(font, font_size, 0, UI_TEMP_TAB_WIDTH, str8_prefix(edited_string, mark.column-1)).x + font_size/8.f; + F32 cursor_pixel_off = f_dim_from_tag_size_string(font, font_size, 0, tab_size, str8_prefix(edited_string, cursor.column-1)).x + font_size/8.f; + F32 mark_pixel_off = f_dim_from_tag_size_string(font, font_size, 0, tab_size, str8_prefix(edited_string, mark.column-1)).x + font_size/8.f; F32 cursor_thickness = ClampBot(4.f, font_size/6.f); Rng2F32 cursor_rect = { @@ -253,7 +254,7 @@ ui_line_edit(TxtPt *cursor, TxtPt *mark, U8 *edit_buffer, U64 edit_buffer_size, } else { - F32 total_text_width = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, UI_TEMP_TAB_WIDTH, edit_string).x; + F32 total_text_width = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), edit_string).x; ui_set_next_pref_width(ui_px(total_text_width+ui_top_font_size()*5, 1.f)); UI_Box *editstr_box = ui_build_box_from_stringf(UI_BoxFlag_DrawText|UI_BoxFlag_DisableTextTrunc, "###editstr"); UI_LineEditDrawData *draw_data = push_array(ui_build_arena(), UI_LineEditDrawData, 1); @@ -265,7 +266,7 @@ ui_line_edit(TxtPt *cursor, TxtPt *mark, U8 *edit_buffer, U64 edit_buffer_size, ui_box_equip_display_string(editstr_box, edit_string); ui_box_equip_custom_draw(editstr_box, ui_line_edit_draw, draw_data); mouse_pt = txt_pt(1, 1+ui_box_char_pos_from_xy(editstr_box, ui_mouse())); - cursor_off = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, UI_TEMP_TAB_WIDTH, str8_prefix(edit_string, cursor->column-1)).x; + cursor_off = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), str8_prefix(edit_string, cursor->column-1)).x; } } diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index d276bbd5..a0e32ef0 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -2170,6 +2170,7 @@ ui_build_box_from_key(UI_BoxFlags flags, UI_Key key) box->overlay_color = ui_state->overlay_color_stack.top->v; box->font = ui_state->font_stack.top->v; box->font_size = ui_state->font_size_stack.top->v; + box->tab_size = ui_state->tab_size_stack.top->v; box->corner_radii[Corner_00] = ui_state->corner_radius_00_stack.top->v; box->corner_radii[Corner_01] = ui_state->corner_radius_01_stack.top->v; box->corner_radii[Corner_10] = ui_state->corner_radius_10_stack.top->v; @@ -2258,7 +2259,7 @@ ui_box_equip_display_string(UI_Box *box, String8 string) String8 display_string = ui_box_display_string(box); D_FancyStringNode fancy_string_n = {0, {box->font, display_string, box->text_color, box->font_size, 0, 0}}; D_FancyStringList fancy_strings = {&fancy_string_n, &fancy_string_n, 1}; - box->display_string_runs = d_fancy_run_list_from_fancy_string_list(ui_build_arena(), UI_TEMP_TAB_WIDTH, &fancy_strings); + box->display_string_runs = d_fancy_run_list_from_fancy_string_list(ui_build_arena(), box->tab_size, &fancy_strings); } else if(box->flags & UI_BoxFlag_DrawText && box->flags & UI_BoxFlag_DrawTextFastpathCodepoint && box->fastpath_codepoint != 0) { @@ -2273,13 +2274,13 @@ ui_box_equip_display_string(UI_Box *box, String8 string) D_FancyStringNode cdp_fancy_string_n = {&pst_fancy_string_n, {box->font, str8_substr(display_string, r1u64(fpcp_pos, fpcp_pos+fpcp.size)), box->text_color, box->font_size, 4.f, 0}}; D_FancyStringNode pre_fancy_string_n = {&cdp_fancy_string_n, {box->font, str8_prefix(display_string, fpcp_pos), box->text_color, box->font_size, 0, 0}}; D_FancyStringList fancy_strings = {&pre_fancy_string_n, &pst_fancy_string_n, 3}; - box->display_string_runs = d_fancy_run_list_from_fancy_string_list(ui_build_arena(), UI_TEMP_TAB_WIDTH, &fancy_strings); + box->display_string_runs = d_fancy_run_list_from_fancy_string_list(ui_build_arena(), box->tab_size, &fancy_strings); } else { D_FancyStringNode fancy_string_n = {0, {box->font, display_string, box->text_color, box->font_size, 0, 0}}; D_FancyStringList fancy_strings = {&fancy_string_n, &fancy_string_n, 1}; - box->display_string_runs = d_fancy_run_list_from_fancy_string_list(ui_build_arena(), UI_TEMP_TAB_WIDTH, &fancy_strings); + box->display_string_runs = d_fancy_run_list_from_fancy_string_list(ui_build_arena(), box->tab_size, &fancy_strings); } scratch_end(scratch); } @@ -2287,11 +2288,11 @@ ui_box_equip_display_string(UI_Box *box, String8 string) } internal void -ui_box_equip_display_fancy_strings(UI_Box *box, D_FancyStringList *strings) +ui_box_equip_display_fancy_strings(UI_Box *box, F32 tab_size, D_FancyStringList *strings) { box->flags |= UI_BoxFlag_HasDisplayString; box->string = d_string_from_fancy_string_list(ui_build_arena(), strings); - box->display_string_runs = d_fancy_run_list_from_fancy_string_list(ui_build_arena(), UI_TEMP_TAB_WIDTH, strings); + box->display_string_runs = d_fancy_run_list_from_fancy_string_list(ui_build_arena(), tab_size, strings); } internal inline void @@ -2381,7 +2382,7 @@ ui_box_char_pos_from_xy(UI_Box *box, Vec2F32 xy) F_Tag font = box->font; F32 font_size = box->font_size; String8 line = ui_box_display_string(box); - U64 result = f_char_pos_from_tag_size_string_p(font, font_size, 0, UI_TEMP_TAB_WIDTH, line, xy.x - ui_box_text_position(box).x); + U64 result = f_char_pos_from_tag_size_string_p(font, font_size, 0, box->tab_size, line, xy.x - ui_box_text_position(box).x); return result; } diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index 81d9d406..8f69313d 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -4,10 +4,6 @@ #ifndef UI_H #define UI_H -// TODO(rjf): @tab_layout -#define UI_TEMP_TAB_WIDTH 4.f -#define UI_TEMP_BASE_COLUMN_TODO 0.f - //////////////////////////////// //~ rjf: Icon Info @@ -340,6 +336,7 @@ struct UI_Box Vec4F32 overlay_color; F_Tag font; F32 font_size; + F32 tab_size; F32 corner_radii[Corner_COUNT]; F32 blur_size; F32 transparency; @@ -731,7 +728,7 @@ internal UI_Box * ui_build_box_from_stringf(UI_BoxFlags flags, char *fm //- rjf: box node equipment internal inline void ui_box_equip_display_string(UI_Box *box, String8 string); -internal inline void ui_box_equip_display_fancy_strings(UI_Box *box, D_FancyStringList *strings); +internal inline void ui_box_equip_display_fancy_strings(UI_Box *box, F32 tab_size, D_FancyStringList *strings); internal inline void ui_box_equip_display_string_fancy_runs(UI_Box *box, String8 string, D_FancyRunList *runs); internal inline void ui_box_equip_fuzzy_match_ranges(UI_Box *box, FuzzyMatchRangeList *matches); internal inline void ui_box_equip_draw_bucket(UI_Box *box, D_Bucket *bucket); @@ -942,6 +939,7 @@ internal void ui_pop_corner_radius(void); #define UI_HoverCursor(v) DeferLoop(ui_push_hover_cursor(v), ui_pop_hover_cursor()) #define UI_Font(v) DeferLoop(ui_push_font(v), ui_pop_font()) #define UI_FontSize(v) DeferLoop(ui_push_font_size(v), ui_pop_font_size()) +#define UI_TabSize(v) DeferLoop(ui_push_tab_size(v), ui_pop_tab_size()) #define UI_CornerRadius00(v) DeferLoop(ui_push_corner_radius_00(v), ui_pop_corner_radius_00()) #define UI_CornerRadius01(v) DeferLoop(ui_push_corner_radius_01(v), ui_pop_corner_radius_01()) #define UI_CornerRadius10(v) DeferLoop(ui_push_corner_radius_10(v), ui_pop_corner_radius_10()) From bddc9c97d9de5f5eb9eab07306e8fe17bb2db5a7 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 24 May 2024 17:18:31 -0700 Subject: [PATCH 17/39] get rdi_dump off dbgi layer, actually, super bad idea; just dedup decompression code --- src/dbgi/dbgi.c | 51 +--------------------- src/lib_rdi_format/rdi_format_parse.c | 11 +++++ src/lib_rdi_format/rdi_format_parse.h | 3 ++ src/raddbg/raddbg_main.cpp | 6 +-- src/rdi_dump/rdi_dump_main.c | 56 +++++++++++++++---------- src/rdi_format_local/rdi_format_local.c | 52 +++++++++++++++++++++++ src/rdi_format_local/rdi_format_local.h | 12 ++++++ 7 files changed, 116 insertions(+), 75 deletions(-) create mode 100644 src/rdi_format_local/rdi_format_local.c create mode 100644 src/rdi_format_local/rdi_format_local.h diff --git a/src/dbgi/dbgi.c b/src/dbgi/dbgi.c index 0b8811cb..6fa63320 100644 --- a/src/dbgi/dbgi.c +++ b/src/dbgi/dbgi.c @@ -840,59 +840,12 @@ di_parse_thread__entry_point(void *p) RDI_Parsed rdi_parsed = rdi_parsed_maybe_compressed; if(got_task) { - U64 decompressed_size = file_props.size; - for(U64 dsec_idx = 0; dsec_idx < rdi_parsed_maybe_compressed.dsec_count; dsec_idx += 1) - { - decompressed_size += (rdi_parsed_maybe_compressed.dsecs[dsec_idx].unpacked_size - rdi_parsed_maybe_compressed.dsecs[dsec_idx].encoded_size); - } + U64 decompressed_size = rdi_decompressed_size_from_parsed(&rdi_parsed_maybe_compressed); if(decompressed_size > file_props.size) { rdi_parsed_arena = arena_alloc(); U8 *decompressed_data = push_array_no_zero(rdi_parsed_arena, U8, decompressed_size); - - // rjf: copy header - RDI_Header *src_header = (RDI_Header *)file_base; - RDI_Header *dst_header = (RDI_Header *)decompressed_data; - { - MemoryCopy(dst_header, src_header, sizeof(RDI_Header)); - } - - // rjf: copy & adjust sections for decompressed version - if(rdi_parsed_maybe_compressed.dsec_count != 0) - { - RDI_DataSection *dsec_base = (RDI_DataSection *)(decompressed_data + dst_header->data_section_off); - MemoryCopy(dsec_base, (U8 *)file_base + src_header->data_section_off, sizeof(RDI_DataSection) * rdi_parsed_maybe_compressed.dsec_count); - U64 off = dst_header->data_section_off + sizeof(RDI_DataSection) * rdi_parsed_maybe_compressed.dsec_count; - off += 7; - off -= off%8; - for(U64 idx = 0; idx < rdi_parsed_maybe_compressed.dsec_count; idx += 1) - { - dsec_base[idx].encoding = RDI_DataSectionEncoding_Unpacked; - dsec_base[idx].off = off; - dsec_base[idx].encoded_size = dsec_base[idx].unpacked_size; - off += dsec_base[idx].unpacked_size; - off += 7; - off -= off%8; - } - } - - // rjf: decompress sections into new decompressed file buffer - if(rdi_parsed_maybe_compressed.dsec_count != 0) - { - RDI_DataSection *src_first = rdi_parsed_maybe_compressed.dsecs; - RDI_DataSection *dst_first = (RDI_DataSection *)(decompressed_data + dst_header->data_section_off); - RDI_DataSection *src_opl = src_first + rdi_parsed_maybe_compressed.dsec_count; - RDI_DataSection *dst_opl = dst_first + rdi_parsed_maybe_compressed.dsec_count; - for(RDI_DataSection *src = src_first, *dst = dst_first; - src < src_opl && dst < dst_opl; - src += 1, dst += 1) - { - rr_lzb_simple_decode((U8*)file_base + src->off, src->encoded_size, - decompressed_data + dst->off, dst->unpacked_size); - } - } - - // rjf: re-parse + rdi_decompress_parsed(decompressed_data, decompressed_size, &rdi_parsed_maybe_compressed); RDI_ParseStatus parse_status = rdi_parse(decompressed_data, decompressed_size, &rdi_parsed); (void)parse_status; } diff --git a/src/lib_rdi_format/rdi_format_parse.c b/src/lib_rdi_format/rdi_format_parse.c index 3b3c2f61..dafce68b 100644 --- a/src/lib_rdi_format/rdi_format_parse.c +++ b/src/lib_rdi_format/rdi_format_parse.c @@ -221,6 +221,17 @@ rdi_parse(RDI_U8 *data, RDI_U64 size, RDI_Parsed *out) return(result); } +RDI_PROC RDI_U64 +rdi_decompressed_size_from_parsed(RDI_Parsed *rdi) +{ + RDI_U64 decompressed_size = rdi->raw_data_size; + for(RDI_U64 dsec_idx = 0; dsec_idx < rdi->dsec_count; dsec_idx += 1) + { + decompressed_size += (rdi->dsecs[dsec_idx].unpacked_size - rdi->dsecs[dsec_idx].encoded_size); + } + return decompressed_size; +} + RDI_PROC RDI_U8* rdi_string_from_idx(RDI_Parsed *parsed, RDI_U32 idx, RDI_U64 *len_out){ RDI_U8 *result = 0; diff --git a/src/lib_rdi_format/rdi_format_parse.h b/src/lib_rdi_format/rdi_format_parse.h index 9e97bcb3..66b29019 100644 --- a/src/lib_rdi_format/rdi_format_parse.h +++ b/src/lib_rdi_format/rdi_format_parse.h @@ -153,6 +153,9 @@ static RDI_Local rdi_local_nil = {0}; RDI_PROC RDI_ParseStatus rdi_parse(RDI_U8 *data, RDI_U64 size, RDI_Parsed *out); +RDI_PROC RDI_U64 +rdi_decompressed_size_from_parsed(RDI_Parsed *rdi); + RDI_PROC RDI_U8* rdi_string_from_idx(RDI_Parsed *parsed, RDI_U32 idx, RDI_U64 *len_out); diff --git a/src/raddbg/raddbg_main.cpp b/src/raddbg/raddbg_main.cpp index 70c881b6..85f5830a 100644 --- a/src/raddbg/raddbg_main.cpp +++ b/src/raddbg/raddbg_main.cpp @@ -22,10 +22,6 @@ //~ rjf: Includes //- rjf: [lib] -#include "lib_rdi_format/rdi_format.h" -#include "lib_rdi_format/rdi_format.c" -#include "lib_rdi_format/rdi_format_parse.h" -#include "lib_rdi_format/rdi_format_parse.c" #include "third_party/rad_lzb_simple/rad_lzb_simple.h" #include "third_party/rad_lzb_simple/rad_lzb_simple.c" @@ -34,6 +30,7 @@ #include "os/os_inc.h" #include "task_system/task_system.h" #include "ico/ico.h" +#include "rdi_format_local/rdi_format_local.h" #include "rdi_make_local/rdi_make_local.h" #include "mdesk/mdesk.h" #include "hash_store/hash_store.h" @@ -73,6 +70,7 @@ #include "os/os_inc.c" #include "task_system/task_system.c" #include "ico/ico.c" +#include "rdi_format_local/rdi_format_local.c" #include "rdi_make_local/rdi_make_local.c" #include "mdesk/mdesk.c" #include "hash_store/hash_store.c" diff --git a/src/rdi_dump/rdi_dump_main.c b/src/rdi_dump/rdi_dump_main.c index 315850e9..c6ad215d 100644 --- a/src/rdi_dump/rdi_dump_main.c +++ b/src/rdi_dump/rdi_dump_main.c @@ -15,25 +15,19 @@ //~ rjf: Includes //- rjf: [lib] -#include "lib_rdi_format/rdi_format.h" -#include "lib_rdi_format/rdi_format_parse.h" -#include "lib_rdi_format/rdi_format.c" -#include "lib_rdi_format/rdi_format_parse.c" #include "third_party/rad_lzb_simple/rad_lzb_simple.h" #include "third_party/rad_lzb_simple/rad_lzb_simple.c" //- rjf: [h] #include "base/base_inc.h" #include "os/os_inc.h" -#include "path/path.h" -#include "dbgi/dbgi.h" +#include "rdi_format_local/rdi_format_local.h" #include "rdi_dump.h" //- rjf: [c] #include "base/base_inc.c" #include "os/os_inc.c" -#include "path/path.c" -#include "dbgi/dbgi.c" +#include "rdi_format_local/rdi_format_local.c" #include "rdi_dump.c" //////////////////////////////// @@ -46,7 +40,6 @@ entry_point(CmdLine *cmd_line) //- rjf: set up // Arena *arena = arena_alloc(); - DI_Scope *di_scope = di_scope_open(); String8List errors = {0}; ////////////////////////////// @@ -74,7 +67,6 @@ entry_point(CmdLine *cmd_line) DumpFlag_Strings = (1<<16), }; String8 input_name = {0}; - String8 input_data = {0}; DumpFlags dump_flags = (U32)0xffffffff; { // rjf: extract input file path @@ -111,24 +103,46 @@ entry_point(CmdLine *cmd_line) } ////////////////////////////// - //- rjf: obtain rdi parse + //- rjf: load file // - RDI_Parsed *rdi = &di_rdi_parsed_nil; + String8 input_data = os_data_from_file_path(arena, input_name); if(input_name.size == 0) { str8_list_pushf(arena, &errors, "error (input): No input RDI file specified."); } - else - { - DI_Key key = {input_name}; - di_open(&key); - rdi = di_rdi_from_key(di_scope, &key, max_U64); - } - if(rdi == &di_rdi_parsed_nil) + else if(input_data.size == 0) { str8_list_pushf(arena, &errors, "error (input): No input RDI file successfully loaded; either the path or file contents are invalid."); } + ////////////////////////////// + //- rjf: obtain initial rdi parse + // + RDI_Parsed rdi_ = {0}; + RDI_Parsed *rdi = &rdi_; + RDI_ParseStatus status = rdi_parse(input_data.str, input_data.size, rdi); + + ////////////////////////////// + //- rjf: decompress rdi if necessary + // + { + U64 decompressed_size = rdi_decompressed_size_from_parsed(rdi); + if(decompressed_size > input_data.size) + { + U8 *decompressed_data = push_array_no_zero(arena, U8, decompressed_size); + rdi_decompress_parsed(decompressed_data, decompressed_size, rdi); + status = rdi_parse(decompressed_data, decompressed_size, rdi); + } + } + + ////////////////////////////// + //- rjf: error on bad parse status + // + if(status != RDI_ParseStatus_Good) + { + str8_list_pushf(arena, &errors, "error (input): RDI file could not be successfully decoded."); + } + ////////////////////////////// //- rjf: output error strings to stderr // @@ -142,7 +156,7 @@ entry_point(CmdLine *cmd_line) //- rjf: build dump strings // String8List dump = {0}; - if(rdi != &di_rdi_parsed_nil) + if(errors.node_count != 0) { //- rjf: DATA SECTIONS if(dump_flags & DumpFlag_DataSections) @@ -437,6 +451,4 @@ entry_point(CmdLine *cmd_line) { fwrite(n->string.str, 1, n->string.size, stdout); } - - di_scope_close(di_scope); } diff --git a/src/rdi_format_local/rdi_format_local.c b/src/rdi_format_local/rdi_format_local.c new file mode 100644 index 00000000..6fae2eb3 --- /dev/null +++ b/src/rdi_format_local/rdi_format_local.c @@ -0,0 +1,52 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +#include "lib_rdi_format/rdi_format.c" +#include "lib_rdi_format/rdi_format_parse.c" + +internal void +rdi_decompress_parsed(U8 *decompressed_data, U64 decompressed_size, RDI_Parsed *og_rdi) +{ + // rjf: copy header + RDI_Header *src_header = (RDI_Header *)og_rdi->raw_data; + RDI_Header *dst_header = (RDI_Header *)decompressed_data; + { + MemoryCopy(dst_header, src_header, sizeof(RDI_Header)); + } + + // rjf: copy & adjust sections for decompressed version + if(og_rdi->dsec_count != 0) + { + RDI_DataSection *dsec_base = (RDI_DataSection *)(decompressed_data + dst_header->data_section_off); + MemoryCopy(dsec_base, (U8 *)og_rdi->raw_data + src_header->data_section_off, sizeof(RDI_DataSection) * og_rdi->dsec_count); + U64 off = dst_header->data_section_off + sizeof(RDI_DataSection) * og_rdi->dsec_count; + off += 7; + off -= off%8; + for(U64 idx = 0; idx < og_rdi->dsec_count; idx += 1) + { + dsec_base[idx].encoding = RDI_DataSectionEncoding_Unpacked; + dsec_base[idx].off = off; + dsec_base[idx].encoded_size = dsec_base[idx].unpacked_size; + off += dsec_base[idx].unpacked_size; + off += 7; + off -= off%8; + } + } + + // rjf: decompress sections into new decompressed file buffer + if(og_rdi->dsec_count != 0) + { + RDI_DataSection *src_first = og_rdi->dsecs; + RDI_DataSection *dst_first = (RDI_DataSection *)(decompressed_data + dst_header->data_section_off); + RDI_DataSection *src_opl = src_first + og_rdi->dsec_count; + RDI_DataSection *dst_opl = dst_first + og_rdi->dsec_count; + for(RDI_DataSection *src = src_first, *dst = dst_first; + src < src_opl && dst < dst_opl; + src += 1, dst += 1) + { + rr_lzb_simple_decode((U8*)og_rdi->raw_data + src->off, src->encoded_size, + decompressed_data + dst->off, dst->unpacked_size); + } + } +} + diff --git a/src/rdi_format_local/rdi_format_local.h b/src/rdi_format_local/rdi_format_local.h new file mode 100644 index 00000000..48f7eea3 --- /dev/null +++ b/src/rdi_format_local/rdi_format_local.h @@ -0,0 +1,12 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +#ifndef RDI_FORMAT_LOCAL_H +#define RDI_FORMAT_LOCAL_H + +#include "lib_rdi_format/rdi_format.h" +#include "lib_rdi_format/rdi_format_parse.h" + +internal void rdi_decompress_parsed(U8 *decompressed_data, U64 decompressed_size, RDI_Parsed *og_rdi); + +#endif // RDI_FORMAT_LOCAL_H From b1e175222929b7c4cbc8ded161757f2a570b7239 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 24 May 2024 17:19:46 -0700 Subject: [PATCH 18/39] oops --- src/rdi_dump/rdi_dump_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rdi_dump/rdi_dump_main.c b/src/rdi_dump/rdi_dump_main.c index c6ad215d..3764759c 100644 --- a/src/rdi_dump/rdi_dump_main.c +++ b/src/rdi_dump/rdi_dump_main.c @@ -156,7 +156,7 @@ entry_point(CmdLine *cmd_line) //- rjf: build dump strings // String8List dump = {0}; - if(errors.node_count != 0) + if(errors.node_count == 0) { //- rjf: DATA SECTIONS if(dump_flags & DumpFlag_DataSections) From dd7cce2c3ad0d888806b32c371507a6d2cd895c5 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 24 May 2024 21:20:44 -0700 Subject: [PATCH 19/39] some progress on the bitmap view rule --- src/df/gfx/df_view_rules.c | 71 ++++++++++++++++++++++++++++--- src/texture_cache/texture_cache.c | 6 ++- src/texture_cache/texture_cache.h | 2 +- 3 files changed, 71 insertions(+), 8 deletions(-) diff --git a/src/df/gfx/df_view_rules.c b/src/df/gfx/df_view_rules.c index 3a992047..d96de95d 100644 --- a/src/df/gfx/df_view_rules.c +++ b/src/df/gfx/df_view_rules.c @@ -955,7 +955,7 @@ DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(bitmap) // U128 texture_key = ctrl_hash_store_key_from_process_vaddr_range(process->ctrl_machine_id, process->ctrl_handle, vaddr_range, 0); TEX_Topology topology = tex_topology_make(v2s32((S32)topology_info.width, (S32)topology_info.height), topology_info.fmt); - R_Handle texture = tex_texture_from_key_topology(tex_scope, texture_key, topology); + R_Handle texture = tex_texture_from_key_topology(tex_scope, texture_key, topology, 0); ////////////////////////////// //- rjf: animate @@ -1097,7 +1097,9 @@ DF_VIEW_UI_FUNCTION_DEF(bitmap) // U128 texture_key = ctrl_hash_store_key_from_process_vaddr_range(process->ctrl_machine_id, process->ctrl_handle, vaddr_range, 0); TEX_Topology topology = tex_topology_make(v2s32((S32)bvs->top.width, (S32)bvs->top.height), bvs->top.fmt); - R_Handle texture = tex_texture_from_key_topology(tex_scope, texture_key, topology); + U128 data_hash = {0}; + R_Handle texture = tex_texture_from_key_topology(tex_scope, texture_key, topology, &data_hash); + String8 data = hs_data_from_hash(hs_scope, data_hash); ////////////////////////////// //- rjf: build canvas box @@ -1112,10 +1114,10 @@ DF_VIEW_UI_FUNCTION_DEF(bitmap) } ////////////////////////////// - //- rjf: canvas box interaction + //- rjf: canvas dragging // + UI_Signal canvas_sig = ui_signal_from_box(canvas_box); { - UI_Signal canvas_sig = ui_signal_from_box(canvas_box); if(ui_dragging(canvas_sig)) { if(ui_pressed(canvas_sig)) @@ -1149,13 +1151,70 @@ DF_VIEW_UI_FUNCTION_DEF(bitmap) } } + ////////////////////////////// + //- rjf: calculate image coordinates + // + Rng2F32 img_rect_cvs = r2f32p(-topology.dim.x/2, -topology.dim.y/2, +topology.dim.x/2, +topology.dim.y/2); + Rng2F32 img_rect_scr = df_bitmap_view_state__screen_from_canvas_rect(bvs, canvas_rect, img_rect_cvs); + + ////////////////////////////// + //- rjf: image-region canvas interaction + // + Vec2S32 mouse_bmp = {-1, -1}; + if(ui_hovering(canvas_sig) && !ui_dragging(canvas_sig)) + { + Vec2F32 mouse_scr = sub_2f32(ui_mouse(), rect.p0); + Vec2F32 mouse_cvs = df_bitmap_view_state__canvas_from_screen_pos(bvs, canvas_rect, mouse_scr); + if(contains_2f32(img_rect_cvs, mouse_cvs)) + { + mouse_bmp = v2s32((S32)(mouse_cvs.x-img_rect_cvs.x0), (S32)(mouse_cvs.y-img_rect_cvs.y0)); + S64 off_px = mouse_bmp.y*topology.dim.x + mouse_bmp.x; + S64 off_bytes = off_px*r_tex2d_format_bytes_per_pixel_table[topology.fmt]; + if(0 <= off_bytes && off_bytes+r_tex2d_format_bytes_per_pixel_table[topology.fmt] <= data.size && + r_tex2d_format_bytes_per_pixel_table[topology.fmt] != 0) + { + B32 color_is_good = 1; + Vec4F32 color = {0}; + switch(topology.fmt) + { + default:{color_is_good = 0;}break; + case R_Tex2DFormat_R8: {color = v4f32(((U8 *)(data.str+off_bytes))[0]/255.f, 0, 0, 1);}break; + case R_Tex2DFormat_RG8: {color = v4f32(((U8 *)(data.str+off_bytes))[0]/255.f, ((U8 *)(data.str+off_bytes))[1]/255.f, 0, 1);}break; + case R_Tex2DFormat_RGBA8: {color = v4f32(((U8 *)(data.str+off_bytes))[0]/255.f, ((U8 *)(data.str+off_bytes))[1]/255.f, ((U8 *)(data.str+off_bytes))[2]/255.f, ((U8 *)(data.str+off_bytes))[3]/255.f);}break; + case R_Tex2DFormat_BGRA8: {color = v4f32(((U8 *)(data.str+off_bytes))[3]/255.f, ((U8 *)(data.str+off_bytes))[2]/255.f, ((U8 *)(data.str+off_bytes))[1]/255.f, ((U8 *)(data.str+off_bytes))[0]/255.f);}break; + case R_Tex2DFormat_R16: {color = v4f32(((U16 *)(data.str+off_bytes))[0]/(F32)max_U16, 0, 0, 1);}break; + case R_Tex2DFormat_RGBA16: {color = v4f32(((U16 *)(data.str+off_bytes))[0]/(F32)max_U16, ((U16 *)(data.str+off_bytes))[1]/(F32)max_U16, ((U16 *)(data.str+off_bytes))[2]/(F32)max_U16, ((U16 *)(data.str+off_bytes))[3]/(F32)max_U16);}break; + case R_Tex2DFormat_R32: {color = v4f32(((F32 *)(data.str+off_bytes))[0], 0, 0, 1);}break; + case R_Tex2DFormat_RG32: {color = v4f32(((F32 *)(data.str+off_bytes))[0], ((F32 *)(data.str+off_bytes))[1], 0, 1);}break; + case R_Tex2DFormat_RGBA32: {color = v4f32(((F32 *)(data.str+off_bytes))[0], ((F32 *)(data.str+off_bytes))[1], ((F32 *)(data.str+off_bytes))[2], ((F32 *)(data.str+off_bytes))[3]);}break; + } + if(color_is_good) + { + Vec4F32 hsva = hsva_from_rgba(color); + ui_do_color_tooltip_hsva(hsva); + } + } + } + } + ////////////////////////////// //- rjf: build image // UI_Parent(canvas_box) { - Rng2F32 img_rect_cvs = r2f32p(-topology.dim.x/2, -topology.dim.y/2, +topology.dim.x/2, +topology.dim.y/2); - Rng2F32 img_rect_scr = df_bitmap_view_state__screen_from_canvas_rect(bvs, canvas_rect, img_rect_cvs); + if(0 <= mouse_bmp.x && mouse_bmp.x < bvs->top.width && + 0 <= mouse_bmp.x && mouse_bmp.x < bvs->top.height) + { + F32 pixel_size_scr = 1.f*bvs->zoom; + Rng2F32 indicator_rect_scr = r2f32p(img_rect_scr.x0 + mouse_bmp.x*pixel_size_scr, + img_rect_scr.y0 + mouse_bmp.y*pixel_size_scr, + img_rect_scr.x0 + (mouse_bmp.x+1)*pixel_size_scr, + img_rect_scr.y0 + (mouse_bmp.y+1)*pixel_size_scr); + UI_Rect(indicator_rect_scr) + { + ui_build_box_from_key(UI_BoxFlag_DrawBorder|UI_BoxFlag_Floating, ui_key_zero()); + } + } UI_Rect(img_rect_scr) UI_Flags(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawDropShadow|UI_BoxFlag_Floating) { ui_image(texture, R_Tex2DSampleKind_Nearest, r2f32p(0, 0, (F32)bvs->top.width, (F32)bvs->top.height), v4f32(1, 1, 1, 1), 0, str8_lit("bmp_image")); diff --git a/src/texture_cache/texture_cache.c b/src/texture_cache/texture_cache.c index bae57895..744e2175 100644 --- a/src/texture_cache/texture_cache.c +++ b/src/texture_cache/texture_cache.c @@ -213,7 +213,7 @@ tex_texture_from_hash_topology(TEX_Scope *scope, U128 hash, TEX_Topology topolog } internal R_Handle -tex_texture_from_key_topology(TEX_Scope *scope, U128 key, TEX_Topology topology) +tex_texture_from_key_topology(TEX_Scope *scope, U128 key, TEX_Topology topology, U128 *hash_out) { R_Handle handle = {0}; for(U64 rewind_idx = 0; rewind_idx < 2; rewind_idx += 1) @@ -222,6 +222,10 @@ tex_texture_from_key_topology(TEX_Scope *scope, U128 key, TEX_Topology topology) handle = tex_texture_from_hash_topology(scope, hash, topology); if(!r_handle_match(handle, r_handle_zero())) { + if(hash_out) + { + *hash_out = hash; + } break; } } diff --git a/src/texture_cache/texture_cache.h b/src/texture_cache/texture_cache.h index ff8ac5a5..1a638c06 100644 --- a/src/texture_cache/texture_cache.h +++ b/src/texture_cache/texture_cache.h @@ -148,7 +148,7 @@ internal void tex_scope_touch_node__stripe_r_guarded(TEX_Scope *scope, TEX_Node //~ rjf: Cache Lookups internal R_Handle tex_texture_from_hash_topology(TEX_Scope *scope, U128 hash, TEX_Topology topology); -internal R_Handle tex_texture_from_key_topology(TEX_Scope *scope, U128 key, TEX_Topology topology); +internal R_Handle tex_texture_from_key_topology(TEX_Scope *scope, U128 key, TEX_Topology topology, U128 *hash_out); //////////////////////////////// //~ rjf: Transfer Threads From 05c751a61adaf2fc211b227b2291b62946076ddb Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sun, 26 May 2024 12:47:47 -0700 Subject: [PATCH 20/39] fix filesystem lister names --- src/df/core/df_core.c | 8 ++++++-- src/df/gfx/df_views.c | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/df/core/df_core.c b/src/df/core/df_core.c index 96bb85dd..826e51bc 100644 --- a/src/df/core/df_core.c +++ b/src/df/core/df_core.c @@ -1516,8 +1516,12 @@ df_display_string_from_entity(Arena *arena, DF_Entity *entity) case DF_EntityKind_Module: { - result = push_str8_copy(arena, entity->name); - result = str8_skip_last_slash(result); + result = push_str8_copy(arena, str8_skip_last_slash(entity->name)); + }break; + + case DF_EntityKind_RecentProject: + { + result = push_str8_copy(arena, str8_skip_last_slash(entity->name)); }break; } return result; diff --git a/src/df/gfx/df_views.c b/src/df/gfx/df_views.c index 946ef6c6..aaf44499 100644 --- a/src/df/gfx/df_views.c +++ b/src/df/gfx/df_views.c @@ -2856,7 +2856,7 @@ DF_VIEW_UI_FUNCTION_DEF(FileSystem) // rjf: filename UI_PrefWidth(ui_pct(1, 0)) { - UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_DrawText, "%S##%p", file->filename, view); + UI_Box *box = ui_build_box_from_string(UI_BoxFlag_DrawText|UI_BoxFlag_DisableIDString, file->filename); ui_box_equip_fuzzy_match_ranges(box, &file->match_ranges); } } From 15f5894c608ef44f87b2e229a3d4942531726944 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sun, 26 May 2024 13:25:03 -0700 Subject: [PATCH 21/39] choose debug info key timestamps from debug info path, rather than module timestamp; the module should be allowed to be newer --- src/ctrl/ctrl_core.c | 25 ++++++++++++------------- src/ctrl/ctrl_core.h | 2 +- src/mule/mule_peb_trample_reload.c | 4 ++-- 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 427ac1d0..924c59b0 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -813,11 +813,7 @@ ctrl_entity_store_apply_events(CTRL_EntityStore *store, CTRL_EventList *list) CTRL_Entity *module = ctrl_entity_alloc(store, process, CTRL_EntityKind_Module, event->arch, event->machine_id, event->entity, event->vaddr_rng.min); ctrl_entity_equip_string(store, module, event->string); module->timestamp = event->timestamp; - CTRL_Entity *debug_info_path = ctrl_entity_alloc(store, module, CTRL_EntityKind_DebugInfoPath, Architecture_Null, 0, dmn_handle_zero(), 0); - String8 initial_debug_info_path = ctrl_initial_debug_info_path_from_module(scratch.arena, event->machine_id, event->entity); - ctrl_entity_equip_string(store, debug_info_path, initial_debug_info_path); module->vaddr_range = event->vaddr_rng; - debug_info_path->timestamp = module->timestamp; scratch_end(scratch); }break; case CTRL_EventKind_EndModule: @@ -834,6 +830,7 @@ ctrl_entity_store_apply_events(CTRL_EntityStore *store, CTRL_EventList *list) debug_info_path = ctrl_entity_alloc(store, module, CTRL_EntityKind_DebugInfoPath, Architecture_Null, 0, dmn_handle_zero(), 0); } ctrl_entity_equip_string(store, debug_info_path, event->string); + debug_info_path->timestamp = event->timestamp; }break; } } @@ -2855,10 +2852,11 @@ ctrl_thread__entry_point(void *p) String8 path = msg->path; CTRL_Entity *module = ctrl_entity_from_machine_id_handle(ctrl_state->ctrl_thread_entity_store, msg->machine_id, msg->entity); CTRL_Entity *debug_info_path = ctrl_entity_child_from_kind(module, CTRL_EntityKind_DebugInfoPath); - DI_Key old_dbgi_key = {debug_info_path->string, module->timestamp}; + DI_Key old_dbgi_key = {debug_info_path->string, debug_info_path->timestamp}; di_close(&old_dbgi_key); ctrl_entity_equip_string(ctrl_state->ctrl_thread_entity_store, debug_info_path, path); - DI_Key new_dbgi_key = {debug_info_path->string, module->timestamp}; + U64 new_dbgi_timestamp = os_properties_from_file_path(path).modified; + DI_Key new_dbgi_key = {debug_info_path->string, new_dbgi_timestamp}; di_open(&new_dbgi_key); CTRL_EventList evts = {0}; CTRL_Event *evt = ctrl_event_list_push(scratch.arena, &evts); @@ -3009,7 +3007,7 @@ ctrl_thread__append_resolved_process_user_bp_traps(Arena *arena, CTRL_MachineID //- rjf: module lifetime open/close work internal void -ctrl_thread__module_open(CTRL_MachineID machine_id, DMN_Handle process, DMN_Handle module, Rng1U64 vaddr_range, String8 path, U64 exe_timestamp) +ctrl_thread__module_open(CTRL_MachineID machine_id, DMN_Handle process, DMN_Handle module, Rng1U64 vaddr_range, String8 path) { ////////////////////////////// //- rjf: parse module image info @@ -3231,8 +3229,8 @@ ctrl_thread__module_open(CTRL_MachineID machine_id, DMN_Handle process, DMN_Hand String8 builtin_debug_info_path__relative = push_str8f(scratch.arena, "%S/%S", exe_folder, builtin_debug_info_path); String8 dbg_path_candidates[] = { - /* inferred (treated as absolute): */ builtin_debug_info_path__absolute, /* inferred (treated as relative): */ builtin_debug_info_path__relative, + /* inferred (treated as absolute): */ builtin_debug_info_path__absolute, /* "foo.exe" -> "foo.pdb" */ push_str8f(scratch.arena, "%S.pdb", str8_chop_last_dot(path)), /* "foo.exe" -> "foo.exe.pdb" */ push_str8f(scratch.arena, "%S.pdb", path), }; @@ -3594,8 +3592,8 @@ ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg, { CTRL_Event *out_evt1 = ctrl_event_list_push(scratch.arena, &evts); String8 module_path = event->string; - U64 timestamp = os_properties_from_file_path(module_path).modified; - ctrl_thread__module_open(CTRL_MachineID_Local, event->process, event->module, r1u64(event->address, event->address+event->size), module_path, timestamp); + U64 exe_timestamp = os_properties_from_file_path(module_path).modified; + ctrl_thread__module_open(CTRL_MachineID_Local, event->process, event->module, r1u64(event->address, event->address+event->size), module_path); out_evt1->kind = CTRL_EventKind_NewModule; out_evt1->msg_id = msg->msg_id; out_evt1->machine_id = CTRL_MachineID_Local; @@ -3605,18 +3603,19 @@ ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg, out_evt1->entity_id = event->code; out_evt1->vaddr_rng = r1u64(event->address, event->address+event->size); out_evt1->rip_vaddr = event->address; - out_evt1->timestamp = timestamp; + out_evt1->timestamp = exe_timestamp; out_evt1->string = module_path; CTRL_Event *out_evt2 = ctrl_event_list_push(scratch.arena, &evts); String8 initial_debug_info_path = ctrl_initial_debug_info_path_from_module(scratch.arena, CTRL_MachineID_Local, event->module); + U64 debug_info_timestamp = os_properties_from_file_path(initial_debug_info_path).modified; out_evt2->kind = CTRL_EventKind_ModuleDebugInfoPathChange; out_evt2->msg_id = msg->msg_id; out_evt2->machine_id = CTRL_MachineID_Local; out_evt2->entity = event->module; out_evt2->parent = event->process; - out_evt2->timestamp = timestamp; + out_evt2->timestamp = debug_info_timestamp; out_evt2->string = initial_debug_info_path; - DI_Key initial_dbgi_key = {initial_debug_info_path, timestamp}; + DI_Key initial_dbgi_key = {initial_debug_info_path, debug_info_timestamp}; di_open(&initial_dbgi_key); }break; case DMN_EventKind_ExitProcess: diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index 995d6b66..9c893b8b 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -806,7 +806,7 @@ internal void ctrl_thread__append_resolved_module_user_bp_traps(Arena *arena, CT internal void ctrl_thread__append_resolved_process_user_bp_traps(Arena *arena, CTRL_MachineID machine_id, DMN_Handle process, CTRL_UserBreakpointList *user_bps, DMN_TrapChunkList *traps_out); //- rjf: module lifetime open/close work -internal void ctrl_thread__module_open(CTRL_MachineID machine_id, DMN_Handle process, DMN_Handle module, Rng1U64 vaddr_range, String8 path, U64 exe_timestamp); +internal void ctrl_thread__module_open(CTRL_MachineID machine_id, DMN_Handle process, DMN_Handle module, Rng1U64 vaddr_range, String8 path); internal void ctrl_thread__module_close(CTRL_MachineID machine_id, DMN_Handle module, String8 path); //- rjf: attached process running/event gathering diff --git a/src/mule/mule_peb_trample_reload.c b/src/mule/mule_peb_trample_reload.c index f505a882..09d1f525 100644 --- a/src/mule/mule_peb_trample_reload.c +++ b/src/mule/mule_peb_trample_reload.c @@ -1,8 +1,8 @@ __declspec(dllexport) int loop_iteration(int it) { - return 111; -#if 0 + //return 111; +#if 1 int sum = 0; for(int i = 0; i < 1000; i += 1) { From d04ee598b24853a4a348e569256c6c829bfeed86 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sun, 26 May 2024 14:35:57 -0700 Subject: [PATCH 22/39] use lower level unwinding path with more generous time allowance, rather than passive cache query, for step-out --- src/df/core/df_core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/df/core/df_core.c b/src/df/core/df_core.c index 826e51bc..5d9f5548 100644 --- a/src/df/core/df_core.c +++ b/src/df/core/df_core.c @@ -6214,7 +6214,7 @@ df_query_cached_unwind_from_thread(DF_Entity *thread) if(node->reggen != reg_gen || node->memgen != mem_gen) { - CTRL_Unwind new_unwind = ctrl_unwind_from_thread(scratch.arena, df_state->ctrl_entity_store, thread->ctrl_machine_id, thread->ctrl_handle, os_now_microseconds()+100); + CTRL_Unwind new_unwind = ctrl_unwind_from_thread(scratch.arena, df_state->ctrl_entity_store, thread->ctrl_machine_id, thread->ctrl_handle, os_now_microseconds()+1000); if(!(new_unwind.flags & (CTRL_UnwindFlag_Error|CTRL_UnwindFlag_Stale)) && new_unwind.frames.count != 0) { node->unwind = ctrl_unwind_deep_copy(node->arena, thread->arch, &new_unwind); @@ -7395,10 +7395,10 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt) case DF_CoreCmdKind_StepOut: { // rjf: thread => full unwind - CTRL_Unwind unwind = df_query_cached_unwind_from_thread(thread); + CTRL_Unwind unwind = ctrl_unwind_from_thread(scratch.arena, df_state->ctrl_entity_store, thread->ctrl_machine_id, thread->ctrl_handle, os_now_microseconds()+10000); // rjf: use first unwind frame to generate trap - if(unwind.frames.count > 1) + if(unwind.flags == 0 && unwind.frames.count > 1) { U64 vaddr = regs_rip_from_arch_block(thread->arch, unwind.frames.v[1].regs); CTRL_Trap trap = {CTRL_TrapFlag_EndStepping|CTRL_TrapFlag_IgnoreStackPointerCheck, vaddr}; From 831985066679310847d7b35e7e61bb1bfa038bd4 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 28 May 2024 06:10:12 -0700 Subject: [PATCH 23/39] fix precision tab alignment issue --- src/font_cache/font_cache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/font_cache/font_cache.c b/src/font_cache/font_cache.c index 4e05a24f..0f7ba96d 100644 --- a/src/font_cache/font_cache.c +++ b/src/font_cache/font_cache.c @@ -792,7 +792,7 @@ f_push_run_from_string(Arena *arena, F_Tag tag, F32 size, F32 base_align_px, F32 F32 advance = info->advance; if(is_tab) { - advance = tab_size_px - mod_f32(base_align_px, tab_size_px); + advance = floor_f32(tab_size_px) - mod_f32(floor_f32(base_align_px), floor_f32(tab_size_px)); } // rjf: push piece From e541fce2bcdc77da59dcf012a75601f3ee53e08b Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 28 May 2024 06:13:14 -0700 Subject: [PATCH 24/39] fix non-enumeration of 0 tex2dfmt --- src/df/gfx/df_gfx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/df/gfx/df_gfx.c b/src/df/gfx/df_gfx.c index 36e994a8..c81e56e7 100644 --- a/src/df/gfx/df_gfx.c +++ b/src/df/gfx/df_gfx.c @@ -4553,7 +4553,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) //- rjf: gather tex2dformats if(ws->autocomp_lister_params.flags & DF_AutoCompListerFlag_Tex2DFormats) { - for(EachNonZeroEnumVal(R_Tex2DFormat, fmt)) + for(EachEnumVal(R_Tex2DFormat, fmt)) { DF_AutoCompListerItem item = {0}; { From 68d3f17ecbcf8ae1a41116273fabf149073a61f6 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 28 May 2024 07:30:54 -0700 Subject: [PATCH 25/39] do not snap-to-thread on soft-halts --- src/df/core/df_core.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/df/core/df_core.c b/src/df/core/df_core.c index 5d9f5548..e2b2de46 100644 --- a/src/df/core/df_core.c +++ b/src/df/core/df_core.c @@ -6214,7 +6214,7 @@ df_query_cached_unwind_from_thread(DF_Entity *thread) if(node->reggen != reg_gen || node->memgen != mem_gen) { - CTRL_Unwind new_unwind = ctrl_unwind_from_thread(scratch.arena, df_state->ctrl_entity_store, thread->ctrl_machine_id, thread->ctrl_handle, os_now_microseconds()+1000); + CTRL_Unwind new_unwind = ctrl_unwind_from_thread(scratch.arena, df_state->ctrl_entity_store, thread->ctrl_machine_id, thread->ctrl_handle, os_now_microseconds()+100); if(!(new_unwind.flags & (CTRL_UnwindFlag_Error|CTRL_UnwindFlag_Stale)) && new_unwind.frames.count != 0) { node->unwind = ctrl_unwind_deep_copy(node->arena, thread->arch, &new_unwind); @@ -6685,6 +6685,7 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt) case CTRL_EventKind_Stopped: { + B32 should_snap = !(df_state->ctrl_soft_halt_issued); df_state->ctrl_is_running = 0; df_state->ctrl_soft_halt_issued = 0; DF_Entity *stop_thread = df_entity_from_ctrl_handle(event->machine_id, event->entity); @@ -6697,7 +6698,7 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt) } // rjf: select & snap to thread causing stop - if(stop_thread->kind == DF_EntityKind_Thread) + if(should_snap && stop_thread->kind == DF_EntityKind_Thread) { DF_CmdParams params = df_cmd_params_zero(); params.entity = df_handle_from_entity(stop_thread); @@ -6706,7 +6707,7 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt) } // rjf: if no stop-causing thread, and if selected thread, snap to selected - if(df_entity_is_nil(stop_thread)) + if(should_snap && df_entity_is_nil(stop_thread)) { DF_Entity *selected_thread = df_entity_from_handle(df_state->ctrl_ctx.thread); if(!df_entity_is_nil(selected_thread)) @@ -6719,7 +6720,7 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt) } // rjf: thread hit user breakpoint -> increment breakpoint hit count - if(event->cause == CTRL_EventCause_UserBreakpoint) + if(should_snap && event->cause == CTRL_EventCause_UserBreakpoint) { U64 stop_thread_vaddr = ctrl_query_cached_rip_from_thread(df_state->ctrl_entity_store, stop_thread->ctrl_machine_id, stop_thread->ctrl_handle); DF_Entity *process = df_entity_ancestor_from_kind(stop_thread, DF_EntityKind_Process); From e80008cb7ed010313cdd7464e1ef8babbb1f0f2b Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 28 May 2024 07:34:10 -0700 Subject: [PATCH 26/39] do not animate disasm load when running --- src/df/gfx/df_views.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/df/gfx/df_views.c b/src/df/gfx/df_views.c index aaf44499..99b1679b 100644 --- a/src/df/gfx/df_views.c +++ b/src/df/gfx/df_views.c @@ -6875,7 +6875,7 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly) ////////////////////////////// //- rjf: is loading -> equip view with loading information // - if(is_loading) + if(is_loading && !df_ctrl_targets_running()) { df_view_equip_loading_info(view, is_loading, 0, 0); } From 5778e75d663be3e329615febcc17179d1295ef7d Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 28 May 2024 21:45:14 -0700 Subject: [PATCH 27/39] oops - do not zero unwind cache node after adding it, zero it before adding it --- src/df/core/df_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/df/core/df_core.c b/src/df/core/df_core.c index e2b2de46..15c3d911 100644 --- a/src/df/core/df_core.c +++ b/src/df/core/df_core.c @@ -6206,8 +6206,8 @@ df_query_cached_unwind_from_thread(DF_Entity *thread) { node = push_array_no_zero(df_state->arena, DF_UnwindCacheNode, 1); } - DLLPushBack(slot->first, slot->last, node); MemoryZeroStruct(node); + DLLPushBack(slot->first, slot->last, node); node->arena = arena_alloc(); node->thread = handle; } From f65cf5436e2ffe02ab3f5d8e19ac8e5573b734ca Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 29 May 2024 08:03:06 -0700 Subject: [PATCH 28/39] fix code off -> instruction idx lookup - fixes busted instruction pointer drawing in disassembly view --- src/dasm_cache/dasm_cache.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dasm_cache/dasm_cache.c b/src/dasm_cache/dasm_cache.c index 1f8b8967..ef3418f1 100644 --- a/src/dasm_cache/dasm_cache.c +++ b/src/dasm_cache/dasm_cache.c @@ -69,7 +69,8 @@ dasm_inst_array_idx_from_code_off__linear_scan(DASM_InstArray *array, U64 off) U64 result = 0; for(U64 idx = 0; idx < array->count; idx += 1) { - if(array->v[idx].code_off == off) + U64 next_off = (idx+1 < array->count ? array->v[idx+1].code_off : max_U64); + if(array->v[idx].code_off <= off && off < next_off) { result = idx; break; From 2512d07c72e6693061539f831d27225e02af1eaf Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 29 May 2024 08:08:44 -0700 Subject: [PATCH 29/39] correctly roll-back late-hits for int3s --- src/demon/win32/demon_core_win32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/demon/win32/demon_core_win32.c b/src/demon/win32/demon_core_win32.c index 2d39e0fe..90ff1abc 100644 --- a/src/demon/win32/demon_core_win32.c +++ b/src/demon/win32/demon_core_win32.c @@ -1981,7 +1981,7 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) } //- rjf: determine whether to roll back instruction pointer - B32 should_do_rollback = (hit_user_trap); + B32 should_do_rollback = (hit_user_trap || (is_trap && !hit_explicit_trap)); //- rjf: roll back thread's instruction pointer U64 post_trap_rip = 0; From e073ff321826b463e1cc742932303f2c207d67cb Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 29 May 2024 08:31:24 -0700 Subject: [PATCH 30/39] more notes on the multithreaded access violation stuff! --- src/demon/win32/demon_core_win32.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/demon/win32/demon_core_win32.c b/src/demon/win32/demon_core_win32.c index 90ff1abc..8bfac593 100644 --- a/src/demon/win32/demon_core_win32.c +++ b/src/demon/win32/demon_core_win32.c @@ -1900,7 +1900,7 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) // case EXCEPTION_DEBUG_EVENT: { - // NOTE(rjf): Notes on multithreaded breakpoint events + //- NOTE(rjf): Notes on multithreaded breakpoint events // (2021/11/1): // // When many threads are simultaneously running, multiple threads @@ -1928,7 +1928,17 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) // #B. If the actual unmodified instruction is an int 3, then this // becomes a trap event and we do not reset RIP. - // NOTE(rjf): The exception record struct has a 32-bit version and a + //- NOTE(rjf): Further notes on MULTITHREADED STEPPING ACCESS VIOLATION + // EVENTS! @rjf @rjf @rjf + // (2024/05/29): + // + // Just adding another comment here to document that the above long + // comment went completely unnoticed by me during a pass over demon, + // and I had removed the proper rollback stuff here without reading + // the above comment. So this comment just serves to make that + // original comment even heftier. + + //- NOTE(rjf): The exception record struct has a 32-bit version and a // 64-bit version. We only currently handle the 64-bit version. //- rjf: unpack From 8f446d1f9a6086fce09f6312a81b6848fd1c19e5 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 29 May 2024 10:36:22 -0700 Subject: [PATCH 31/39] pass over callstack view to display function type info and properly display richer/weirder C++ symbol names --- src/df/gfx/df_gfx.c | 2 +- src/df/gfx/df_views.c | 64 ++++++++++++++++++++++++++----------- src/draw/draw.c | 17 ++++++++++ src/draw/draw.h | 1 + src/type_graph/type_graph.h | 2 +- 5 files changed, 65 insertions(+), 21 deletions(-) diff --git a/src/df/gfx/df_gfx.c b/src/df/gfx/df_gfx.c index c81e56e7..487e253a 100644 --- a/src/df/gfx/df_gfx.c +++ b/src/df/gfx/df_gfx.c @@ -5992,7 +5992,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) //- rjf: calculate width of exp row if(row == viz_rows.first) { - expr_column_width_px = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), row->display_expr).x + ui_top_font_size()*0.5f; + expr_column_width_px = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), row->display_expr).x + ui_top_font_size()*2.5f; expr_column_width_px = Max(expr_column_width_px, ui_top_font_size()*10.f); } diff --git a/src/df/gfx/df_views.c b/src/df/gfx/df_views.c index 99b1679b..18b8e41d 100644 --- a/src/df/gfx/df_views.c +++ b/src/df/gfx/df_views.c @@ -4835,6 +4835,7 @@ DF_VIEW_UI_FUNCTION_DEF(CallStack) { ProfBeginFunction(); Temp scratch = scratch_begin(0, 0); + DI_Scope *scope = di_scope_open(); DF_CtrlCtx ctrl_ctx = df_ctrl_ctx_from_view(ws, view); DF_Entity *thread = df_entity_from_handle(ctrl_ctx.thread); U64 selected_unwind_count = ctrl_ctx.unwind_count; @@ -4915,20 +4916,33 @@ DF_VIEW_UI_FUNCTION_DEF(CallStack) { continue; } - U64 frame_idx = row_num-1; - CTRL_UnwindFrame *frame = &unwind.frames.v[frame_idx]; - - // rjf: determine selection B32 row_selected = (cs->cursor.y == row_num); - // rjf: regs => rip + // rjf: unpack frame + U64 frame_idx = row_num-1; + CTRL_UnwindFrame *frame = &unwind.frames.v[frame_idx]; U64 rip_vaddr = regs_rip_from_arch_block(thread->arch, frame->regs); - - // rjf: rip_vaddr => module DF_Entity *module = df_module_from_process_vaddr(process, rip_vaddr); - - // rjf: rip => validity? B32 frame_valid = (rip_vaddr != 0); + U64 rip_voff = df_voff_from_vaddr(module, rip_vaddr); + DI_Key dbgi_key = df_dbgi_key_from_module(module); + RDI_Parsed *rdi = di_rdi_from_key(scope, &dbgi_key, 0); + String8 symbol_name = {0}; + String8 symbol_type_string = {0}; + if(rdi->scope_vmap != 0) + { + U64 scope_idx = rdi_vmap_idx_from_voff(rdi->scope_vmap, rdi->scope_vmap_count, rip_voff); + RDI_Scope *scope = rdi_element_from_idx(rdi, scopes, scope_idx); + U64 proc_idx = scope->proc_idx; + RDI_Procedure *procedure = &rdi->procedures[proc_idx]; + RDI_TypeNode *type_node = rdi_element_from_idx(rdi, type_nodes, procedure->type_idx); + TG_Key type_key = tg_key_ext(tg_kind_from_rdi_type_kind(type_node->kind), procedure->type_idx); + U64 name_size = 0; + U8 *name_ptr = rdi_string_from_idx(rdi, procedure->name_string_idx, &name_size); + TG_Graph *graph = tg_graph_begin(rdi_addr_size_from_arch(rdi->top_level_info->architecture), 256); + symbol_name = str8(name_ptr, name_size); + symbol_type_string = tg_string_from_key(scratch.arena, graph, rdi, type_key); + } // rjf: build row if(frame_valid) UI_NamedTableVectorF("###callstack_%p_%I64x", view, frame_idx) @@ -4981,21 +4995,32 @@ DF_VIEW_UI_FUNCTION_DEF(CallStack) } } - // rjf: build cell for function name + // rjf: build cell for function header UI_TableCell UI_Font(df_font_from_slot(DF_FontSlot_Code)) UI_FocusHot((row_selected && cs->cursor.x == 2) ? UI_FocusKind_On : UI_FocusKind_Off) { - String8 symbol = df_symbol_name_from_process_vaddr(scratch.arena, process, rip_vaddr); - if(symbol.size == 0) + ui_set_next_child_layout_axis(Axis2_X); + UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clickable|UI_BoxFlag_Clip, "frame_%I64x", frame_idx); + UI_Parent(box) { - symbol = str8_lit("[external code]"); - ui_set_next_text_color(df_rgba_from_theme_color(DF_ThemeColor_WeakText)); + if(symbol_name.size == 0) + { + ui_set_next_text_color(df_rgba_from_theme_color(DF_ThemeColor_WeakText)); + ui_label(str8_lit("[unknown symbol]")); + } + else UI_WidthFill + { + D_FancyStringList symbol_name_fstrs = df_fancy_string_list_from_code_string(scratch.arena, 1.f, 0, df_rgba_from_theme_color(DF_ThemeColor_CodeFunction), symbol_name); + D_FancyStringList symbol_type_fstrs = df_fancy_string_list_from_code_string(scratch.arena, 0.5f, 0, df_rgba_from_theme_color(DF_ThemeColor_CodeDefault), symbol_type_string); + D_FancyStringList fstrs = {0}; + d_fancy_string_list_concat_in_place(&fstrs, &symbol_name_fstrs); + D_FancyString sep = {ui_top_font(), str8_lit(": "), df_rgba_from_theme_color(DF_ThemeColor_WeakText), ui_top_font_size()}; + d_fancy_string_list_push(scratch.arena, &fstrs, &sep); + d_fancy_string_list_concat_in_place(&fstrs, &symbol_type_fstrs); + UI_Box *label = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero()); + ui_box_equip_display_fancy_strings(label, 0, &fstrs); + } } - else - { - ui_set_next_text_color(df_rgba_from_theme_color(DF_ThemeColor_CodeFunction)); - } - UI_Box *box = ui_build_box_from_string(UI_BoxFlag_DrawText|UI_BoxFlag_Clickable, symbol); UI_Signal sig = ui_signal_from_box(box); if(ui_pressed(sig)) { @@ -5046,6 +5071,7 @@ DF_VIEW_UI_FUNCTION_DEF(CallStack) } } + di_scope_close(scope); scratch_end(scratch); ProfEnd(); } diff --git a/src/draw/draw.c b/src/draw/draw.c index b8a2c94b..16f47342 100644 --- a/src/draw/draw.c +++ b/src/draw/draw.c @@ -54,6 +54,23 @@ d_fancy_string_list_push(Arena *arena, D_FancyStringList *list, D_FancyString *s list->total_size += str->string.size; } +internal void +d_fancy_string_list_concat_in_place(D_FancyStringList *dst, D_FancyStringList *to_push) +{ + if(dst->last != 0 && to_push->first != 0) + { + dst->last->next = to_push->first; + dst->last = to_push->last; + dst->node_count += to_push->node_count; + dst->total_size += to_push->total_size; + } + else if(to_push->first != 0) + { + MemoryCopyStruct(dst, to_push); + } + MemoryZeroStruct(to_push); +} + internal String8 d_string_from_fancy_string_list(Arena *arena, D_FancyStringList *list) { diff --git a/src/draw/draw.h b/src/draw/draw.h index 2764605d..b3de754a 100644 --- a/src/draw/draw.h +++ b/src/draw/draw.h @@ -109,6 +109,7 @@ internal U64 d_hash_from_string(String8 string); //~ rjf: Fancy String Type Functions internal void d_fancy_string_list_push(Arena *arena, D_FancyStringList *list, D_FancyString *str); +internal void d_fancy_string_list_concat_in_place(D_FancyStringList *dst, D_FancyStringList *to_push); internal String8 d_string_from_fancy_string_list(Arena *arena, D_FancyStringList *list); internal D_FancyRunList d_fancy_run_list_from_fancy_string_list(Arena *arena, F32 tab_size_px, D_FancyStringList *strs); internal D_FancyRunList d_fancy_run_list_copy(Arena *arena, D_FancyRunList *src); diff --git a/src/type_graph/type_graph.h b/src/type_graph/type_graph.h index a413dc24..7299a1c9 100644 --- a/src/type_graph/type_graph.h +++ b/src/type_graph/type_graph.h @@ -180,7 +180,7 @@ global read_only TG_Type tg_type_nil = { /* kind */ TG_Kind_Null, /* flags */ 0, - /* name */ {(U8*)"",5}, + /* name */ {(U8*)"???",3}, }; global read_only TG_Type tg_type_variadic = From f808e8ae2987158ae1404b66251a34ac506c4b52 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 29 May 2024 10:43:04 -0700 Subject: [PATCH 32/39] adjust force-contain on tooltips; we don't want it for drag/drop, we do for tooltips, so use active interaction as a proxy --- src/ui/ui_core.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index a0e32ef0..e7ea9a27 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -1155,7 +1155,13 @@ ui_end_build(void) //- rjf: ensure special floating roots are within screen bounds UI_Box *floating_roots[] = {ui_state->tooltip_root, ui_state->ctx_menu_root}; - B32 force_contain[] = {0, 1}; + B32 force_contain[] = + { + (ui_key_match(ui_active_key(UI_MouseButtonKind_Left), ui_key_zero()) && + ui_key_match(ui_active_key(UI_MouseButtonKind_Right), ui_key_zero()) && + ui_key_match(ui_active_key(UI_MouseButtonKind_Middle), ui_key_zero())), + 1, + }; for(U64 idx = 0; idx < ArrayCount(floating_roots); idx += 1) { UI_Box *root = floating_roots[idx]; @@ -1164,11 +1170,10 @@ ui_end_build(void) Rng2F32 window_rect = os_client_rect_from_window(ui_window()); Vec2F32 window_dim = dim_2f32(window_rect); Rng2F32 root_rect = root->rect; - Vec2F32 root_rect_dim = dim_2f32(root_rect); Vec2F32 shift = { - -ClampBot(0, root_rect.x1 - window_rect.x1) * (root_rect_dim.x < root->font_size*15.f || force_contain[idx]), - -ClampBot(0, root_rect.y1 - window_rect.y1) * (root_rect_dim.y < root->font_size*15.f || force_contain[idx]), + -ClampBot(0, root_rect.x1 - window_rect.x1) * (force_contain[idx]), + -ClampBot(0, root_rect.y1 - window_rect.y1) * (force_contain[idx]), }; Rng2F32 new_root_rect = shift_2f32(root_rect, shift); root->fixed_position = new_root_rect.p0; From 0e179f3844f62a74a2baf702e1434d31d32276a7 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 29 May 2024 10:56:46 -0700 Subject: [PATCH 33/39] fix clips, occlusion, for ui-tree-wide truncated text tooltips --- src/ui/ui_core.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index e7ea9a27..adc59066 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -1425,14 +1425,22 @@ ui_end_build(void) { if(b->flags & UI_BoxFlag_DrawText && !(b->flags & UI_BoxFlag_DisableTextTrunc)) { + Rng2F32 rect = b->rect; + for(UI_Box *p = b->parent; !ui_box_is_nil(p); p = p->parent) + { + if(p->flags & UI_BoxFlag_Clip) + { + rect = intersect_2f32(rect, p->rect); + } + } String8 box_display_string = ui_box_display_string(b); Vec2F32 text_pos = ui_box_text_position(b); Vec2F32 drawn_text_dim = b->display_string_runs.dim; - B32 text_is_truncated = (drawn_text_dim.x + text_pos.x > b->rect.x1); + B32 text_is_truncated = (drawn_text_dim.x + text_pos.x > rect.x1); B32 mouse_is_hovering = contains_2f32(r2f32p(text_pos.x, - b->rect.y0, - Min(text_pos.x+drawn_text_dim.x, b->rect.x1), - b->rect.y1), + rect.y0, + Min(text_pos.x+drawn_text_dim.x, rect.x1), + rect.y1), ui_state->mouse); if(text_is_truncated && mouse_is_hovering) { @@ -1448,6 +1456,10 @@ ui_end_build(void) goto break_all_hover_string; } } + if(b != box && ui_key_match(b->key, ui_hot_key())) + { + goto break_all_hover_string; + } if(b != box && contains_2f32(b->rect, ui_state->mouse) && b->flags & UI_BoxFlag_DrawText) { goto break_all_hover_string; From 62fa397e299175fef97251c34075f6cef363b154 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 29 May 2024 11:51:04 -0700 Subject: [PATCH 34/39] split code slice margin into two parts - priority, and catchall. priority for selected thread so it is always necessarily visible, and catchall for other threads, breakpoints, watch pins, etc. also tweak targets view behavior to prioritize selection as the common path, and to make checkboxes less idiosyncratic --- src/df/gfx/df_gfx.c | 211 ++++++++++++++++++++++++++++++++++--- src/df/gfx/df_gfx.h | 10 +- src/df/gfx/df_view_rules.c | 6 +- src/df/gfx/df_views.c | 38 +++---- 4 files changed, 224 insertions(+), 41 deletions(-) diff --git a/src/df/gfx/df_gfx.c b/src/df/gfx/df_gfx.c index 487e253a..945241df 100644 --- a/src/df/gfx/df_gfx.c +++ b/src/df/gfx/df_gfx.c @@ -2903,6 +2903,13 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds) df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_Entity); df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_SelectThread)); }break; + case DF_EntityKind_Target: + { + DF_CmdParams params = df_cmd_params_from_window(ws); + params.entity = df_handle_from_entity(entity); + df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_Entity); + df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_SelectTarget)); + }break; } }break; case DF_CoreCmdKind_SpawnEntityView: @@ -10424,9 +10431,9 @@ internal UI_BOX_CUSTOM_DRAW(df_thread_box_draw_extensions) // rjf: draw line before next-to-execute line { - R_Rect2DInst *inst = d_rect(r2f32p(box->rect.x0, + R_Rect2DInst *inst = d_rect(r2f32p(box->parent->parent->parent->rect.x0, box->parent->rect.y0 - box->font_size*0.125f, - box->rect.x0 + box->font_size*260*u->alive_t, + box->parent->parent->parent->rect.x0 + box->font_size*260*u->alive_t, box->parent->rect.y0 + box->font_size*0.125f), v4f32(u->thread_color.x, u->thread_color.y, u->thread_color.z, 0), 0, 0, 1); @@ -10451,9 +10458,9 @@ internal UI_BOX_CUSTOM_DRAW(df_thread_box_draw_extensions) { Vec4F32 weak_thread_color = u->thread_color; weak_thread_color.w *= 0.3f; - R_Rect2DInst *inst = d_rect(r2f32p(box->rect.x0, + R_Rect2DInst *inst = d_rect(r2f32p(box->parent->parent->parent->rect.x0, box->parent->rect.y0, - box->rect.x0 + ui_top_font_size()*22.f*u->alive_t, + box->parent->parent->parent->rect.x0 + ui_top_font_size()*22.f*u->alive_t, box->parent->rect.y1), v4f32(0, 0, 0, 0), 0, 0, 1); @@ -10491,9 +10498,9 @@ internal UI_BOX_CUSTOM_DRAW(df_bp_box_draw_extensions) // rjf: draw line before next-to-execute line { - R_Rect2DInst *inst = d_rect(r2f32p(box->rect.x0, + R_Rect2DInst *inst = d_rect(r2f32p(box->parent->parent->parent->rect.x0, box->parent->rect.y0 - box->font_size*0.125f, - box->rect.x0 + ui_top_font_size()*250.f*u->alive_t, + box->parent->parent->parent->rect.x0 + ui_top_font_size()*250.f*u->alive_t, box->parent->rect.y0 + box->font_size*0.125f), v4f32(u->color.x, u->color.y, u->color.z, 0), 0, 0, 1.f); @@ -10504,9 +10511,9 @@ internal UI_BOX_CUSTOM_DRAW(df_bp_box_draw_extensions) { Vec4F32 weak_thread_color = u->color; weak_thread_color.w *= 0.3f; - R_Rect2DInst *inst = d_rect(r2f32p(box->rect.x0, + R_Rect2DInst *inst = d_rect(r2f32p(box->parent->parent->parent->rect.x0, box->parent->rect.y0, - box->rect.x0 + ui_top_font_size()*22.f*u->alive_t, + box->parent->parent->parent->rect.x0 + ui_top_font_size()*22.f*u->alive_t, box->parent->rect.y1), v4f32(0, 0, 0, 0), 0, 0, 1); @@ -10677,24 +10684,24 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ } ////////////////////////////// - //- rjf: build margins + //- rjf: build priority margin // - UI_Box *margin_container_box = &ui_g_nil_box; - if(params->flags & DF_CodeSliceFlag_Margin) UI_Focus(UI_FocusKind_Off) UI_Parent(top_container_box) ProfScope("build margins") + UI_Box *priority_margin_container_box = &ui_g_nil_box; + if(params->flags & DF_CodeSliceFlag_PriorityMargin) UI_Focus(UI_FocusKind_Off) UI_Parent(top_container_box) ProfScope("build priority margins") { if(params->margin_float_off_px != 0) { - ui_set_next_pref_width(ui_px(params->margin_width_px, 1)); + ui_set_next_pref_width(ui_px(params->priority_margin_width_px, 1)); ui_set_next_pref_height(ui_px(params->line_height_px*(dim_1s64(params->line_num_range)+1), 1.f)); ui_build_box_from_key(0, ui_key_zero()); ui_set_next_fixed_x(params->margin_float_off_px); ui_set_next_flags(UI_BoxFlag_DrawBackground); } - ui_set_next_pref_width(ui_px(params->margin_width_px, 1)); + ui_set_next_pref_width(ui_px(params->priority_margin_width_px, 1)); ui_set_next_pref_height(ui_px(params->line_height_px*(dim_1s64(params->line_num_range)+1), 1.f)); ui_set_next_child_layout_axis(Axis2_Y); - margin_container_box = ui_build_box_from_string(UI_BoxFlag_Clickable*!!(params->flags & DF_CodeSliceFlag_Clickable), str8_lit("margin_container")); - UI_Parent(margin_container_box) UI_PrefHeight(ui_px(params->line_height_px, 1.f)) + priority_margin_container_box = ui_build_box_from_string(UI_BoxFlag_Clickable*!!(params->flags & DF_CodeSliceFlag_Clickable), str8_lit("priority_margin_container")); + UI_Parent(priority_margin_container_box) UI_PrefHeight(ui_px(params->line_height_px, 1.f)) { U64 line_idx = 0; for(S64 line_num = params->line_num_range.min; @@ -10714,6 +10721,176 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ { // rjf: unpack thread DF_Entity *thread = n->entity; + if(thread != selected_thread) + { + continue; + } + U64 unwind_count = (thread == selected_thread) ? ctrl_ctx->unwind_count : 0; + U64 thread_rip_vaddr = df_query_cached_rip_from_thread_unwind(thread, unwind_count); + DF_Entity *process = df_entity_ancestor_from_kind(thread, DF_EntityKind_Process); + DF_Entity *module = df_module_from_process_vaddr(process, thread_rip_vaddr); + DI_Key dbgi_key = df_dbgi_key_from_module(module); + U64 thread_rip_voff = df_voff_from_vaddr(module, thread_rip_vaddr); + + // rjf: thread info => color + Vec4F32 color = v4f32(1, 1, 1, 1); + { + if(unwind_count != 0) + { + color = df_rgba_from_theme_color(DF_ThemeColor_ThreadUnwound); + } + else if(thread == stopper_thread && + (stop_event.cause == CTRL_EventCause_InterruptedByHalt || + stop_event.cause == CTRL_EventCause_InterruptedByTrap || + stop_event.cause == CTRL_EventCause_InterruptedByException)) + { + color = df_rgba_from_theme_color(DF_ThemeColor_FailureBackground); + } + else if(thread->flags & DF_EntityFlag_HasColor) + { + color = df_rgba_from_entity(thread); + } + if(df_ctrl_targets_running() && df_ctrl_last_run_frame_idx() < df_frame_index()) + { + color.w *= 0.5f; + } + if(thread != selected_thread) + { + color.w *= 0.8f; + } + } + + // rjf: build thread box + ui_set_next_hover_cursor(OS_Cursor_UpDownLeftRight); + ui_set_next_font(ui_icon_font()); + ui_set_next_font_size(params->font_size); + ui_set_next_pref_width(ui_pct(1, 0)); + ui_set_next_pref_height(ui_pct(1, 0)); + ui_set_next_text_color(color); + ui_set_next_text_alignment(UI_TextAlign_Center); + 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*!!(params->flags & DF_CodeSliceFlag_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 + { + DF_ThreadBoxDrawExtData *u = push_array(ui_build_arena(), DF_ThreadBoxDrawExtData, 1); + u->thread_color = color; + u->alive_t = thread->alive_t; + u->is_selected = (thread == selected_thread); + u->is_frozen = df_entity_is_frozen(thread); + ui_box_equip_custom_draw(thread_box, df_thread_box_draw_extensions, u); + + // rjf: fill out progress t (progress into range of current line's + // voff range) + if(params->line_src2dasm[line_idx].first != 0) + { + DF_TextLineSrc2DasmInfoList *line_info_list = ¶ms->line_src2dasm[line_idx]; + DF_TextLineSrc2DasmInfo *line_info = 0; + for(DF_TextLineSrc2DasmInfoNode *n = line_info_list->first; + n != 0; + n = n->next) + { + if(di_key_match(&n->v.dbgi_key, &dbgi_key)) + { + line_info = &n->v; + break; + } + } + if(line_info != 0) + { + Rng1U64 line_voff_rng = line_info->voff_range; + Vec4F32 weak_thread_color = color; + weak_thread_color.w *= 0.4f; + F32 progress_t = (line_voff_rng.max != line_voff_rng.min) ? ((F32)(thread_rip_voff - line_voff_rng.min) / (F32)(line_voff_rng.max - line_voff_rng.min)) : 0; + progress_t = Clamp(0, progress_t, 1); + u->progress_t = progress_t; + } + } + } + + // rjf: hover tooltips + if(ui_hovering(thread_sig)) + { + df_entity_tooltips(thread); + } + + // rjf: ip right-click menu + if(ui_right_clicked(thread_sig)) + { + DF_Handle handle = df_handle_from_entity(thread); + if(ui_ctx_menu_is_open(ws->entity_ctx_menu_key) && df_handle_match(ws->entity_ctx_menu_entity, handle)) + { + ui_ctx_menu_close(); + } + else + { + ui_ctx_menu_open(ws->entity_ctx_menu_key, thread_box->key, v2f32(0, thread_box->rect.y1-thread_box->rect.y0)); + ws->entity_ctx_menu_entity = handle; + } + } + + // rjf: drag start + if(ui_dragging(thread_sig) && !contains_2f32(thread_box->rect, ui_mouse())) + { + DF_DragDropPayload payload = {0}; + payload.key = thread_box->key; + payload.entity = df_handle_from_entity(thread); + df_drag_begin(&payload); + } + } + } + } + } + } + + ////////////////////////////// + //- rjf: build catchall margin + // + UI_Box *catchall_margin_container_box = &ui_g_nil_box; + if(params->flags & DF_CodeSliceFlag_CatchallMargin) UI_Focus(UI_FocusKind_Off) UI_Parent(top_container_box) ProfScope("build catchall margins") + { + if(params->margin_float_off_px != 0) + { + ui_set_next_pref_width(ui_px(params->catchall_margin_width_px, 1)); + ui_set_next_pref_height(ui_px(params->line_height_px*(dim_1s64(params->line_num_range)+1), 1.f)); + ui_build_box_from_key(0, ui_key_zero()); + ui_set_next_fixed_x(params->margin_float_off_px + params->priority_margin_width_px); + ui_set_next_flags(UI_BoxFlag_DrawBackground); + } + ui_set_next_pref_width(ui_px(params->catchall_margin_width_px, 1)); + ui_set_next_pref_height(ui_px(params->line_height_px*(dim_1s64(params->line_num_range)+1), 1.f)); + ui_set_next_child_layout_axis(Axis2_Y); + catchall_margin_container_box = ui_build_box_from_string(UI_BoxFlag_Clickable*!!(params->flags & DF_CodeSliceFlag_Clickable), str8_lit("catchall_margin_container")); + UI_Parent(catchall_margin_container_box) UI_PrefHeight(ui_px(params->line_height_px, 1.f)) + { + U64 line_idx = 0; + for(S64 line_num = params->line_num_range.min; + line_num <= params->line_num_range.max; + line_num += 1, line_idx += 1) + { + DF_EntityList line_ips = params->line_ips[line_idx]; + DF_EntityList line_bps = params->line_bps[line_idx]; + DF_EntityList line_pins = params->line_pins[line_idx]; + ui_set_next_hover_cursor(OS_Cursor_HandPoint); + ui_set_next_background_color(v4f32(0, 0, 0, 0)); + UI_Box *line_margin_box = ui_build_box_from_stringf(UI_BoxFlag_Clickable*!!(params->flags & DF_CodeSliceFlag_Clickable)|UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawActiveEffects, "line_margin_%I64x", line_num); + UI_Parent(line_margin_box) + { + //- rjf: build margin thread ip ui + for(DF_EntityNode *n = line_ips.first; n != 0; n = n->next) + { + // rjf: unpack thread + DF_Entity *thread = n->entity; + if(thread == selected_thread) + { + continue; + } U64 unwind_count = (thread == selected_thread) ? ctrl_ctx->unwind_count : 0; U64 thread_rip_vaddr = df_query_cached_rip_from_thread_unwind(thread, unwind_count); DF_Entity *process = df_entity_ancestor_from_kind(thread, DF_EntityKind_Process); @@ -10831,6 +11008,7 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ params.entity = df_handle_from_entity(thread); df_cmd_params_mark_slot(¶ms, DF_CmdParamSlot_Entity); df_push_cmd__root(¶ms, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_SelectThread)); + ui_kill_action(); } // rjf: drag start @@ -11236,7 +11414,8 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ ////////////////////////////// //- rjf: interact with margin box & text box // - UI_Signal margin_container_sig = ui_signal_from_box(margin_container_box); + UI_Signal priority_margin_container_sig = ui_signal_from_box(priority_margin_container_box); + UI_Signal catchall_margin_container_sig = ui_signal_from_box(catchall_margin_container_box); UI_Signal text_container_sig = ui_signal_from_box(text_container_box); DF_Entity *line_drag_entity = &df_g_nil_entity; { diff --git a/src/df/gfx/df_gfx.h b/src/df/gfx/df_gfx.h index 3c317042..3a724f90 100644 --- a/src/df/gfx/df_gfx.h +++ b/src/df/gfx/df_gfx.h @@ -388,9 +388,10 @@ enum typedef U32 DF_CodeSliceFlags; enum { - DF_CodeSliceFlag_Clickable = (1<<0), - DF_CodeSliceFlag_Margin = (1<<1), - DF_CodeSliceFlag_LineNums = (1<<2), + DF_CodeSliceFlag_Clickable = (1<<0), + DF_CodeSliceFlag_PriorityMargin = (1<<1), + DF_CodeSliceFlag_CatchallMargin = (1<<2), + DF_CodeSliceFlag_LineNums = (1<<3), }; typedef struct DF_CodeSliceParams DF_CodeSliceParams; @@ -415,7 +416,8 @@ struct DF_CodeSliceParams F32 tab_size; String8 search_query; F32 line_height_px; - F32 margin_width_px; + F32 priority_margin_width_px; + F32 catchall_margin_width_px; F32 line_num_width_px; F32 line_text_max_width_px; DF_EntityList flash_ranges; diff --git a/src/df/gfx/df_view_rules.c b/src/df/gfx/df_view_rules.c index d96de95d..13472ff5 100644 --- a/src/df/gfx/df_view_rules.c +++ b/src/df/gfx/df_view_rules.c @@ -570,7 +570,8 @@ DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(text) code_slice_params.font_size = ui_top_font_size(); code_slice_params.tab_size = f_column_size_from_tag_size(code_slice_params.font, code_slice_params.font_size)*4.f; code_slice_params.line_height_px = ui_top_font_size()*1.5f; - code_slice_params.margin_width_px = 0; + code_slice_params.priority_margin_width_px = 0; + code_slice_params.catchall_margin_width_px = 0; code_slice_params.line_num_width_px = ui_top_font_size()*5.f; code_slice_params.line_text_max_width_px = ui_top_font_size()*2.f*info.lines_max_size; } @@ -731,7 +732,8 @@ DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(disasm) code_slice_params.font_size = ui_top_font_size(); code_slice_params.tab_size = f_column_size_from_tag_size(code_slice_params.font, code_slice_params.font_size)*4.f; code_slice_params.line_height_px = ui_top_font_size()*1.5f; - code_slice_params.margin_width_px = 0; + code_slice_params.priority_margin_width_px = 0; + code_slice_params.catchall_margin_width_px = 0; code_slice_params.line_num_width_px = ui_top_font_size()*5.f; code_slice_params.line_text_max_width_px = ui_top_font_size()*2.f*dasm_text_info.lines_max_size; } diff --git a/src/df/gfx/df_views.c b/src/df/gfx/df_views.c index 18b8e41d..93a85a2e 100644 --- a/src/df/gfx/df_views.c +++ b/src/df/gfx/df_views.c @@ -3867,13 +3867,7 @@ DF_VIEW_UI_FUNCTION_DEF(Targets) UI_FocusHot((row_selected && cursor.x == 0) ? UI_FocusKind_On : UI_FocusKind_Off) { UI_Signal sig = df_icon_buttonf(target->b32 ? DF_IconKind_CheckFilled : DF_IconKind_CheckHollow, 0, "###ebl_%p", target); - if(ui_clicked(sig) && sig.event_flags == 0) - { - DF_CmdParams p = df_cmd_params_from_view(ws, panel, view); - p.entity = df_handle_from_entity(target); - df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_SelectTarget)); - } - else if(ui_clicked(sig) && sig.event_flags == OS_EventFlag_Ctrl) + if(ui_clicked(sig)) { DF_CmdParams p = df_cmd_params_from_view(ws, panel, view); p.entity = df_handle_from_entity(target); @@ -5845,7 +5839,8 @@ DF_VIEW_UI_FUNCTION_DEF(Code) ////////////////////////////// //- rjf: calculate line-range-dependent info // - F32 margin_width_px = big_glyph_advance*3.5f; + F32 priority_margin_width_px = big_glyph_advance*3.5f; + F32 catchall_margin_width_px = big_glyph_advance*3.5f; F32 line_num_width_px = big_glyph_advance * (log10(visible_line_num_range.max) + 3); TXT_LineTokensSlice slice = txt_line_tokens_slice_from_info_data_line_range(scratch.arena, &text_info, data, visible_line_num_range); @@ -5873,7 +5868,7 @@ DF_VIEW_UI_FUNCTION_DEF(Code) if(text_info_is_ready) { // rjf: fill basics - code_slice_params.flags = DF_CodeSliceFlag_Margin|DF_CodeSliceFlag_LineNums|DF_CodeSliceFlag_Clickable; + code_slice_params.flags = DF_CodeSliceFlag_PriorityMargin|DF_CodeSliceFlag_CatchallMargin|DF_CodeSliceFlag_LineNums|DF_CodeSliceFlag_Clickable; code_slice_params.line_num_range = visible_line_num_range; code_slice_params.line_text = push_array(scratch.arena, String8, visible_line_count); code_slice_params.line_ranges = push_array(scratch.arena, Rng1U64, visible_line_count); @@ -5888,7 +5883,8 @@ DF_VIEW_UI_FUNCTION_DEF(Code) code_slice_params.tab_size = code_tab_size; code_slice_params.line_height_px = code_line_height; code_slice_params.search_query = search_query; - code_slice_params.margin_width_px = margin_width_px; + code_slice_params.priority_margin_width_px = priority_margin_width_px; + code_slice_params.catchall_margin_width_px = catchall_margin_width_px; code_slice_params.line_num_width_px = line_num_width_px; code_slice_params.line_text_max_width_px = (F32)line_size_x; code_slice_params.flash_ranges = df_push_entity_child_list_with_kind(scratch.arena, entity, DF_EntityKind_FlashMarker); @@ -6408,7 +6404,7 @@ DF_VIEW_UI_FUNCTION_DEF(Code) if(snap[Axis2_X]) { String8 cursor_line = str8_substr(data, text_info.lines_ranges[tv->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, tv->cursor.column-1)).x + margin_width_px + line_num_width_px); + S64 cursor_off = (S64)(f_dim_from_tag_size_string(code_font, code_font_size, 0, code_tab_size, str8_prefix(cursor_line, tv->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, @@ -6416,7 +6412,7 @@ DF_VIEW_UI_FUNCTION_DEF(Code) }; Rng1S64 cursor_pixel_range = { - cursor_off - (S64)(big_glyph_advance*4) - (S64)(margin_width_px + line_num_width_px), + cursor_off - (S64)(big_glyph_advance*4) - (S64)(priority_margin_width_px + catchall_margin_width_px + line_num_width_px), cursor_off + (S64)(big_glyph_advance*4), }; S64 min_delta = Min(0, cursor_pixel_range.min - visible_pixel_range.min); @@ -6921,7 +6917,8 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly) ////////////////////////////// //- rjf: calculate line-range-dependent info // - F32 margin_width_px = big_glyph_advance*3.5f; + F32 priority_margin_width_px = big_glyph_advance*3.5f; + F32 catchall_margin_width_px = big_glyph_advance*3.5f; F32 line_num_width_px = big_glyph_advance * (log10(visible_line_num_range.max) + 3); TXT_LineTokensSlice slice = txt_line_tokens_slice_from_info_data_line_range(scratch.arena, &dasm_text_info, dasm_text_data, visible_line_num_range); @@ -6962,7 +6959,7 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly) if(has_disasm) { // rjf: fill basics - code_slice_params.flags = DF_CodeSliceFlag_Margin|DF_CodeSliceFlag_LineNums|DF_CodeSliceFlag_Clickable; + code_slice_params.flags = DF_CodeSliceFlag_PriorityMargin|DF_CodeSliceFlag_CatchallMargin|DF_CodeSliceFlag_LineNums|DF_CodeSliceFlag_Clickable; code_slice_params.line_num_range = visible_line_num_range; code_slice_params.line_text = push_array(scratch.arena, String8, visible_line_count); code_slice_params.line_ranges = push_array(scratch.arena, Rng1U64, visible_line_count); @@ -6977,7 +6974,8 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly) code_slice_params.tab_size = code_tab_size; code_slice_params.line_height_px = code_line_height; code_slice_params.search_query = search_query; - code_slice_params.margin_width_px = margin_width_px; + code_slice_params.priority_margin_width_px = priority_margin_width_px; + code_slice_params.catchall_margin_width_px = catchall_margin_width_px; code_slice_params.line_num_width_px = line_num_width_px; code_slice_params.line_text_max_width_px = (F32)line_size_x; code_slice_params.flash_ranges = df_push_entity_child_list_with_kind(scratch.arena, process, DF_EntityKind_FlashMarker); @@ -7776,7 +7774,8 @@ DF_VIEW_UI_FUNCTION_DEF(Output) ////////////////////////////// //- rjf: calculate line-range-dependent info // - F32 margin_width_px = big_glyph_advance*3.5f; + F32 priority_margin_width_px = big_glyph_advance*3.5f; + F32 catchall_margin_width_px = big_glyph_advance*3.5f; F32 line_num_width_px = big_glyph_advance * (log10(visible_line_num_range.max) + 3); TXTI_Slice slice = txti_slice_from_handle_line_range(scratch.arena, txti_handle, visible_line_num_range); @@ -7819,7 +7818,8 @@ DF_VIEW_UI_FUNCTION_DEF(Output) code_slice_params.tab_size = code_tab_size; code_slice_params.line_height_px = code_line_height; code_slice_params.search_query = search_query; - code_slice_params.margin_width_px = margin_width_px; + code_slice_params.priority_margin_width_px = priority_margin_width_px; + code_slice_params.catchall_margin_width_px = catchall_margin_width_px; code_slice_params.line_num_width_px = line_num_width_px; code_slice_params.line_text_max_width_px = (F32)line_size_x; code_slice_params.flash_ranges = df_push_entity_child_list_with_kind(scratch.arena, entity, DF_EntityKind_FlashMarker); @@ -8105,7 +8105,7 @@ DF_VIEW_UI_FUNCTION_DEF(Output) if(snap[Axis2_X]) { String8 cursor_line = txti_string_from_handle_line_num(scratch.arena, txti_handle, tv->cursor.line); - S64 cursor_off = (S64)(f_dim_from_tag_size_string(code_font, code_font_size, 0, code_tab_size, str8_prefix(cursor_line, tv->cursor.column-1)).x + margin_width_px + line_num_width_px); + S64 cursor_off = (S64)(f_dim_from_tag_size_string(code_font, code_font_size, 0, code_tab_size, str8_prefix(cursor_line, tv->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, @@ -8113,7 +8113,7 @@ DF_VIEW_UI_FUNCTION_DEF(Output) }; Rng1S64 cursor_pixel_range = { - cursor_off - (S64)(big_glyph_advance*4) - (S64)(margin_width_px + line_num_width_px), + cursor_off - (S64)(big_glyph_advance*4) - (S64)(priority_margin_width_px + catchall_margin_width_px + line_num_width_px), cursor_off + (S64)(big_glyph_advance*4), }; S64 min_delta = Min(0, cursor_pixel_range.min - visible_pixel_range.min); From c4268183640ad3cb2533705e5863333d0d9adc85 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 29 May 2024 11:53:48 -0700 Subject: [PATCH 35/39] draw line between priority & catchall marging --- src/df/gfx/df_gfx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/df/gfx/df_gfx.c b/src/df/gfx/df_gfx.c index 945241df..8f1128ed 100644 --- a/src/df/gfx/df_gfx.c +++ b/src/df/gfx/df_gfx.c @@ -10866,7 +10866,7 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ ui_set_next_pref_width(ui_px(params->catchall_margin_width_px, 1)); ui_set_next_pref_height(ui_px(params->line_height_px*(dim_1s64(params->line_num_range)+1), 1.f)); ui_set_next_child_layout_axis(Axis2_Y); - catchall_margin_container_box = ui_build_box_from_string(UI_BoxFlag_Clickable*!!(params->flags & DF_CodeSliceFlag_Clickable), str8_lit("catchall_margin_container")); + catchall_margin_container_box = ui_build_box_from_string(UI_BoxFlag_DrawSideLeft|UI_BoxFlag_Clickable*!!(params->flags & DF_CodeSliceFlag_Clickable), str8_lit("catchall_margin_container")); UI_Parent(catchall_margin_container_box) UI_PrefHeight(ui_px(params->line_height_px, 1.f)) { U64 line_idx = 0; From 89c8f844987a487751646fd5be85e5d01e5f0c5f Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 29 May 2024 12:25:03 -0700 Subject: [PATCH 36/39] more tweaks with new double-margin; do not try to display non-printable ascii characters in watch --- src/df/core/df_core.c | 16 ++++++++++++---- src/df/gfx/df_gfx.c | 6 ------ 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/df/core/df_core.c b/src/df/core/df_core.c index 15c3d911..c627903c 100644 --- a/src/df/core/df_core.c +++ b/src/df/core/df_core.c @@ -4473,6 +4473,7 @@ df_string_from_ascii_value(Arena *arena, U8 val) case '\'':{result = str8_lit("\\'");}break; case '\\':{result = str8_lit("\\\\");}break; default: + if(32 <= val && val < 255) { result = push_str8f(arena, "%c", val); }break; @@ -4511,14 +4512,21 @@ df_string_from_simple_typed_eval(Arena *arena, TG_Graph *graph, RDI_Parsed *rdi, case TG_Kind_UChar32: { String8 char_str = df_string_from_ascii_value(arena, eval.imm_s64); - if(flags & DF_EvalVizStringFlag_ReadOnlyDisplayRules) + if(char_str.size != 0) { - String8 imm_string = str8_from_s64(arena, eval.imm_s64, radix, 0, digit_group_separator); - result = push_str8f(arena, "'%S' (%S)", char_str, imm_string); + if(flags & DF_EvalVizStringFlag_ReadOnlyDisplayRules) + { + String8 imm_string = str8_from_s64(arena, eval.imm_s64, radix, 0, digit_group_separator); + result = push_str8f(arena, "'%S' (%S)", char_str, imm_string); + } + else + { + result = push_str8f(arena, "'%S'", char_str); + } } else { - result = push_str8f(arena, "'%S'", char_str); + result = str8_from_s64(arena, eval.imm_s64, radix, 0, digit_group_separator); } }break; diff --git a/src/df/gfx/df_gfx.c b/src/df/gfx/df_gfx.c index 8f1128ed..d0b8ae1a 100644 --- a/src/df/gfx/df_gfx.c +++ b/src/df/gfx/df_gfx.c @@ -10709,8 +10709,6 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ line_num += 1, line_idx += 1) { DF_EntityList line_ips = params->line_ips[line_idx]; - DF_EntityList line_bps = params->line_bps[line_idx]; - DF_EntityList line_pins = params->line_pins[line_idx]; ui_set_next_hover_cursor(OS_Cursor_HandPoint); ui_set_next_background_color(v4f32(0, 0, 0, 0)); UI_Box *line_margin_box = ui_build_box_from_stringf(UI_BoxFlag_Clickable*!!(params->flags & DF_CodeSliceFlag_Clickable)|UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawActiveEffects, "line_margin_%I64x", line_num); @@ -10771,7 +10769,6 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ 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*!!(params->flags & DF_CodeSliceFlag_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]); @@ -10937,7 +10934,6 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ 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*!!(params->flags & DF_CodeSliceFlag_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]); @@ -11062,7 +11058,6 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ UI_BoxFlag_DrawActiveEffects| UI_BoxFlag_DrawHotEffects| UI_BoxFlag_DrawBorder| - UI_BoxFlag_AnimatePosX| UI_BoxFlag_Clickable*!!(params->flags & DF_CodeSliceFlag_Clickable)| UI_BoxFlag_DisableTextTrunc, "%S##bp_%p", @@ -11131,7 +11126,6 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ UI_BoxFlag_DrawHotEffects| UI_BoxFlag_DrawBorder| UI_BoxFlag_Clickable*!!(params->flags & DF_CodeSliceFlag_Clickable)| - UI_BoxFlag_AnimatePosX| UI_BoxFlag_DisableTextTrunc, "%S##watch_%p", df_g_icon_kind_text_table[DF_IconKind_Pin], From 34bba958392dabca553826de555ed4ea91e22d15 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 29 May 2024 21:25:47 -0700 Subject: [PATCH 37/39] import todo notes from awkwardly aggressive user feedback --- src/raddbg/raddbg.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/raddbg/raddbg.h b/src/raddbg/raddbg.h index 6b12cd6f..4c065424 100644 --- a/src/raddbg/raddbg.h +++ b/src/raddbg/raddbg.h @@ -40,6 +40,10 @@ //////////////////////////////// //~ rjf: Hot, High Priority Tasks (Complete Unusability, Crashes, Fire-Worthy) // +// [ ] investigate heavy outputdebugstring usage causing major issues +// (both in debugger and in target application, apparently) +// [ ] "Browse..." buttons should adopt a more relevant starting search path, +// if possible // [ ] PDB files distributed with the build are not found by DbgHelp!!! // [ ] Jai compiler debugging crash // @@ -66,6 +70,10 @@ // [ ] min view rule // [ ] double click on procedure in procedures tab to jump to source // +// [ ] filesystem drag/drop support +// [ ] double-click vs. single-click for folder navigation, see if we can infer +// [ ] use backslashes on windows by default, forward slashes elsewhere +// // [ ] investigate /DEBUG:FASTLINK - can we somehow alert that we do not // support it? // From da54fd12175dc594bef833763e8c1ed44bbec3c9 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 30 May 2024 07:06:29 -0700 Subject: [PATCH 38/39] majorly improve outputdebugstring performance --- src/demon/win32/demon_core_win32.c | 1294 ++++++++++++++-------------- 1 file changed, 668 insertions(+), 626 deletions(-) diff --git a/src/demon/win32/demon_core_win32.c b/src/demon/win32/demon_core_win32.c index 8bfac593..2742830f 100644 --- a/src/demon/win32/demon_core_win32.c +++ b/src/demon/win32/demon_core_win32.c @@ -355,7 +355,7 @@ internal String8 dmn_w32_read_memory_str(Arena *arena, HANDLE process_handle, U64 address) { // TODO(rjf): @rewrite - // + // // OLD: this could be done better with a demon_w32_read_memory // that returns a read amount instead of a success/fail. // @@ -404,7 +404,7 @@ internal String16 dmn_w32_read_memory_str16(Arena *arena, HANDLE process_handle, U64 address) { // TODO(rjf): @rewrite - // + // // OLD: this could be done better with a demon_w32_read_memory // that returns a read amount instead of a success/fail. // @@ -1418,6 +1418,7 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) //- rjf: write all traps into memory // U8 *trap_swap_bytes = push_array_no_zero(scratch.arena, U8, ctrls->traps.trap_count); + ProfScope("write all traps into memory") { U64 trap_idx = 0; for(DMN_TrapChunkNode *n = ctrls->traps.first; n != 0; n = n->next) @@ -1438,6 +1439,7 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) // DMN_W32_EntityNode *first_run_thread = 0; DMN_W32_EntityNode *last_run_thread = 0; + ProfScope("produce list of threads which will run") { //- rjf: scan all processes for(DMN_W32_Entity *process = dmn_w32_shared->entities_base->first; @@ -1446,7 +1448,7 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) { if(process->kind != DMN_W32_EntityKind_Process) {continue;} - //- rjf: determine if this process is frozen + //- rjf: determine if this process is frozen B32 process_is_frozen = 0; if(ctrls->run_entities_are_processes) { @@ -1519,696 +1521,735 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) ////////////////////////// //- rjf: resume threads which will run // - for(DMN_W32_EntityNode *n = first_run_thread; n != 0; n = n->next) + ProfScope("resume threads which will run") { - DMN_W32_Entity *thread = n->v; - DWORD resume_result = ResumeThread(thread->handle); - switch(resume_result) + for(DMN_W32_EntityNode *n = first_run_thread; n != 0; n = n->next) { - case 0xffffffffu: + DMN_W32_Entity *thread = n->v; + DWORD resume_result = ResumeThread(thread->handle); + switch(resume_result) { - // TODO(rjf): error - unknown cause. need to do GetLastError, FormatMessage - }break; - default: - { - DWORD desired_counter = 0; - DWORD current_counter = resume_result - 1; - if(current_counter != desired_counter) + case 0xffffffffu: { - // NOTE(rjf): Warning. The user has manually suspended this thread, - // so even though from Demon's perspective it thinks this thread - // should run, it will not, because the user has manually called - // SuspendThread or used CREATE_SUSPENDED or whatever. - } - }break; - } - } - - ////////////////////////// - //- rjf: choose win32 resume code - // - DWORD resume_code = DBG_CONTINUE; - { - if(dmn_w32_shared->exception_not_handled && !ctrls->ignore_previous_exception) - { - dmn_w32_shared->exception_not_handled = 0; - resume_code = DBG_EXCEPTION_NOT_HANDLED; - } - } - - ////////////////////////// - //- rjf: inform windows that we're resuming, run, & obtain next debug event - // - DEBUG_EVENT evt = {0}; - B32 evt_good = 0; - { - B32 resume_good = 1; - if(dmn_w32_shared->resume_needed) - { - dmn_w32_shared->resume_needed = 0; - resume_good = !!ContinueDebugEvent(dmn_w32_shared->resume_pid, dmn_w32_shared->resume_tid, resume_code); - dmn_w32_shared->resume_needed = 0; - dmn_w32_shared->resume_tid = 0; - dmn_w32_shared->resume_pid = 0; - } - if(resume_good) - { - evt_good = !!WaitForDebugEvent(&evt, INFINITE); - if(evt_good) - { - dmn_w32_shared->resume_needed = 1; - dmn_w32_shared->resume_pid = evt.dwProcessId; - dmn_w32_shared->resume_tid = evt.dwThreadId; - } - ins_atomic_u64_inc_eval(&dmn_w32_shared->run_gen); - ins_atomic_u64_inc_eval(&dmn_w32_shared->mem_gen); - ins_atomic_u64_inc_eval(&dmn_w32_shared->reg_gen); - } - } - - ////////////////////////// - //- rjf: suspend threads which ran - // - if(evt_good) for(DMN_W32_EntityNode *n = first_run_thread; n != 0; n = n->next) - { - DMN_W32_Entity *thread = n->v; - DWORD suspend_result = SuspendThread(thread->handle); - switch(suspend_result) - { - case 0xffffffffu: - { - // TODO(rjf): error - unknown cause. need to do do GetLastError, FormatMessage - // - // NOTE(rjf): this can happen when the event is EXIT_THREAD_DEBUG_EVENT - // or EXIT_PROCESS_DEBUG_EVENT. after such an event, SuspendThread - // gives error code 5 (access denied). this has no adverse effects, but - // if we want to start reporting errors we should take care to avoid - // calling SuspendThread in that case. - }break; - default: - { - DWORD desired_counter = 1; - DWORD current_counter = suspend_result + 1; - if(current_counter != desired_counter) + // TODO(rjf): error - unknown cause. need to do GetLastError, FormatMessage + }break; + default: { - // NOTE(rjf): Warning. We've suspended to something higher than 1. - // In this case, it means the user probably created the thread in - // a suspended state, or they called SuspendThread. - } - }break; - } - } - - ////////////////////////// - //- rjf: process the new event - // - if(evt_good) - { - switch(evt.dwDebugEventCode) - { - ////////////////////// - //- rjf: process was created - // - case CREATE_PROCESS_DEBUG_EVENT: - { - // rjf: zero out "process pending" state - dmn_w32_shared->new_process_pending = 0; - - // rjf: unpack event - HANDLE process_handle = evt.u.CreateProcessInfo.hProcess; - HANDLE thread_handle = evt.u.CreateProcessInfo.hThread; - HANDLE module_handle = evt.u.CreateProcessInfo.hFile; - U64 tls_base = (U64)evt.u.CreateProcessInfo.lpThreadLocalBase; - U64 module_base = (U64)evt.u.CreateProcessInfo.lpBaseOfImage; - U64 module_name_vaddr = (U64)evt.u.CreateProcessInfo.lpImageName; - B32 module_name_is_unicode = (evt.u.CreateProcessInfo.fUnicode != 0); - DMN_W32_ImageInfo image_info = dmn_w32_image_info_from_process_base_vaddr(process_handle, module_base); - - // rjf: create entities (thread/module are implied for initial - they are not reported by win32) - DMN_W32_Entity *process = dmn_w32_entity_alloc(dmn_w32_shared->entities_base, DMN_W32_EntityKind_Process, evt.dwProcessId); - DMN_W32_Entity *thread = dmn_w32_entity_alloc(process, DMN_W32_EntityKind_Thread, evt.dwThreadId); - DMN_W32_Entity *module = dmn_w32_entity_alloc(process, DMN_W32_EntityKind_Module, module_base); - { - process->handle = process_handle; - process->arch = image_info.arch; - thread->handle = thread_handle; - thread->arch = image_info.arch; - thread->thread.thread_local_base = tls_base; - module->handle = module_handle; - module->module.vaddr_range = r1u64(module_base, image_info.size); - module->module.is_main = 1; - module->module.address_of_name_pointer = module_name_vaddr; - module->module.name_is_unicode = module_name_is_unicode; - } - - // rjf: put thread into suspended state, so it matches expected initial state - SuspendThread(thread_handle); - - // rjf: set up per-process injected code (to run halter threads on & - // generate debug events) - { - U8 injection_code[DMN_W32_INJECTED_CODE_SIZE]; - MemorySet(injection_code, 0xCC, DMN_W32_INJECTED_CODE_SIZE); - injection_code[0] = 0xC3; - U64 injection_size = DMN_W32_INJECTED_CODE_SIZE + sizeof(DMN_W32_InjectedBreak); - U64 injection_address = (U64)VirtualAllocEx(process_handle, 0, injection_size, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE); - dmn_w32_process_write(process_handle, r1u64(injection_address, injection_address+sizeof(injection_code)), injection_code); - process->proc.injection_address = injection_address; - } - - // rjf: generate events - { - // rjf: create process + DWORD desired_counter = 0; + DWORD current_counter = resume_result - 1; + if(current_counter != desired_counter) { - DMN_Event *e = dmn_event_list_push(arena, &events); - e->kind = DMN_EventKind_CreateProcess; - e->process = dmn_w32_handle_from_entity(process); - e->arch = image_info.arch; - e->code = evt.dwProcessId; + // NOTE(rjf): Warning. The user has manually suspended this thread, + // so even though from Demon's perspective it thinks this thread + // should run, it will not, because the user has manually called + // SuspendThread or used CREATE_SUSPENDED or whatever. + } + }break; + } + } + } + + ////////////////////////// + //- rjf: loop, consume win32 debug events until we produce the relevant demon events + // + String8List debug_strings = {0}; + for(B32 keep_going = 1; keep_going;) + { + keep_going = 0; + + //////////////////////// + //- rjf: choose win32 resume code + // + DWORD resume_code = DBG_CONTINUE; + { + if(dmn_w32_shared->exception_not_handled && !ctrls->ignore_previous_exception) + { + dmn_w32_shared->exception_not_handled = 0; + resume_code = DBG_EXCEPTION_NOT_HANDLED; + } + } + + //////////////////////// + //- rjf: inform windows that we're resuming, run, & obtain next debug event + // + DEBUG_EVENT evt = {0}; + B32 evt_good = 0; + ProfScope("inform windows that we're resuming, run, & obtain next debug event") + { + B32 resume_good = 1; + if(dmn_w32_shared->resume_needed) + { + dmn_w32_shared->resume_needed = 0; + resume_good = !!ContinueDebugEvent(dmn_w32_shared->resume_pid, dmn_w32_shared->resume_tid, resume_code); + dmn_w32_shared->resume_needed = 0; + dmn_w32_shared->resume_tid = 0; + dmn_w32_shared->resume_pid = 0; + } + if(resume_good) + { + evt_good = !!WaitForDebugEvent(&evt, INFINITE); + if(evt_good) + { + dmn_w32_shared->resume_needed = 1; + dmn_w32_shared->resume_pid = evt.dwProcessId; + dmn_w32_shared->resume_tid = evt.dwThreadId; + } + ins_atomic_u64_inc_eval(&dmn_w32_shared->run_gen); + ins_atomic_u64_inc_eval(&dmn_w32_shared->mem_gen); + ins_atomic_u64_inc_eval(&dmn_w32_shared->reg_gen); + } + } + + //////////////////////// + //- rjf: process the new event + // + if(evt_good) ProfScope("process the new event") + { + switch(evt.dwDebugEventCode) + { + ////////////////////// + //- rjf: process was created + // + case CREATE_PROCESS_DEBUG_EVENT: + { + // rjf: zero out "process pending" state + dmn_w32_shared->new_process_pending = 0; + + // rjf: unpack event + HANDLE process_handle = evt.u.CreateProcessInfo.hProcess; + HANDLE thread_handle = evt.u.CreateProcessInfo.hThread; + HANDLE module_handle = evt.u.CreateProcessInfo.hFile; + U64 tls_base = (U64)evt.u.CreateProcessInfo.lpThreadLocalBase; + U64 module_base = (U64)evt.u.CreateProcessInfo.lpBaseOfImage; + U64 module_name_vaddr = (U64)evt.u.CreateProcessInfo.lpImageName; + B32 module_name_is_unicode = (evt.u.CreateProcessInfo.fUnicode != 0); + DMN_W32_ImageInfo image_info = dmn_w32_image_info_from_process_base_vaddr(process_handle, module_base); + + // rjf: create entities (thread/module are implied for initial - they are not reported by win32) + DMN_W32_Entity *process = dmn_w32_entity_alloc(dmn_w32_shared->entities_base, DMN_W32_EntityKind_Process, evt.dwProcessId); + DMN_W32_Entity *thread = dmn_w32_entity_alloc(process, DMN_W32_EntityKind_Thread, evt.dwThreadId); + DMN_W32_Entity *module = dmn_w32_entity_alloc(process, DMN_W32_EntityKind_Module, module_base); + { + process->handle = process_handle; + process->arch = image_info.arch; + thread->handle = thread_handle; + thread->arch = image_info.arch; + thread->thread.thread_local_base = tls_base; + module->handle = module_handle; + module->module.vaddr_range = r1u64(module_base, image_info.size); + module->module.is_main = 1; + module->module.address_of_name_pointer = module_name_vaddr; + module->module.name_is_unicode = module_name_is_unicode; } - // rjf: create thread + // rjf: put thread into suspended state, so it matches expected initial state + SuspendThread(thread_handle); + + // rjf: set up per-process injected code (to run halter threads on & + // generate debug events) + { + U8 injection_code[DMN_W32_INJECTED_CODE_SIZE]; + MemorySet(injection_code, 0xCC, DMN_W32_INJECTED_CODE_SIZE); + injection_code[0] = 0xC3; + U64 injection_size = DMN_W32_INJECTED_CODE_SIZE + sizeof(DMN_W32_InjectedBreak); + U64 injection_address = (U64)VirtualAllocEx(process_handle, 0, injection_size, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE); + dmn_w32_process_write(process_handle, r1u64(injection_address, injection_address+sizeof(injection_code)), injection_code); + process->proc.injection_address = injection_address; + } + + // rjf: generate events + { + // rjf: create process + { + DMN_Event *e = dmn_event_list_push(arena, &events); + e->kind = DMN_EventKind_CreateProcess; + e->process = dmn_w32_handle_from_entity(process); + e->arch = image_info.arch; + e->code = evt.dwProcessId; + } + + // rjf: create thread + { + DMN_Event *e = dmn_event_list_push(arena, &events); + e->kind = DMN_EventKind_CreateThread; + e->process = dmn_w32_handle_from_entity(process); + e->thread = dmn_w32_handle_from_entity(thread); + e->arch = image_info.arch; + e->code = evt.dwThreadId; + } + + // rjf: load module + { + DMN_Event *e = dmn_event_list_push(arena, &events); + e->kind = DMN_EventKind_LoadModule; + e->process = dmn_w32_handle_from_entity(process); + e->module = dmn_w32_handle_from_entity(module); + e->arch = image_info.arch; + e->address = module_base; + e->size = image_info.size; + e->string = dmn_w32_full_path_from_module(arena, module); + } + } + }break; + + ////////////////////// + //- rjf: process exited + // + case EXIT_PROCESS_DEBUG_EVENT: + { + DMN_W32_Entity *process = dmn_w32_entity_from_kind_id(DMN_W32_EntityKind_Process, evt.dwProcessId); + + // rjf: generate events for children + for(DMN_W32_Entity *child = process->first; child != &dmn_w32_entity_nil; child = child->next) + { + switch(child->kind) + { + default:{}break; + case DMN_W32_EntityKind_Thread: + { + DMN_Event *e = dmn_event_list_push(arena, &events); + e->kind = DMN_EventKind_ExitThread; + e->process = dmn_w32_handle_from_entity(process); + e->thread = dmn_w32_handle_from_entity(child); + }break; + case DMN_W32_EntityKind_Module: + { + DMN_Event *e = dmn_event_list_push(arena, &events); + e->kind = DMN_EventKind_UnloadModule; + e->process = dmn_w32_handle_from_entity(process); + e->module = dmn_w32_handle_from_entity(child); + e->string = dmn_w32_full_path_from_module(arena, child); + }break; + } + } + + // rjf: generate event for process { DMN_Event *e = dmn_event_list_push(arena, &events); - e->kind = DMN_EventKind_CreateThread; + e->kind = DMN_EventKind_ExitProcess; + e->process = dmn_w32_handle_from_entity(process); + e->code = evt.u.ExitProcess.dwExitCode; + } + + // rjf: release entity storage + dmn_w32_entity_release(process); + + // rjf: detach + DebugActiveProcessStop(evt.dwProcessId); + }break; + + ////////////////////// + //- rjf: thread was created + // + case CREATE_THREAD_DEBUG_EVENT: + { + DMN_W32_Entity *process = dmn_w32_entity_from_kind_id(DMN_W32_EntityKind_Process, evt.dwProcessId); + + // rjf: create thread entity + DMN_W32_Entity *thread = dmn_w32_entity_alloc(process, DMN_W32_EntityKind_Thread, evt.dwThreadId); + { + thread->handle = evt.u.CreateThread.hThread; + thread->arch = process->arch; + thread->thread.thread_local_base = (U64)evt.u.CreateThread.lpThreadLocalBase; + } + + // rjf: suspend thread immediately upon creation, to match with expected suspension state + DWORD sus_result = SuspendThread(thread->handle); + (void)sus_result; + + // rjf: unpack thread name + String8 thread_name = {0}; + if(dmn_w32_GetThreadDescription != 0) + { + WCHAR *thread_name_w = 0; + HRESULT hr = dmn_w32_GetThreadDescription(thread->handle, &thread_name_w); + if(SUCCEEDED(hr)) + { + thread_name = str8_from_16(arena, str16_cstring((U16 *)thread_name_w)); + LocalFree(thread_name_w); + } + } + + // rjf: determine if this is a "halter thread" - the threads we spawn to halt processes + B32 is_halter = (evt.dwThreadId == dmn_w32_shared->halter_tid); + + // rjf: generate events for non-halter threads + if(!is_halter) + { + DMN_Event *e = dmn_event_list_push(arena, &events); + e->kind = DMN_EventKind_CreateThread; e->process = dmn_w32_handle_from_entity(process); e->thread = dmn_w32_handle_from_entity(thread); - e->arch = image_info.arch; + e->arch = thread->arch; e->code = evt.dwThreadId; + e->string = thread_name; } + }break; + + ////////////////////// + //- rjf: thread exited + // + case EXIT_THREAD_DEBUG_EVENT: + { + DMN_W32_Entity *thread = dmn_w32_entity_from_kind_id(DMN_W32_EntityKind_Thread, evt.dwThreadId); + DMN_W32_Entity *process = thread->parent; - // rjf: load module + // rjf: determine if this is the halter thread + B32 is_halter = (evt.dwThreadId == dmn_w32_shared->halter_tid); + + // rjf: generate a halt event if this thread is the halter + if(is_halter) { DMN_Event *e = dmn_event_list_push(arena, &events); - e->kind = DMN_EventKind_LoadModule; + e->kind = DMN_EventKind_Halt; + dmn_w32_shared->halter_process = dmn_handle_zero(); + dmn_w32_shared->halter_tid = 0; + } + + // rjf: if this thread is *not* the halter, then generate a regular exit-thread event + if(!is_halter) + { + DMN_Event *e = dmn_event_list_push(arena, &events); + e->kind = DMN_EventKind_ExitThread; + e->process = dmn_w32_handle_from_entity(process); + e->thread = dmn_w32_handle_from_entity(thread); + e->code = evt.u.ExitThread.dwExitCode; + } + + // rjf: release entity storage + dmn_w32_entity_release(thread); + }break; + + ////////////////////// + //- rjf: DLL was loaded + // + case LOAD_DLL_DEBUG_EVENT: + { + DMN_W32_Entity *process = dmn_w32_entity_from_kind_id(DMN_W32_EntityKind_Process, evt.dwProcessId); + + // rjf: extract image info + U64 module_base = (U64)evt.u.LoadDll.lpBaseOfDll; + DMN_W32_ImageInfo image_info = dmn_w32_image_info_from_process_base_vaddr(process->handle, module_base); + + // rjf: create module entity + DMN_W32_Entity *module = dmn_w32_entity_alloc(process, DMN_W32_EntityKind_Module, module_base); + { + module->handle = evt.u.LoadDll.hFile; + module->arch = image_info.arch; + module->module.vaddr_range = r1u64(module_base, module_base+image_info.size); + module->module.address_of_name_pointer = (U64)evt.u.LoadDll.lpImageName; + module->module.name_is_unicode = (evt.u.LoadDll.fUnicode != 0); + } + + // rjf: generate event + { + DMN_Event *e = dmn_event_list_push(arena, &events); + e->kind = DMN_EventKind_LoadModule; e->process = dmn_w32_handle_from_entity(process); e->module = dmn_w32_handle_from_entity(module); - e->arch = image_info.arch; + e->arch = module->arch; e->address = module_base; e->size = image_info.size; e->string = dmn_w32_full_path_from_module(arena, module); } - } - }break; - - ////////////////////// - //- rjf: process exited - // - case EXIT_PROCESS_DEBUG_EVENT: - { - DMN_W32_Entity *process = dmn_w32_entity_from_kind_id(DMN_W32_EntityKind_Process, evt.dwProcessId); + }break; - // rjf: generate events for children - for(DMN_W32_Entity *child = process->first; child != &dmn_w32_entity_nil; child = child->next) + ////////////////////// + //- rjf: DLL was unloaded + // + case UNLOAD_DLL_DEBUG_EVENT: { - switch(child->kind) + U64 module_base = (U64)evt.u.UnloadDll.lpBaseOfDll; + DMN_W32_Entity *module = dmn_w32_entity_from_kind_id(DMN_W32_EntityKind_Module, module_base); + DMN_W32_Entity *process = module->parent; + + // rjf: generate event { - default:{}break; - case DMN_W32_EntityKind_Thread: - { - DMN_Event *e = dmn_event_list_push(arena, &events); - e->kind = DMN_EventKind_ExitThread; - e->process = dmn_w32_handle_from_entity(process); - e->thread = dmn_w32_handle_from_entity(child); - }break; - case DMN_W32_EntityKind_Module: - { - DMN_Event *e = dmn_event_list_push(arena, &events); - e->kind = DMN_EventKind_UnloadModule; - e->process = dmn_w32_handle_from_entity(process); - e->module = dmn_w32_handle_from_entity(child); - e->string = dmn_w32_full_path_from_module(arena, child); - }break; + DMN_Event *e = dmn_event_list_push(arena, &events); + e->kind = DMN_EventKind_UnloadModule; + e->process = dmn_w32_handle_from_entity(process); + e->module = dmn_w32_handle_from_entity(module); + e->string = dmn_w32_full_path_from_module(arena, module); } - } + + // rjf: release entity storage + dmn_w32_entity_release(module); + }break; - // rjf: generate event for process + ////////////////////// + //- rjf: exception was hit + // + case EXCEPTION_DEBUG_EVENT: { - DMN_Event *e = dmn_event_list_push(arena, &events); - e->kind = DMN_EventKind_ExitProcess; - e->process = dmn_w32_handle_from_entity(process); - e->code = evt.u.ExitProcess.dwExitCode; - } - - // rjf: release entity storage - dmn_w32_entity_release(process); - - // rjf: detach - DebugActiveProcessStop(evt.dwProcessId); - }break; - - ////////////////////// - //- rjf: thread was created - // - case CREATE_THREAD_DEBUG_EVENT: - { - DMN_W32_Entity *process = dmn_w32_entity_from_kind_id(DMN_W32_EntityKind_Process, evt.dwProcessId); - - // rjf: create thread entity - DMN_W32_Entity *thread = dmn_w32_entity_alloc(process, DMN_W32_EntityKind_Thread, evt.dwThreadId); - { - thread->handle = evt.u.CreateThread.hThread; - thread->arch = process->arch; - thread->thread.thread_local_base = (U64)evt.u.CreateThread.lpThreadLocalBase; - } - - // rjf: suspend thread immediately upon creation, to match with expected suspension state - DWORD sus_result = SuspendThread(thread->handle); - (void)sus_result; - - // rjf: unpack thread name - String8 thread_name = {0}; - if(dmn_w32_GetThreadDescription != 0) - { - WCHAR *thread_name_w = 0; - HRESULT hr = dmn_w32_GetThreadDescription(thread->handle, &thread_name_w); - if(SUCCEEDED(hr)) + //- NOTE(rjf): Notes on multithreaded breakpoint events + // (2021/11/1): + // + // When many threads are simultaneously running, multiple threads + // may hit a trap "at the same time". When this happens there will be + // multiple events in an internal queue that we cannot see. If there + // is another event in the queue we will not see it until we call + // ContinueDebugEvent again, in a subsequent call to demon_os_run. + // + // When we get a trap event, the instruction pointer stored + // in the event will have the address of the int 3 instruction that + // was hit. Our RIP register, however, will be one byte past that. + // So, to get the behavior we want, we need to set the RIP register + // back to the address of the int 3. + // + // To deal with the fact that we may get breakpoint events later that + // were actually from this run what we do is: + // + // #1. If we get a trap event, and it corresponds to a user submitted + // trap, then we treat it is a breakpoint event. + // #2. If we get a trap event, and it does NOT correspond to a user + // trap in this call: + // #A. If the actual unmodified instruction byte is NOT an int 3, + // then this is a queued event from a previous run that is no + // longer applicable and we skip it. + // #B. If the actual unmodified instruction is an int 3, then this + // becomes a trap event and we do not reset RIP. + + //- NOTE(rjf): Further notes on MULTITHREADED STEPPING ACCESS VIOLATION + // EVENTS! @rjf @rjf @rjf + // (2024/05/29): + // + // Just adding another comment here to document that the above long + // comment went completely unnoticed by me during a pass over demon, + // and I had removed the proper rollback stuff here without reading + // the above comment. So this comment just serves to make that + // original comment even heftier. + + //- NOTE(rjf): The exception record struct has a 32-bit version and a + // 64-bit version. We only currently handle the 64-bit version. + + //- rjf: unpack + DMN_W32_Entity *thread = dmn_w32_entity_from_kind_id(DMN_W32_EntityKind_Thread, evt.dwThreadId); + DMN_W32_Entity *process = thread->parent; + EXCEPTION_DEBUG_INFO *edi = &evt.u.Exception; + EXCEPTION_RECORD *exception = &edi->ExceptionRecord; + U64 instruction_pointer = (U64)exception->ExceptionAddress; + + //- rjf: determine if this is the first breakpoint in a process + // (breakpoint notifying us that the debugger is attached) + B32 first_bp = 0; + if(!process->proc.did_first_bp && exception->ExceptionCode == DMN_W32_EXCEPTION_BREAKPOINT) { - thread_name = str8_from_16(arena, str16_cstring((U16 *)thread_name_w)); - LocalFree(thread_name_w); + process->proc.did_first_bp = 1; + first_bp = 1; } - } - - // rjf: determine if this is a "halter thread" - the threads we spawn to halt processes - B32 is_halter = (evt.dwThreadId == dmn_w32_shared->halter_tid); - - // rjf: generate events for non-halter threads - if(!is_halter) - { - DMN_Event *e = dmn_event_list_push(arena, &events); - e->kind = DMN_EventKind_CreateThread; - e->process = dmn_w32_handle_from_entity(process); - e->thread = dmn_w32_handle_from_entity(thread); - e->arch = thread->arch; - e->code = evt.dwThreadId; - e->string = thread_name; - } - }break; - - ////////////////////// - //- rjf: thread exited - // - case EXIT_THREAD_DEBUG_EVENT: - { - DMN_W32_Entity *thread = dmn_w32_entity_from_kind_id(DMN_W32_EntityKind_Thread, evt.dwThreadId); - DMN_W32_Entity *process = thread->parent; - - // rjf: determine if this is the halter thread - B32 is_halter = (evt.dwThreadId == dmn_w32_shared->halter_tid); - - // rjf: generate a halt event if this thread is the halter - if(is_halter) - { - DMN_Event *e = dmn_event_list_push(arena, &events); - e->kind = DMN_EventKind_Halt; - dmn_w32_shared->halter_process = dmn_handle_zero(); - dmn_w32_shared->halter_tid = 0; - } - - // rjf: if this thread is *not* the halter, then generate a regular exit-thread event - if(!is_halter) - { - DMN_Event *e = dmn_event_list_push(arena, &events); - e->kind = DMN_EventKind_ExitThread; - e->process = dmn_w32_handle_from_entity(process); - e->thread = dmn_w32_handle_from_entity(thread); - e->code = evt.u.ExitThread.dwExitCode; - } - - // rjf: release entity storage - dmn_w32_entity_release(thread); - }break; - - ////////////////////// - //- rjf: DLL was loaded - // - case LOAD_DLL_DEBUG_EVENT: - { - DMN_W32_Entity *process = dmn_w32_entity_from_kind_id(DMN_W32_EntityKind_Process, evt.dwProcessId); - - // rjf: extract image info - U64 module_base = (U64)evt.u.LoadDll.lpBaseOfDll; - DMN_W32_ImageInfo image_info = dmn_w32_image_info_from_process_base_vaddr(process->handle, module_base); - - // rjf: create module entity - DMN_W32_Entity *module = dmn_w32_entity_alloc(process, DMN_W32_EntityKind_Module, module_base); - { - module->handle = evt.u.LoadDll.hFile; - module->arch = image_info.arch; - module->module.vaddr_range = r1u64(module_base, module_base+image_info.size); - module->module.address_of_name_pointer = (U64)evt.u.LoadDll.lpImageName; - module->module.name_is_unicode = (evt.u.LoadDll.fUnicode != 0); - } - - // rjf: generate event - { - DMN_Event *e = dmn_event_list_push(arena, &events); - e->kind = DMN_EventKind_LoadModule; - e->process = dmn_w32_handle_from_entity(process); - e->module = dmn_w32_handle_from_entity(module); - e->arch = module->arch; - e->address = module_base; - e->size = image_info.size; - e->string = dmn_w32_full_path_from_module(arena, module); - } - }break; - - ////////////////////// - //- rjf: DLL was unloaded - // - case UNLOAD_DLL_DEBUG_EVENT: - { - U64 module_base = (U64)evt.u.UnloadDll.lpBaseOfDll; - DMN_W32_Entity *module = dmn_w32_entity_from_kind_id(DMN_W32_EntityKind_Module, module_base); - DMN_W32_Entity *process = module->parent; - - // rjf: generate event - { - DMN_Event *e = dmn_event_list_push(arena, &events); - e->kind = DMN_EventKind_UnloadModule; - e->process = dmn_w32_handle_from_entity(process); - e->module = dmn_w32_handle_from_entity(module); - e->string = dmn_w32_full_path_from_module(arena, module); - } - - // rjf: release entity storage - dmn_w32_entity_release(module); - }break; - - ////////////////////// - //- rjf: exception was hit - // - case EXCEPTION_DEBUG_EVENT: - { - //- NOTE(rjf): Notes on multithreaded breakpoint events - // (2021/11/1): - // - // When many threads are simultaneously running, multiple threads - // may hit a trap "at the same time". When this happens there will be - // multiple events in an internal queue that we cannot see. If there - // is another event in the queue we will not see it until we call - // ContinueDebugEvent again, in a subsequent call to demon_os_run. - // - // When we get a trap event, the instruction pointer stored - // in the event will have the address of the int 3 instruction that - // was hit. Our RIP register, however, will be one byte past that. - // So, to get the behavior we want, we need to set the RIP register - // back to the address of the int 3. - // - // To deal with the fact that we may get breakpoint events later that - // were actually from this run what we do is: - // - // #1. If we get a trap event, and it corresponds to a user submitted - // trap, then we treat it is a breakpoint event. - // #2. If we get a trap event, and it does NOT correspond to a user - // trap in this call: - // #A. If the actual unmodified instruction byte is NOT an int 3, - // then this is a queued event from a previous run that is no - // longer applicable and we skip it. - // #B. If the actual unmodified instruction is an int 3, then this - // becomes a trap event and we do not reset RIP. - - //- NOTE(rjf): Further notes on MULTITHREADED STEPPING ACCESS VIOLATION - // EVENTS! @rjf @rjf @rjf - // (2024/05/29): - // - // Just adding another comment here to document that the above long - // comment went completely unnoticed by me during a pass over demon, - // and I had removed the proper rollback stuff here without reading - // the above comment. So this comment just serves to make that - // original comment even heftier. - - //- NOTE(rjf): The exception record struct has a 32-bit version and a - // 64-bit version. We only currently handle the 64-bit version. - - //- rjf: unpack - DMN_W32_Entity *thread = dmn_w32_entity_from_kind_id(DMN_W32_EntityKind_Thread, evt.dwThreadId); - DMN_W32_Entity *process = thread->parent; - EXCEPTION_DEBUG_INFO *edi = &evt.u.Exception; - EXCEPTION_RECORD *exception = &edi->ExceptionRecord; - U64 instruction_pointer = (U64)exception->ExceptionAddress; - - //- rjf: determine if this is the first breakpoint in a process - // (breakpoint notifying us that the debugger is attached) - B32 first_bp = 0; - if(!process->proc.did_first_bp && exception->ExceptionCode == DMN_W32_EXCEPTION_BREAKPOINT) - { - process->proc.did_first_bp = 1; - first_bp = 1; - } - - //- rjf: determine if this exception is a trap - B32 is_trap = (!first_bp && - (exception->ExceptionCode == DMN_W32_EXCEPTION_BREAKPOINT || - exception->ExceptionCode == DMN_W32_EXCEPTION_STACK_BUFFER_OVERRUN)); - - //- rjf: check if this trap is a usage-code-specified trap or something else - B32 hit_user_trap = 0; - if(is_trap) - { - for(DMN_TrapChunkNode *n = ctrls->traps.first; n != 0; n = n->next) + + //- rjf: determine if this exception is a trap + B32 is_trap = (!first_bp && + (exception->ExceptionCode == DMN_W32_EXCEPTION_BREAKPOINT || + exception->ExceptionCode == DMN_W32_EXCEPTION_STACK_BUFFER_OVERRUN)); + + //- rjf: check if this trap is a usage-code-specified trap or something else + B32 hit_user_trap = 0; + if(is_trap) { - for(U64 idx = 0; idx < n->count; idx += 1) + for(DMN_TrapChunkNode *n = ctrls->traps.first; n != 0; n = n->next) { - if(dmn_handle_match(n->v[idx].process, dmn_w32_handle_from_entity(process)) && n->v[idx].vaddr == instruction_pointer) + for(U64 idx = 0; idx < n->count; idx += 1) { - hit_user_trap = 1; - break; + if(dmn_handle_match(n->v[idx].process, dmn_w32_handle_from_entity(process)) && n->v[idx].vaddr == instruction_pointer) + { + hit_user_trap = 1; + break; + } } } } - } - - //- rjf: check if trap is explicit in the actual code memory - B32 hit_explicit_trap = 0; - if(is_trap && !hit_user_trap) - { - U8 instruction_byte = 0; - if(dmn_w32_process_read_struct(process->handle, instruction_pointer, &instruction_byte)) - { - hit_explicit_trap = (instruction_byte == 0xCC || instruction_byte == 0xCD); - } - } - - //- rjf: determine whether to roll back instruction pointer - B32 should_do_rollback = (hit_user_trap || (is_trap && !hit_explicit_trap)); - - //- rjf: roll back thread's instruction pointer - U64 post_trap_rip = 0; - if(should_do_rollback) - { - Temp temp = temp_begin(scratch.arena); - U64 regs_block_size = regs_block_size_from_architecture(thread->arch); - void *regs_block = push_array(scratch.arena, U8, regs_block_size); - if(dmn_w32_thread_read_reg_block(thread->arch, thread->handle, regs_block)) - { - post_trap_rip = regs_rip_from_arch_block(thread->arch, regs_block); - regs_arch_block_write_rip(thread->arch, regs_block, instruction_pointer); - dmn_w32_thread_write_reg_block(thread->arch, thread->handle, regs_block); - } - temp_end(temp); - } - - //- rjf: not a user trap, not an explicit trap, then it's a trap that - // this thread hit previously but has since skipped - B32 hit_previous_trap = (is_trap && !hit_user_trap && !hit_explicit_trap); - - //- rjf: determine whether to skip this event - B32 skip_event = (hit_previous_trap); - - //- rjf: generate event - if(!skip_event) - { - // rjf: fill top-level info - DMN_Event *e = dmn_event_list_push(arena, &events); - e->kind = DMN_EventKind_Exception; - e->process = dmn_w32_handle_from_entity(process); - e->thread = dmn_w32_handle_from_entity(thread); - e->code = exception->ExceptionCode; - e->flags = exception->ExceptionFlags; - e->instruction_pointer = (U64)exception->ExceptionAddress; - //- rjf: fill according to exception code - switch(exception->ExceptionCode) + //- rjf: check if trap is explicit in the actual code memory + B32 hit_explicit_trap = 0; + if(is_trap && !hit_user_trap) { - //- rjf: fill breakpoint event info - case DMN_W32_EXCEPTION_BREAKPOINT: + U8 instruction_byte = 0; + if(dmn_w32_process_read_struct(process->handle, instruction_pointer, &instruction_byte)) { - DMN_EventKind report_event_kind = DMN_EventKind_Trap; - if(first_bp) + hit_explicit_trap = (instruction_byte == 0xCC || instruction_byte == 0xCD); + } + } + + //- rjf: determine whether to roll back instruction pointer + B32 should_do_rollback = (hit_user_trap || (is_trap && !hit_explicit_trap)); + + //- rjf: roll back thread's instruction pointer + U64 post_trap_rip = 0; + if(should_do_rollback) + { + Temp temp = temp_begin(scratch.arena); + U64 regs_block_size = regs_block_size_from_architecture(thread->arch); + void *regs_block = push_array(scratch.arena, U8, regs_block_size); + if(dmn_w32_thread_read_reg_block(thread->arch, thread->handle, regs_block)) + { + post_trap_rip = regs_rip_from_arch_block(thread->arch, regs_block); + regs_arch_block_write_rip(thread->arch, regs_block, instruction_pointer); + dmn_w32_thread_write_reg_block(thread->arch, thread->handle, regs_block); + } + temp_end(temp); + } + + //- rjf: not a user trap, not an explicit trap, then it's a trap that + // this thread hit previously but has since skipped + B32 hit_previous_trap = (is_trap && !hit_user_trap && !hit_explicit_trap); + + //- rjf: determine whether to skip this event + B32 skip_event = (hit_previous_trap); + + //- rjf: generate event + if(!skip_event) + { + // rjf: fill top-level info + DMN_Event *e = dmn_event_list_push(arena, &events); + e->kind = DMN_EventKind_Exception; + e->process = dmn_w32_handle_from_entity(process); + e->thread = dmn_w32_handle_from_entity(thread); + e->code = exception->ExceptionCode; + e->flags = exception->ExceptionFlags; + e->instruction_pointer = (U64)exception->ExceptionAddress; + + //- rjf: fill according to exception code + switch(exception->ExceptionCode) + { + //- rjf: fill breakpoint event info + case DMN_W32_EXCEPTION_BREAKPOINT: { - report_event_kind = DMN_EventKind_HandshakeComplete; - } - else if(hit_user_trap) + DMN_EventKind report_event_kind = DMN_EventKind_Trap; + if(first_bp) + { + report_event_kind = DMN_EventKind_HandshakeComplete; + } + else if(hit_user_trap) + { + report_event_kind = DMN_EventKind_Breakpoint; + } + e->kind = report_event_kind; + }break; + + //- rjf: fill stack buffer overrun event info + case DMN_W32_EXCEPTION_STACK_BUFFER_OVERRUN: { - report_event_kind = DMN_EventKind_Breakpoint; - } - e->kind = report_event_kind; - }break; - - //- rjf: fill stack buffer overrun event info - case DMN_W32_EXCEPTION_STACK_BUFFER_OVERRUN: - { - e->kind = DMN_EventKind_Trap; - }break; - - //- rjf: fill single-step event info - case DMN_W32_EXCEPTION_SINGLE_STEP: - { - e->kind = DMN_EventKind_SingleStep; - }break; - - //- rjf: fill throw info - case DMN_W32_EXCEPTION_THROW: - { - U64 exception_sp = 0; - U64 exception_ip = 0; - if(exception->NumberParameters >= 3) + e->kind = DMN_EventKind_Trap; + }break; + + //- rjf: fill single-step event info + case DMN_W32_EXCEPTION_SINGLE_STEP: { - exception_sp = (U64)exception->ExceptionInformation[1]; - exception_ip = (U64)exception->ExceptionInformation[2]; - } - e->stack_pointer = exception_sp; - e->exception_kind = DMN_ExceptionKind_CppThrow; - e->exception_repeated = (edi->dwFirstChance == 0); - dmn_w32_shared->exception_not_handled = (edi->dwFirstChance != 0); - }break; - - //- rjf: fill access violation info - case DMN_W32_EXCEPTION_ACCESS_VIOLATION: - case DMN_W32_EXCEPTION_IN_PAGE_ERROR: - { - U64 exception_address = 0; - DMN_ExceptionKind exception_kind = DMN_ExceptionKind_Null; + e->kind = DMN_EventKind_SingleStep; + }break; + + //- rjf: fill throw info + case DMN_W32_EXCEPTION_THROW: + { + U64 exception_sp = 0; + U64 exception_ip = 0; + if(exception->NumberParameters >= 3) + { + exception_sp = (U64)exception->ExceptionInformation[1]; + exception_ip = (U64)exception->ExceptionInformation[2]; + } + e->stack_pointer = exception_sp; + e->exception_kind = DMN_ExceptionKind_CppThrow; + e->exception_repeated = (edi->dwFirstChance == 0); + dmn_w32_shared->exception_not_handled = (edi->dwFirstChance != 0); + }break; + + //- rjf: fill access violation info + case DMN_W32_EXCEPTION_ACCESS_VIOLATION: + case DMN_W32_EXCEPTION_IN_PAGE_ERROR: + { + U64 exception_address = 0; + DMN_ExceptionKind exception_kind = DMN_ExceptionKind_Null; + if(exception->NumberParameters >= 2) + { + switch(exception->ExceptionInformation[0]) + { + case 0: exception_kind = DMN_ExceptionKind_MemoryRead; break; + case 1: exception_kind = DMN_ExceptionKind_MemoryWrite; break; + case 8: exception_kind = DMN_ExceptionKind_MemoryExecute; break; + } + exception_address = exception->ExceptionInformation[1]; + } + e->address = exception_address; + e->exception_kind = exception_kind; + e->exception_repeated = (edi->dwFirstChance == 0); + dmn_w32_shared->exception_not_handled = (edi->dwFirstChance != 0); + }break; + + //- rjf: fill set-thread-name info + case DMN_W32_EXCEPTION_SET_THREAD_NAME: if(exception->NumberParameters >= 2) { - switch(exception->ExceptionInformation[0]) + U64 thread_name_address = exception->ExceptionInformation[1]; + DMN_W32_Entity *process = dmn_w32_entity_from_kind_id(DMN_W32_EntityKind_Process, evt.dwProcessId); + String8List thread_name_strings = {0}; { - case 0: exception_kind = DMN_ExceptionKind_MemoryRead; break; - case 1: exception_kind = DMN_ExceptionKind_MemoryWrite; break; - case 8: exception_kind = DMN_ExceptionKind_MemoryExecute; break; - } - exception_address = exception->ExceptionInformation[1]; - } - e->address = exception_address; - e->exception_kind = exception_kind; - e->exception_repeated = (edi->dwFirstChance == 0); - dmn_w32_shared->exception_not_handled = (edi->dwFirstChance != 0); - }break; - - //- rjf: fill set-thread-name info - case DMN_W32_EXCEPTION_SET_THREAD_NAME: - if(exception->NumberParameters >= 2) - { - U64 thread_name_address = exception->ExceptionInformation[1]; - DMN_W32_Entity *process = dmn_w32_entity_from_kind_id(DMN_W32_EntityKind_Process, evt.dwProcessId); - String8List thread_name_strings = {0}; - { - U64 read_addr = thread_name_address; - U64 total_string_size = 0; - for(;total_string_size < KB(4);) - { - U8 *buffer = push_array(scratch.arena, U8, 256); - B32 good_read = dmn_w32_process_read(process->handle, r1u64(read_addr, read_addr+256), buffer); - if(good_read) + U64 read_addr = thread_name_address; + U64 total_string_size = 0; + for(;total_string_size < KB(4);) { - U64 size = 256; - for(U64 idx = 0; idx < 256; idx += 1) + U8 *buffer = push_array(scratch.arena, U8, 256); + B32 good_read = dmn_w32_process_read(process->handle, r1u64(read_addr, read_addr+256), buffer); + if(good_read) { - if(buffer[idx] == 0) + U64 size = 256; + for(U64 idx = 0; idx < 256; idx += 1) + { + if(buffer[idx] == 0) + { + size = idx; + break; + } + } + String8 string_part = str8(buffer, size); + str8_list_push(scratch.arena, &thread_name_strings, string_part); + total_string_size += size; + read_addr += size; + if(size < 256) { - size = idx; break; } } - String8 string_part = str8(buffer, size); - str8_list_push(scratch.arena, &thread_name_strings, string_part); - total_string_size += size; - read_addr += size; - if(size < 256) + else { break; } } - else - { - break; - } } - } - e->kind = DMN_EventKind_SetThreadName; - e->string = str8_list_join(arena, &thread_name_strings, 0); - if(exception->NumberParameters > 2) + e->kind = DMN_EventKind_SetThreadName; + e->string = str8_list_join(arena, &thread_name_strings, 0); + if(exception->NumberParameters > 2) + { + e->code = exception->ExceptionInformation[2]; + } + }break; + + //- rjf: unhandled exception case + default: { - e->code = exception->ExceptionInformation[2]; - } - }break; - - //- rjf: unhandled exception case - default: - { - e->exception_repeated = (edi->dwFirstChance == 0); - dmn_w32_shared->exception_not_handled = (edi->dwFirstChance != 0); - }break; + e->exception_repeated = (edi->dwFirstChance == 0); + dmn_w32_shared->exception_not_handled = (edi->dwFirstChance != 0); + }break; + } } - } - }break; - - ////////////////////// - //- rjf: output debug string was gathered - // - case OUTPUT_DEBUG_STRING_EVENT: - { - // rjf: unpack event - DMN_W32_Entity *process = dmn_w32_entity_from_kind_id(DMN_W32_EntityKind_Process, evt.dwProcessId); - DMN_W32_Entity *thread = dmn_w32_entity_from_kind_id(DMN_W32_EntityKind_Thread, evt.dwThreadId); - U64 string_address = (U64)evt.u.DebugString.lpDebugStringData; - U64 string_size = (U64)evt.u.DebugString.nDebugStringLength; + }break; - // rjf: read memory - U8 *buffer = push_array_no_zero(arena, U8, string_size + 1); - dmn_w32_process_read(process->handle, r1u64(string_address, string_address+string_size), buffer); - buffer[string_size] = 0; - - // rjf: generate event + ////////////////////// + //- rjf: output debug string was gathered + // + case OUTPUT_DEBUG_STRING_EVENT: { - DMN_Event *e = dmn_event_list_push(arena, &events); - e->kind = DMN_EventKind_DebugString; - e->process = dmn_w32_handle_from_entity(process); - e->thread = dmn_w32_handle_from_entity(thread); - e->string = str8(buffer, string_size); - if(string_size != 0 && buffer[string_size-1] == 0) + // rjf: unpack event + DMN_W32_Entity *process = dmn_w32_entity_from_kind_id(DMN_W32_EntityKind_Process, evt.dwProcessId); + DMN_W32_Entity *thread = dmn_w32_entity_from_kind_id(DMN_W32_EntityKind_Thread, evt.dwThreadId); + U64 string_address = (U64)evt.u.DebugString.lpDebugStringData; + U64 string_size = (U64)evt.u.DebugString.nDebugStringLength; + + // rjf: read memory + U8 *buffer = push_array_no_zero(scratch.arena, U8, string_size + 1); + dmn_w32_process_read(process->handle, r1u64(string_address, string_address+string_size), buffer); + buffer[string_size] = 0; + + // rjf: extract into string + String8 debug_string = str8(buffer, string_size); + if(debug_string.size != 0 && buffer[string_size-1] == 0) { - e->string.size -= 1; + debug_string.size -= 1; } - } - }break; - - ////////////////////// - //- rjf: a "rip event" - a "system debugging error". - // - case RIP_EVENT: + + // rjf: push into debug strings + str8_list_push(scratch.arena, &debug_strings, debug_string); + keep_going = 1; + + // rjf: generate event, given sufficient amount of text + if(debug_strings.total_size >= KB(4)) + { + String8 debug_strings_joined = str8_list_join(arena, &debug_strings, 0); + MemoryZeroStruct(&debug_strings); + DMN_Event *e = dmn_event_list_push(arena, &events); + e->kind = DMN_EventKind_DebugString; + e->process = dmn_w32_handle_from_entity(process); + e->thread = dmn_w32_handle_from_entity(thread); + e->string = debug_strings_joined; + keep_going = 0; + } + }break; + + ////////////////////// + //- rjf: a "rip event" - a "system debugging error". + // + case RIP_EVENT: + { + DMN_W32_Entity *process = dmn_w32_entity_from_kind_id(DMN_W32_EntityKind_Process, evt.dwProcessId); + DMN_W32_Entity *thread = dmn_w32_entity_from_kind_id(DMN_W32_EntityKind_Thread, evt.dwThreadId); + DMN_Event *e = dmn_event_list_push(arena, &events); + e->kind = DMN_EventKind_Exception; + e->process = dmn_w32_handle_from_entity(process); + e->thread = dmn_w32_handle_from_entity(thread); + }break; + + ////////////////////// + //- rjf: default case - some kind of debugging event that we don't currently consume. + // + default: + { + NoOp; + }break; + } + } + } + + //////////////////////// + //- rjf: send out event for any remaining debug strings + // + if(debug_strings.total_size != 0) + { + String8 debug_strings_joined = str8_list_join(arena, &debug_strings, 0); + MemoryZeroStruct(&debug_strings); + DMN_Event *e = dmn_event_list_push(arena, &events); + e->kind = DMN_EventKind_DebugString; + e->string = debug_strings_joined; + } + + //////////////////////// + //- rjf: suspend threads which ran + // + ProfScope("suspend threads which ran") + { + for(DMN_W32_EntityNode *n = first_run_thread; n != 0; n = n->next) + { + DMN_W32_Entity *thread = n->v; + DWORD suspend_result = SuspendThread(thread->handle); + switch(suspend_result) { - DMN_W32_Entity *process = dmn_w32_entity_from_kind_id(DMN_W32_EntityKind_Process, evt.dwProcessId); - DMN_W32_Entity *thread = dmn_w32_entity_from_kind_id(DMN_W32_EntityKind_Thread, evt.dwThreadId); - DMN_Event *e = dmn_event_list_push(arena, &events); - e->kind = DMN_EventKind_Exception; - e->process = dmn_w32_handle_from_entity(process); - e->thread = dmn_w32_handle_from_entity(thread); - }break; - - ////////////////////// - //- rjf: default case - some kind of debugging event that we don't currently consume. - // - default: - { - NoOp; - }break; + case 0xffffffffu: + { + // TODO(rjf): error - unknown cause. need to do do GetLastError, FormatMessage + // + // NOTE(rjf): this can happen when the event is EXIT_THREAD_DEBUG_EVENT + // or EXIT_PROCESS_DEBUG_EVENT. after such an event, SuspendThread + // gives error code 5 (access denied). this has no adverse effects, but + // if we want to start reporting errors we should take care to avoid + // calling SuspendThread in that case. + }break; + default: + { + DWORD desired_counter = 1; + DWORD current_counter = suspend_result + 1; + if(current_counter != desired_counter) + { + // NOTE(rjf): Warning. We've suspended to something higher than 1. + // In this case, it means the user probably created the thread in + // a suspended state, or they called SuspendThread. + } + }break; + } } } //- rjf: gather new thread-names - if(dmn_w32_GetThreadDescription != 0) + ProfScope("gather new thread names") if(dmn_w32_GetThreadDescription != 0) { for(DMN_W32_Entity *process = dmn_w32_shared->entities_base->first; process != &dmn_w32_entity_nil; @@ -2252,6 +2293,7 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) ////////////////////////// //- rjf: restore original memory at trap locations // + ProfScope("restore original memory at trap locations") { U64 trap_idx = 0; for(DMN_TrapChunkNode *n = ctrls->traps.first; n != 0; n = n->next) @@ -2271,7 +2313,7 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) ////////////////////////// //- rjf: unset single step bit // - if(!dmn_handle_match(ctrls->single_step_thread, dmn_handle_zero())) + if(!dmn_handle_match(ctrls->single_step_thread, dmn_handle_zero())) ProfScope("unset single step bit") { DMN_W32_Entity *thread = dmn_w32_entity_from_handle(ctrls->single_step_thread); Architecture arch = thread->arch; From 6d4b4b15261a5de17a24fed335f6698a17991c4c Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 30 May 2024 07:10:21 -0700 Subject: [PATCH 39/39] time-based exit path for demon win32 event consumption loop, to not overly-aggressively-buffer things --- src/demon/win32/demon_core_win32.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/demon/win32/demon_core_win32.c b/src/demon/win32/demon_core_win32.c index 2742830f..c7f0ec9e 100644 --- a/src/demon/win32/demon_core_win32.c +++ b/src/demon/win32/demon_core_win32.c @@ -1552,6 +1552,7 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) ////////////////////////// //- rjf: loop, consume win32 debug events until we produce the relevant demon events // + U64 begin_time = os_now_microseconds(); String8List debug_strings = {0}; for(B32 keep_going = 1; keep_going;) { @@ -2198,6 +2199,14 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) }break; } } + + //////////////////////// + //- rjf: exit loop after a little while, so we keep pumping e.g. debug strings + // + if(os_now_microseconds() >= begin_time+100000) + { + keep_going = 0; + } } ////////////////////////