improve flow around multi-target debugging: prefer one-target-only in default path; only enable command line specified target if present; explicit commands for enabling/disabling targets, as well as mutually-exclusive selection of targets; make default clicking path in UI go through mutually exclusive selection, whereas ctrl+clicks will do multi-target selection

This commit is contained in:
Ryan Fleury
2024-01-25 11:49:05 -08:00
parent dd38822a4c
commit c8c5da4f4a
6 changed files with 101 additions and 39 deletions
+73 -36
View File
@@ -7571,46 +7571,63 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt)
//- rjf: apply targets
DF_CfgVal *targets = df_cfg_val_from_string(table, str8_lit("target"));
for(DF_CfgNode *target = targets->first;
target != &df_g_nil_cfg_node;
target = target->next)
{
if(target->source == src)
B32 cmd_line_target_present = 0;
{
DF_CfgNode *label_cfg = df_cfg_node_child_from_string(target, str8_lit("label"), StringMatchFlag_CaseInsensitive);
DF_CfgNode *exe_cfg = df_cfg_node_child_from_string(target, str8_lit("exe"), StringMatchFlag_CaseInsensitive);
if(exe_cfg == &df_g_nil_cfg_node)
DF_EntityList existing_target_entities = df_query_cached_entity_list_with_kind(DF_EntityKind_Target);
for(DF_EntityNode *n = existing_target_entities.first; n != 0; n = n->next)
{
exe_cfg = df_cfg_node_child_from_string(target, str8_lit("name"), StringMatchFlag_CaseInsensitive);
DF_Entity *target = n->entity;
if(target->cfg_src == DF_CfgSrc_CommandLine && target->b32)
{
cmd_line_target_present = 1;
}
}
DF_CfgNode *args_cfg = df_cfg_node_child_from_string(target, str8_lit("arguments"), StringMatchFlag_CaseInsensitive);
DF_CfgNode *wdir_cfg = df_cfg_node_child_from_string(target, str8_lit("working_directory"), StringMatchFlag_CaseInsensitive);
DF_CfgNode *entry_cfg = df_cfg_node_child_from_string(target, str8_lit("entry_point"), StringMatchFlag_CaseInsensitive);
DF_CfgNode *active_cfg = df_cfg_node_child_from_string(target, str8_lit("active"), StringMatchFlag_CaseInsensitive);
Vec4F32 hsva = df_hsva_from_cfg_node(target);
U64 is_active_u64 = 0;
try_u64_from_str8_c_rules(active_cfg->first->string, &is_active_u64);
DF_Entity *target__ent = df_entity_alloc(0, df_entity_root(), DF_EntityKind_Target);
DF_Entity *exe__ent = df_entity_alloc(0, target__ent, DF_EntityKind_Executable);
DF_Entity *args__ent = df_entity_alloc(0, target__ent, DF_EntityKind_Arguments);
DF_Entity *path__ent = df_entity_alloc(0, target__ent, DF_EntityKind_ExecutionPath);
DF_Entity *entry__ent = df_entity_alloc(0, target__ent, DF_EntityKind_EntryPointName);
String8 saved_label = label_cfg->first->string;
String8 saved_exe = exe_cfg->first->string;
String8 saved_exe_absolute = path_absolute_dst_from_relative_dst_src(scratch.arena, saved_exe, cfg_folder);
String8 saved_wdir = wdir_cfg->first->string;
String8 saved_wdir_absolute = path_absolute_dst_from_relative_dst_src(scratch.arena, saved_wdir, cfg_folder);
String8 saved_entry_point = entry_cfg->first->string;
df_entity_equip_b32(target__ent, active_cfg != &df_g_nil_cfg_node ? !!is_active_u64 : 1);
df_entity_equip_name(0, target__ent, saved_label);
df_entity_equip_name(0, exe__ent, saved_exe_absolute);
df_entity_equip_name(0, args__ent, args_cfg->first->string);
df_entity_equip_name(0, path__ent, saved_wdir_absolute);
df_entity_equip_name(0, entry__ent, saved_entry_point);
df_entity_equip_cfg_src(target__ent, src);
if(!memory_is_zero(&hsva, sizeof(hsva)))
}
for(DF_CfgNode *target = targets->first;
target != &df_g_nil_cfg_node;
target = target->next)
{
if(target->source == src)
{
df_entity_equip_color_hsva(target__ent, hsva);
DF_CfgNode *label_cfg = df_cfg_node_child_from_string(target, str8_lit("label"), StringMatchFlag_CaseInsensitive);
DF_CfgNode *exe_cfg = df_cfg_node_child_from_string(target, str8_lit("exe"), StringMatchFlag_CaseInsensitive);
if(exe_cfg == &df_g_nil_cfg_node)
{
exe_cfg = df_cfg_node_child_from_string(target, str8_lit("name"), StringMatchFlag_CaseInsensitive);
}
DF_CfgNode *args_cfg = df_cfg_node_child_from_string(target, str8_lit("arguments"), StringMatchFlag_CaseInsensitive);
DF_CfgNode *wdir_cfg = df_cfg_node_child_from_string(target, str8_lit("working_directory"), StringMatchFlag_CaseInsensitive);
DF_CfgNode *entry_cfg = df_cfg_node_child_from_string(target, str8_lit("entry_point"), StringMatchFlag_CaseInsensitive);
DF_CfgNode *active_cfg = df_cfg_node_child_from_string(target, str8_lit("active"), StringMatchFlag_CaseInsensitive);
Vec4F32 hsva = df_hsva_from_cfg_node(target);
U64 is_active_u64 = 0;
if(!cmd_line_target_present)
{
try_u64_from_str8_c_rules(active_cfg->first->string, &is_active_u64);
}
DF_Entity *target__ent = df_entity_alloc(0, df_entity_root(), DF_EntityKind_Target);
DF_Entity *exe__ent = df_entity_alloc(0, target__ent, DF_EntityKind_Executable);
DF_Entity *args__ent = df_entity_alloc(0, target__ent, DF_EntityKind_Arguments);
DF_Entity *path__ent = df_entity_alloc(0, target__ent, DF_EntityKind_ExecutionPath);
DF_Entity *entry__ent = df_entity_alloc(0, target__ent, DF_EntityKind_EntryPointName);
String8 saved_label = label_cfg->first->string;
String8 saved_exe = exe_cfg->first->string;
String8 saved_exe_absolute = path_absolute_dst_from_relative_dst_src(scratch.arena, saved_exe, cfg_folder);
String8 saved_wdir = wdir_cfg->first->string;
String8 saved_wdir_absolute = path_absolute_dst_from_relative_dst_src(scratch.arena, saved_wdir, cfg_folder);
String8 saved_entry_point = entry_cfg->first->string;
df_entity_equip_b32(target__ent, active_cfg != &df_g_nil_cfg_node ? !!is_active_u64 : 1);
df_entity_equip_name(0, target__ent, saved_label);
df_entity_equip_name(0, exe__ent, saved_exe_absolute);
df_entity_equip_name(0, args__ent, args_cfg->first->string);
df_entity_equip_name(0, path__ent, saved_wdir_absolute);
df_entity_equip_name(0, entry__ent, saved_entry_point);
df_entity_equip_cfg_src(target__ent, src);
if(!memory_is_zero(&hsva, sizeof(hsva)))
{
df_entity_equip_color_hsva(target__ent, hsva);
}
}
}
}
@@ -7971,6 +7988,7 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt)
//- rjf: general entity operations
case DF_CoreCmdKind_EnableEntity:
case DF_CoreCmdKind_EnableBreakpoint:
case DF_CoreCmdKind_EnableTarget:
{
DF_Entity *entity = df_entity_from_handle(params.entity);
df_state_delta_history_push_batch(df_state->hist, &entity->generation);
@@ -7979,6 +7997,7 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt)
}break;
case DF_CoreCmdKind_DisableEntity:
case DF_CoreCmdKind_DisableBreakpoint:
case DF_CoreCmdKind_DisableTarget:
{
DF_Entity *entity = df_entity_from_handle(params.entity);
df_state_delta_history_push_batch(df_state->hist, &entity->generation);
@@ -8196,7 +8215,6 @@ 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_b32(entity, 1);
df_entity_equip_cfg_src(entity, DF_CfgSrc_Profile);
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);
@@ -8211,6 +8229,25 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt)
p.entity = df_handle_from_entity(entity);
df_cmd_params_mark_slot(&p, DF_CmdParamSlot_Entity);
df_cmd_list_push(arena, cmds, &p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_EditTarget));
df_cmd_list_push(arena, cmds, &p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_SelectTarget));
}break;
case DF_CoreCmdKind_SelectTarget:
{
DF_Entity *entity = df_entity_from_handle(params.entity);
if(entity->kind == DF_EntityKind_Target)
{
DF_EntityList all_targets = df_query_cached_entity_list_with_kind(DF_EntityKind_Target);
B32 is_selected = entity->b32;
for(DF_EntityNode *n = all_targets.first; n != 0; n = n->next)
{
DF_Entity *target = n->entity;
df_entity_equip_b32(target, 0);
}
if(!is_selected)
{
df_entity_equip_b32(entity, 1);
}
}
}break;
//- rjf: ended processes
+3
View File
@@ -337,6 +337,9 @@ DF_CoreCmdTable:// | | |
{AddTarget 0 FilePath Nil 1 0 0 0 0 1 Target "add_target" "Add Target" "Adds a new target." "application,executable,debug" }
{RemoveTarget 0 Entity Target 0 0 0 0 0 1 Trash "remove_target" "Remove Target" "Removes an existing target." "delete,remove,target" }
{EditTarget 0 Entity Target 0 0 0 0 0 1 Pencil "edit_target" "Edit Target" "Edits an existing target." "" }
{SelectTarget 0 Entity Target 0 0 0 0 0 1 Target "select_target" "Select Target" "Selects a target." "" }
{EnableTarget 0 Entity Target 0 0 0 0 0 1 CheckFilled "enable_target" "Enable Target" "Enables a target, in addition to all targets currently enabled." "" }
{DisableTarget 0 Entity Target 0 0 0 0 0 1 CheckHollow "disable_target" "Disable Target" "Disables a target." "" }
//- rjf: ended processes
{RetryEndedProcess 1 Entity Process 0 0 0 0 0 0 Null "retry_ended_process" "Retry Ended Process" "Launches a new process with the same options as the passed ended process." "" }
+3
View File
@@ -170,6 +170,9 @@ DF_CmdSpecInfo df_g_core_cmd_kind_spec_info_table[] =
{ str8_lit_comp("add_target"), str8_lit_comp("Adds a new target."), str8_lit_comp("application,executable,debug"), str8_lit_comp("Add Target"), (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_Target},
{ str8_lit_comp("remove_target"), str8_lit_comp("Removes an existing target."), str8_lit_comp("delete,remove,target"), str8_lit_comp("Remove Target"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Entity, DF_EntityKind_Target, (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_Trash},
{ str8_lit_comp("edit_target"), str8_lit_comp("Edits an existing target."), str8_lit_comp(""), str8_lit_comp("Edit Target"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Entity, DF_EntityKind_Target, (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_Pencil},
{ str8_lit_comp("select_target"), str8_lit_comp("Selects a target."), str8_lit_comp(""), str8_lit_comp("Select Target"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Entity, DF_EntityKind_Target, (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_Target},
{ str8_lit_comp("enable_target"), str8_lit_comp("Enables a target, in addition to all targets currently enabled."), str8_lit_comp(""), str8_lit_comp("Enable Target"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Entity, DF_EntityKind_Target, (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_CheckFilled},
{ str8_lit_comp("disable_target"), str8_lit_comp("Disables a target."), str8_lit_comp(""), str8_lit_comp("Disable Target"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Entity, DF_EntityKind_Target, (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_CheckHollow},
{ str8_lit_comp("retry_ended_process"), str8_lit_comp("Launches a new process with the same options as the passed ended process."), str8_lit_comp(""), str8_lit_comp("Retry Ended Process"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Entity, DF_EntityKind_Process, (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("attach"), str8_lit_comp("Attaches to a process that is already running on the local machine."), str8_lit_comp(""), str8_lit_comp("Attach"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_ID, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*1)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_Null},
{ str8_lit_comp("register_as_jit_debugger"), str8_lit_comp("Registers the RAD debugger as the just-in-time (JIT) debugger used by the operating system."), str8_lit_comp(""), str8_lit_comp("Register As Just-In-Time (JIT) Debugger"), (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_Null},
+3
View File
@@ -221,6 +221,9 @@ DF_CoreCmdKind_ToggleWatchPinAtCursor,
DF_CoreCmdKind_AddTarget,
DF_CoreCmdKind_RemoveTarget,
DF_CoreCmdKind_EditTarget,
DF_CoreCmdKind_SelectTarget,
DF_CoreCmdKind_EnableTarget,
DF_CoreCmdKind_DisableTarget,
DF_CoreCmdKind_RetryEndedProcess,
DF_CoreCmdKind_Attach,
DF_CoreCmdKind_RegisterAsJITDebugger,
+6 -1
View File
@@ -8692,12 +8692,17 @@ df_entity_desc_button(DF_Window *ws, DF_Entity *entity)
ui_set_next_background_color(special_color);
}
}
ui_set_next_hover_cursor(OS_Cursor_HandPoint);
if(entity->cfg_src == DF_CfgSrc_CommandLine)
{
Vec4F32 bg_color = mix_4f32(ui_top_background_color(), df_rgba_from_theme_color(DF_ThemeColor_Highlight0), 0.25f);
ui_set_next_background_color(bg_color);
}
else if(entity->kind == DF_EntityKind_Target && entity->b32 != 0)
{
Vec4F32 bg_color = mix_4f32(ui_top_background_color(), df_rgba_from_theme_color(DF_ThemeColor_Highlight1), 0.25f);
ui_set_next_background_color(bg_color);
}
ui_set_next_hover_cursor(OS_Cursor_HandPoint);
UI_Key key = ui_key_from_stringf(ui_top_parent()->key, "entity_ref_button_%p", entity);
UI_Box *box = ui_build_box_from_key(UI_BoxFlag_Clickable|
UI_BoxFlag_DrawBorder|
+13 -2
View File
@@ -3216,9 +3216,20 @@ DF_VIEW_UI_FUNCTION_DEF(Targets)
// rjf: enabled
UI_PrefWidth(ui_em(2.25f, 1))
UI_FocusHot((row_selected && cursor.x == 0) ? UI_FocusKind_On : UI_FocusKind_Off)
if(df_icon_buttonf(target->b32 ? DF_IconKind_CheckFilled : DF_IconKind_CheckHollow, "###ebl_%p", target).clicked)
{
df_entity_equip_b32(target, !target->b32);
UI_Signal sig = df_icon_buttonf(target->b32 ? DF_IconKind_CheckFilled : DF_IconKind_CheckHollow, "###ebl_%p", target);
if(sig.clicked && 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(sig.clicked && sig.event_flags == OS_EventFlag_Ctrl)
{
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(target->b32 ? DF_CoreCmdKind_DisableTarget : DF_CoreCmdKind_EnableTarget));
}
}
// rjf: target name