From 8064f780af6fb3783baf65283fd1fa2f7b895f98 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Mon, 12 Aug 2019 02:16:04 -0700 Subject: [PATCH] New working set implementation --- 4ed.cpp | 25 ++--- 4ed_api_implementation.cpp | 26 ++--- 4ed_edit.cpp | 16 +-- 4ed_file.cpp | 11 +- 4ed_file.h | 13 +-- 4ed_system_allocator.cpp | 11 +- 4ed_view.cpp | 13 +-- 4ed_working_set.cpp | 217 ++++++++++++------------------------- 4ed_working_set.h | 35 +++++- 9 files changed, 155 insertions(+), 212 deletions(-) diff --git a/4ed.cpp b/4ed.cpp index 44ac9039..44a9dff0 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -67,11 +67,9 @@ app_coroutine_run(Models *models, App_Coroutine_Purpose purpose, Coroutine *co, internal void output_file_append(Models *models, Editing_File *file, String_Const_u8 value){ - if (!file->is_dummy){ - i32 end = buffer_size(&file->state.buffer); - Edit_Behaviors behaviors = {}; - edit_single(models->system, models, file, make_range(end), value, behaviors); - } + i32 end = buffer_size(&file->state.buffer); + Edit_Behaviors behaviors = {}; + edit_single(models->system, models, file, make_range(end), value, behaviors); } internal void @@ -895,7 +893,7 @@ App_Init_Sig(app_init){ dynamic_workspace_init(&models->mem.heap, &models->lifetime_allocator, DynamicWorkspace_Global, 0, &models->dynamic_workspace); // NOTE(allen): file setup - working_set_init(system, &models->working_set, arena); + working_set_init(system, &models->working_set); models->working_set.default_display_width = DEFAULT_DISPLAY_WIDTH; models->working_set.default_minimum_base_display_width = DEFAULT_MINIMUM_BASE_DISPLAY_WIDTH; @@ -943,7 +941,7 @@ App_Init_Sig(app_init){ Heap *heap = &models->mem.heap; for (i32 i = 0; i < ArrayCount(init_files); ++i){ - Editing_File *file = working_set_alloc_always(&models->working_set, heap, &models->lifetime_allocator); + Editing_File *file = working_set_allocate_file(&models->working_set, &models->lifetime_allocator); buffer_bind_name(models, heap, arena, &models->working_set, file, init_files[i].name); if (init_files[i].ptr != 0){ @@ -1373,8 +1371,7 @@ App_Step_Sig(app_step){ if (hook_file_edit_finished != 0){ Working_Set *working_set = &models->working_set; if (working_set->edit_finished_count > 0){ - Assert(working_set->edit_finished_list_first != 0); - Assert(working_set->edit_finished_list_last != 0); + Assert(working_set->edit_finished_sentinel.next != 0); b32 trigger_hook = false; u32 elapse_time = models->edit_finished_hook_repeat_speed; @@ -1396,18 +1393,19 @@ App_Step_Sig(app_step){ if (trigger_hook){ Arena *scratch = &models->mem.arena; Temp_Memory temp = begin_temp(scratch); - Node *first = working_set->edit_finished_list_first; + Node *first = working_set->edit_finished_sentinel.next; + Node *one_past_last = &working_set->edit_finished_sentinel; i32 max_id_count = working_set->edit_finished_count; Editing_File **file_ptrs = push_array(scratch, Editing_File*, max_id_count); Buffer_ID *ids = push_array(scratch, Buffer_ID, max_id_count); i32 id_count = 0; for (Node *node = first; - node != 0; + node != one_past_last; node = node->next){ Editing_File *file_ptr = CastFromMember(Editing_File, edit_finished_mark_node, node); file_ptrs[id_count] = file_ptr; - ids[id_count] = file_ptr->id.id; + ids[id_count] = file_ptr->id; id_count += 1; } @@ -1419,8 +1417,7 @@ App_Step_Sig(app_step){ file_ptrs[i]->edit_finished_marked = false; } - working_set->edit_finished_list_first = 0; - working_set->edit_finished_list_last = 0; + block_zero_struct(&working_set->edit_finished_sentinel); working_set->edit_finished_count = 0; working_set->time_of_next_edit_finished_signal = 0; diff --git a/4ed_api_implementation.cpp b/4ed_api_implementation.cpp index 4533546e..d3827bd8 100644 --- a/4ed_api_implementation.cpp +++ b/4ed_api_implementation.cpp @@ -25,7 +25,7 @@ api_check_panel(Panel *panel){ internal b32 api_check_buffer(Editing_File *file){ - return(file != 0 && !file->is_dummy); + return(file != 0); } internal b32 @@ -142,7 +142,7 @@ Child_Process_Get_Attached_Buffer(Application_Links *app, Child_Process_ID child Child_Process *child_process = child_process_from_id(&models->child_processes, child_process_id); Buffer_ID result = 0; if (child_process != 0 && child_process->out_file != 0){ - result = child_process->out_file->id.id; + result = child_process->out_file->id; } return(result); } @@ -227,8 +227,7 @@ DOC(Gives the total number of buffers in the application.) */{ Models *models = (Models*)app->cmd_context; Working_Set *working_set = &models->working_set; - i32 result = working_set->file_count; - return(result); + return(working_set->active_file_count); } // TODO(allen): redocument @@ -249,14 +248,14 @@ DOC_SEE(get_buffer_first) */{ Models *models = (Models*)app->cmd_context; Working_Set *working_set = &models->working_set; - Editing_File *file = working_set_get_active_file(working_set, buffer_id); + Editing_File *file = working_set_get_file(working_set, buffer_id); file = file_get_next(working_set, file); for (;file != 0 && !access_test(file_get_access_flags(file), access);){ file = file_get_next(working_set, file); } Buffer_ID result = 0; if (file != 0){ - result = file->id.id; + result = file->id; } return(result); } @@ -280,7 +279,7 @@ DOC_SEE(Access_Flag) Editing_File *file = working_set_contains_name(working_set, name); Buffer_ID result = 0; if (api_check_buffer(file, access)){ - result = file->id.id; + result = file->id; } return(result); } @@ -309,7 +308,7 @@ DOC_SEE(Access_Flag) Working_Set *working_set = &models->working_set; Editing_File *file = working_set_contains_canon(working_set, string_from_file_name(&canon)); if (api_check_buffer(file, access)){ - result = file->id.id; + result = file->id; } } return(result); @@ -972,7 +971,7 @@ DOC_SEE(Buffer_Create_Flag) Editing_File *new_file = create_file(models, file_name, flags); Buffer_ID result = 0; if (new_file != 0){ - result = new_file->id.id; + result = new_file->id; } return(result); } @@ -1041,7 +1040,7 @@ DOC_SEE(Buffer_Identifier) b32 needs_to_save = file_needs_save(file); if (!needs_to_save || (flags & BufferKill_AlwaysKill) != 0){ if (models->hook_end_file != 0){ - models->hook_end_file(&models->app_links, file->id.id); + models->hook_end_file(&models->app_links, file->id); } buffer_unbind_name_low_level(working_set, file); @@ -1053,7 +1052,7 @@ DOC_SEE(Buffer_Identifier) Layout *layout = &models->layout; - Node *used = &working_set->used_sentinel; + Node *used = &working_set->active_file_sentinel; Node *file_node = used->next; for (Panel *panel = layout_get_first_open_panel(layout); panel != 0; @@ -1318,7 +1317,7 @@ View_Get_Buffer(Application_Links *app, View_ID view_id, Access_Flag access){ if (api_check_view(view)){ Editing_File *file = view->file; if (api_check_buffer(file, access)){ - result = file->id.id; + result = file->id; } } return(result); @@ -1880,10 +1879,9 @@ DOC_SEE(Set_Buffer_Flag) */{ Models *models = (Models*)app->cmd_context; View *view = imp_get_view(models, view_id); - b32 result = false; if (api_check_view(view)){ - Editing_File *file = working_set_get_active_file(&models->working_set, buffer_id); + Editing_File *file = working_set_get_file(&models->working_set, buffer_id); if (api_check_buffer(file)){ if (file != view->file){ view_set_file(models->system, models, view, file); diff --git a/4ed_edit.cpp b/4ed_edit.cpp index 117912d4..cdfda5bb 100644 --- a/4ed_edit.cpp +++ b/4ed_edit.cpp @@ -87,7 +87,7 @@ edit_fix_markers(System_Functions *system, Models *models, Editing_File *file, E Layout *layout = &models->layout; Lifetime_Object *file_lifetime_object = file->lifetime_object; - Buffer_ID file_id = file->id.id; + Buffer_ID file_id = file->id; Assert(file_lifetime_object != 0); i32 cursor_max = layout_get_open_panel_count(layout)*4; @@ -253,7 +253,7 @@ edit_single(System_Functions *system, Models *models, Editing_File *file, Range // NOTE(allen): edit range hook if (models->hook_file_edit_range != 0){ - models->hook_file_edit_range(&models->app_links, file->id.id, edit.range, SCu8(edit.str, edit.length)); + models->hook_file_edit_range(&models->app_links, file->id, edit.range, SCu8(edit.str, edit.length)); } // NOTE(allen): expand spec, compute shift @@ -313,7 +313,7 @@ edit_single(System_Functions *system, Models *models, Editing_File *file, Range internal void file_end_file(Models *models, Editing_File *file){ if (models->hook_end_file != 0){ - models->hook_end_file(&models->app_links, file->id.id); + models->hook_end_file(&models->app_links, file->id); } Heap *heap = &models->mem.heap; Lifetime_Allocator *lifetime_allocator = &models->lifetime_allocator; @@ -560,7 +560,7 @@ create_file(Models *models, String_Const_u8 file_name, Buffer_Create_Flag flags) buffer_is_for_new_file = true; } if (!HasFlag(flags, BufferCreate_NeverNew)){ - file = working_set_alloc_always(working_set, heap, &models->lifetime_allocator); + file = working_set_allocate_file(working_set, &models->lifetime_allocator); if (file != 0){ if (has_canon_name){ file_bind_file_name(system, heap, working_set, file, string_from_file_name(&canon)); @@ -586,7 +586,7 @@ create_file(Models *models, String_Const_u8 file_name, Buffer_Create_Flag flags) if (system->load_file(handle, buffer, (i32)attributes.size)){ system->load_close(handle); - file = working_set_alloc_always(working_set, heap, &models->lifetime_allocator); + file = working_set_allocate_file(working_set, &models->lifetime_allocator); if (file != 0){ file_bind_file_name(system, heap, working_set, file, string_from_file_name(&canon)); String_Const_u8 front = string_front_of_path(file_name); @@ -623,8 +623,10 @@ create_file(Models *models, String_Const_u8 file_name, Buffer_Create_Flag flags) } } - if (file != 0 && buffer_is_for_new_file && !HasFlag(flags, BufferCreate_SuppressNewFileHook) && models->hook_new_file != 0){ - models->hook_new_file(&models->app_links, file->id.id); + if (file != 0 && buffer_is_for_new_file && + !HasFlag(flags, BufferCreate_SuppressNewFileHook) && + models->hook_new_file != 0){ + models->hook_new_file(&models->app_links, file->id); } end_temp(temp); diff --git a/4ed_file.cpp b/4ed_file.cpp index ccaac86b..388be730 100644 --- a/4ed_file.cpp +++ b/4ed_file.cpp @@ -9,13 +9,6 @@ // TOP -internal Buffer_Slot_ID -to_file_id(i32 id){ - Buffer_Slot_ID result = {}; - result.id = id; - return(result); -} - internal String_Const_u8 string_from_file_name(Editing_File_Name *name){ return(SCu8(name->name_space, name->name_size)); @@ -153,7 +146,7 @@ save_file_to_name(System_Functions *system, Models *models, Editing_File *file, if (file_name != 0){ Mem_Options *mem = &models->mem; if (models->hook_save_file != 0){ - models->hook_save_file(&models->app_links, file->id.id); + models->hook_save_file(&models->app_links, file->id); } Gap_Buffer *buffer = &file->state.buffer; @@ -468,7 +461,7 @@ file_create_from_string(System_Functions *system, Models *models, Editing_File * // be to make sure it always happens in one way. Open_File_Hook_Function *hook_open_file = models->hook_open_file; if (hook_open_file != 0){ - hook_open_file(app_links, file->id.id); + hook_open_file(app_links, file->id); } if (file->settings.tokens_exist){ diff --git a/4ed_file.h b/4ed_file.h index 89a12112..a586e276 100644 --- a/4ed_file.h +++ b/4ed_file.h @@ -33,11 +33,6 @@ struct Text_Effect{ f32 seconds_max; }; -union Buffer_Slot_ID{ - Buffer_ID id; - i16 part[2]; -}; - struct Editing_File_Settings{ i32 base_map_id; i32 display_width; @@ -98,17 +93,19 @@ struct Editing_File_Name{ }; struct Editing_File{ - Buffer_Slot_ID id; + union{ + Editing_File *next; + Node main_chain_node; + }; + Buffer_ID id; Editing_File_Settings settings; b32 is_loading; - b32 is_dummy; Editing_File_State state; File_Attributes attributes; Lifetime_Object *lifetime_object; Editing_File_Name base_name; Editing_File_Name unique_name; Editing_File_Name canon; - Node main_chain_node; b32 edit_finished_marked; Node edit_finished_mark_node; }; diff --git a/4ed_system_allocator.cpp b/4ed_system_allocator.cpp index 6a8da5b6..c8921fc9 100644 --- a/4ed_system_allocator.cpp +++ b/4ed_system_allocator.cpp @@ -34,12 +34,17 @@ make_base_allocator_system(System_Functions *system){ global Base_Allocator base_allocator_system = {}; -internal Arena -make_arena_system(System_Functions *system, umem chunk_size, umem align){ +internal Base_Allocator* +get_base_allocator_system(System_Functions *system){ if (base_allocator_system.reserve == 0){ base_allocator_system = make_base_allocator_system(system); } - return(make_arena(&base_allocator_system, chunk_size, align)); + return(&base_allocator_system); +} + +internal Arena +make_arena_system(System_Functions *system, umem chunk_size, umem align){ + return(make_arena(get_base_allocator_system(system), chunk_size, align)); } internal Arena diff --git a/4ed_view.cpp b/4ed_view.cpp index a753d6f2..80daccff 100644 --- a/4ed_view.cpp +++ b/4ed_view.cpp @@ -403,8 +403,8 @@ file_set_font(System_Functions *system, Models *models, Editing_File *file, Face internal void global_set_font_and_update_files(System_Functions *system, Models *models, Face_ID font_id){ - for (Node *node = models->working_set.used_sentinel.next; - node != &models->working_set.used_sentinel; + for (Node *node = models->working_set.active_file_sentinel.next; + node != &models->working_set.active_file_sentinel; node = node->next){ Editing_File *file = CastFromMember(Editing_File, main_chain_node, node); file_set_font(system, models, file, font_id); @@ -417,8 +417,8 @@ alter_font_and_update_files(System_Functions *system, Models *models, Face_ID fa b32 success = false; if (font_set_modify_face(&models->font_set, face_id, new_description)){ success = true; - for (Node *node = models->working_set.used_sentinel.next; - node != &models->working_set.used_sentinel; + for (Node *node = models->working_set.active_file_sentinel.next; + node != &models->working_set.active_file_sentinel; node = node->next){ Editing_File *file = CastFromMember(Editing_File, main_chain_node, node); if (file->settings.font_id == face_id){ @@ -438,8 +438,8 @@ release_font_and_update_files(System_Functions *system, Models *models, Face_ID replacement_id = font_set_get_fallback_face(&models->font_set); Assert(font_set_face_from_id(&models->font_set, replacement_id) != 0); } - for (Node *node = models->working_set.used_sentinel.next; - node != &models->working_set.used_sentinel; + for (Node *node = models->working_set.active_file_sentinel.next; + node != &models->working_set.active_file_sentinel; node = node->next){ Editing_File *file = CastFromMember(Editing_File, main_chain_node, node); if (file->settings.font_id == font_id){ @@ -521,7 +521,6 @@ render_loaded_file_in_view__inner(Models *models, Render_Target *target, View *v Font_Set *font_set = &models->font_set; Assert(file != 0); - Assert(!file->is_dummy); Assert(buffer_good(&file->state.buffer)); Cpp_Token_Array token_array = file->state.token_array; diff --git a/4ed_working_set.cpp b/4ed_working_set.cpp index 0fc43546..52020b85 100644 --- a/4ed_working_set.cpp +++ b/4ed_working_set.cpp @@ -9,149 +9,74 @@ // TOP -internal void -working_set_extend_memory(Working_Set *working_set, Editing_File *new_space, i16 number_of_files){ - Assert(working_set->array_count < working_set->array_max); - - i16 high_part = working_set->array_count++; - working_set->file_arrays[high_part].files = new_space; - working_set->file_arrays[high_part].size = number_of_files; - - working_set->file_max += number_of_files; - - Buffer_Slot_ID id = {}; - id.part[1] = high_part; - - Editing_File *file_ptr = new_space; - Node *free_sentinel = &working_set->free_sentinel; - for (i16 i = 0; i < number_of_files; ++i, ++file_ptr){ - id.part[0] = i; - file_ptr->id = id; - dll_insert(free_sentinel, &file_ptr->main_chain_node); - } -} - internal void working_set_file_default_settings(Working_Set *working_set, Editing_File *file){ - memset(&file->settings, 0, sizeof(file->settings)); + block_zero_struct(&file->settings); file->settings.display_width = working_set->default_display_width; file->settings.minimum_base_display_width = working_set->default_minimum_base_display_width; file->settings.wrap_indicator = WrapIndicator_Show_At_Wrap_Edge; } -// TODO(allen): do(restructure so that editing file is returned cleared to zero) +//////////////////////////////// + internal Editing_File* -working_set_alloc_always(Working_Set *working_set, Heap *heap, Lifetime_Allocator *lifetime_allocator){ - Editing_File *result = 0; - if (working_set->file_count == working_set->file_max && working_set->array_count < working_set->array_max){ - i16 new_count = (i16)clamp_top(working_set->file_max, max_i16); - Editing_File *new_chunk = heap_array(heap, Editing_File, new_count); - working_set_extend_memory(working_set, new_chunk, new_count); +working_set_allocate_file(Working_Set *working_set, Lifetime_Allocator *lifetime_allocator){ + Editing_File *file = working_set->free_files; + if (file == 0){ + file = push_array(&working_set->arena, Editing_File, 1); } - - if (working_set->file_count < working_set->file_max){ - Node *node = working_set->free_sentinel.next; - Assert(node != &working_set->free_sentinel); - result = CastFromMember(Editing_File, main_chain_node, node); - - ++working_set->file_count; - - dll_remove(node); - dll_insert(&working_set->used_sentinel, node); - - Node node_val = result->main_chain_node; - Buffer_Slot_ID id_val = result->id; - memset(result, 0, sizeof(*result)); - result->main_chain_node = node_val; - result->id = id_val; - - working_set_file_default_settings(working_set, result); + else{ + sll_stack_pop(working_set->free_files); } + block_zero_struct(file); - return(result); + dll_insert_back(&working_set->active_file_sentinel, &file->main_chain_node); + working_set->active_file_count += 1; + + file->id = working_set->id_counter; + working_set->id_counter += 1; + + working_set_file_default_settings(working_set, file); + + table_insert(&working_set->id_to_ptr_table, + (u64)file->id, (u64)(PtrAsInt(file))); + + return(file); } internal void working_set_free_file(Heap *heap, Working_Set *working_set, Editing_File *file){ - if (working_set->sync_check_iter == &file->main_chain_node){ - working_set->sync_check_iter = working_set->sync_check_iter->next; - } - file->is_dummy = true; dll_remove(&file->main_chain_node); - dll_insert(&working_set->free_sentinel, &file->main_chain_node); - --working_set->file_count; + working_set->active_file_count -= 1; + table_erase(&working_set->id_to_ptr_table, file->id); + sll_stack_push(working_set->free_files, file); } internal Editing_File* -working_set_index(Working_Set *working_set, Buffer_Slot_ID id){ +working_set_get_file(Working_Set *working_set, Buffer_ID id){ Editing_File *result = 0; - File_Array *array = 0; - if (id.part[1] >= 0 && id.part[1] < working_set->array_count){ - array = working_set->file_arrays + id.part[1]; - if (id.part[0] >= 0 && id.part[0] < array->size){ - result = array->files + id.part[0]; - } + u64 val = 0; + if (table_read(&working_set->id_to_ptr_table, id, &val)){ + result = (Editing_File*)(IntAsPtr(val)); } return(result); } -internal Editing_File* -working_set_index(Working_Set *working_set, i32 id){ - return(working_set_index(working_set, to_file_id(id))); -} - -internal Editing_File* -working_set_get_active_file(Working_Set *working_set, Buffer_Slot_ID id){ - Editing_File *result = working_set_index(working_set, id); - if (result != 0 && result->is_dummy){ - result = 0; - } - return(result); -} - -internal Editing_File* -working_set_get_active_file(Working_Set *working_set, Buffer_ID id){ - return(working_set_get_active_file(working_set, to_file_id(id))); -} - -// TODO(allen): REWRITE all of working set internal void -working_set_init(System_Functions *system, Working_Set *working_set, Arena *arena){ - i16 init_count = 16; - i16 array_init_count = 256; +working_set_init(System_Functions *system, Working_Set *working_set){ + block_zero_struct(working_set); + working_set->arena = make_arena_system(system); - dll_init_sentinel(&working_set->free_sentinel); - dll_init_sentinel(&working_set->used_sentinel); + working_set->id_counter = 1; - working_set->edit_finished_list_first = 0; - working_set->edit_finished_list_last = 0; - working_set->edit_finished_count = 0; + dll_init_sentinel(&working_set->active_file_sentinel); + dll_init_sentinel(&working_set->edit_finished_sentinel); - working_set->time_of_next_edit_finished_signal = 0; - working_set->edit_finished_timer = system->wake_up_timer_create(); - working_set->do_not_mark_edits = false; - - working_set->array_max = array_init_count; - working_set->file_arrays = push_array(arena, File_Array, array_init_count); - - Editing_File *files = push_array(arena, Editing_File, init_count); - working_set_extend_memory(working_set, files, init_count); - - // TODO(NAME): do(clean up the rest of the null_file) - // Unclear that this is still needed. But double check that the buffer id 0 does not start getting used by the next real buffer when this - // is removed before actually removing it. Buffer id cannot be allowed to be zero on real buffers. -#if 1 - // NOTE(allen): init null file - { - Editing_File *null_file = working_set_index(working_set, 0); - dll_remove(&null_file->main_chain_node); - null_file->is_dummy = true; - ++working_set->file_count; - } -#endif - - working_set->canon_table = make_table_Data_u64(arena->base_allocator, 128); - working_set->name_table = make_table_Data_u64(arena->base_allocator, 128); + local_const i32 slot_count = 128; + Base_Allocator *allocator = get_base_allocator_system(system); + working_set->id_to_ptr_table = make_table_u64_u64(allocator, slot_count); + working_set->canon_table = make_table_Data_u64(allocator, slot_count); + working_set->name_table = make_table_Data_u64(allocator, slot_count); } internal Editing_File* @@ -159,7 +84,7 @@ working_set_contains__generic(Working_Set *working_set, Table_Data_u64 *table, S Editing_File *result = 0; u64 val = 0; if (table_read(table, make_data(name.str, name.size), &val)){ - result = working_set_index(working_set, to_file_id((Buffer_ID)val)); + result = working_set_get_file(working_set, (Buffer_ID)val); } return(result); } @@ -181,7 +106,7 @@ working_set_contains_canon(Working_Set *working_set, String_Const_u8 name){ internal b32 working_set_canon_add(Working_Set *working_set, Editing_File *file, String_Const_u8 name){ - return(working_set_add__generic(&working_set->canon_table, file->id.id, name)); + return(working_set_add__generic(&working_set->canon_table, file->id, name)); } internal void @@ -196,7 +121,7 @@ working_set_contains_name(Working_Set *working_set, String_Const_u8 name){ internal b32 working_set_add_name(Heap *heap, Working_Set *working_set, Editing_File *file, String_Const_u8 name){ - return(working_set_add__generic(&working_set->name_table, file->id.id, name)); + return(working_set_add__generic(&working_set->name_table, file->id, name)); } internal void @@ -208,7 +133,7 @@ internal Editing_File* get_file_from_identifier(System_Functions *system, Working_Set *working_set, Buffer_Identifier buffer){ Editing_File *file = 0; if (buffer.id != 0){ - file = working_set_get_active_file(working_set, buffer.id); + file = working_set_get_file(working_set, buffer.id); } else if (buffer.name != 0){ String_Const_u8 name = SCu8(buffer.name, buffer.name_len); @@ -322,10 +247,13 @@ buffer_unbind_file(System_Functions *system, Working_Set *working_set, Editing_F internal b32 buffer_name_has_conflict(Working_Set *working_set, String_Const_u8 base_name){ b32 hit_conflict = false; - Node *used_nodes = &working_set->used_sentinel; - for (Node *node = used_nodes->next; node != used_nodes; node = node->next){ + Node *used_nodes = &working_set->active_file_sentinel; + for (Node *node = used_nodes->next; + node != used_nodes; + node = node->next){ Editing_File *file_ptr = CastFromMember(Editing_File, main_chain_node, node); - if (file_is_ready(file_ptr) && string_match(base_name, string_from_file_name(&file_ptr->unique_name))){ + if (file_is_ready(file_ptr) && + string_match(base_name, string_from_file_name(&file_ptr->unique_name))){ hit_conflict = true; break; } @@ -411,12 +339,13 @@ buffer_bind_name(Models *models, Heap *heap, Arena *scratch, Working_Set *workin conflict_count += 1; } - Node *used_nodes = &working_set->used_sentinel; + Node *used_nodes = &working_set->active_file_sentinel; for (Node *node = used_nodes->next; node != used_nodes; node = node->next){ Editing_File *file_ptr = CastFromMember(Editing_File, main_chain_node, node); - if (file_is_ready(file_ptr) && string_match(base_name, string_from_file_name(&file_ptr->base_name))){ + if (file_is_ready(file_ptr) && + string_match(base_name, string_from_file_name(&file_ptr->base_name))){ Node_Ptr *new_node = push_array(scratch, Node_Ptr, 1); sll_queue_push(conflict_first, conflict_last, new_node); new_node->file_ptr = file_ptr; @@ -434,7 +363,7 @@ buffer_bind_name(Models *models, Heap *heap, Arena *scratch, Working_Set *workin node = node->next, i += 1){ Editing_File *file_ptr = node->file_ptr; Buffer_Name_Conflict_Entry *entry = &conflicts[i]; - entry->buffer_id = file_ptr->id.id; + entry->buffer_id = file_ptr->id; entry->file_name = push_string_copy(scratch, string_from_file_name(&file_ptr->canon)); entry->base_name = push_string_copy(scratch, base_name); @@ -491,22 +420,23 @@ buffer_bind_name(Models *models, Heap *heap, Arena *scratch, Working_Set *workin internal void file_touch(Working_Set *working_set, Editing_File *file){ Assert(file != 0); - Assert(!file->is_dummy); - dll_remove(&file->main_chain_node); - dll_insert(&working_set->used_sentinel, &file->main_chain_node); + // TODO(allen): create a reorderable list of files in working + // set used to keep track of "most recently touched" + //NotImplemented; } internal Editing_File* file_get_next(Working_Set *working_set, Editing_File *file){ if (file != 0){ - file = CastFromMember(Editing_File, main_chain_node, file->main_chain_node.next); - if (file == CastFromMember(Editing_File, main_chain_node, &working_set->used_sentinel)){ + Node *node = file->main_chain_node.next; + file = CastFromMember(Editing_File, main_chain_node, node); + if (node == &working_set->active_file_sentinel){ file = 0; } } else{ - if (working_set->file_count > 0){ - Node *node = working_set->used_sentinel.next; + if (working_set->active_file_count > 0){ + Node *node = working_set->active_file_sentinel.next; file = CastFromMember(Editing_File, main_chain_node, node); } } @@ -516,14 +446,13 @@ file_get_next(Working_Set *working_set, Editing_File *file){ internal void file_mark_edit_finished(Working_Set *working_set, Editing_File *file){ // TODO(allen): do(propogate do_not_mark_edits down the edit pipeline to here) - // This current method only works for synchronous calls, asynchronous calls will get the - // wrong do_not_mark_edits value. + // This current method only works for synchronous calls, asynchronous calls + // will get the wrong do_not_mark_edits value. if (!working_set->do_not_mark_edits){ - if (!file->edit_finished_marked == 0){ - zdll_push_back(working_set->edit_finished_list_first, - working_set->edit_finished_list_last, - &file->edit_finished_mark_node); + if (!file->edit_finished_marked){ file->edit_finished_marked = true; + dll_insert_back(&working_set->edit_finished_sentinel, + &file->edit_finished_mark_node); working_set->edit_finished_count += 1; } } @@ -534,14 +463,10 @@ file_unmark_edit_finished(Working_Set *working_set, Editing_File *file){ b32 result = false; if (!working_set->do_not_mark_edits){ if (file->edit_finished_marked){ - zdll_remove(working_set->edit_finished_list_first, - working_set->edit_finished_list_last, - &file->edit_finished_mark_node); - file->edit_finished_mark_node.next = 0; - file->edit_finished_mark_node.prev = 0; file->edit_finished_marked = false; + dll_remove(&file->edit_finished_mark_node); working_set->edit_finished_count -= 1; - + block_zero_struct(&file->edit_finished_mark_node); result = true; } } @@ -553,7 +478,7 @@ file_unmark_edit_finished(Working_Set *working_set, Editing_File *file){ internal Editing_File* imp_get_file(Models *models, Buffer_ID buffer_id){ Working_Set *working_set = &models->working_set; - Editing_File *file = working_set_get_active_file(working_set, buffer_id); + Editing_File *file = working_set_get_file(working_set, buffer_id); if (file != 0 && !file_is_ready(file)){ file = 0; } @@ -562,3 +487,5 @@ imp_get_file(Models *models, Buffer_ID buffer_id){ // BOTTOM + + diff --git a/4ed_working_set.h b/4ed_working_set.h index a535522e..9ab92432 100644 --- a/4ed_working_set.h +++ b/4ed_working_set.h @@ -12,11 +12,37 @@ #if !defined(FRED_WORKING_SET_H) #define FRED_WORKING_SET_H -struct File_Array{ - Editing_File *files; - i32 size; +struct Working_Set{ + Arena arena; + + Editing_File *free_files; + Buffer_ID id_counter; + + Node active_file_sentinel; + i32 active_file_count; + + Node edit_finished_sentinel; + i32 edit_finished_count; + u64 time_of_next_edit_finished_signal; + Plat_Handle edit_finished_timer; + b32 do_not_mark_edits; + + Table_u64_u64 id_to_ptr_table; + Table_Data_u64 canon_table; + Table_Data_u64 name_table; + + // TODO(allen): do(update clipboard system to exist fully in the custom layer) + String_Const_u8 clipboards[64]; + i32 clipboard_size; + i32 clipboard_max_size; + i32 clipboard_current; + i32 clipboard_rolling; + + i32 default_display_width; + i32 default_minimum_base_display_width; }; +#if 0 struct Working_Set{ File_Array *file_arrays; i32 file_count; @@ -45,11 +71,10 @@ struct Working_Set{ i32 clipboard_current; i32 clipboard_rolling; - Node *sync_check_iter; - i32 default_display_width; i32 default_minimum_base_display_width; }; +#endif internal void file_mark_edit_finished(Working_Set *working_set, Editing_File *file);