diff --git a/4ed.cpp b/4ed.cpp index 4932f53e..0bc9be89 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -268,6 +268,8 @@ App_Init_Sig(app_init){ profile_init(&models->profile_list); + managed_ids_init(tctx->allocator, &models->managed_id_set); + API_VTable_custom custom_vtable = {}; custom_api_fill_vtable(&custom_vtable); API_VTable_system system_vtable = {}; @@ -275,11 +277,6 @@ App_Init_Sig(app_init){ Custom_Layer_Init_Type *custom_init = api.init_apis(&custom_vtable, &system_vtable); Assert(custom_init != 0); - Application_Links app = {}; - app.tctx = tctx; - app.cmd_context = models; - custom_init(&app); - // NOTE(allen): coroutines coroutine_system_init(&models->coroutines); @@ -308,13 +305,11 @@ App_Init_Sig(app_init){ } } - managed_ids_init(tctx->allocator, &models->managed_id_set); lifetime_allocator_init(tctx->allocator, &models->lifetime_allocator); dynamic_workspace_init(&models->lifetime_allocator, DynamicWorkspace_Global, 0, &models->dynamic_workspace); // NOTE(allen): file setup working_set_init(models, &models->working_set); - Mutex_Lock file_order_lock(models->working_set.mutex); // NOTE(allen): @@ -350,6 +345,17 @@ App_Init_Sig(app_init){ models->title_space = push_array(arena, char, models->title_capacity); block_copy(models->title_space, WINDOW_NAME, sizeof(WINDOW_NAME)); + // NOTE(allen): miscellaneous init + hot_directory_init(arena, &models->hot_directory, current_directory); + child_process_container_init(tctx->allocator, &models->child_processes); + models->period_wakeup_timer = system_wake_up_timer_create(); + + // NOTE(allen): custom layer init + Application_Links app = {}; + app.tctx = tctx; + app.cmd_context = models; + custom_init(&app); + // NOTE(allen): init baked in buffers File_Init init_files[] = { { string_u8_litinit("*messages*"), &models->message_buffer , true , }, @@ -384,11 +390,6 @@ App_Init_Sig(app_init){ View *new_view = live_set_alloc_view(&models->lifetime_allocator, &models->view_set, panel); view_init(tctx, models, new_view, models->scratch_buffer, models->view_event_handler); } - - // NOTE(allen): miscellaneous init - hot_directory_init(arena, &models->hot_directory, current_directory); - child_process_container_init(tctx->allocator, &models->child_processes); - models->period_wakeup_timer = system_wake_up_timer_create(); } App_Step_Sig(app_step){ @@ -601,12 +602,12 @@ App_Step_Sig(app_step){ if (cmd_func.custom_func != 0){ View *view = imp_get_view(models, cmd_func.view_id); if (view != 0){ - input_node_next = input_node; - Input_Event cmd_func_event = {}; + input_node_next = input_node; + Input_Event cmd_func_event = {}; cmd_func_event.kind = InputEventKind_CustomFunction; cmd_func_event.custom_func = cmd_func.custom_func; - co_send_event(tctx, models, view, &cmd_func_event); - continue; + co_send_event(tctx, models, view, &cmd_func_event); + continue; } } @@ -618,9 +619,9 @@ App_Step_Sig(app_step){ simulated_input = &virtual_event; } else{ - if (input_node == 0){ - break; - } + if (input_node == 0){ + break; + } input_node_next = input_node->next; simulated_input = &input_node->event; @@ -632,9 +633,9 @@ App_Step_Sig(app_step){ if (simulated_input->kind == InputEventKind_KeyStroke || simulated_input->kind == InputEventKind_KeyRelease || simulated_input->kind == InputEventKind_TextInsert){ - Temp_Memory_Block temp_key_line(scratch); - String_Const_u8 key_line = stringize_keyboard_event(scratch, simulated_input); - output_file_append(tctx, models, models->keyboard_buffer, key_line); + Temp_Memory_Block temp_key_line(scratch); + String_Const_u8 key_line = stringize_keyboard_event(scratch, simulated_input); + output_file_append(tctx, models, models->keyboard_buffer, key_line); } } diff --git a/4ed_api_implementation.cpp b/4ed_api_implementation.cpp index 7774a320..8d1a5bcb 100644 --- a/4ed_api_implementation.cpp +++ b/4ed_api_implementation.cpp @@ -2019,11 +2019,11 @@ managed_scope_allocator(Application_Links *app, Managed_Scope scope) } api(custom) function Managed_ID -managed_id_declare(Application_Links *app, String_Const_u8 name) +managed_id_declare(Application_Links *app, String_Const_u8 group, String_Const_u8 name) { Models *models = (Models*)app->cmd_context; Managed_ID_Set *set = &models->managed_id_set; - return(managed_ids_declare(set, name)); + return(managed_ids_declare(set, group, name)); } api(custom) function void* diff --git a/4ed_app_target.cpp b/4ed_app_target.cpp index 09c60b4c..b37f9e09 100644 --- a/4ed_app_target.cpp +++ b/4ed_app_target.cpp @@ -15,8 +15,8 @@ #include "4coder_version.h" #include "4coder_table.h" #include "4coder_events.h" -#include "4coder_default_colors.h" #include "4coder_types.h" +#include "4coder_default_colors.h" #define STATIC_LINK_API #include "generated/custom_api.h" diff --git a/4ed_dynamic_variables.cpp b/4ed_dynamic_variables.cpp index 0b66b9db..877e3413 100644 --- a/4ed_dynamic_variables.cpp +++ b/4ed_dynamic_variables.cpp @@ -1,476 +1,493 @@ -/* - * Mr. 4th Dimention - Allen Webster - * - * 22.06.2018 - * - * Dynamic variable system - * - */ - -// TOP - -internal void -managed_ids_init(Base_Allocator *allocator, Managed_ID_Set *set){ - set->arena = make_arena(allocator, KB(4), 8); - set->name_to_id_table = make_table_Data_u64(allocator, 40); - set->id_counter = 1; -} - -internal Managed_ID -managed_ids_declare(Managed_ID_Set *set, String_Const_u8 name){ - Managed_ID result = 0; - Data data = make_data(name.str, name.size); - Table_Lookup lookup = table_lookup(&set->name_to_id_table, data); - if (lookup.found_match){ - table_read(&set->name_to_id_table, lookup, &result); - } - else{ - result = set->id_counter; - set->id_counter += 1; - data = push_data_copy(&set->arena, data); - table_insert(&set->name_to_id_table, data, result); - } - return(result); -} - -//////////////////////////////// - -internal void -dynamic_variable_block_init(Base_Allocator *allocator, Dynamic_Variable_Block *block){ - block->arena = make_arena(allocator, KB(4), 8); - block->id_to_data_table = make_table_u64_Data(allocator, 20); -} - -internal Data -dynamic_variable_get(Dynamic_Variable_Block *block, Managed_ID id, umem size){ - Data result = {}; - Table_Lookup lookup = table_lookup(&block->id_to_data_table, id); - if (lookup.found_match){ - table_read(&block->id_to_data_table, lookup, &result); - } - else{ - result = push_data(&block->arena, size); - block_zero(result); - table_insert(&block->id_to_data_table, id, result); - } - return(result); -} - -internal void -dynamic_variable_erase(Dynamic_Variable_Block *block, Managed_ID id){ - table_erase(&block->id_to_data_table, id); -} - -//////////////////////////////// - -internal void -lifetime_allocator_init(Base_Allocator *base_allocator, Lifetime_Allocator *lifetime_allocator){ - block_zero_struct(lifetime_allocator); - lifetime_allocator->allocator = base_allocator; - lifetime_allocator->node_arena = make_arena(base_allocator, KB(4)); - lifetime_allocator->key_table = make_table_Data_u64(base_allocator, 100); - lifetime_allocator->key_check_table = make_table_u64_u64(base_allocator, 100); - lifetime_allocator->scope_id_to_scope_ptr_table = make_table_u64_u64(base_allocator, 100); -} - -//////////////////////////////// - -internal void -dynamic_workspace_init(Lifetime_Allocator *lifetime_allocator, i32 user_type, void *user_back_ptr, Dynamic_Workspace *workspace){ - block_zero_struct(workspace); - heap_init(&workspace->heap, lifetime_allocator->allocator); - workspace->heap_wrapper = base_allocator_on_heap(&workspace->heap); - workspace->object_id_to_object_ptr = make_table_u64_u64(&workspace->heap_wrapper, 10); - dynamic_variable_block_init(&workspace->heap_wrapper, &workspace->var_block); - if (lifetime_allocator->scope_id_counter == 0){ - lifetime_allocator->scope_id_counter = 1; - } - workspace->scope_id = lifetime_allocator->scope_id_counter++; - table_insert(&lifetime_allocator->scope_id_to_scope_ptr_table, - workspace->scope_id, (u64)PtrAsInt(workspace)); - workspace->user_type = user_type; - workspace->user_back_ptr = user_back_ptr; -} - -internal void -dynamic_workspace_free(Lifetime_Allocator *lifetime_allocator, Dynamic_Workspace *workspace){ - table_erase(&lifetime_allocator->scope_id_to_scope_ptr_table, workspace->scope_id); - heap_free_all(&workspace->heap); -} - -internal void -dynamic_workspace_clear_contents(Dynamic_Workspace *workspace){ - Base_Allocator *base_allocator = heap_get_base_allocator(&workspace->heap); - heap_free_all(&workspace->heap); - heap_init(&workspace->heap, base_allocator); - workspace->heap_wrapper = base_allocator_on_heap(&workspace->heap); - workspace->object_id_to_object_ptr = make_table_u64_u64(&workspace->heap_wrapper, 10); - dynamic_variable_block_init(&workspace->heap_wrapper, &workspace->var_block); - block_zero_struct(&workspace->buffer_markers_list); - workspace->total_marker_count = 0; -} - -internal u32 -dynamic_workspace_store_pointer(Dynamic_Workspace *workspace, void *ptr){ - if (workspace->object_id_counter == 0){ - workspace->object_id_counter = 1; - } - u32 id = workspace->object_id_counter++; - table_insert(&workspace->object_id_to_object_ptr, id, (u64)PtrAsInt(ptr)); - return(id); -} - -internal void -dynamic_workspace_erase_pointer(Dynamic_Workspace *workspace, u32 id){ - table_erase(&workspace->object_id_to_object_ptr, id); -} - -internal void* -dynamic_workspace_get_pointer(Dynamic_Workspace *workspace, u32 id){ - void *result = 0; - Table_Lookup lookup = table_lookup(&workspace->object_id_to_object_ptr, id); - if (lookup.found_match){ - u64 val = 0; - table_read(&workspace->object_id_to_object_ptr, lookup, &val); - result = IntAsPtr(val); - } - return(result); -} - -//////////////////////////////// - -internal Data -lifetime__key_as_data(Lifetime_Object **members, i32 count){ - return(make_data(members, sizeof(*members)*count)); -} - -internal Data -lifetime__key_as_data(Lifetime_Key *key){ - return(lifetime__key_as_data(key->members, key->count)); -} - -internal void -lifetime__free_key(Lifetime_Allocator *lifetime_allocator, Lifetime_Key *key, Lifetime_Object *skip_object){ - // Deinit - dynamic_workspace_free(lifetime_allocator, &key->dynamic_workspace); - - // Remove From Objects - i32 count = key->count; - Lifetime_Object **object_ptr = key->members; - for (i32 i = 0; i < count; i += 1, object_ptr += 1){ - if (*object_ptr == skip_object) continue; - - Lifetime_Key_Ref_Node *delete_point_node = 0; - i32 delete_point_i = 0; - - i32 key_i = 0; - Lifetime_Object *object = *object_ptr; - for (Lifetime_Key_Ref_Node *node = object->key_node_first; - node != 0; - node = node->next){ - i32 one_past_last = clamp_top(ArrayCount(node->keys), object->key_count - key_i); - for (i32 j = 0; j < one_past_last; j += 1){ - if (node->keys[j] == key){ - delete_point_node = node; - delete_point_i = j; - goto double_break; - } - } - key_i += one_past_last; - } - double_break:; - - Assert(delete_point_node != 0); - Lifetime_Key_Ref_Node *last_node = object->key_node_last; - Lifetime_Key *last_key = last_node->keys[(object->key_count - 1) % ArrayCount(last_node->keys)]; - Assert(last_key != 0); - delete_point_node->keys[delete_point_i] = last_key; - object->key_count -= 1; - - if ((object->key_count % lifetime_key_reference_per_node) == 0){ - zdll_remove(object->key_node_first, object->key_node_last, last_node); - sll_stack_push(lifetime_allocator->free_key_references, last_node); - } - } - - // Free - Data key_data = lifetime__key_as_data(key); - table_erase(&lifetime_allocator->key_table, key_data); - table_erase(&lifetime_allocator->key_check_table, (u64)PtrAsInt(key)); - base_free(lifetime_allocator->allocator, key->members); - sll_stack_push(lifetime_allocator->free_keys, key); -} - -internal Lifetime_Key_Ref_Node* -lifetime__alloc_key_reference_node(Lifetime_Allocator *lifetime_allocator){ - Assert(lifetime_allocator != 0); - Lifetime_Key_Ref_Node *result = lifetime_allocator->free_key_references; - if (result == 0){ - result = push_array(&lifetime_allocator->node_arena, Lifetime_Key_Ref_Node, 1); - } - else{ - sll_stack_pop(lifetime_allocator->free_key_references); - } - return(result); -} - -internal void -lifetime__object_add_key(Lifetime_Allocator *lifetime_allocator, Lifetime_Object *object, Lifetime_Key *key){ - Lifetime_Key_Ref_Node *last_node = object->key_node_last; - b32 insert_on_new_node = false; - if (last_node == 0){ - insert_on_new_node = true; - } - else{ - i32 next_insert_slot = object->key_count%ArrayCount(last_node->keys); - if (next_insert_slot != 0){ - last_node->keys[next_insert_slot] = key; - object->key_count += 1; - } - else{ - insert_on_new_node = true; - } - } - if (insert_on_new_node){ - Lifetime_Key_Ref_Node *new_node = lifetime__alloc_key_reference_node(lifetime_allocator); - zdll_push_back(object->key_node_first, object->key_node_last, new_node); - block_zero_struct(new_node->keys); - new_node->keys[0] = key; - object->key_count += 1; - } -} - -internal Lifetime_Object* -lifetime_alloc_object(Lifetime_Allocator *lifetime_allocator, i32 user_type, void *user_back_ptr){ - Lifetime_Object *object = lifetime_allocator->free_objects; - if (object == 0){ - object = push_array(&lifetime_allocator->node_arena, Lifetime_Object, 1); - } - else{ - sll_stack_pop(lifetime_allocator->free_objects); - } - block_zero_struct(object); - dynamic_workspace_init(lifetime_allocator, user_type, user_back_ptr, &object->workspace); - return(object); -} - -internal void -lifetime__object_free_all_keys(Lifetime_Allocator *lifetime_allocator, Lifetime_Object *lifetime_object){ - i32 key_i = 0; - for (Lifetime_Key_Ref_Node *node = lifetime_object->key_node_first; - node != 0; - node = node->next){ - i32 one_past_last = clamp_top(ArrayCount(node->keys), lifetime_object->key_count - key_i); - for (i32 i = 0; i < one_past_last; i += 1){ - lifetime__free_key(lifetime_allocator, node->keys[i], lifetime_object); - } - key_i += one_past_last; - } - - if (lifetime_object->key_count > 0){ - lifetime_object->key_node_last->next = lifetime_allocator->free_key_references; - lifetime_allocator->free_key_references = lifetime_object->key_node_first; - } -} - -internal void -lifetime__object_clear_all_keys(Lifetime_Allocator *lifetime_allocator, Lifetime_Object *lifetime_object){ - i32 key_i = 0; - for (Lifetime_Key_Ref_Node *node = lifetime_object->key_node_first; - node != 0; - node = node->next){ - i32 one_past_last = clamp_top(ArrayCount(node->keys), lifetime_object->key_count - key_i); - Lifetime_Key **key_ptr = node->keys; - for (i32 i = 0; i < one_past_last; i += 1, key_ptr += 1){ - dynamic_workspace_clear_contents(&(*key_ptr)->dynamic_workspace); - } - key_i += one_past_last; - } -} - -internal void -lifetime_free_object(Lifetime_Allocator *lifetime_allocator, Lifetime_Object *lifetime_object){ - lifetime__object_free_all_keys(lifetime_allocator, lifetime_object); - dynamic_workspace_free(lifetime_allocator, &lifetime_object->workspace); - sll_stack_push(lifetime_allocator->free_objects, lifetime_object); -} - -internal void -lifetime_object_reset(Lifetime_Allocator *lifetime_allocator, Lifetime_Object *lifetime_object){ - lifetime__object_clear_all_keys(lifetime_allocator, lifetime_object); - dynamic_workspace_clear_contents(&lifetime_object->workspace); -} - -internal i32 -lifetime_sort_object_set__part(Lifetime_Object **ptr_array, i32 first, i32 one_past_last){ - i32 pivot_index = one_past_last - 1; - Lifetime_Object *pivot = ptr_array[pivot_index]; - i32 j = first; - for (i32 i = first; i < pivot_index; i += 1){ - Lifetime_Object *object = ptr_array[i]; - if (object < pivot){ - Swap(Lifetime_Object*, ptr_array[i], ptr_array[j]); - j += 1; - } - } - Swap(Lifetime_Object*, ptr_array[j], ptr_array[pivot_index]); - return(j); -} - -internal void -lifetime_sort_object_set__quick(Lifetime_Object **ptr_array, i32 first, i32 one_past_last){ - if (first + 1 < one_past_last){ - i32 pivot = lifetime_sort_object_set__part(ptr_array, first, one_past_last); - lifetime_sort_object_set__quick(ptr_array, first, pivot); - lifetime_sort_object_set__quick(ptr_array, pivot + 1, one_past_last); - } -} - -internal i32 -lifetime_sort_and_dedup_object_set(Lifetime_Object **ptr_array, i32 count){ - lifetime_sort_object_set__quick(ptr_array, 0, count); - Lifetime_Object **ptr_write = ptr_array + 1; - Lifetime_Object **ptr_read = ptr_array + 1; - for (i32 i = 1; i < count; i += 1, ptr_read += 1){ - if (ptr_read[-1] < ptr_read[0]){ - *ptr_write = *ptr_read; - ptr_write += 1; - } - } - return((i32)(ptr_write - ptr_array)); -} - -internal Lifetime_Key* -lifetime_get_or_create_intersection_key(Lifetime_Allocator *lifetime_allocator, Lifetime_Object **object_ptr_array, i32 count){ - { - Data key_data = lifetime__key_as_data(object_ptr_array, count); - Table_Lookup lookup = table_lookup(&lifetime_allocator->key_table, key_data); - if (lookup.found_match){ - u64 val = 0; - table_read(&lifetime_allocator->key_table, lookup, &val); - return((Lifetime_Key*)IntAsPtr(val)); - } - } - - // Allocate - Lifetime_Key *new_key = lifetime_allocator->free_keys; - if (new_key == 0){ - new_key = push_array(&lifetime_allocator->node_arena, Lifetime_Key, 1); - } - else{ - sll_stack_pop(lifetime_allocator->free_keys); - } - block_zero_struct(new_key); - - // Add to Objects - Lifetime_Object **object_ptr = object_ptr_array; - for (i32 i = 0; i < count; i += 1, object_ptr += 1){ - Lifetime_Object *object = *object_ptr; - lifetime__object_add_key(lifetime_allocator, object, new_key); - } - - // Initialize - umem new_memory_size = sizeof(Lifetime_Object*)*count; - Data new_memory = base_allocate(lifetime_allocator->allocator, new_memory_size); - new_key->members = (Lifetime_Object**)new_memory.data; - block_copy_dynamic_array(new_key->members, object_ptr_array, count); - new_key->count = count; - dynamic_workspace_init(lifetime_allocator, - DynamicWorkspace_Intersected, new_key, - &new_key->dynamic_workspace); - - { - Data key_data = lifetime__key_as_data(new_key); - u64 new_key_val = (u64)PtrAsInt(new_key); - table_insert(&lifetime_allocator->key_table, key_data, new_key_val); - table_insert(&lifetime_allocator->key_check_table, new_key_val, new_key_val); - } - - return(new_key); -} - -internal b32 -lifetime_key_check(Lifetime_Allocator *lifetime_allocator, Lifetime_Key *key){ - Table_Lookup lookup = table_lookup(&lifetime_allocator->key_check_table, (u64)PtrAsInt(key)); - return(lookup.found_match); -} - -//////////////////////////////// - -// TODO(allen): move this shit somewhere real, clean up all object creation functions to be more cleanly layered. -internal u8* -get_dynamic_object_memory_ptr(Managed_Object_Standard_Header *header){ - u8 *ptr = 0; - if (header != 0){ - switch (header->type){ - case ManagedObjectType_Memory: - case ManagedObjectType_Markers: - { - ptr = ((u8*)header) + managed_header_type_sizes[header->type]; - }break; - } - } - return(ptr); -} - -internal Managed_Object -managed_object_alloc_managed_memory(Dynamic_Workspace *workspace, i32 item_size, i32 count, void **ptr_out){ - i32 size = item_size*count; - Data new_memory = base_allocate(&workspace->heap_wrapper, sizeof(Managed_Memory_Header) + size); - void *ptr = new_memory.data; - Managed_Memory_Header *header = (Managed_Memory_Header*)ptr; - header->std_header.type = ManagedObjectType_Memory; - header->std_header.item_size = item_size; - header->std_header.count = count; - if (ptr_out != 0){ - *ptr_out = get_dynamic_object_memory_ptr(&header->std_header); - } - u32 id = dynamic_workspace_store_pointer(workspace, ptr); - return(((u64)workspace->scope_id << 32) | (u64)id); -} - -internal Managed_Object -managed_object_alloc_buffer_markers(Dynamic_Workspace *workspace, Buffer_ID buffer_id, i32 count, Marker **markers_out){ - i32 size = count*sizeof(Marker); - Data new_memory = base_allocate(&workspace->heap_wrapper, size + sizeof(Managed_Buffer_Markers_Header)); - void *ptr = new_memory.data; - Managed_Buffer_Markers_Header *header = (Managed_Buffer_Markers_Header*)ptr; - header->std_header.type = ManagedObjectType_Markers; - header->std_header.item_size = sizeof(Marker); - header->std_header.count = count; - zdll_push_back(workspace->buffer_markers_list.first, workspace->buffer_markers_list.last, header); - workspace->buffer_markers_list.count += 1; - workspace->total_marker_count += count; - header->buffer_id = buffer_id; - if (markers_out != 0){ - *markers_out = (Marker*)get_dynamic_object_memory_ptr(&header->std_header); - } - u32 id = dynamic_workspace_store_pointer(workspace, ptr); - return(((u64)workspace->scope_id << 32) | (u64)id); -} - -internal b32 -managed_object_free(Dynamic_Workspace *workspace, Managed_Object object){ - b32 result = false; - u32 lo_id = object&max_u32; - u8 *object_ptr = (u8*)dynamic_workspace_get_pointer(workspace, lo_id); - if (object_ptr != 0){ - Managed_Object_Type *type = (Managed_Object_Type*)object_ptr; - switch (*type){ - case ManagedObjectType_Markers: - { - Managed_Buffer_Markers_Header *header = (Managed_Buffer_Markers_Header*)object_ptr; - workspace->total_marker_count -= header->std_header.count; - zdll_remove(workspace->buffer_markers_list.first, workspace->buffer_markers_list.last, header); - workspace->buffer_markers_list.count -= 1; - }break; - } - dynamic_workspace_erase_pointer(workspace, lo_id); - base_free(&workspace->heap_wrapper, object_ptr); - result = true; - } - return(result); -} - -// BOTTOM - +/* + * Mr. 4th Dimention - Allen Webster + * + * 22.06.2018 + * + * Dynamic variable system + * + */ + +// TOP + +internal void +managed_ids_init(Base_Allocator *allocator, Managed_ID_Set *set){ + set->arena = make_arena(allocator, KB(4), 8); + set->name_to_group_table = make_table_Data_u64(allocator, 20); + } + +internal Managed_ID +managed_ids_declare(Managed_ID_Set *set, String_Const_u8 group_name, String_Const_u8 name){ + Managed_ID_Group *group = 0; +{ + Data data = make_data(group_name.str, group_name.size); + Table_Lookup lookup = table_lookup(&set->name_to_group_table, data); + if (lookup.found_match){ + u64 val = 0; + table_read(&set->name_to_group_table, lookup, &val); + group = (Managed_ID_Group*)IntAsPtr(val); + } + else{ + group = push_array(&set->arena, Managed_ID_Group, 1); + group->name_to_id_table = make_table_Data_u64(set->arena.base_allocator, 50); + data = push_data_copy(&set->arena, data); + table_insert(&set->name_to_group_table, data, PtrAsInt(group)); + } + } + Managed_ID result = 0; + { + Data data = make_data(name.str, name.size); + Table_Lookup lookup = table_lookup(&group->name_to_id_table, data); + if (lookup.found_match){ + table_read(&group->name_to_id_table, lookup, &result); + } + else{ + result = group->id_counter; + group->id_counter += 1; + data = push_data_copy(&set->arena, data); + table_insert(&group->name_to_id_table, data, result); + } + } + return(result); +} + +//////////////////////////////// + +internal void +dynamic_variable_block_init(Base_Allocator *allocator, Dynamic_Variable_Block *block){ + block->arena = make_arena(allocator, KB(4), 8); + block->id_to_data_table = make_table_u64_Data(allocator, 20); +} + +internal Data +dynamic_variable_get(Dynamic_Variable_Block *block, Managed_ID id, umem size){ + Data result = {}; + Table_Lookup lookup = table_lookup(&block->id_to_data_table, id); + if (lookup.found_match){ + table_read(&block->id_to_data_table, lookup, &result); + } + else{ + result = push_data(&block->arena, size); + block_zero(result); + table_insert(&block->id_to_data_table, id, result); + } + return(result); +} + +internal void +dynamic_variable_erase(Dynamic_Variable_Block *block, Managed_ID id){ + table_erase(&block->id_to_data_table, id); +} + +//////////////////////////////// + +internal void +lifetime_allocator_init(Base_Allocator *base_allocator, Lifetime_Allocator *lifetime_allocator){ + block_zero_struct(lifetime_allocator); + lifetime_allocator->allocator = base_allocator; + lifetime_allocator->node_arena = make_arena(base_allocator, KB(4)); + lifetime_allocator->key_table = make_table_Data_u64(base_allocator, 100); + lifetime_allocator->key_check_table = make_table_u64_u64(base_allocator, 100); + lifetime_allocator->scope_id_to_scope_ptr_table = make_table_u64_u64(base_allocator, 100); +} + +//////////////////////////////// + +internal void +dynamic_workspace_init(Lifetime_Allocator *lifetime_allocator, i32 user_type, void *user_back_ptr, Dynamic_Workspace *workspace){ + block_zero_struct(workspace); + heap_init(&workspace->heap, lifetime_allocator->allocator); + workspace->heap_wrapper = base_allocator_on_heap(&workspace->heap); + workspace->object_id_to_object_ptr = make_table_u64_u64(&workspace->heap_wrapper, 10); + dynamic_variable_block_init(&workspace->heap_wrapper, &workspace->var_block); + if (lifetime_allocator->scope_id_counter == 0){ + lifetime_allocator->scope_id_counter = 1; + } + workspace->scope_id = lifetime_allocator->scope_id_counter++; + table_insert(&lifetime_allocator->scope_id_to_scope_ptr_table, + workspace->scope_id, (u64)PtrAsInt(workspace)); + workspace->user_type = user_type; + workspace->user_back_ptr = user_back_ptr; +} + +internal void +dynamic_workspace_free(Lifetime_Allocator *lifetime_allocator, Dynamic_Workspace *workspace){ + table_erase(&lifetime_allocator->scope_id_to_scope_ptr_table, workspace->scope_id); + heap_free_all(&workspace->heap); +} + +internal void +dynamic_workspace_clear_contents(Dynamic_Workspace *workspace){ + Base_Allocator *base_allocator = heap_get_base_allocator(&workspace->heap); + heap_free_all(&workspace->heap); + heap_init(&workspace->heap, base_allocator); + workspace->heap_wrapper = base_allocator_on_heap(&workspace->heap); + workspace->object_id_to_object_ptr = make_table_u64_u64(&workspace->heap_wrapper, 10); + dynamic_variable_block_init(&workspace->heap_wrapper, &workspace->var_block); + block_zero_struct(&workspace->buffer_markers_list); + workspace->total_marker_count = 0; +} + +internal u32 +dynamic_workspace_store_pointer(Dynamic_Workspace *workspace, void *ptr){ + if (workspace->object_id_counter == 0){ + workspace->object_id_counter = 1; + } + u32 id = workspace->object_id_counter++; + table_insert(&workspace->object_id_to_object_ptr, id, (u64)PtrAsInt(ptr)); + return(id); +} + +internal void +dynamic_workspace_erase_pointer(Dynamic_Workspace *workspace, u32 id){ + table_erase(&workspace->object_id_to_object_ptr, id); +} + +internal void* +dynamic_workspace_get_pointer(Dynamic_Workspace *workspace, u32 id){ + void *result = 0; + Table_Lookup lookup = table_lookup(&workspace->object_id_to_object_ptr, id); + if (lookup.found_match){ + u64 val = 0; + table_read(&workspace->object_id_to_object_ptr, lookup, &val); + result = IntAsPtr(val); + } + return(result); +} + +//////////////////////////////// + +internal Data +lifetime__key_as_data(Lifetime_Object **members, i32 count){ + return(make_data(members, sizeof(*members)*count)); +} + +internal Data +lifetime__key_as_data(Lifetime_Key *key){ + return(lifetime__key_as_data(key->members, key->count)); +} + +internal void +lifetime__free_key(Lifetime_Allocator *lifetime_allocator, Lifetime_Key *key, Lifetime_Object *skip_object){ + // Deinit + dynamic_workspace_free(lifetime_allocator, &key->dynamic_workspace); + + // Remove From Objects + i32 count = key->count; + Lifetime_Object **object_ptr = key->members; + for (i32 i = 0; i < count; i += 1, object_ptr += 1){ + if (*object_ptr == skip_object) continue; + + Lifetime_Key_Ref_Node *delete_point_node = 0; + i32 delete_point_i = 0; + + i32 key_i = 0; + Lifetime_Object *object = *object_ptr; + for (Lifetime_Key_Ref_Node *node = object->key_node_first; + node != 0; + node = node->next){ + i32 one_past_last = clamp_top(ArrayCount(node->keys), object->key_count - key_i); + for (i32 j = 0; j < one_past_last; j += 1){ + if (node->keys[j] == key){ + delete_point_node = node; + delete_point_i = j; + goto double_break; + } + } + key_i += one_past_last; + } + double_break:; + + Assert(delete_point_node != 0); + Lifetime_Key_Ref_Node *last_node = object->key_node_last; + Lifetime_Key *last_key = last_node->keys[(object->key_count - 1) % ArrayCount(last_node->keys)]; + Assert(last_key != 0); + delete_point_node->keys[delete_point_i] = last_key; + object->key_count -= 1; + + if ((object->key_count % lifetime_key_reference_per_node) == 0){ + zdll_remove(object->key_node_first, object->key_node_last, last_node); + sll_stack_push(lifetime_allocator->free_key_references, last_node); + } + } + + // Free + Data key_data = lifetime__key_as_data(key); + table_erase(&lifetime_allocator->key_table, key_data); + table_erase(&lifetime_allocator->key_check_table, (u64)PtrAsInt(key)); + base_free(lifetime_allocator->allocator, key->members); + sll_stack_push(lifetime_allocator->free_keys, key); +} + +internal Lifetime_Key_Ref_Node* +lifetime__alloc_key_reference_node(Lifetime_Allocator *lifetime_allocator){ + Assert(lifetime_allocator != 0); + Lifetime_Key_Ref_Node *result = lifetime_allocator->free_key_references; + if (result == 0){ + result = push_array(&lifetime_allocator->node_arena, Lifetime_Key_Ref_Node, 1); + } + else{ + sll_stack_pop(lifetime_allocator->free_key_references); + } + return(result); +} + +internal void +lifetime__object_add_key(Lifetime_Allocator *lifetime_allocator, Lifetime_Object *object, Lifetime_Key *key){ + Lifetime_Key_Ref_Node *last_node = object->key_node_last; + b32 insert_on_new_node = false; + if (last_node == 0){ + insert_on_new_node = true; + } + else{ + i32 next_insert_slot = object->key_count%ArrayCount(last_node->keys); + if (next_insert_slot != 0){ + last_node->keys[next_insert_slot] = key; + object->key_count += 1; + } + else{ + insert_on_new_node = true; + } + } + if (insert_on_new_node){ + Lifetime_Key_Ref_Node *new_node = lifetime__alloc_key_reference_node(lifetime_allocator); + zdll_push_back(object->key_node_first, object->key_node_last, new_node); + block_zero_struct(new_node->keys); + new_node->keys[0] = key; + object->key_count += 1; + } +} + +internal Lifetime_Object* +lifetime_alloc_object(Lifetime_Allocator *lifetime_allocator, i32 user_type, void *user_back_ptr){ + Lifetime_Object *object = lifetime_allocator->free_objects; + if (object == 0){ + object = push_array(&lifetime_allocator->node_arena, Lifetime_Object, 1); + } + else{ + sll_stack_pop(lifetime_allocator->free_objects); + } + block_zero_struct(object); + dynamic_workspace_init(lifetime_allocator, user_type, user_back_ptr, &object->workspace); + return(object); +} + +internal void +lifetime__object_free_all_keys(Lifetime_Allocator *lifetime_allocator, Lifetime_Object *lifetime_object){ + i32 key_i = 0; + for (Lifetime_Key_Ref_Node *node = lifetime_object->key_node_first; + node != 0; + node = node->next){ + i32 one_past_last = clamp_top(ArrayCount(node->keys), lifetime_object->key_count - key_i); + for (i32 i = 0; i < one_past_last; i += 1){ + lifetime__free_key(lifetime_allocator, node->keys[i], lifetime_object); + } + key_i += one_past_last; + } + + if (lifetime_object->key_count > 0){ + lifetime_object->key_node_last->next = lifetime_allocator->free_key_references; + lifetime_allocator->free_key_references = lifetime_object->key_node_first; + } +} + +internal void +lifetime__object_clear_all_keys(Lifetime_Allocator *lifetime_allocator, Lifetime_Object *lifetime_object){ + i32 key_i = 0; + for (Lifetime_Key_Ref_Node *node = lifetime_object->key_node_first; + node != 0; + node = node->next){ + i32 one_past_last = clamp_top(ArrayCount(node->keys), lifetime_object->key_count - key_i); + Lifetime_Key **key_ptr = node->keys; + for (i32 i = 0; i < one_past_last; i += 1, key_ptr += 1){ + dynamic_workspace_clear_contents(&(*key_ptr)->dynamic_workspace); + } + key_i += one_past_last; + } +} + +internal void +lifetime_free_object(Lifetime_Allocator *lifetime_allocator, Lifetime_Object *lifetime_object){ + lifetime__object_free_all_keys(lifetime_allocator, lifetime_object); + dynamic_workspace_free(lifetime_allocator, &lifetime_object->workspace); + sll_stack_push(lifetime_allocator->free_objects, lifetime_object); +} + +internal void +lifetime_object_reset(Lifetime_Allocator *lifetime_allocator, Lifetime_Object *lifetime_object){ + lifetime__object_clear_all_keys(lifetime_allocator, lifetime_object); + dynamic_workspace_clear_contents(&lifetime_object->workspace); +} + +internal i32 +lifetime_sort_object_set__part(Lifetime_Object **ptr_array, i32 first, i32 one_past_last){ + i32 pivot_index = one_past_last - 1; + Lifetime_Object *pivot = ptr_array[pivot_index]; + i32 j = first; + for (i32 i = first; i < pivot_index; i += 1){ + Lifetime_Object *object = ptr_array[i]; + if (object < pivot){ + Swap(Lifetime_Object*, ptr_array[i], ptr_array[j]); + j += 1; + } + } + Swap(Lifetime_Object*, ptr_array[j], ptr_array[pivot_index]); + return(j); +} + +internal void +lifetime_sort_object_set__quick(Lifetime_Object **ptr_array, i32 first, i32 one_past_last){ + if (first + 1 < one_past_last){ + i32 pivot = lifetime_sort_object_set__part(ptr_array, first, one_past_last); + lifetime_sort_object_set__quick(ptr_array, first, pivot); + lifetime_sort_object_set__quick(ptr_array, pivot + 1, one_past_last); + } +} + +internal i32 +lifetime_sort_and_dedup_object_set(Lifetime_Object **ptr_array, i32 count){ + lifetime_sort_object_set__quick(ptr_array, 0, count); + Lifetime_Object **ptr_write = ptr_array + 1; + Lifetime_Object **ptr_read = ptr_array + 1; + for (i32 i = 1; i < count; i += 1, ptr_read += 1){ + if (ptr_read[-1] < ptr_read[0]){ + *ptr_write = *ptr_read; + ptr_write += 1; + } + } + return((i32)(ptr_write - ptr_array)); +} + +internal Lifetime_Key* +lifetime_get_or_create_intersection_key(Lifetime_Allocator *lifetime_allocator, Lifetime_Object **object_ptr_array, i32 count){ + { + Data key_data = lifetime__key_as_data(object_ptr_array, count); + Table_Lookup lookup = table_lookup(&lifetime_allocator->key_table, key_data); + if (lookup.found_match){ + u64 val = 0; + table_read(&lifetime_allocator->key_table, lookup, &val); + return((Lifetime_Key*)IntAsPtr(val)); + } + } + + // Allocate + Lifetime_Key *new_key = lifetime_allocator->free_keys; + if (new_key == 0){ + new_key = push_array(&lifetime_allocator->node_arena, Lifetime_Key, 1); + } + else{ + sll_stack_pop(lifetime_allocator->free_keys); + } + block_zero_struct(new_key); + + // Add to Objects + Lifetime_Object **object_ptr = object_ptr_array; + for (i32 i = 0; i < count; i += 1, object_ptr += 1){ + Lifetime_Object *object = *object_ptr; + lifetime__object_add_key(lifetime_allocator, object, new_key); + } + + // Initialize + umem new_memory_size = sizeof(Lifetime_Object*)*count; + Data new_memory = base_allocate(lifetime_allocator->allocator, new_memory_size); + new_key->members = (Lifetime_Object**)new_memory.data; + block_copy_dynamic_array(new_key->members, object_ptr_array, count); + new_key->count = count; + dynamic_workspace_init(lifetime_allocator, + DynamicWorkspace_Intersected, new_key, + &new_key->dynamic_workspace); + + { + Data key_data = lifetime__key_as_data(new_key); + u64 new_key_val = (u64)PtrAsInt(new_key); + table_insert(&lifetime_allocator->key_table, key_data, new_key_val); + table_insert(&lifetime_allocator->key_check_table, new_key_val, new_key_val); + } + + return(new_key); +} + +internal b32 +lifetime_key_check(Lifetime_Allocator *lifetime_allocator, Lifetime_Key *key){ + Table_Lookup lookup = table_lookup(&lifetime_allocator->key_check_table, (u64)PtrAsInt(key)); + return(lookup.found_match); +} + +//////////////////////////////// + +// TODO(allen): move this shit somewhere real, clean up all object creation functions to be more cleanly layered. +internal u8* +get_dynamic_object_memory_ptr(Managed_Object_Standard_Header *header){ + u8 *ptr = 0; + if (header != 0){ + switch (header->type){ + case ManagedObjectType_Memory: + case ManagedObjectType_Markers: + { + ptr = ((u8*)header) + managed_header_type_sizes[header->type]; + }break; + } + } + return(ptr); +} + +internal Managed_Object +managed_object_alloc_managed_memory(Dynamic_Workspace *workspace, i32 item_size, i32 count, void **ptr_out){ + i32 size = item_size*count; + Data new_memory = base_allocate(&workspace->heap_wrapper, sizeof(Managed_Memory_Header) + size); + void *ptr = new_memory.data; + Managed_Memory_Header *header = (Managed_Memory_Header*)ptr; + header->std_header.type = ManagedObjectType_Memory; + header->std_header.item_size = item_size; + header->std_header.count = count; + if (ptr_out != 0){ + *ptr_out = get_dynamic_object_memory_ptr(&header->std_header); + } + u32 id = dynamic_workspace_store_pointer(workspace, ptr); + return(((u64)workspace->scope_id << 32) | (u64)id); +} + +internal Managed_Object +managed_object_alloc_buffer_markers(Dynamic_Workspace *workspace, Buffer_ID buffer_id, i32 count, Marker **markers_out){ + i32 size = count*sizeof(Marker); + Data new_memory = base_allocate(&workspace->heap_wrapper, size + sizeof(Managed_Buffer_Markers_Header)); + void *ptr = new_memory.data; + Managed_Buffer_Markers_Header *header = (Managed_Buffer_Markers_Header*)ptr; + header->std_header.type = ManagedObjectType_Markers; + header->std_header.item_size = sizeof(Marker); + header->std_header.count = count; + zdll_push_back(workspace->buffer_markers_list.first, workspace->buffer_markers_list.last, header); + workspace->buffer_markers_list.count += 1; + workspace->total_marker_count += count; + header->buffer_id = buffer_id; + if (markers_out != 0){ + *markers_out = (Marker*)get_dynamic_object_memory_ptr(&header->std_header); + } + u32 id = dynamic_workspace_store_pointer(workspace, ptr); + return(((u64)workspace->scope_id << 32) | (u64)id); +} + +internal b32 +managed_object_free(Dynamic_Workspace *workspace, Managed_Object object){ + b32 result = false; + u32 lo_id = object&max_u32; + u8 *object_ptr = (u8*)dynamic_workspace_get_pointer(workspace, lo_id); + if (object_ptr != 0){ + Managed_Object_Type *type = (Managed_Object_Type*)object_ptr; + switch (*type){ + case ManagedObjectType_Markers: + { + Managed_Buffer_Markers_Header *header = (Managed_Buffer_Markers_Header*)object_ptr; + workspace->total_marker_count -= header->std_header.count; + zdll_remove(workspace->buffer_markers_list.first, workspace->buffer_markers_list.last, header); + workspace->buffer_markers_list.count -= 1; + }break; + } + dynamic_workspace_erase_pointer(workspace, lo_id); + base_free(&workspace->heap_wrapper, object_ptr); + result = true; + } + return(result); +} + +// BOTTOM + diff --git a/4ed_dynamic_variables.h b/4ed_dynamic_variables.h index 519358ac..9bc5e7dd 100644 --- a/4ed_dynamic_variables.h +++ b/4ed_dynamic_variables.h @@ -60,12 +60,16 @@ struct Managed_Arena_Header_List{ //////////////////////////////// -struct Managed_ID_Set{ - Arena arena; +struct Managed_ID_Group{ Table_Data_u64 name_to_id_table; Managed_ID id_counter; }; +struct Managed_ID_Set{ + Arena arena; + Table_Data_u64 name_to_group_table; +}; + struct Dynamic_Variable_Block{ Arena arena; Table_u64_Data id_to_data_table; diff --git a/custom/4coder_default_bindings.cpp b/custom/4coder_default_bindings.cpp index a2423f96..083cb7cc 100644 --- a/custom/4coder_default_bindings.cpp +++ b/custom/4coder_default_bindings.cpp @@ -24,6 +24,26 @@ custom_layer_init(Application_Links *app){ Profile_Global_List *list = get_core_profile_list(app); ProfileThreadName(tctx, list, string_u8_litexpr("main")); + +#define BindAttachmentID(N) N = managed_id_declare(app, SCu8("attachment"), SCu8(#N)) + + BindAttachmentID(view_rewrite_loc); + BindAttachmentID(view_next_rewrite_loc); + BindAttachmentID(view_paste_index_loc); + BindAttachmentID(view_is_passive_loc); + BindAttachmentID(view_snap_mark_to_cursor); + BindAttachmentID(view_ui_data); + BindAttachmentID(view_highlight_range); + BindAttachmentID(view_highlight_buffer); + BindAttachmentID(view_render_hook); + BindAttachmentID(view_word_complete_menu); + + BindAttachmentID(buffer_map_id); + BindAttachmentID(buffer_eol_setting); + BindAttachmentID(buffer_lex_task); + + BindAttachmentID(sticky_jump_marker_handle); + BindAttachmentID(attachment_tokens); } #endif diff --git a/custom/4coder_default_framework.cpp b/custom/4coder_default_framework.cpp index ebcb6872..057dc0ac 100644 --- a/custom/4coder_default_framework.cpp +++ b/custom/4coder_default_framework.cpp @@ -450,24 +450,6 @@ default_4coder_initialize(Application_Links *app, String_Const_u8_Array file_nam global_config_arena = reserve_arena(app); load_config_and_apply(app, global_config_arena, &global_config, override_font_size, override_hinting); - view_rewrite_loc = managed_id_declare(app, SCu8("DEFAULT.rewrite" )); - view_next_rewrite_loc = managed_id_declare(app, SCu8("DEFAULT.next_rewrite" )); - view_paste_index_loc = managed_id_declare(app, SCu8("DEFAULT.paste_index" )); - view_is_passive_loc = managed_id_declare(app, SCu8("DEFAULT.is_passive" )); - view_snap_mark_to_cursor = managed_id_declare(app, SCu8("DEFAULT.mark_to_cursor")); - view_ui_data = managed_id_declare(app, SCu8("DEFAULT.ui_data" )); - view_highlight_range = managed_id_declare(app, SCu8("DEFAULT.highlight" )); - view_highlight_buffer = managed_id_declare(app, SCu8("DEFAULT.highlight_buf" )); - view_render_hook = managed_id_declare(app, SCu8("DEFAULT.render" )); - view_word_complete_menu = managed_id_declare(app, SCu8("DEFAULT.word_complete_menu")); - - buffer_map_id = managed_id_declare(app, SCu8("DEFAULT.buffer_map_id" )); - buffer_eol_setting = managed_id_declare(app, SCu8("DEFAULT.buffer_eol_setting")); - buffer_lex_task = managed_id_declare(app, SCu8("DEFAULT.buffer_lex_task")); - - sticky_jump_marker_handle = managed_id_declare(app, SCu8("DEFAULT.sticky_jump_marker_handle")); - attachment_tokens = managed_id_declare(app, SCu8("DEFAULT.tokens")); - // open command line files Scratch_Block scratch(app); String_Const_u8 hot_directory = push_hot_directory(app, scratch); diff --git a/custom/4coder_default_framework_variables.cpp b/custom/4coder_default_framework_variables.cpp index a68097d1..e988981c 100644 --- a/custom/4coder_default_framework_variables.cpp +++ b/custom/4coder_default_framework_variables.cpp @@ -5,6 +5,27 @@ the default 4coder behavior. // TOP +CUSTOM_ID(attachment, view_rewrite_loc); +CUSTOM_ID(attachment, view_next_rewrite_loc); +CUSTOM_ID(attachment, view_paste_index_loc); +CUSTOM_ID(attachment, view_is_passive_loc); +CUSTOM_ID(attachment, view_snap_mark_to_cursor); +CUSTOM_ID(attachment, view_ui_data); +CUSTOM_ID(attachment, view_highlight_range); +CUSTOM_ID(attachment, view_highlight_buffer); +CUSTOM_ID(attachment, view_render_hook); +CUSTOM_ID(attachment, view_word_complete_menu); + +CUSTOM_ID(attachment, buffer_map_id); +CUSTOM_ID(attachment, buffer_eol_setting); +CUSTOM_ID(attachment, buffer_lex_task); +CUSTOM_ID(attachment, buffer_wrap_lines); + +CUSTOM_ID(attachment, sticky_jump_marker_handle); +CUSTOM_ID(attachment, attachment_tokens); + +//////////////////////////////// + global b32 allow_immediate_close_without_checking_for_changes = false; global char *default_extensions[] = { @@ -30,27 +51,6 @@ global String_Const_u8 locked_buffer = {}; global View_ID build_footer_panel_view_id = 0; - -global Managed_ID view_rewrite_loc = 0; -global Managed_ID view_next_rewrite_loc = 0; -global Managed_ID view_paste_index_loc = 0; -global Managed_ID view_is_passive_loc = 0; -global Managed_ID view_snap_mark_to_cursor = 0; -global Managed_ID view_ui_data = 0; -global Managed_ID view_highlight_range = 0; -global Managed_ID view_highlight_buffer = 0; -global Managed_ID view_render_hook = 0; -global Managed_ID view_word_complete_menu = 0; - -global Managed_ID buffer_map_id = 0; -global Managed_ID buffer_eol_setting = 0; -global Managed_ID buffer_lex_task = 0; -global Managed_ID buffer_wrap_lines = 0; - -global Managed_ID sticky_jump_marker_handle = 0; - -global Managed_ID attachment_tokens = 0; - global u8 out_buffer_space[1024]; global u8 command_space[1024]; global char hot_directory_space[1024]; diff --git a/custom/4coder_default_hooks.cpp b/custom/4coder_default_hooks.cpp index ee1505cc..651de150 100644 --- a/custom/4coder_default_hooks.cpp +++ b/custom/4coder_default_hooks.cpp @@ -947,15 +947,6 @@ BUFFER_HOOK_SIG(default_begin_buffer){ } } - local_persist b32 first_call = true; - if (first_call){ - first_call = false; - buffer_map_id = managed_id_declare(app, SCu8("DEFAULT.buffer_map_id")); - buffer_eol_setting = managed_id_declare(app, SCu8("DEFAULT.buffer_eol_setting")); - buffer_lex_task = managed_id_declare(app, SCu8("DEFAULT.buffer_lex_task")); - buffer_wrap_lines = managed_id_declare(app, SCu8("DEFAULT.buffer_wrap_lines")); - } - Command_Map_ID map_id = (treat_as_code)?(default_code_map):(mapid_file); Managed_Scope scope = buffer_get_managed_scope(app, buffer_id); Command_Map_ID *map_id_ptr = scope_attachment(app, scope, buffer_map_id, Command_Map_ID); diff --git a/custom/4coder_default_include.cpp b/custom/4coder_default_include.cpp index 90362a5c..94d71592 100644 --- a/custom/4coder_default_include.cpp +++ b/custom/4coder_default_include.cpp @@ -10,9 +10,9 @@ #include "4coder_base_types.h" #include "4coder_version.h" #include "4coder_table.h" -#include "4coder_default_colors.h" #include "4coder_events.h" #include "4coder_types.h" +#include "4coder_default_colors.h" #define DYNAMIC_LINK_API #include "generated/custom_api.h" #include "4coder_system_types.h" @@ -111,6 +111,8 @@ #include "4coder_default_hooks.cpp" +#include "generated/managed_id_metadata.cpp" + #endif // BOTTOM diff --git a/custom/4coder_metadata_generator.cpp b/custom/4coder_metadata_generator.cpp index f33c1f57..092ffe3d 100644 --- a/custom/4coder_metadata_generator.cpp +++ b/custom/4coder_metadata_generator.cpp @@ -5,6 +5,7 @@ // TOP #define COMMAND_METADATA_OUT "generated/command_metadata.h" +#define ID_METADATA_OUT "generated/managed_id_metadata.cpp" #include "4coder_base_types.h" #include "4coder_token.h" @@ -23,9 +24,6 @@ #include #include -#define str_to_l_c(s) ((i32)(s).size), ((s).str) -#define str_to_c_l(s) ((s).str), ((i32)(s).size) - /////////////////////////////// struct Line_Column_Coordinates{ @@ -33,6 +31,61 @@ struct Line_Column_Coordinates{ i64 column; }; +struct Reader{ + Arena *error_arena; + u8 *source_name; + String_Const_u8 text; + Token_Array tokens; + Token *ptr; +}; + +struct Temp_Read{ + Reader *reader; + Token *pos; +}; + +typedef i32 Meta_Command_Entry_Kind; +enum{ + MetaCommandEntryKind_ERROR, + MetaCommandEntryKind_Normal, + MetaCommandEntryKind_UI, +}; + +struct Meta_Command_Entry{ + Meta_Command_Entry *next; + Meta_Command_Entry_Kind kind; + String_Const_u8 name; + u8 *source_name; + i64 line_number; + union{ + struct{ + String_Const_u8 doc; + } docstring; + }; +}; + +struct Meta_ID_Entry{ + Meta_ID_Entry *next; + String_Const_u8 group_name; + String_Const_u8 id_name; +}; + +struct Meta_Command_Entry_Arrays{ + Meta_Command_Entry *first_doc_string; + Meta_Command_Entry *last_doc_string; + i32 doc_string_count; + + Meta_Command_Entry *first_ui; + Meta_Command_Entry *last_ui; + i32 ui_count; + + Meta_ID_Entry *first_id; + Meta_ID_Entry *last_id; + i32 id_count; +}; + +/////////////////////////////// + static Line_Column_Coordinates line_column_coordinates(String_Const_u8 text, i64 pos){ if (pos < 0){ @@ -75,22 +128,10 @@ error(u8 *source_name, String_Const_u8 text, i64 pos, u8 *msg){ /////////////////////////////// -struct Reader{ - Arena *error_arena; - u8 *source_name; - String_Const_u8 text; - Token_Array tokens; - Token *ptr; -}; - -struct Temp_Read{ - Reader *reader; - Token *pos; -}; - static Reader -make_reader(Token_Array array, u8 *source_name, String_Const_u8 text){ +make_reader(Arena *error_arena, Token_Array array, u8 *source_name, String_Const_u8 text){ Reader reader = {}; + reader.error_arena = error_arena; reader.tokens = array; reader.ptr = array.tokens; reader.source_name = source_name; @@ -214,38 +255,6 @@ token_str(String_Const_u8 text, Token token){ /////////////////////////////// -typedef i32 Meta_Command_Entry_Kind; -enum{ - MetaCommandEntryKind_ERROR, - MetaCommandEntryKind_Normal, - MetaCommandEntryKind_UI, -}; - -struct Meta_Command_Entry{ - Meta_Command_Entry *next; - Meta_Command_Entry_Kind kind; - String_Const_u8 name; - u8 *source_name; - i64 line_number; - union{ - struct{ - String_Const_u8 doc; - } docstring; - }; -}; - -struct Meta_Command_Entry_Arrays{ - Meta_Command_Entry *first_doc_string; - Meta_Command_Entry *last_doc_string; - i32 doc_string_count; - - Meta_Command_Entry *first_ui; - Meta_Command_Entry *last_ui; - i32 ui_count; -}; - -/////////////////////////////// - static i32 quick_sort_part(Meta_Command_Entry **entries, i32 first, i32 one_past_last){ i32 pivot = one_past_last - 1; @@ -616,11 +625,50 @@ parse_documented_command(Arena *arena, Meta_Command_Entry_Arrays *arrays, Reader new_entry->line_number = (i32)string_to_integer(line_number, 10); new_entry->docstring.doc = doc; sll_queue_push(arrays->first_doc_string, arrays->last_doc_string, new_entry); - ++arrays->doc_string_count; + arrays->doc_string_count += 1; return(true); } +static b32 +parse_custom_id(Arena *arena, Meta_Command_Entry_Arrays *arrays, Reader *reader){ + String_Const_u8 group = {}; + String_Const_u8 id = {}; + + i64 start_pos = 0; + if (!require_key_identifier(reader, "CUSTOM_ID", &start_pos)){ + return(false); + } + + if (!require_open_parenthese(reader)){ + return(false); + } + + if (!extract_identifier(reader, &group)){ + return(false); + } + + if (!require_comma(reader)){ + return(false); + } + + if (!extract_identifier(reader, &id)){ + return(false); + } + + if (!require_close_parenthese(reader)){ + return(false); + } + + Meta_ID_Entry *new_id = push_array(arena, Meta_ID_Entry, 1); + sll_queue_push(arrays->first_id, arrays->last_id, new_id); + new_id->group_name = group; + new_id->id_name = id; + arrays->id_count += 1; + + return(true); + } + /////////////////////////////// static void @@ -628,20 +676,17 @@ parse_text(Arena *arena, Meta_Command_Entry_Arrays *entry_arrays, u8 *source_nam Token_List token_list = lex_full_input_cpp(arena, text); Token_Array array = token_array_from_list(arena, &token_list); - Reader reader_ = make_reader(array, source_name, text); + Reader reader_ = make_reader(arena, array, source_name, text); Reader *reader = &reader_; for (;;){ Token token = get_token(reader); if (token.kind == TokenBaseKind_Identifier){ - String_Const_u8 lexeme = token_str(text, token); - - b32 in_preproc_body = HasFlag(token.flags, TokenBaseFlag_PreprocessorBody); - - if (!in_preproc_body && - string_match(lexeme, string_u8_litexpr("CUSTOM_DOC"))){ - Temp_Read temp_read = begin_temp_read(reader); + if (!HasFlag(token.flags, TokenBaseFlag_PreprocessorBody)){ + String_Const_u8 lexeme = token_str(text, token); + if (string_match(lexeme, string_u8_litexpr("CUSTOM_DOC"))){ + Temp_Read temp_read = begin_temp_read(reader); b32 found_start_pos = false; for (i32 R = 0; R < 12; ++R){ @@ -666,6 +711,14 @@ parse_text(Arena *arena, Meta_Command_Entry_Arrays *entry_arrays, u8 *source_nam end_temp_read(temp_read); } } + } + else if (string_match(lexeme, string_u8_litexpr("CUSTOM_ID"))){ + Temp_Read temp_read = begin_temp_read(reader); + prev_token(reader); + if (!parse_custom_id(arena, entry_arrays, reader)){ + end_temp_read(temp_read); + } + } } } @@ -762,7 +815,7 @@ main(int argc, char **argv){ Arena arena_ = make_arena_malloc(MB(1), 8); Arena *arena = &arena_; - char *out_directory = argv[2]; + String_Const_u8 out_directory = SCu8(argv[2]); i32 start_i = 2; if (recursive){ @@ -782,50 +835,43 @@ main(int argc, char **argv){ parse_files_by_pattern(arena, &entry_arrays, pattern_name, recursive); } - umem out_dir_len = cstring_length(out_directory); - if (out_directory[0] == '"'){ - out_directory += 1; - out_dir_len -= 2; + if (out_directory.size > 2 && + out_directory.str[0] == '"' && + out_directory.str[out_directory.size - 1] == '"'){ + out_directory.str += 1; + out_directory.size -= 2; } - { - String_Const_u8 str = SCu8(out_directory, out_dir_len); - str = string_skip_chop_whitespace(str); - out_directory = (char*)str.str; - out_dir_len = str.size; - } + out_directory = string_skip_chop_whitespace(out_directory); - umem len = out_dir_len + 1 + sizeof(COMMAND_METADATA_OUT) - 1; - char *out_file_name = (char*)malloc(len + 1); - memcpy(out_file_name, out_directory, out_dir_len); - memcpy(out_file_name + out_dir_len, "/", 1); - memcpy(out_file_name + out_dir_len + 1, COMMAND_METADATA_OUT, sizeof(COMMAND_METADATA_OUT)); + String_Const_u8 cmd_out_name = push_u8_stringf(arena, "%.*s/%s", + string_expand(out_directory), + COMMAND_METADATA_OUT); + FILE *cmd_out = fopen((char*)cmd_out_name.str, "wb"); - FILE *out = fopen(out_file_name, "wb"); - - if (out != 0){ + if (cmd_out != 0){ i32 entry_count = entry_arrays.doc_string_count; Meta_Command_Entry **entries = get_sorted_meta_commands(arena, entry_arrays.first_doc_string, entry_count); - fprintf(out, "#if !defined(META_PASS)\n"); - fprintf(out, "#define command_id(c) (fcoder_metacmd_ID_##c)\n"); - fprintf(out, "#define command_metadata(c) (&fcoder_metacmd_table[command_id(c)])\n"); - fprintf(out, "#define command_metadata_by_id(id) (&fcoder_metacmd_table[id])\n"); - fprintf(out, "#define command_one_past_last_id %d\n", entry_arrays.doc_string_count); - fprintf(out, "#if defined(CUSTOM_COMMAND_SIG)\n"); - fprintf(out, "#define PROC_LINKS(x,y) x\n"); - fprintf(out, "#else\n"); - fprintf(out, "#define PROC_LINKS(x,y) y\n"); - fprintf(out, "#endif\n"); + fprintf(cmd_out, "#if !defined(META_PASS)\n"); + fprintf(cmd_out, "#define command_id(c) (fcoder_metacmd_ID_##c)\n"); + fprintf(cmd_out, "#define command_metadata(c) (&fcoder_metacmd_table[command_id(c)])\n"); + fprintf(cmd_out, "#define command_metadata_by_id(id) (&fcoder_metacmd_table[id])\n"); + fprintf(cmd_out, "#define command_one_past_last_id %d\n", entry_arrays.doc_string_count); + fprintf(cmd_out, "#if defined(CUSTOM_COMMAND_SIG)\n"); + fprintf(cmd_out, "#define PROC_LINKS(x,y) x\n"); + fprintf(cmd_out, "#else\n"); + fprintf(cmd_out, "#define PROC_LINKS(x,y) y\n"); + fprintf(cmd_out, "#endif\n"); - fprintf(out, "#if defined(CUSTOM_COMMAND_SIG)\n"); + fprintf(cmd_out, "#if defined(CUSTOM_COMMAND_SIG)\n"); for (i32 i = 0; i < entry_count; ++i){ Meta_Command_Entry *entry = entries[i]; - fprintf(out, "CUSTOM_COMMAND_SIG(%.*s);\n", str_to_l_c(entry->name)); + fprintf(cmd_out, "CUSTOM_COMMAND_SIG(%.*s);\n", string_expand(entry->name)); } - fprintf(out, "#endif\n"); + fprintf(cmd_out, "#endif\n"); - fprintf(out, + fprintf(cmd_out, "struct Command_Metadata{\n" "PROC_LINKS(Custom_Command_Function, void) *proc;\n" "b32 is_ui;\n" @@ -838,7 +884,7 @@ main(int argc, char **argv){ "i32 line_number;\n" "};\n"); - fprintf(out, + fprintf(cmd_out, "static Command_Metadata fcoder_metacmd_table[%d] = {\n", entry_arrays.doc_string_count); for (i32 i = 0; i < entry_count; ++i){ @@ -856,7 +902,7 @@ main(int argc, char **argv){ is_ui = "true"; } - fprintf(out, + fprintf(cmd_out, "{ PROC_LINKS(%.*s, 0), %s, \"%.*s\", %d, " "\"%.*s\", %d, \"%s\", %d, %lld },\n", string_expand(entry->name), @@ -870,23 +916,47 @@ main(int argc, char **argv){ entry->line_number); end_temp(temp); } - fprintf(out, "};\n"); + fprintf(cmd_out, "};\n"); i32 id = 0; for (i32 i = 0; i < entry_count; ++i){ Meta_Command_Entry *entry = entries[i]; - - fprintf(out, "static i32 fcoder_metacmd_ID_%.*s = %d;\n", - string_expand(entry->name), id); + fprintf(cmd_out, "static i32 fcoder_metacmd_ID_%.*s = %d;\n", string_expand(entry->name), id); ++id; } - fprintf(out, "#endif\n"); + fprintf(cmd_out, "#endif\n"); - fclose(out); + fclose(cmd_out); } else{ - fprintf(stdout, "fatal error: could not open output file %s%s\n", out_directory, COMMAND_METADATA_OUT); + fprintf(stdout, "fatal error: could not open output file %.*s\n", string_expand(cmd_out_name)); + } + + String_Const_u8 id_out_name = push_u8_stringf(arena, "%.*s/%s", + string_expand(out_directory), + ID_METADATA_OUT); + FILE *id_out = fopen((char*)id_out_name.str, "wb"); + + if (id_out != 0){ + fprintf(id_out, "function void\n"); + fprintf(id_out, "initialize_managed_id_metadata(Application_Links *app){\n"); + + for (Meta_ID_Entry *node = entry_arrays.first_id; + node != 0; + node = node->next){ + fprintf(id_out, "%.*s = managed_id_declare(app, string_u8_litexpr(\"%.*s\"), string_u8_litexpr(\"%.*s\"));\n", + string_expand(node->id_name), + string_expand(node->group_name), + string_expand(node->id_name)); + } + + fprintf(id_out, "}\n"); + + fclose(id_out); + } + else{ + fprintf(stdout, "fatal error: could not open output file %.*s\n", string_expand(id_out_name)); } return(0); diff --git a/custom/4coder_types.h b/custom/4coder_types.h index 7eab73e5..22d742f0 100644 --- a/custom/4coder_types.h +++ b/custom/4coder_types.h @@ -538,10 +538,12 @@ struct Record_Info{ #define CUSTOM_COMMAND_SIG(name) void name(struct Application_Links *app) #define CUSTOM_UI_COMMAND_SIG(name) void name(struct Application_Links *app) #define CUSTOM_DOC(str) +#define CUSTOM_ID(group, name) global Managed_ID name; #else #define CUSTOM_COMMAND_SIG(name) CUSTOM_COMMAND(name, __FILE__, __LINE__, Normal) #define CUSTOM_UI_COMMAND_SIG(name) CUSTOM_COMMAND(name, __FILE__, __LINE__, UI) #define CUSTOM_DOC(str) CUSTOM_DOC(str) +#define CUSTOM_ID(group, name) CUSTOM_ID(group, name) #endif // TODO(allen): rename diff --git a/custom/generated/custom_api.h b/custom/generated/custom_api.h index fb040bd8..caea61aa 100644 --- a/custom/generated/custom_api.h +++ b/custom/generated/custom_api.h @@ -106,7 +106,7 @@ #define custom_managed_scope_clear_contents_sig() b32 custom_managed_scope_clear_contents(Application_Links* app, Managed_Scope scope) #define custom_managed_scope_clear_self_all_dependent_scopes_sig() b32 custom_managed_scope_clear_self_all_dependent_scopes(Application_Links* app, Managed_Scope scope) #define custom_managed_scope_allocator_sig() Base_Allocator* custom_managed_scope_allocator(Application_Links* app, Managed_Scope scope) -#define custom_managed_id_declare_sig() Managed_ID custom_managed_id_declare(Application_Links* app, String_Const_u8 name) +#define custom_managed_id_declare_sig() Managed_ID custom_managed_id_declare(Application_Links* app, String_Const_u8 group, String_Const_u8 name) #define custom_managed_scope_get_attachment_sig() void* custom_managed_scope_get_attachment(Application_Links* app, Managed_Scope scope, Managed_ID id, umem size) #define custom_managed_scope_attachment_erase_sig() void* custom_managed_scope_attachment_erase(Application_Links* app, Managed_Scope scope, Managed_ID id) #define custom_alloc_managed_memory_in_scope_sig() Managed_Object custom_alloc_managed_memory_in_scope(Application_Links* app, Managed_Scope scope, i32 item_size, i32 count) @@ -286,7 +286,7 @@ typedef Managed_Scope custom_get_managed_scope_with_multiple_dependencies_type(A typedef b32 custom_managed_scope_clear_contents_type(Application_Links* app, Managed_Scope scope); typedef b32 custom_managed_scope_clear_self_all_dependent_scopes_type(Application_Links* app, Managed_Scope scope); typedef Base_Allocator* custom_managed_scope_allocator_type(Application_Links* app, Managed_Scope scope); -typedef Managed_ID custom_managed_id_declare_type(Application_Links* app, String_Const_u8 name); +typedef Managed_ID custom_managed_id_declare_type(Application_Links* app, String_Const_u8 group, String_Const_u8 name); typedef void* custom_managed_scope_get_attachment_type(Application_Links* app, Managed_Scope scope, Managed_ID id, umem size); typedef void* custom_managed_scope_attachment_erase_type(Application_Links* app, Managed_Scope scope, Managed_ID id); typedef Managed_Object custom_alloc_managed_memory_in_scope_type(Application_Links* app, Managed_Scope scope, i32 item_size, i32 count); @@ -649,7 +649,7 @@ internal Managed_Scope get_managed_scope_with_multiple_dependencies(Application_ internal b32 managed_scope_clear_contents(Application_Links* app, Managed_Scope scope); internal b32 managed_scope_clear_self_all_dependent_scopes(Application_Links* app, Managed_Scope scope); internal Base_Allocator* managed_scope_allocator(Application_Links* app, Managed_Scope scope); -internal Managed_ID managed_id_declare(Application_Links* app, String_Const_u8 name); +internal Managed_ID managed_id_declare(Application_Links* app, String_Const_u8 group, String_Const_u8 name); internal void* managed_scope_get_attachment(Application_Links* app, Managed_Scope scope, Managed_ID id, umem size); internal void* managed_scope_attachment_erase(Application_Links* app, Managed_Scope scope, Managed_ID id); internal Managed_Object alloc_managed_memory_in_scope(Application_Links* app, Managed_Scope scope, i32 item_size, i32 count); diff --git a/custom/generated/custom_api_master_list.h b/custom/generated/custom_api_master_list.h index 17b0d636..54b254da 100644 --- a/custom/generated/custom_api_master_list.h +++ b/custom/generated/custom_api_master_list.h @@ -106,7 +106,7 @@ api(custom) function Managed_Scope get_managed_scope_with_multiple_dependencies( api(custom) function b32 managed_scope_clear_contents(Application_Links* app, Managed_Scope scope); api(custom) function b32 managed_scope_clear_self_all_dependent_scopes(Application_Links* app, Managed_Scope scope); api(custom) function Base_Allocator* managed_scope_allocator(Application_Links* app, Managed_Scope scope); -api(custom) function Managed_ID managed_id_declare(Application_Links* app, String_Const_u8 name); +api(custom) function Managed_ID managed_id_declare(Application_Links* app, String_Const_u8 group, String_Const_u8 name); api(custom) function void* managed_scope_get_attachment(Application_Links* app, Managed_Scope scope, Managed_ID id, umem size); api(custom) function void* managed_scope_attachment_erase(Application_Links* app, Managed_Scope scope, Managed_ID id); api(custom) function Managed_Object alloc_managed_memory_in_scope(Application_Links* app, Managed_Scope scope, i32 item_size, i32 count); diff --git a/custom/generated/managed_id_metadata.cpp b/custom/generated/managed_id_metadata.cpp new file mode 100644 index 00000000..046d9bbf --- /dev/null +++ b/custom/generated/managed_id_metadata.cpp @@ -0,0 +1,19 @@ +function void +initialize_managed_id_metadata(Application_Links *app){ +view_rewrite_loc = managed_id_declare(app, string_u8_litexpr("attachment"), string_u8_litexpr("view_rewrite_loc")); +view_next_rewrite_loc = managed_id_declare(app, string_u8_litexpr("attachment"), string_u8_litexpr("view_next_rewrite_loc")); +view_paste_index_loc = managed_id_declare(app, string_u8_litexpr("attachment"), string_u8_litexpr("view_paste_index_loc")); +view_is_passive_loc = managed_id_declare(app, string_u8_litexpr("attachment"), string_u8_litexpr("view_is_passive_loc")); +view_snap_mark_to_cursor = managed_id_declare(app, string_u8_litexpr("attachment"), string_u8_litexpr("view_snap_mark_to_cursor")); +view_ui_data = managed_id_declare(app, string_u8_litexpr("attachment"), string_u8_litexpr("view_ui_data")); +view_highlight_range = managed_id_declare(app, string_u8_litexpr("attachment"), string_u8_litexpr("view_highlight_range")); +view_highlight_buffer = managed_id_declare(app, string_u8_litexpr("attachment"), string_u8_litexpr("view_highlight_buffer")); +view_render_hook = managed_id_declare(app, string_u8_litexpr("attachment"), string_u8_litexpr("view_render_hook")); +view_word_complete_menu = managed_id_declare(app, string_u8_litexpr("attachment"), string_u8_litexpr("view_word_complete_menu")); +buffer_map_id = managed_id_declare(app, string_u8_litexpr("attachment"), string_u8_litexpr("buffer_map_id")); +buffer_eol_setting = managed_id_declare(app, string_u8_litexpr("attachment"), string_u8_litexpr("buffer_eol_setting")); +buffer_lex_task = managed_id_declare(app, string_u8_litexpr("attachment"), string_u8_litexpr("buffer_lex_task")); +buffer_wrap_lines = managed_id_declare(app, string_u8_litexpr("attachment"), string_u8_litexpr("buffer_wrap_lines")); +sticky_jump_marker_handle = managed_id_declare(app, string_u8_litexpr("attachment"), string_u8_litexpr("sticky_jump_marker_handle")); +attachment_tokens = managed_id_declare(app, string_u8_litexpr("attachment"), string_u8_litexpr("attachment_tokens")); +} diff --git a/platform_win32/win32_4ed.cpp b/platform_win32/win32_4ed.cpp index d9a6e035..a5339f18 100644 --- a/platform_win32/win32_4ed.cpp +++ b/platform_win32/win32_4ed.cpp @@ -17,8 +17,8 @@ #include "4coder_events.h" #include "4coder_table.h" -#include "4coder_default_colors.h" #include "4coder_types.h" +#include "4coder_default_colors.h" #include "4coder_system_types.h" #define STATIC_LINK_API