New working set implementation
This commit is contained in:
parent
62d8c4bae0
commit
8064f780af
19
4ed.cpp
19
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);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
16
4ed_edit.cpp
16
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);
|
||||
|
|
11
4ed_file.cpp
11
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){
|
||||
|
|
13
4ed_file.h
13
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;
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
13
4ed_view.cpp
13
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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue