New working set implementation

master
Allen Webster 2019-08-12 02:16:04 -07:00
parent 62d8c4bae0
commit 8064f780af
9 changed files with 155 additions and 212 deletions

25
4ed.cpp
View File

@ -67,11 +67,9 @@ app_coroutine_run(Models *models, App_Coroutine_Purpose purpose, Coroutine *co,
internal void internal void
output_file_append(Models *models, Editing_File *file, String_Const_u8 value){ output_file_append(Models *models, Editing_File *file, String_Const_u8 value){
if (!file->is_dummy){ i32 end = buffer_size(&file->state.buffer);
i32 end = buffer_size(&file->state.buffer); Edit_Behaviors behaviors = {};
Edit_Behaviors behaviors = {}; edit_single(models->system, models, file, make_range(end), value, behaviors);
edit_single(models->system, models, file, make_range(end), value, behaviors);
}
} }
internal void 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); dynamic_workspace_init(&models->mem.heap, &models->lifetime_allocator, DynamicWorkspace_Global, 0, &models->dynamic_workspace);
// NOTE(allen): file setup // 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_display_width = DEFAULT_DISPLAY_WIDTH;
models->working_set.default_minimum_base_display_width = DEFAULT_MINIMUM_BASE_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; Heap *heap = &models->mem.heap;
for (i32 i = 0; i < ArrayCount(init_files); ++i){ 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); buffer_bind_name(models, heap, arena, &models->working_set, file, init_files[i].name);
if (init_files[i].ptr != 0){ if (init_files[i].ptr != 0){
@ -1373,8 +1371,7 @@ App_Step_Sig(app_step){
if (hook_file_edit_finished != 0){ if (hook_file_edit_finished != 0){
Working_Set *working_set = &models->working_set; Working_Set *working_set = &models->working_set;
if (working_set->edit_finished_count > 0){ if (working_set->edit_finished_count > 0){
Assert(working_set->edit_finished_list_first != 0); Assert(working_set->edit_finished_sentinel.next != 0);
Assert(working_set->edit_finished_list_last != 0);
b32 trigger_hook = false; b32 trigger_hook = false;
u32 elapse_time = models->edit_finished_hook_repeat_speed; u32 elapse_time = models->edit_finished_hook_repeat_speed;
@ -1396,18 +1393,19 @@ App_Step_Sig(app_step){
if (trigger_hook){ if (trigger_hook){
Arena *scratch = &models->mem.arena; Arena *scratch = &models->mem.arena;
Temp_Memory temp = begin_temp(scratch); 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; i32 max_id_count = working_set->edit_finished_count;
Editing_File **file_ptrs = push_array(scratch, Editing_File*, max_id_count); Editing_File **file_ptrs = push_array(scratch, Editing_File*, max_id_count);
Buffer_ID *ids = push_array(scratch, Buffer_ID, max_id_count); Buffer_ID *ids = push_array(scratch, Buffer_ID, max_id_count);
i32 id_count = 0; i32 id_count = 0;
for (Node *node = first; for (Node *node = first;
node != 0; node != one_past_last;
node = node->next){ node = node->next){
Editing_File *file_ptr = CastFromMember(Editing_File, edit_finished_mark_node, node); Editing_File *file_ptr = CastFromMember(Editing_File, edit_finished_mark_node, node);
file_ptrs[id_count] = file_ptr; file_ptrs[id_count] = file_ptr;
ids[id_count] = file_ptr->id.id; ids[id_count] = file_ptr->id;
id_count += 1; id_count += 1;
} }
@ -1419,8 +1417,7 @@ App_Step_Sig(app_step){
file_ptrs[i]->edit_finished_marked = false; file_ptrs[i]->edit_finished_marked = false;
} }
working_set->edit_finished_list_first = 0; block_zero_struct(&working_set->edit_finished_sentinel);
working_set->edit_finished_list_last = 0;
working_set->edit_finished_count = 0; working_set->edit_finished_count = 0;
working_set->time_of_next_edit_finished_signal = 0; working_set->time_of_next_edit_finished_signal = 0;

View File

@ -25,7 +25,7 @@ api_check_panel(Panel *panel){
internal b32 internal b32
api_check_buffer(Editing_File *file){ api_check_buffer(Editing_File *file){
return(file != 0 && !file->is_dummy); return(file != 0);
} }
internal b32 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); Child_Process *child_process = child_process_from_id(&models->child_processes, child_process_id);
Buffer_ID result = 0; Buffer_ID result = 0;
if (child_process != 0 && child_process->out_file != 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); return(result);
} }
@ -227,8 +227,7 @@ DOC(Gives the total number of buffers in the application.)
*/{ */{
Models *models = (Models*)app->cmd_context; Models *models = (Models*)app->cmd_context;
Working_Set *working_set = &models->working_set; Working_Set *working_set = &models->working_set;
i32 result = working_set->file_count; return(working_set->active_file_count);
return(result);
} }
// TODO(allen): redocument // TODO(allen): redocument
@ -249,14 +248,14 @@ DOC_SEE(get_buffer_first)
*/{ */{
Models *models = (Models*)app->cmd_context; Models *models = (Models*)app->cmd_context;
Working_Set *working_set = &models->working_set; 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); file = file_get_next(working_set, file);
for (;file != 0 && !access_test(file_get_access_flags(file), access);){ for (;file != 0 && !access_test(file_get_access_flags(file), access);){
file = file_get_next(working_set, file); file = file_get_next(working_set, file);
} }
Buffer_ID result = 0; Buffer_ID result = 0;
if (file != 0){ if (file != 0){
result = file->id.id; result = file->id;
} }
return(result); return(result);
} }
@ -280,7 +279,7 @@ DOC_SEE(Access_Flag)
Editing_File *file = working_set_contains_name(working_set, name); Editing_File *file = working_set_contains_name(working_set, name);
Buffer_ID result = 0; Buffer_ID result = 0;
if (api_check_buffer(file, access)){ if (api_check_buffer(file, access)){
result = file->id.id; result = file->id;
} }
return(result); return(result);
} }
@ -309,7 +308,7 @@ DOC_SEE(Access_Flag)
Working_Set *working_set = &models->working_set; Working_Set *working_set = &models->working_set;
Editing_File *file = working_set_contains_canon(working_set, string_from_file_name(&canon)); Editing_File *file = working_set_contains_canon(working_set, string_from_file_name(&canon));
if (api_check_buffer(file, access)){ if (api_check_buffer(file, access)){
result = file->id.id; result = file->id;
} }
} }
return(result); return(result);
@ -972,7 +971,7 @@ DOC_SEE(Buffer_Create_Flag)
Editing_File *new_file = create_file(models, file_name, flags); Editing_File *new_file = create_file(models, file_name, flags);
Buffer_ID result = 0; Buffer_ID result = 0;
if (new_file != 0){ if (new_file != 0){
result = new_file->id.id; result = new_file->id;
} }
return(result); return(result);
} }
@ -1041,7 +1040,7 @@ DOC_SEE(Buffer_Identifier)
b32 needs_to_save = file_needs_save(file); b32 needs_to_save = file_needs_save(file);
if (!needs_to_save || (flags & BufferKill_AlwaysKill) != 0){ if (!needs_to_save || (flags & BufferKill_AlwaysKill) != 0){
if (models->hook_end_file != 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); buffer_unbind_name_low_level(working_set, file);
@ -1053,7 +1052,7 @@ DOC_SEE(Buffer_Identifier)
Layout *layout = &models->layout; Layout *layout = &models->layout;
Node *used = &working_set->used_sentinel; Node *used = &working_set->active_file_sentinel;
Node *file_node = used->next; Node *file_node = used->next;
for (Panel *panel = layout_get_first_open_panel(layout); for (Panel *panel = layout_get_first_open_panel(layout);
panel != 0; panel != 0;
@ -1318,7 +1317,7 @@ View_Get_Buffer(Application_Links *app, View_ID view_id, Access_Flag access){
if (api_check_view(view)){ if (api_check_view(view)){
Editing_File *file = view->file; Editing_File *file = view->file;
if (api_check_buffer(file, access)){ if (api_check_buffer(file, access)){
result = file->id.id; result = file->id;
} }
} }
return(result); return(result);
@ -1880,10 +1879,9 @@ DOC_SEE(Set_Buffer_Flag)
*/{ */{
Models *models = (Models*)app->cmd_context; Models *models = (Models*)app->cmd_context;
View *view = imp_get_view(models, view_id); View *view = imp_get_view(models, view_id);
b32 result = false; b32 result = false;
if (api_check_view(view)){ 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 (api_check_buffer(file)){
if (file != view->file){ if (file != view->file){
view_set_file(models->system, models, view, file); view_set_file(models->system, models, view, file);

View File

@ -87,7 +87,7 @@ edit_fix_markers(System_Functions *system, Models *models, Editing_File *file, E
Layout *layout = &models->layout; Layout *layout = &models->layout;
Lifetime_Object *file_lifetime_object = file->lifetime_object; 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); Assert(file_lifetime_object != 0);
i32 cursor_max = layout_get_open_panel_count(layout)*4; 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 // NOTE(allen): edit range hook
if (models->hook_file_edit_range != 0){ 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 // NOTE(allen): expand spec, compute shift
@ -313,7 +313,7 @@ edit_single(System_Functions *system, Models *models, Editing_File *file, Range
internal void internal void
file_end_file(Models *models, Editing_File *file){ file_end_file(Models *models, Editing_File *file){
if (models->hook_end_file != 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);
} }
Heap *heap = &models->mem.heap; Heap *heap = &models->mem.heap;
Lifetime_Allocator *lifetime_allocator = &models->lifetime_allocator; 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; buffer_is_for_new_file = true;
} }
if (!HasFlag(flags, BufferCreate_NeverNew)){ 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 (file != 0){
if (has_canon_name){ if (has_canon_name){
file_bind_file_name(system, heap, working_set, file, string_from_file_name(&canon)); 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)){ if (system->load_file(handle, buffer, (i32)attributes.size)){
system->load_close(handle); 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){ if (file != 0){
file_bind_file_name(system, heap, working_set, file, string_from_file_name(&canon)); file_bind_file_name(system, heap, working_set, file, string_from_file_name(&canon));
String_Const_u8 front = string_front_of_path(file_name); 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){ if (file != 0 && buffer_is_for_new_file &&
models->hook_new_file(&models->app_links, file->id.id); !HasFlag(flags, BufferCreate_SuppressNewFileHook) &&
models->hook_new_file != 0){
models->hook_new_file(&models->app_links, file->id);
} }
end_temp(temp); end_temp(temp);

View File

@ -9,13 +9,6 @@
// TOP // TOP
internal Buffer_Slot_ID
to_file_id(i32 id){
Buffer_Slot_ID result = {};
result.id = id;
return(result);
}
internal String_Const_u8 internal String_Const_u8
string_from_file_name(Editing_File_Name *name){ string_from_file_name(Editing_File_Name *name){
return(SCu8(name->name_space, name->name_size)); 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){ if (file_name != 0){
Mem_Options *mem = &models->mem; Mem_Options *mem = &models->mem;
if (models->hook_save_file != 0){ 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; 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. // be to make sure it always happens in one way.
Open_File_Hook_Function *hook_open_file = models->hook_open_file; Open_File_Hook_Function *hook_open_file = models->hook_open_file;
if (hook_open_file != 0){ 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){ if (file->settings.tokens_exist){

View File

@ -33,11 +33,6 @@ struct Text_Effect{
f32 seconds_max; f32 seconds_max;
}; };
union Buffer_Slot_ID{
Buffer_ID id;
i16 part[2];
};
struct Editing_File_Settings{ struct Editing_File_Settings{
i32 base_map_id; i32 base_map_id;
i32 display_width; i32 display_width;
@ -98,17 +93,19 @@ struct Editing_File_Name{
}; };
struct Editing_File{ struct Editing_File{
Buffer_Slot_ID id; union{
Editing_File *next;
Node main_chain_node;
};
Buffer_ID id;
Editing_File_Settings settings; Editing_File_Settings settings;
b32 is_loading; b32 is_loading;
b32 is_dummy;
Editing_File_State state; Editing_File_State state;
File_Attributes attributes; File_Attributes attributes;
Lifetime_Object *lifetime_object; Lifetime_Object *lifetime_object;
Editing_File_Name base_name; Editing_File_Name base_name;
Editing_File_Name unique_name; Editing_File_Name unique_name;
Editing_File_Name canon; Editing_File_Name canon;
Node main_chain_node;
b32 edit_finished_marked; b32 edit_finished_marked;
Node edit_finished_mark_node; Node edit_finished_mark_node;
}; };

View File

@ -34,12 +34,17 @@ make_base_allocator_system(System_Functions *system){
global Base_Allocator base_allocator_system = {}; global Base_Allocator base_allocator_system = {};
internal Arena internal Base_Allocator*
make_arena_system(System_Functions *system, umem chunk_size, umem align){ get_base_allocator_system(System_Functions *system){
if (base_allocator_system.reserve == 0){ if (base_allocator_system.reserve == 0){
base_allocator_system = make_base_allocator_system(system); 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 internal Arena

View File

@ -403,8 +403,8 @@ file_set_font(System_Functions *system, Models *models, Editing_File *file, Face
internal void internal void
global_set_font_and_update_files(System_Functions *system, Models *models, Face_ID font_id){ global_set_font_and_update_files(System_Functions *system, Models *models, Face_ID font_id){
for (Node *node = models->working_set.used_sentinel.next; for (Node *node = models->working_set.active_file_sentinel.next;
node != &models->working_set.used_sentinel; node != &models->working_set.active_file_sentinel;
node = node->next){ node = node->next){
Editing_File *file = CastFromMember(Editing_File, main_chain_node, node); Editing_File *file = CastFromMember(Editing_File, main_chain_node, node);
file_set_font(system, models, file, font_id); 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; b32 success = false;
if (font_set_modify_face(&models->font_set, face_id, new_description)){ if (font_set_modify_face(&models->font_set, face_id, new_description)){
success = true; success = true;
for (Node *node = models->working_set.used_sentinel.next; for (Node *node = models->working_set.active_file_sentinel.next;
node != &models->working_set.used_sentinel; node != &models->working_set.active_file_sentinel;
node = node->next){ node = node->next){
Editing_File *file = CastFromMember(Editing_File, main_chain_node, node); Editing_File *file = CastFromMember(Editing_File, main_chain_node, node);
if (file->settings.font_id == face_id){ 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); replacement_id = font_set_get_fallback_face(&models->font_set);
Assert(font_set_face_from_id(&models->font_set, replacement_id) != 0); Assert(font_set_face_from_id(&models->font_set, replacement_id) != 0);
} }
for (Node *node = models->working_set.used_sentinel.next; for (Node *node = models->working_set.active_file_sentinel.next;
node != &models->working_set.used_sentinel; node != &models->working_set.active_file_sentinel;
node = node->next){ node = node->next){
Editing_File *file = CastFromMember(Editing_File, main_chain_node, node); Editing_File *file = CastFromMember(Editing_File, main_chain_node, node);
if (file->settings.font_id == font_id){ 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; Font_Set *font_set = &models->font_set;
Assert(file != 0); Assert(file != 0);
Assert(!file->is_dummy);
Assert(buffer_good(&file->state.buffer)); Assert(buffer_good(&file->state.buffer));
Cpp_Token_Array token_array = file->state.token_array; Cpp_Token_Array token_array = file->state.token_array;

View File

@ -9,149 +9,74 @@
// TOP // 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 internal void
working_set_file_default_settings(Working_Set *working_set, Editing_File *file){ 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.display_width = working_set->default_display_width;
file->settings.minimum_base_display_width = working_set->default_minimum_base_display_width; file->settings.minimum_base_display_width = working_set->default_minimum_base_display_width;
file->settings.wrap_indicator = WrapIndicator_Show_At_Wrap_Edge; 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* internal Editing_File*
working_set_alloc_always(Working_Set *working_set, Heap *heap, Lifetime_Allocator *lifetime_allocator){ working_set_allocate_file(Working_Set *working_set, Lifetime_Allocator *lifetime_allocator){
Editing_File *result = 0; Editing_File *file = working_set->free_files;
if (working_set->file_count == working_set->file_max && working_set->array_count < working_set->array_max){ if (file == 0){
i16 new_count = (i16)clamp_top(working_set->file_max, max_i16); file = push_array(&working_set->arena, Editing_File, 1);
Editing_File *new_chunk = heap_array(heap, Editing_File, new_count);
working_set_extend_memory(working_set, new_chunk, new_count);
} }
else{
if (working_set->file_count < working_set->file_max){ sll_stack_pop(working_set->free_files);
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);
} }
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 internal void
working_set_free_file(Heap *heap, Working_Set *working_set, Editing_File *file){ 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_remove(&file->main_chain_node);
dll_insert(&working_set->free_sentinel, &file->main_chain_node); working_set->active_file_count -= 1;
--working_set->file_count; table_erase(&working_set->id_to_ptr_table, file->id);
sll_stack_push(working_set->free_files, file);
} }
internal Editing_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; Editing_File *result = 0;
File_Array *array = 0; u64 val = 0;
if (id.part[1] >= 0 && id.part[1] < working_set->array_count){ if (table_read(&working_set->id_to_ptr_table, id, &val)){
array = working_set->file_arrays + id.part[1]; result = (Editing_File*)(IntAsPtr(val));
if (id.part[0] >= 0 && id.part[0] < array->size){
result = array->files + id.part[0];
}
} }
return(result); 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 internal void
working_set_init(System_Functions *system, Working_Set *working_set, Arena *arena){ working_set_init(System_Functions *system, Working_Set *working_set){
i16 init_count = 16; block_zero_struct(working_set);
i16 array_init_count = 256; working_set->arena = make_arena_system(system);
dll_init_sentinel(&working_set->free_sentinel); working_set->id_counter = 1;
dll_init_sentinel(&working_set->used_sentinel);
working_set->edit_finished_list_first = 0; dll_init_sentinel(&working_set->active_file_sentinel);
working_set->edit_finished_list_last = 0; dll_init_sentinel(&working_set->edit_finished_sentinel);
working_set->edit_finished_count = 0;
working_set->time_of_next_edit_finished_signal = 0; local_const i32 slot_count = 128;
working_set->edit_finished_timer = system->wake_up_timer_create(); Base_Allocator *allocator = get_base_allocator_system(system);
working_set->do_not_mark_edits = false; 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->array_max = array_init_count; working_set->name_table = make_table_Data_u64(allocator, slot_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);
} }
internal Editing_File* internal Editing_File*
@ -159,7 +84,7 @@ working_set_contains__generic(Working_Set *working_set, Table_Data_u64 *table, S
Editing_File *result = 0; Editing_File *result = 0;
u64 val = 0; u64 val = 0;
if (table_read(table, make_data(name.str, name.size), &val)){ 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); return(result);
} }
@ -181,7 +106,7 @@ working_set_contains_canon(Working_Set *working_set, String_Const_u8 name){
internal b32 internal b32
working_set_canon_add(Working_Set *working_set, Editing_File *file, String_Const_u8 name){ 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 internal void
@ -196,7 +121,7 @@ working_set_contains_name(Working_Set *working_set, String_Const_u8 name){
internal b32 internal b32
working_set_add_name(Heap *heap, Working_Set *working_set, Editing_File *file, String_Const_u8 name){ 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 internal void
@ -208,7 +133,7 @@ internal Editing_File*
get_file_from_identifier(System_Functions *system, Working_Set *working_set, Buffer_Identifier buffer){ get_file_from_identifier(System_Functions *system, Working_Set *working_set, Buffer_Identifier buffer){
Editing_File *file = 0; Editing_File *file = 0;
if (buffer.id != 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){ else if (buffer.name != 0){
String_Const_u8 name = SCu8(buffer.name, buffer.name_len); 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 internal b32
buffer_name_has_conflict(Working_Set *working_set, String_Const_u8 base_name){ buffer_name_has_conflict(Working_Set *working_set, String_Const_u8 base_name){
b32 hit_conflict = false; b32 hit_conflict = false;
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){ for (Node *node = used_nodes->next;
node != used_nodes;
node = node->next){
Editing_File *file_ptr = CastFromMember(Editing_File, main_chain_node, node); 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; hit_conflict = true;
break; break;
} }
@ -411,12 +339,13 @@ buffer_bind_name(Models *models, Heap *heap, Arena *scratch, Working_Set *workin
conflict_count += 1; conflict_count += 1;
} }
Node *used_nodes = &working_set->used_sentinel; Node *used_nodes = &working_set->active_file_sentinel;
for (Node *node = used_nodes->next; for (Node *node = used_nodes->next;
node != used_nodes; node != used_nodes;
node = node->next){ node = node->next){
Editing_File *file_ptr = CastFromMember(Editing_File, main_chain_node, node); 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); Node_Ptr *new_node = push_array(scratch, Node_Ptr, 1);
sll_queue_push(conflict_first, conflict_last, new_node); sll_queue_push(conflict_first, conflict_last, new_node);
new_node->file_ptr = file_ptr; 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){ node = node->next, i += 1){
Editing_File *file_ptr = node->file_ptr; Editing_File *file_ptr = node->file_ptr;
Buffer_Name_Conflict_Entry *entry = &conflicts[i]; 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->file_name = push_string_copy(scratch, string_from_file_name(&file_ptr->canon));
entry->base_name = push_string_copy(scratch, base_name); 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 internal void
file_touch(Working_Set *working_set, Editing_File *file){ file_touch(Working_Set *working_set, Editing_File *file){
Assert(file != 0); Assert(file != 0);
Assert(!file->is_dummy); // TODO(allen): create a reorderable list of files in working
dll_remove(&file->main_chain_node); // set used to keep track of "most recently touched"
dll_insert(&working_set->used_sentinel, &file->main_chain_node); //NotImplemented;
} }
internal Editing_File* internal Editing_File*
file_get_next(Working_Set *working_set, Editing_File *file){ file_get_next(Working_Set *working_set, Editing_File *file){
if (file != 0){ if (file != 0){
file = CastFromMember(Editing_File, main_chain_node, file->main_chain_node.next); Node *node = file->main_chain_node.next;
if (file == CastFromMember(Editing_File, main_chain_node, &working_set->used_sentinel)){ file = CastFromMember(Editing_File, main_chain_node, node);
if (node == &working_set->active_file_sentinel){
file = 0; file = 0;
} }
} }
else{ else{
if (working_set->file_count > 0){ if (working_set->active_file_count > 0){
Node *node = working_set->used_sentinel.next; Node *node = working_set->active_file_sentinel.next;
file = CastFromMember(Editing_File, main_chain_node, node); file = CastFromMember(Editing_File, main_chain_node, node);
} }
} }
@ -516,14 +446,13 @@ file_get_next(Working_Set *working_set, Editing_File *file){
internal void internal void
file_mark_edit_finished(Working_Set *working_set, Editing_File *file){ 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) // 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 // This current method only works for synchronous calls, asynchronous calls
// wrong do_not_mark_edits value. // will get the wrong do_not_mark_edits value.
if (!working_set->do_not_mark_edits){ if (!working_set->do_not_mark_edits){
if (!file->edit_finished_marked == 0){ if (!file->edit_finished_marked){
zdll_push_back(working_set->edit_finished_list_first,
working_set->edit_finished_list_last,
&file->edit_finished_mark_node);
file->edit_finished_marked = true; file->edit_finished_marked = true;
dll_insert_back(&working_set->edit_finished_sentinel,
&file->edit_finished_mark_node);
working_set->edit_finished_count += 1; working_set->edit_finished_count += 1;
} }
} }
@ -534,14 +463,10 @@ file_unmark_edit_finished(Working_Set *working_set, Editing_File *file){
b32 result = false; b32 result = false;
if (!working_set->do_not_mark_edits){ if (!working_set->do_not_mark_edits){
if (file->edit_finished_marked){ 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; file->edit_finished_marked = false;
dll_remove(&file->edit_finished_mark_node);
working_set->edit_finished_count -= 1; working_set->edit_finished_count -= 1;
block_zero_struct(&file->edit_finished_mark_node);
result = true; result = true;
} }
} }
@ -553,7 +478,7 @@ file_unmark_edit_finished(Working_Set *working_set, Editing_File *file){
internal Editing_File* internal Editing_File*
imp_get_file(Models *models, Buffer_ID buffer_id){ imp_get_file(Models *models, Buffer_ID buffer_id){
Working_Set *working_set = &models->working_set; 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)){ if (file != 0 && !file_is_ready(file)){
file = 0; file = 0;
} }
@ -562,3 +487,5 @@ imp_get_file(Models *models, Buffer_ID buffer_id){
// BOTTOM // BOTTOM

View File

@ -12,11 +12,37 @@
#if !defined(FRED_WORKING_SET_H) #if !defined(FRED_WORKING_SET_H)
#define FRED_WORKING_SET_H #define FRED_WORKING_SET_H
struct File_Array{ struct Working_Set{
Editing_File *files; Arena arena;
i32 size;
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{ struct Working_Set{
File_Array *file_arrays; File_Array *file_arrays;
i32 file_count; i32 file_count;
@ -45,11 +71,10 @@ struct Working_Set{
i32 clipboard_current; i32 clipboard_current;
i32 clipboard_rolling; i32 clipboard_rolling;
Node *sync_check_iter;
i32 default_display_width; i32 default_display_width;
i32 default_minimum_base_display_width; i32 default_minimum_base_display_width;
}; };
#endif
internal void internal void
file_mark_edit_finished(Working_Set *working_set, Editing_File *file); file_mark_edit_finished(Working_Set *working_set, Editing_File *file);