diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index fcefa45d..6b0da6b3 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -729,8 +729,9 @@ ctrl_entity_alloc(CTRL_EntityStore *store, CTRL_Entity *parent, CTRL_EntityKind } } - // rjf: bump counter + // rjf: bump counters store->entity_kind_counts[kind] += 1; + store->entity_kind_alloc_gens[kind] += 1; } return entity; } diff --git a/src/dbg_engine/dbg_engine_core.c b/src/dbg_engine/dbg_engine_core.c index 49dfc66a..615d9ec5 100644 --- a/src/dbg_engine/dbg_engine_core.c +++ b/src/dbg_engine/dbg_engine_core.c @@ -1287,203 +1287,6 @@ d_entity_equip_namef(D_Entity *entity, char *fmt, ...) scratch_end(scratch); } -//- rjf: params tree equipment - -internal void -d_entity_equip_params(D_Entity *entity, MD_Node *params) -{ - if(entity->params_arena == 0) - { - entity->params_arena = arena_alloc(); - } - arena_clear(entity->params_arena); - entity->params_root = md_tree_copy(entity->params_arena, params); -} - -internal void -d_entity_equip_param(D_Entity *entity, String8 key, String8 value) -{ - Temp scratch = scratch_begin(0, 0); - - //- rjf: try to incrementally add to existing tree - B32 incrementally_added = 0; - if(!md_node_is_nil(entity->params_root)) - { - MD_Node *params = entity->params_root; - MD_Node *key_node = md_child_from_string(params, key, 0); - if(md_node_is_nil(key_node)) - { - String8 key_copy = push_str8_copy(entity->params_arena, key); - key_node = md_push_node(entity->params_arena, MD_NodeKind_Main, MD_NodeFlag_Identifier, key_copy, key_copy, 0); - md_node_push_child(params, key_node); - String8 value_copy = push_str8_copy(entity->params_arena, value); - MD_TokenizeResult value_tokenize = md_tokenize_from_text(scratch.arena, value_copy); - MD_ParseResult value_parse = md_parse_from_text_tokens(scratch.arena, str8_zero(), value_copy, value_tokenize.tokens); - for(MD_EachNode(child, value_parse.root->first)) - { - child->parent = key_node; - } - key_node->first = value_parse.root->first; - key_node->last = value_parse.root->last; - incrementally_added = 1; - } - } - - //- rjf: not incrementally added -> fully rewrite parameter tree - if(!incrementally_added) - { - MD_Node *params = md_tree_copy(scratch.arena, entity->params_root); - MD_Node *key_node = md_child_from_string(params, key, 0); - if(md_node_is_nil(key_node)) - { - key_node = md_push_node(scratch.arena, MD_NodeKind_Main, MD_NodeFlag_Identifier, key, key, 0); - md_node_push_child(params, key_node); - } - MD_TokenizeResult value_tokenize = md_tokenize_from_text(scratch.arena, value); - MD_ParseResult value_parse = md_parse_from_text_tokens(scratch.arena, str8_zero(), value, value_tokenize.tokens); - for(MD_EachNode(child, value_parse.root->first)) - { - child->parent = key_node; - } - key_node->first = value_parse.root->first; - key_node->last = value_parse.root->last; - d_entity_equip_params(entity, params); - } - - scratch_end(scratch); -} - -//- rjf: opening folders/files & maintaining the entity model of the filesystem - -internal D_Entity * -d_entity_from_path(String8 path, D_EntityFromPathFlags flags) -{ - Temp scratch = scratch_begin(0, 0); - PathStyle path_style = PathStyle_Relative; - String8List path_parts = path_normalized_list_from_string(scratch.arena, path, &path_style); - StringMatchFlags path_match_flags = path_match_flags_from_os(operating_system_from_context()); - - //- rjf: pass 1: open parts, ignore overrides - D_Entity *file_no_override = &d_nil_entity; - { - D_Entity *parent = d_entity_root(); - for(String8Node *path_part_n = path_parts.first; - path_part_n != 0; - path_part_n = path_part_n->next) - { - // rjf: find next child - D_Entity *next_parent = &d_nil_entity; - for(D_Entity *child = parent->first; !d_entity_is_nil(child); child = child->next) - { - B32 name_matches = str8_match(child->string, path_part_n->string, path_match_flags); - if(name_matches && child->kind == D_EntityKind_File) - { - next_parent = child; - break; - } - } - - // rjf: no next -> allocate one - if(d_entity_is_nil(next_parent)) - { - if(flags & D_EntityFromPathFlag_OpenAsNeeded) - { - String8 parent_path = d_full_path_from_entity(scratch.arena, parent); - String8 path = push_str8f(scratch.arena, "%S%s%S", parent_path, parent_path.size != 0 ? "/" : "", path_part_n->string); - FileProperties file_properties = os_properties_from_file_path(path); - if(file_properties.created != 0 || flags & D_EntityFromPathFlag_OpenMissing) - { - next_parent = d_entity_alloc(parent, D_EntityKind_File); - d_entity_equip_name(next_parent, path_part_n->string); - next_parent->timestamp = file_properties.modified; - next_parent->flags |= D_EntityFlag_IsFolder * !!(file_properties.flags & FilePropertyFlag_IsFolder); - next_parent->flags |= D_EntityFlag_IsMissing * !!(file_properties.created == 0); - if(path_part_n->next != 0) - { - next_parent->flags |= D_EntityFlag_IsFolder; - } - } - } - else - { - parent = &d_nil_entity; - break; - } - } - - // rjf: next parent -> follow it - parent = next_parent; - } - file_no_override = (parent != d_entity_root() ? parent : &d_nil_entity); - } - - //- rjf: pass 2: follow overrides - D_Entity *file_overrides_applied = &d_nil_entity; - if(flags & D_EntityFromPathFlag_AllowOverrides) - { - D_Entity *parent = d_entity_root(); - for(String8Node *path_part_n = path_parts.first; - path_part_n != 0; - path_part_n = path_part_n->next) - { - // rjf: find next child - D_Entity *next_parent = &d_nil_entity; - for(D_Entity *child = parent->first; !d_entity_is_nil(child); child = child->next) - { - B32 name_matches = str8_match(child->string, path_part_n->string, path_match_flags); - if(name_matches && child->kind == D_EntityKind_File) - { - next_parent = child; - } - } - - // rjf: no next -> allocate one - if(d_entity_is_nil(next_parent)) - { - if(flags & D_EntityFromPathFlag_OpenAsNeeded) - { - String8 parent_path = d_full_path_from_entity(scratch.arena, parent); - String8 path = push_str8f(scratch.arena, "%S%s%S", parent_path, parent_path.size != 0 ? "/" : "", path_part_n->string); - FileProperties file_properties = os_properties_from_file_path(path); - if(file_properties.created != 0 || flags & D_EntityFromPathFlag_OpenMissing) - { - next_parent = d_entity_alloc(parent, D_EntityKind_File); - d_entity_equip_name(next_parent, path_part_n->string); - next_parent->timestamp = file_properties.modified; - next_parent->flags |= D_EntityFlag_IsFolder * !!(file_properties.flags & FilePropertyFlag_IsFolder); - next_parent->flags |= D_EntityFlag_IsMissing * !!(file_properties.created == 0); - if(path_part_n->next != 0) - { - next_parent->flags |= D_EntityFlag_IsFolder; - } - } - } - else - { - parent = &d_nil_entity; - break; - } - } - - // rjf: next parent -> follow it - parent = next_parent; - } - file_overrides_applied = (parent != d_entity_root() ? parent : &d_nil_entity);; - } - - //- rjf: pick & return result - D_Entity *result = (flags & D_EntityFromPathFlag_AllowOverrides) ? file_overrides_applied : file_no_override; - if(flags & D_EntityFromPathFlag_AllowOverrides && - result == file_overrides_applied && - result->flags & D_EntityFlag_IsMissing) - { - result = file_no_override; - } - - scratch_end(scratch); - return result; -} - //- rjf: file path map override lookups internal String8List diff --git a/src/dbg_engine/dbg_engine_core.h b/src/dbg_engine/dbg_engine_core.h index af763b07..b386f614 100644 --- a/src/dbg_engine/dbg_engine_core.h +++ b/src/dbg_engine/dbg_engine_core.h @@ -873,13 +873,6 @@ internal void d_entity_equip_vaddr(D_Entity *entity, U64 vaddr); internal void d_entity_equip_name(D_Entity *entity, String8 name); internal void d_entity_equip_namef(D_Entity *entity, char *fmt, ...); -//- rjf: params tree equipment -internal void d_entity_equip_params(D_Entity *entity, MD_Node *params); -internal void d_entity_equip_param(D_Entity *entity, String8 key, String8 value); - -//- rjf: opening folders/files & maintaining the entity model of the filesystem -internal D_Entity *d_entity_from_path(String8 path, D_EntityFromPathFlags flags); - //- rjf: file path map override lookups internal String8List d_possible_overrides_from_file_path(Arena *arena, String8 file_path); diff --git a/src/dbg_frontend/dbg_frontend_core.c b/src/dbg_frontend/dbg_frontend_core.c index ea5f97c2..962a71af 100644 --- a/src/dbg_frontend/dbg_frontend_core.c +++ b/src/dbg_frontend/dbg_frontend_core.c @@ -8262,17 +8262,31 @@ df_frame(void) //- rjf: exiting case DF_CmdKind_Exit: { - // rjf: save + // rjf: if control processes are live, but this is not force-confirmed, then + // get confirmation from user + CTRL_EntityList processes = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Process); + UI_Key key = ui_key_from_string(ui_key_zero(), str8_lit("lossy_exit_confirmation")); + if(processes.count != 0 && !params->force_confirm && !ui_key_match(df_state->confirm_key, key)) + { + df_state->confirm_key = key; + df_state->confirm_active = 1; + arena_clear(df_state->confirm_arena); + MemoryZeroStruct(&df_state->confirm_cmds); + df_state->confirm_title = push_str8f(df_state->confirm_arena, "Are you sure you want to exit?"); + df_state->confirm_desc = push_str8f(df_state->confirm_arena, "The debugger is still attached to %slive process%s.", + processes.count == 1 ? "a " : "", + processes.count == 1 ? "" : "es"); + D_CmdParams p = *params; + p.force_confirm = 1; + d_cmd_list_push(df_state->confirm_arena, &df_state->confirm_cmds, &p, df_cmd_spec_from_kind(DF_CmdKind_Exit)); + } + + // rjf: otherwise, actually exit + else { df_cmd(DF_CmdKind_WriteUserData); df_cmd(DF_CmdKind_WriteProjectData); - df_state->last_window_queued_save = 1; - } - - // rjf: close all windows - for(DF_Window *window = df_state->first_window; window != 0; window = window->next) - { - df_cmd(DF_CmdKind_CloseWindow, .window = df_handle_from_window(window)); + df_state->quit = 1; } }break; @@ -8308,40 +8322,13 @@ df_frame(void) DF_Window *ws = df_window_from_handle(params->window); if(ws != 0) { - D_EntityList running_processes = d_query_cached_entity_list_with_kind(D_EntityKind_Process); - - // NOTE(rjf): if this is the last window, and targets are running, but - // this command is not force-confirmed, then we should query the user - // to ensure they want to close the debugger before exiting - UI_Key key = ui_key_from_string(ui_key_zero(), str8_lit("lossy_exit_confirmation")); - if(!ui_key_match(key, df_state->confirm_key) && running_processes.count != 0 && ws == df_state->first_window && ws == df_state->last_window && !params->force_confirm) + // rjf: is this the last window? -> exit + if(df_state->first_window == df_state->last_window && df_state->first_window == ws) { - df_state->confirm_key = key; - df_state->confirm_active = 1; - arena_clear(df_state->confirm_arena); - MemoryZeroStruct(&df_state->confirm_cmds); - df_state->confirm_title = push_str8f(df_state->confirm_arena, "Are you sure you want to exit?"); - df_state->confirm_desc = push_str8f(df_state->confirm_arena, "The debugger is still attached to %slive process%s.", - running_processes.count == 1 ? "a " : "", - running_processes.count == 1 ? "" : "es"); - D_CmdParams p = df_cmd_params_from_window(ws); - p.force_confirm = 1; - d_cmd_list_push(df_state->confirm_arena, &df_state->confirm_cmds, &p, df_cmd_spec_from_kind(DF_CmdKind_CloseWindow)); + df_cmd(DF_CmdKind_Exit); } - // NOTE(rjf): if this is the last window, and it is being closed, then - // we need to auto-save, and provide one last chance to process saving - // commands. after doing so, we can retry. - else if(ws == df_state->first_window && ws == df_state->last_window && df_state->last_window_queued_save == 0) - { - df_state->last_window_queued_save = 1; - df_cmd(DF_CmdKind_WriteUserData); - df_cmd(DF_CmdKind_WriteProjectData); - df_cmd(DF_CmdKind_CloseWindow, .force_confirm = 1, .window = df_handle_from_window(ws)); - } - - // NOTE(rjf): if this is the last window and we've queued the final autosave, - // or if it's not the last window, then we're free to release everything. + // rjf: not the last window? -> just release this window else { // NOTE(rjf): we need to explicitly release all panel views, because views @@ -10637,6 +10624,7 @@ df_frame(void) } // rjf: try to resolve name as a file +#if 0 // TODO(rjf): @msgs D_Entity *file = &d_nil_entity; if(name_resolved == 0) { @@ -10725,6 +10713,7 @@ df_frame(void) } name_resolved = !d_entity_is_nil(file) && !(file->flags & D_EntityFlag_IsMissing) && !(file->flags & D_EntityFlag_IsFolder); } +#endif // rjf: process resolved info if(name_resolved == 0) @@ -10759,6 +10748,7 @@ df_frame(void) } // rjf: name resolved to a file +#if 0 // TODO(rjf): @msgs if(name_resolved != 0 && !d_entity_is_nil(file)) { String8 path = d_full_path_from_entity(scratch.arena, file); @@ -10767,6 +10757,7 @@ df_frame(void) p.text_point = txt_pt(1, 1); df_push_cmd(df_cmd_spec_from_kind(DF_CmdKind_FindCodeLocation), &p); } +#endif } }break;