From c7f69d26a0d9b943b23d779c5856a804d597b55e Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Mon, 21 Oct 2019 21:10:29 -0700 Subject: [PATCH] Async system setup WITHOUT cancelation working yet --- 4ed.cpp | 81 +++++++------ 4ed.h | 6 +- 4ed_allocator_models.cpp | 37 ------ 4ed_api_implementation.cpp | 147 ++++++++++++----------- 4ed_app_models.h | 14 +-- 4ed_app_target.cpp | 1 - 4ed_cli.cpp | 4 +- 4ed_coroutine.cpp | 4 + 4ed_dynamic_variables.cpp | 24 ++-- 4ed_dynamic_variables.h | 30 ++--- 4ed_edit.cpp | 75 ++++++------ 4ed_file.cpp | 83 ++++++------- 4ed_history.cpp | 7 +- 4ed_log.cpp | 6 +- 4ed_text_layout.cpp | 18 +-- 4ed_view.cpp | 201 +++++++++++++++----------------- 4ed_working_set.cpp | 7 +- custom/4coder_async_tasks.cpp | 139 ++++++++++++++++++++-- custom/4coder_async_tasks.h | 38 +++++- custom/4coder_base_types.h | 4 +- custom/4coder_default_hooks.cpp | 7 +- custom/4coder_types.h | 8 +- platform_win32/win32_4ed.cpp | 4 +- 23 files changed, 531 insertions(+), 414 deletions(-) delete mode 100644 4ed_allocator_models.cpp diff --git a/4ed.cpp b/4ed.cpp index d52c7a56..096c7f01 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -10,14 +10,14 @@ // TOP internal void -output_file_append(Models *models, Editing_File *file, String_Const_u8 value){ +output_file_append(Thread_Context *tctx, Models *models, Editing_File *file, String_Const_u8 value){ i64 end = buffer_size(&file->state.buffer); Edit_Behaviors behaviors = {}; - edit_single(models, file, Ii64(end), value, behaviors); + edit_single(tctx, models, file, Ii64(end), value, behaviors); } internal void -file_cursor_to_end(Models *models, Editing_File *file){ +file_cursor_to_end(Thread_Context *tctx, Models *models, Editing_File *file){ Assert(file != 0); i64 pos = buffer_size(&file->state.buffer); Layout *layout = &models->layout; @@ -28,7 +28,7 @@ file_cursor_to_end(Models *models, Editing_File *file){ if (view->file != file){ continue; } - view_set_cursor(models, view, pos); + view_set_cursor(tctx, models, view, pos); view->mark = pos; } } @@ -281,12 +281,12 @@ init_command_line_settings(App_Settings *settings, Plat_Settings *plat_settings, //////////////////////////////// internal Models* -models_init(Thread_Context *tctx){ - Arena *arena = reserve_arena(tctx); - Models *models = push_array_zero(arena, Models, 1); - models->tctx = tctx; - models->arena = arena; - heap_init(&models->heap, tctx->allocator); +models_init(void){ + Arena arena = make_arena_system(); + Models *models = push_array_zero(&arena, Models, 1); + models->arena_ = arena; + models->arena = &models->arena_; + heap_init(&models->heap, get_base_allocator_system()); return(models); } @@ -306,7 +306,7 @@ app_get_logger(void){ } App_Read_Command_Line_Sig(app_read_command_line){ - Models *models = models_init(tctx); + Models *models = models_init(); App_Settings *settings = &models->settings; block_zero_struct(settings); if (argc > 1){ @@ -322,7 +322,6 @@ App_Init_Sig(app_init){ models->keep_playing = true; models->config_api = api; - models->app_links.cmd_context = models; API_VTable_custom custom_vtable = {}; custom_api_fill_vtable(&custom_vtable); @@ -330,7 +329,11 @@ App_Init_Sig(app_init){ system_api_fill_vtable(&system_vtable); Custom_Layer_Init_Type *custom_init = api.init_apis(&custom_vtable, &system_vtable); Assert(custom_init != 0); - custom_init(&models->app_links); + + Application_Links app = {}; + app.tctx = tctx; + app.cmd_context = models; + custom_init(&app); // NOTE(allen): coroutines coroutine_system_init(&models->coroutines); @@ -360,8 +363,8 @@ App_Init_Sig(app_init){ } } - managed_ids_init(models->tctx->allocator, &models->managed_id_set); - lifetime_allocator_init(models->tctx->allocator, &models->lifetime_allocator); + 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 @@ -371,7 +374,7 @@ App_Init_Sig(app_init){ // NOTE(allen): global_history_init(&models->global_history); - text_layout_init(models, &models->text_layouts); + text_layout_init(tctx, &models->text_layouts); // NOTE(allen): clipboard setup models->working_set.clipboard_max_size = ArrayCount(models->working_set.clipboards); @@ -412,17 +415,17 @@ App_Init_Sig(app_init){ Heap *heap = &models->heap; for (i32 i = 0; i < ArrayCount(init_files); ++i){ Editing_File *file = working_set_allocate_file(&models->working_set, &models->lifetime_allocator); - buffer_bind_name(models, arena, &models->working_set, file, init_files[i].name); + buffer_bind_name(tctx, models, arena, &models->working_set, file, init_files[i].name); if (init_files[i].ptr != 0){ *init_files[i].ptr = file; } File_Attributes attributes = {}; - file_create_from_string(models, file, SCu8(), attributes); + file_create_from_string(tctx, models, file, SCu8(), attributes); if (init_files[i].read_only){ file->settings.read_only = true; - history_free(models, &file->state.history); + history_free(tctx, &file->state.history); } file->settings.never_kill = true; @@ -433,12 +436,12 @@ App_Init_Sig(app_init){ { Panel *panel = layout_initialize(arena, &models->layout); View *new_view = live_set_alloc_view(&models->lifetime_allocator, &models->live_set, panel); - view_init(models, new_view, models->scratch_buffer, models->view_event_handler); + 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(models->tctx->allocator, &models->child_processes); + child_process_container_init(tctx->allocator, &models->child_processes); models->period_wakeup_timer = system_wake_up_timer_create(); } @@ -446,7 +449,7 @@ App_Step_Sig(app_step){ Models *models = (Models*)base_ptr; Mutex_Lock file_order_lock(models->working_set.mutex); - Scratch_Block scratch(models->tctx, Scratch_Share); + Scratch_Block scratch(tctx, Scratch_Share); models->next_animate_delay = max_u32; models->animate_next_frame = false; @@ -462,7 +465,7 @@ App_Step_Sig(app_step){ String_Const_u8 *dest = working_set_next_clipboard_string(&models->heap, &models->working_set, clipboard.size); dest->size = eol_convert_in((char*)dest->str, (char*)clipboard.str, (i32)clipboard.size); if (input->clipboard_changed){ - co_send_core_event(models, CoreCode_NewClipboardContents, *dest); + co_send_core_event(tctx, models, CoreCode_NewClipboardContents, *dest); } } @@ -499,7 +502,7 @@ App_Step_Sig(app_step){ if (system_cli_update_step(cli, dest, max, &amount)){ if (file != 0 && amount > 0){ amount = eol_in_place_convert_in(dest, amount); - output_file_append(models, file, SCu8(dest, amount)); + output_file_append(tctx, models, file, SCu8(dest, amount)); edited_file = true; } } @@ -507,7 +510,7 @@ App_Step_Sig(app_step){ if (system_cli_end_update(cli)){ if (file != 0){ String_Const_u8 str = push_u8_stringf(scratch, "exited with code %d", cli->exit); - output_file_append(models, file, str); + output_file_append(tctx, models, file, str); edited_file = true; } processes_to_free[processes_to_free_count++] = child_process; @@ -515,7 +518,7 @@ App_Step_Sig(app_step){ } if (child_process->cursor_at_end && file != 0){ - file_cursor_to_end(models, file); + file_cursor_to_end(tctx, models, file); } } @@ -639,7 +642,7 @@ App_Step_Sig(app_step){ event.core.code = CoreCode_Startup; event.core.flag_strings = flags; event.core.file_names = file_names; - co_send_event(models, &event); + co_send_event(tctx, models, &event); } // NOTE(allen): consume event stream @@ -689,7 +692,7 @@ App_Step_Sig(app_step){ case EventConsume_ClickChangeView: { // NOTE(allen): run deactivate command - co_send_core_event(models, view, CoreCode_ClickDeactivateView); + co_send_core_event(tctx, models, view, CoreCode_ClickDeactivateView); layout->active_panel = mouse_panel; models->animate_next_frame = true; @@ -697,14 +700,14 @@ App_Step_Sig(app_step){ view = active_panel->view; // NOTE(allen): run activate command - co_send_core_event(models, view, CoreCode_ClickActivateView); + co_send_core_event(tctx, models, view, CoreCode_ClickActivateView); event_was_handled = true; }break; case EventConsume_CustomCommand: { - event_was_handled = co_send_event(models, view, event); + event_was_handled = co_send_event(tctx, models, view, event); }break; } }break; @@ -745,7 +748,10 @@ App_Step_Sig(app_step){ if (models->layout.panel_state_dirty){ models->layout.panel_state_dirty = false; if (models->buffer_viewer_update != 0){ - models->buffer_viewer_update(&models->app_links); + Application_Links app = {}; + app.tctx = tctx; + app.cmd_context = models; + models->buffer_viewer_update(&app); } } @@ -769,7 +775,7 @@ App_Step_Sig(app_step){ panel = layout_get_next_open_panel(layout, panel)){ View *view = panel->view; File_Edit_Positions edit_pos = view_get_edit_pos(view); - edit_pos.scroll.position = view_normalize_buffer_point(models, view, edit_pos.scroll.target); + edit_pos.scroll.position = view_normalize_buffer_point(tctx, models, view, edit_pos.scroll.target); block_zero_struct(&edit_pos.scroll.target); view_set_edit_pos(view, edit_pos); } @@ -787,7 +793,7 @@ App_Step_Sig(app_step){ Editing_File *file = CastFromMember(Editing_File, external_mod_node, node); dll_remove(node); block_zero_struct(node); - co_send_core_event(models, CoreCode_FileExternallyModified, file->id); + co_send_core_event(tctx, models, CoreCode_FileExternallyModified, file->id); } } } @@ -797,7 +803,7 @@ App_Step_Sig(app_step){ models->keep_playing = false; } if (!models->keep_playing){ - if (co_send_core_event(models, CoreCode_TryExit)){ + if (co_send_core_event(tctx, models, CoreCode_TryExit)){ models->keep_playing = true; } } @@ -836,7 +842,10 @@ App_Step_Sig(app_step){ if (ctx != 0){ Render_Caller_Function *render_caller = ctx->ctx.render_caller; if (render_caller != 0){ - render_caller(&models->app_links, frame, view_get_id(live_views, view)); + Application_Links app = {}; + app.tctx = tctx; + app.cmd_context = models; + render_caller(&app, frame, view_get_id(live_views, view)); } } } @@ -846,7 +855,7 @@ App_Step_Sig(app_step){ } // NOTE(allen): flush the log - log_flush(models); + log_flush(tctx, models); // NOTE(allen): set the app_result Application_Step_Result app_result = {}; diff --git a/4ed.h b/4ed.h index ff546206..705a11e2 100644 --- a/4ed.h +++ b/4ed.h @@ -47,7 +47,8 @@ struct Custom_API{ }; #define App_Init_Sig(name) \ -void name(Render_Target *target, \ +void name(Thread_Context *tctx, \ +Render_Target *target, \ void *base_ptr, \ String_Const_u8 clipboard,\ String_Const_u8 current_directory,\ @@ -77,7 +78,8 @@ struct Application_Step_Input{ }; #define App_Step_Sig(name) Application_Step_Result \ -name(Render_Target *target, \ +name(Thread_Context *tctx, \ +Render_Target *target, \ void *base_ptr, \ Application_Step_Input *input) diff --git a/4ed_allocator_models.cpp b/4ed_allocator_models.cpp deleted file mode 100644 index fe74d240..00000000 --- a/4ed_allocator_models.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Mr. 4th Dimention - Allen Webster - * - * 27.08.2019 - * - * Models based arena constructors - * - */ - -// TOP - -internal Arena* -reserve_arena(Models *models, umem chunk_size, umem align){ - Thread_Context *tctx = models->tctx; - return(reserve_arena(tctx, chunk_size, align)); -} - -internal Arena* -reserve_arena(Models *models, umem chunk_size){ - Thread_Context *tctx = models->tctx; - return(reserve_arena(tctx, chunk_size)); -} - -internal Arena* -reserve_arena(Models *models){ - Thread_Context *tctx = models->tctx; - return(reserve_arena(tctx)); -} - -internal void -release_arena(Models *models, Arena *arena){ - Thread_Context *tctx = models->tctx; - release_arena(tctx, arena); -} - -// BOTTOM - diff --git a/4ed_api_implementation.cpp b/4ed_api_implementation.cpp index f82a0a7e..c2ef5986 100644 --- a/4ed_api_implementation.cpp +++ b/4ed_api_implementation.cpp @@ -45,7 +45,9 @@ api_check_view(View *view, Access_Flag access){ function b32 is_running_coroutine(Application_Links *app){ - return(app->current_coroutine != 0); + Thread_Context *tctx = app->tctx; + Thread_Context_Extra_Info *info = (Thread_Context_Extra_Info*)tctx->user_data; + return(info->coroutine != 0); } api(custom) function b32 @@ -73,25 +75,13 @@ global_get_screen_rectangle(Application_Links *app){ api(custom) function Thread_Context* get_thread_context(Application_Links *app){ - Thread_Context *tctx = 0; - if (app->current_coroutine == 0){ - Models *models = (Models*)app->cmd_context; - tctx = models->tctx; - } - else if (app->current_thread != 0){ - tctx = (Thread_Context*)app->current_thread; - } - else{ - Coroutine *coroutine = (Coroutine*)app->current_coroutine; - tctx = coroutine->tctx; - } - return(tctx); + return(app->tctx); } api(custom) function b32 create_child_process(Application_Links *app, String_Const_u8 path, String_Const_u8 command, Child_Process_ID *child_process_id_out){ Models *models = (Models*)app->cmd_context; - return(child_process_call(models, path, command, child_process_id_out)); + return(child_process_call(app->tctx, models, path, command, child_process_id_out)); } api(custom) function b32 @@ -246,7 +236,7 @@ buffer_replace_range(Application_Links *app, Buffer_ID buffer_id, Range_i64 rang i64 size = buffer_size(&file->state.buffer); if (0 <= range.first && range.first <= range.one_past_last && range.one_past_last <= size){ Edit_Behaviors behaviors = {}; - edit_single(models, file, range, string, behaviors); + edit_single(app->tctx, models, file, range, string, behaviors); result = true; } } @@ -261,7 +251,7 @@ buffer_batch_edit(Application_Links *app, Buffer_ID buffer_id, Batch_Edit *batch b32 result = false; if (api_check_buffer(file)){ Edit_Behaviors behaviors = {}; - result = edit_batch(models, file, batch, behaviors); + result = edit_batch(app->tctx, models, file, batch, behaviors); } return(result); } @@ -373,7 +363,7 @@ buffer_line_y_difference(Application_Links *app, Buffer_ID buffer_id, f32 width, if (api_check_buffer(file)){ Face *face = font_set_face_from_id(&models->font_set, face_id); if (face != 0){ - result = file_line_y_difference(models, file, width, face, line_a, line_b); + result = file_line_y_difference(app->tctx, models, file, width, face, line_a, line_b); } } return(result); @@ -387,7 +377,7 @@ buffer_line_shift_y(Application_Links *app, Buffer_ID buffer_id, f32 width, Face if (api_check_buffer(file)){ Face *face = font_set_face_from_id(&models->font_set, face_id); if (face != 0){ - result = file_line_shift_y(models, file, width, face, line, y_shift); + result = file_line_shift_y(app->tctx, models, file, width, face, line, y_shift); } } return(result); @@ -401,7 +391,7 @@ buffer_pos_at_relative_xy(Application_Links *app, Buffer_ID buffer_id, f32 width if (api_check_buffer(file)){ Face *face = font_set_face_from_id(&models->font_set, face_id); if (face != 0){ - result = file_pos_at_relative_xy(models, file, width, face, base_line, relative_xy); + result = file_pos_at_relative_xy(app->tctx, models, file, width, face, base_line, relative_xy); } } return(result); @@ -416,7 +406,7 @@ buffer_relative_xy_of_pos(Application_Links *app, Buffer_ID buffer_id, f32 width if (api_check_buffer(file)){ Face *face = font_set_face_from_id(&models->font_set, face_id); if (face != 0){ - result = file_relative_xy_of_pos(models, file, width, face, base_line, pos); + result = file_relative_xy_of_pos(app->tctx, models, file, width, face, base_line, pos); } } return(result); @@ -431,7 +421,7 @@ buffer_relative_character_from_pos(Application_Links *app, Buffer_ID buffer_id, if (api_check_buffer(file)){ Face *face = font_set_face_from_id(&models->font_set, face_id); if (face != 0){ - result = file_relative_character_from_pos(models, file, width, face, base_line, pos); + result = file_relative_character_from_pos(app->tctx, models, file, width, face, base_line, pos); } } return(result); @@ -446,7 +436,7 @@ buffer_pos_from_relative_character(Application_Links *app, Buffer_ID buffer_id, if (api_check_buffer(file)){ Face *face = font_set_face_from_id(&models->font_set, face_id); if (face != 0){ - result = file_pos_from_relative_character(models, file, width, face, base_line, relative_character); + result = file_pos_from_relative_character(app->tctx, models, file, width, face, base_line, relative_character); } } return(result); @@ -460,7 +450,7 @@ view_line_y_difference(Application_Links *app, View_ID view_id, i64 line_a, i64 View *view = imp_get_view(models, view_id); f32 result = {}; if (api_check_view(view)){ - result = view_line_y_difference(models, view, line_a, line_b); + result = view_line_y_difference(app->tctx, models, view, line_a, line_b); } return(result); } @@ -471,7 +461,7 @@ view_line_shift_y(Application_Links *app, View_ID view_id, i64 line, f32 y_shift View *view = imp_get_view(models, view_id); Line_Shift_Vertical result = {}; if (api_check_view(view)){ - result = view_line_shift_y(models, view, line, y_shift); + result = view_line_shift_y(app->tctx, models, view, line, y_shift); } return(result); } @@ -482,7 +472,7 @@ view_pos_at_relative_xy(Application_Links *app, View_ID view_id, i64 base_line, View *view = imp_get_view(models, view_id); i64 result = -1; if (api_check_view(view)){ - result = view_pos_at_relative_xy(models, view, base_line, relative_xy); + result = view_pos_at_relative_xy(app->tctx, models, view, base_line, relative_xy); } return(result); } @@ -493,7 +483,7 @@ view_relative_xy_of_pos(Application_Links *app, View_ID view_id, i64 base_line, View *view = imp_get_view(models, view_id); Vec2_f32 result = {}; if (api_check_view(view)){ - result = view_relative_xy_of_pos(models, view, base_line, pos); + result = view_relative_xy_of_pos(app->tctx, models, view, base_line, pos); } return(result); } @@ -504,7 +494,7 @@ view_relative_character_from_pos(Application_Links *app, View_ID view_id, i64 b View *view = imp_get_view(models, view_id); i64 result = {}; if (api_check_view(view)){ - result = view_relative_character_from_pos(models, view, base_line, pos); + result = view_relative_character_from_pos(app->tctx, models, view, base_line, pos); } return(result); } @@ -515,7 +505,7 @@ view_pos_from_relative_character(Application_Links *app, View_ID view_id, i64 b View *view = imp_get_view(models, view_id); i64 result = {}; if (api_check_view(view)){ - result = view_pos_from_relative_character(models, view, base_line, character); + result = view_pos_from_relative_character(app->tctx, models, view, base_line, character); } return(result); } @@ -693,12 +683,12 @@ buffer_set_setting(Application_Links *app, Buffer_ID buffer_id, Buffer_Setting_I { if (value){ if (!history_is_activated(&file->state.history)){ - history_init(models, &file->state.history); + history_init(app->tctx, models, &file->state.history); } } else{ if (history_is_activated(&file->state.history)){ - history_free(models, &file->state.history); + history_free(app->tctx, &file->state.history); } } }break; @@ -732,7 +722,7 @@ buffer_send_end_signal(Application_Links *app, Buffer_ID buffer_id) Editing_File *file = imp_get_file(models, buffer_id); b32 result = false; if (api_check_buffer(file)){ - file_end_file(models, file); + file_end_file(app->tctx, models, file); result = true; } return(result); @@ -742,7 +732,7 @@ api(custom) function Buffer_ID create_buffer(Application_Links *app, String_Const_u8 file_name, Buffer_Create_Flag flags) { Models *models = (Models*)app->cmd_context; - Editing_File *new_file = create_file(models, file_name, flags); + Editing_File *new_file = create_file(app->tctx, models, file_name, flags); Buffer_ID result = 0; if (new_file != 0){ result = new_file->id; @@ -766,9 +756,10 @@ buffer_save(Application_Links *app, Buffer_ID buffer_id, String_Const_u8 file_na } if (!skip_save){ - Scratch_Block scratch(models->tctx, Scratch_Share); + Thread_Context *tctx = app->tctx; + Scratch_Block scratch(app->tctx, Scratch_Share); String_Const_u8 name = push_string_copy(scratch, file_name); - save_file_to_name(models, file, name.str); + save_file_to_name(tctx, models, file, name.str); result = true; } } @@ -787,15 +778,16 @@ buffer_kill(Application_Links *app, Buffer_ID buffer_id, Buffer_Kill_Flag flags) if (!file->settings.never_kill){ b32 needs_to_save = file_needs_save(file); if (!needs_to_save || (flags & BufferKill_AlwaysKill) != 0){ + Thread_Context *tctx = app->tctx; if (models->end_buffer != 0){ - models->end_buffer(&models->app_links, file->id); + models->end_buffer(app, file->id); } buffer_unbind_name_low_level(working_set, file); if (file->canon.name_size != 0){ buffer_unbind_file(working_set, file); } - file_free(models, file); + file_free(tctx, models, file); working_set_free_file(&models->heap, working_set, file); Layout *layout = &models->layout; @@ -810,7 +802,7 @@ buffer_kill(Application_Links *app, Buffer_ID buffer_id, Buffer_Kill_Flag flags) Assert(file_node != order); view->file = 0; Editing_File *new_file = CastFromMember(Editing_File, touch_node, file_node); - view_set_file(models, view, new_file); + view_set_file(tctx, models, view, new_file); file_node = file_node->next; if (file_node == order){ file_node = file_node->next; @@ -836,7 +828,8 @@ api(custom) function Buffer_Reopen_Result buffer_reopen(Application_Links *app, Buffer_ID buffer_id, Buffer_Reopen_Flag flags) { Models *models = (Models*)app->cmd_context; - Scratch_Block scratch(models->tctx, Scratch_Share); + Thread_Context *tctx = app->tctx; + Scratch_Block scratch(tctx, Scratch_Share); Editing_File *file = imp_get_file(models, buffer_id); Buffer_Reopen_Result result = BufferReopenResult_Failed; if (api_check_buffer(file)){ @@ -875,18 +868,18 @@ buffer_reopen(Application_Links *app, Buffer_ID buffer_id, Buffer_Reopen_Flag fl } Working_Set *working_set = &models->working_set; - file_free(models, file); + file_free(tctx, models, file); working_set_file_default_settings(working_set, file); - file_create_from_string(models, file, SCu8(file_memory, attributes.size), attributes); + file_create_from_string(tctx, models, file, SCu8(file_memory, attributes.size), attributes); for (i32 i = 0; i < vptr_count; ++i){ - view_set_file(models, vptrs[i], file); + view_set_file(tctx, models, vptrs[i], file); vptrs[i]->file = file; i64 line = line_numbers[i]; i64 col = column_numbers[i]; Buffer_Cursor cursor = file_compute_cursor(file, seek_line_col(line, col)); - view_set_cursor(models, vptrs[i], cursor.pos); + view_set_cursor(tctx, models, vptrs[i], cursor.pos); } result = BufferReopenResult_Reopened; } @@ -919,7 +912,7 @@ api(custom) function File_Attributes get_file_attributes(Application_Links *app, String_Const_u8 file_name) { Models *models = (Models*)app->cmd_context; - Scratch_Block scratch(models->tctx, Scratch_Share); + Scratch_Block scratch(app->tctx, Scratch_Share); return(system_quick_file_attributes(scratch, file_name)); } @@ -1172,7 +1165,7 @@ panel_split(Application_Links *app, Panel_ID panel_id, Dimension split_dim){ Live_Views *live_set = &models->live_set; View *new_view = live_set_alloc_view(&models->lifetime_allocator, live_set, new_panel); - view_init(models, new_view, models->scratch_buffer, + view_init(app->tctx, models, new_view, models->scratch_buffer, models->view_event_handler); result = true; } @@ -1321,7 +1314,7 @@ view_get_buffer_region(Application_Links *app, View_ID view_id){ View *view = imp_get_view(models, view_id); Rect_f32 result = {}; if (api_check_view(view)){ - result = view_get_buffer_rect(models, view); + result = view_get_buffer_rect(app->tctx, models, view); } return(result); } @@ -1466,7 +1459,7 @@ view_set_cursor(Application_Links *app, View_ID view_id, Buffer_Seek seek) Assert(file != 0); if (api_check_buffer(file)){ Buffer_Cursor cursor = file_compute_cursor(file, seek); - view_set_cursor(models, view, cursor.pos); + view_set_cursor(app->tctx, models, view, cursor.pos); result = true; } } @@ -1481,15 +1474,16 @@ view_set_buffer_scroll(Application_Links *app, View_ID view_id, Buffer_Scroll sc b32 result = false; View *view = imp_get_view(models, view_id); if (api_check_view(view)){ - scroll.position = view_normalize_buffer_point(models, view, scroll.position); - scroll.target = view_normalize_buffer_point(models, view, scroll.target); + Thread_Context *tctx = app->tctx; + scroll.position = view_normalize_buffer_point(tctx, models, view, scroll.position); + scroll.target = view_normalize_buffer_point(tctx, models, view, scroll.target); scroll.target.pixel_shift.x = f32_round32(scroll.target.pixel_shift.x); scroll.target.pixel_shift.y = f32_round32(scroll.target.pixel_shift.y); scroll.target.pixel_shift.x = clamp_bot(0.f, scroll.target.pixel_shift.x); - Buffer_Layout_Item_List line = view_get_line_layout(models, view, scroll.target.line_number); + Buffer_Layout_Item_List line = view_get_line_layout(tctx, models, view, scroll.target.line_number); scroll.target.pixel_shift.y = clamp(0.f, scroll.target.pixel_shift.y, line.height); if (rule == SetBufferScroll_SnapCursorIntoView){ - view_set_scroll(models, view, scroll); + view_set_scroll(tctx, models, view, scroll); } else{ File_Edit_Positions edit_pos = view_get_edit_pos(view); @@ -1536,7 +1530,7 @@ view_set_buffer(Application_Links *app, View_ID view_id, Buffer_ID buffer_id, Se 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, view, file); + view_set_file(app->tctx, models, view, file); if (!(flags & SetBuffer_KeepOriginalGUI)){ //view_quit_ui(models, view); // TODO(allen): back to base context @@ -1707,7 +1701,7 @@ get_managed_scope_with_multiple_dependencies(Application_Links *app, Managed_Sco Models *models = (Models*)app->cmd_context; Lifetime_Allocator *lifetime_allocator = &models->lifetime_allocator; - Scratch_Block scratch(models->tctx, Scratch_Share); + Scratch_Block scratch(app->tctx, Scratch_Share); // TODO(allen): revisit this struct Node_Ptr{ @@ -2029,9 +2023,11 @@ api(custom) function User_Input get_next_input(Application_Links *app, Event_Property get_properties, Event_Property abort_properties) { Models *models = (Models*)app->cmd_context; + Thread_Context *tctx = app->tctx; + Thread_Context_Extra_Info *tctx_info = (Thread_Context_Extra_Info*)tctx->user_data; User_Input result = {}; - if (app->type_coroutine == Co_View){ - Coroutine *coroutine = (Coroutine*)app->current_coroutine; + if (tctx_info->coroutine != 0){ + Coroutine *coroutine = (Coroutine*)tctx_info->coroutine; if (coroutine != 0){ Co_Out *out = (Co_Out*)coroutine->out; out->request = CoRequest_None; @@ -2213,8 +2209,8 @@ print_message(Application_Links *app, String_Const_u8 message) Editing_File *file = models->message_buffer; b32 result = false; if (file != 0){ - output_file_append(models, file, message); - file_cursor_to_end(models, file); + output_file_append(app->tctx, models, file, message); + file_cursor_to_end(app->tctx, models, file); result = true; } return(result); @@ -2385,7 +2381,7 @@ buffer_history_set_current_state_index(Application_Links *app, Buffer_ID buffer_ if (api_check_buffer(file) && history_is_activated(&file->state.history)){ i32 max_index = history_get_record_count(&file->state.history); if (0 <= index && index <= max_index){ - edit_change_current_history_state(models, file, index); + edit_change_current_history_state(app->tctx, models, file, index); result = true; } } @@ -2398,7 +2394,7 @@ buffer_history_merge_record_range(Application_Links *app, Buffer_ID buffer_id, H Editing_File *file = imp_get_file(models, buffer_id); b32 result = false; if (api_check_buffer(file)){ - result = edit_merge_history_range(models, file, first_index, last_index, flags); + result = edit_merge_history_range(app->tctx, models, file, first_index, last_index, flags); } return(result); } @@ -2502,9 +2498,11 @@ api(custom) function Face_ID try_create_new_face(Application_Links *app, Face_Description *description) { Models *models = (Models*)app->cmd_context; + Thread_Context *tctx = app->tctx; + Thread_Context_Extra_Info *tctx_info = (Thread_Context_Extra_Info*)tctx->user_data; Face_ID result = 0; - if (is_running_coroutine(app)){ - Coroutine *coroutine = (Coroutine*)app->current_coroutine; + if (tctx_info != 0 && tctx_info->coroutine != 0){ + Coroutine *coroutine = (Coroutine*)tctx_info->coroutine; Assert(coroutine != 0); Co_Out *out = (Co_Out*)coroutine->out; out->request = CoRequest_NewFontFace; @@ -2513,6 +2511,9 @@ try_create_new_face(Application_Links *app, Face_Description *description) Co_In *in = (Co_In*)coroutine->in; result = in->face_id; } + else if (tctx_info != 0){ + // This API does nothing when called from an async thread. + } else{ Face *new_face = font_set_new_face(&models->font_set, description); result = new_face->id; @@ -2524,9 +2525,11 @@ api(custom) function b32 try_modify_face(Application_Links *app, Face_ID id, Face_Description *description) { Models *models = (Models*)app->cmd_context; + Thread_Context *tctx = app->tctx; + Thread_Context_Extra_Info *tctx_info = (Thread_Context_Extra_Info*)tctx->user_data; b32 result = false; - if (is_running_coroutine(app)){ - Coroutine *coroutine = (Coroutine*)app->current_coroutine; + if (tctx_info != 0 && tctx_info->coroutine != 0){ + Coroutine *coroutine = (Coroutine*)tctx_info->coroutine; Assert(coroutine != 0); Co_Out *out = (Co_Out*)coroutine->out; out->request = CoRequest_ModifyFace; @@ -2536,6 +2539,9 @@ try_modify_face(Application_Links *app, Face_ID id, Face_Description *descriptio Co_In *in = (Co_In*)coroutine->in; result = in->success; } + else if (tctx_info != 0){ + // This API does nothing when called from an async thread. + } else{ result = font_set_modify_face(&models->font_set, id, description); } @@ -2689,8 +2695,9 @@ text_layout_create(Application_Links *app, Buffer_ID buffer_id, Rect_f32 rect, B Editing_File *file = imp_get_file(models, buffer_id); Text_Layout_ID result = {}; if (api_check_buffer(file)){ - Scratch_Block scratch(app); - Arena *arena = reserve_arena(models->tctx); + Thread_Context *tctx = app->tctx; + Scratch_Block scratch(tctx); + Arena *arena = reserve_arena(tctx); Face *face = file_get_face(models, file); Gap_Buffer *buffer = &file->state.buffer; @@ -2702,7 +2709,7 @@ text_layout_create(Application_Links *app, Buffer_ID buffer_id, Rect_f32 rect, B f32 y = -buffer_point.pixel_shift.y; for (;line_number <= line_count; line_number += 1){ - Buffer_Layout_Item_List line = file_get_line_layout(models, file, dim.x, face, line_number); + Buffer_Layout_Item_List line = file_get_line_layout(tctx, models, file, dim.x, face, line_number); f32 next_y = y + line.height; if (next_y >= dim.y){ break; @@ -2775,7 +2782,7 @@ text_layout_line_on_screen(Application_Links *app, Text_Layout_ID layout_id, i64 for (i64 line_number_it = layout->visible_line_number_range.first;; line_number_it += 1){ - Buffer_Layout_Item_List line = file_get_line_layout(models, file, width, face, line_number_it); + Buffer_Layout_Item_List line = file_get_line_layout(app->tctx, models, file, width, face, line_number_it); result.max += line.height; if (line_number_it == line_number){ break; @@ -2816,7 +2823,7 @@ text_layout_character_on_screen(Application_Links *app, Text_Layout_ID layout_id Buffer_Layout_Item_List line = {}; for (i64 line_number_it = layout->visible_line_number_range.first;; line_number_it += 1){ - line = file_get_line_layout(models, file, width, face, line_number_it); + line = file_get_line_layout(app->tctx, models, file, width, face, line_number_it); if (line_number_it == line_number){ break; } @@ -2874,7 +2881,7 @@ paint_text_color(Application_Links *app, Text_Layout_ID layout_id, Interval_i64 api(custom) function b32 text_layout_free(Application_Links *app, Text_Layout_ID text_layout_id){ Models *models = (Models*)app->cmd_context; - return(text_layout_erase(models, &models->text_layouts, text_layout_id)); + return(text_layout_erase(app->tctx, models, &models->text_layouts, text_layout_id)); } api(custom) function void @@ -2882,7 +2889,7 @@ draw_text_layout(Application_Links *app, Text_Layout_ID layout_id){ Models *models = (Models*)app->cmd_context; Text_Layout *layout = text_layout_get(&models->text_layouts, layout_id); if (layout != 0 && models->target != 0){ - text_layout_render(models, layout); + text_layout_render(app->tctx, models, layout); } } diff --git a/4ed_app_models.h b/4ed_app_models.h index 472d406b..cdf8b1d1 100644 --- a/4ed_app_models.h +++ b/4ed_app_models.h @@ -35,8 +35,7 @@ enum App_State{ }; struct Models{ - Thread_Context *tctx; - + Arena arena_; Arena *arena; Heap heap; @@ -50,8 +49,6 @@ struct Models{ Child_Process_Container child_processes; Custom_API config_api; - Application_Links app_links; - Render_Caller_Function *render_caller; Delta_Rule_Function *delta_rule; umem delta_rule_memory_size; @@ -141,15 +138,6 @@ struct Consumption_Record{ char consumer[32]; }; -typedef i32 App_Coroutine_Purpose; -enum{ - Co_View, -}; -struct App_Coroutine_State{ - void *co; - i32 type; -}; - struct File_Init{ String_Const_u8 name; Editing_File **ptr; diff --git a/4ed_app_target.cpp b/4ed_app_target.cpp index 99dea7e6..ff1dbf0f 100644 --- a/4ed_app_target.cpp +++ b/4ed_app_target.cpp @@ -79,7 +79,6 @@ #define DYNAMIC_LINK_API #include "generated/font_api.cpp" -#include "4ed_allocator_models.cpp" #include "4ed_log.cpp" #include "4ed_coroutine.cpp" #include "4ed_mem.cpp" diff --git a/4ed_cli.cpp b/4ed_cli.cpp index 72cc8b5e..3c219ef8 100644 --- a/4ed_cli.cpp +++ b/4ed_cli.cpp @@ -98,9 +98,9 @@ child_process_lookup_return_code(Child_Process_Container *container, Child_Proce //////////////////////////////// internal b32 -child_process_call(Models *models, String_Const_u8 path, String_Const_u8 command, Child_Process_ID *id_out){ +child_process_call(Thread_Context *tctx, Models *models, String_Const_u8 path, String_Const_u8 command, Child_Process_ID *id_out){ b32 result = false; - Scratch_Block scratch(&models->app_links); + Scratch_Block scratch(tctx); String_Const_u8 path_n = push_string_copy(scratch, path); String_Const_u8 command_n = push_string_copy(scratch, command); CLI_Handles cli_handles = {}; diff --git a/4ed_coroutine.cpp b/4ed_coroutine.cpp index d14823a5..10224a9d 100644 --- a/4ed_coroutine.cpp +++ b/4ed_coroutine.cpp @@ -30,9 +30,13 @@ internal void coroutine_main(void *ptr){ Coroutine *me = (Coroutine*)ptr; + Thread_Context_Extra_Info tctx_info = {}; + tctx_info.coroutine = me; + Thread_Context tctx_ = {}; thread_ctx_init(&tctx_, ThreadKind_MainCoroutine, get_base_allocator_system(), get_base_allocator_system()); + tctx_.user_data = &tctx_info; me->tctx = &tctx_; // NOTE(allen): Init handshake diff --git a/4ed_dynamic_variables.cpp b/4ed_dynamic_variables.cpp index 5dad2e76..48779479 100644 --- a/4ed_dynamic_variables.cpp +++ b/4ed_dynamic_variables.cpp @@ -67,6 +67,7 @@ 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); @@ -250,26 +251,15 @@ lifetime__object_add_key(Lifetime_Allocator *lifetime_allocator, Lifetime_Object internal Lifetime_Object* lifetime_alloc_object(Lifetime_Allocator *lifetime_allocator, i32 user_type, void *user_back_ptr){ - Lifetime_Object *object = lifetime_allocator->free_objects.first; + Lifetime_Object *object = lifetime_allocator->free_objects; if (object == 0){ - i32 new_object_count = 256; - umem new_memory_size = new_object_count*sizeof(Lifetime_Object); - Data new_memory = base_allocate(lifetime_allocator->allocator, new_memory_size); - Lifetime_Object *new_objects = (Lifetime_Object*)new_memory.data; - Lifetime_Object *new_object_ptr = new_objects; - for (i32 i = 0; i < new_object_count; i += 1, new_object_ptr += 1){ - zdll_push_back(lifetime_allocator->free_objects.first, lifetime_allocator->free_objects.last, new_object_ptr); - } - lifetime_allocator->free_objects.count += new_object_count; - object = lifetime_allocator->free_objects.first; + object = push_array(&lifetime_allocator->node_arena, Lifetime_Object, 1); + } + else{ + sll_stack_pop(lifetime_allocator->free_objects); } - - zdll_remove(lifetime_allocator->free_objects.first, lifetime_allocator->free_objects.last, object); - lifetime_allocator->free_objects.count -= 1; - block_zero_struct(object); dynamic_workspace_init(lifetime_allocator, user_type, user_back_ptr, &object->workspace); - return(object); } @@ -313,7 +303,7 @@ 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); - zdll_push_back(lifetime_allocator->free_objects.first, lifetime_allocator->free_objects.last, lifetime_object); + sll_stack_push(lifetime_allocator->free_objects, lifetime_object); } internal void diff --git a/4ed_dynamic_variables.h b/4ed_dynamic_variables.h index 5cb2e4db..1f8352ae 100644 --- a/4ed_dynamic_variables.h +++ b/4ed_dynamic_variables.h @@ -98,18 +98,13 @@ struct Lifetime_Key_Ref_Node{ struct Lifetime_Key *keys[lifetime_key_reference_per_node]; }; -struct Lifetime_Object{ - union{ - struct{ - Lifetime_Object *next; - Lifetime_Object *prev; - }; - struct{ - Lifetime_Key_Ref_Node *key_node_first; - Lifetime_Key_Ref_Node *key_node_last; - i32 key_count; - Dynamic_Workspace workspace; - }; +union Lifetime_Object{ + Lifetime_Object *next; + struct{ + Lifetime_Key_Ref_Node *key_node_first; + Lifetime_Key_Ref_Node *key_node_last; + i32 key_count; + Dynamic_Workspace workspace; }; }; @@ -120,7 +115,7 @@ struct Lifetime_Key{ Lifetime_Key *prev; }; struct{ - struct Lifetime_Object **members; + Lifetime_Object **members; i32 count; Dynamic_Workspace dynamic_workspace; }; @@ -136,12 +131,6 @@ struct Lifetime_Key_Ref_Node_List{ i32 count; }; -struct Lifetime_Object_List{ - Lifetime_Object *first; - Lifetime_Object *last; - i32 count; -}; - struct Lifetime_Key_List{ Lifetime_Key *first; Lifetime_Key *last; @@ -150,8 +139,9 @@ struct Lifetime_Key_List{ struct Lifetime_Allocator{ Base_Allocator *allocator; + Arena node_arena; Lifetime_Key_Ref_Node_List free_key_references; - Lifetime_Object_List free_objects; + Lifetime_Object *free_objects; Lifetime_Key_List free_keys; Table_Data_u64 key_table; Table_u64_u64 key_check_table; diff --git a/4ed_edit.cpp b/4ed_edit.cpp index 558d891c..1d9a28d1 100644 --- a/4ed_edit.cpp +++ b/4ed_edit.cpp @@ -70,7 +70,7 @@ edit_fix_markers__compute_scroll_y(i32 line_height, i32 old_y_val, f32 new_y_val } internal void -edit_fix_markers(Models *models, Editing_File *file, Edit edit){ +edit_fix_markers(Thread_Context *tctx, Models *models, Editing_File *file, Edit edit){ Layout *layout = &models->layout; Lifetime_Object *file_lifetime_object = file->lifetime_object; @@ -97,7 +97,7 @@ edit_fix_markers(Models *models, Editing_File *file, Edit edit){ } cursor_max += total_marker_count; - Scratch_Block scratch(models->tctx, Scratch_Share); + Scratch_Block scratch(tctx, Scratch_Share); Cursor_With_Index *cursors = push_array(scratch, Cursor_With_Index, cursor_max); Cursor_With_Index *r_cursors = push_array(scratch, Cursor_With_Index, cursor_max); @@ -155,7 +155,7 @@ edit_fix_markers(Models *models, Editing_File *file, Edit edit){ i64 cursor_pos = cursors[cursor_count++].pos; view->mark = cursors[cursor_count++].pos; File_Edit_Positions edit_pos = view_get_edit_pos(view); - view_set_cursor_and_scroll(models, view, cursor_pos, edit_pos.scroll); + view_set_cursor_and_scroll(tctx, models, view, cursor_pos, edit_pos.scroll); // TODO(allen): read a cursor for the current scroll line } } @@ -178,7 +178,7 @@ edit_fix_markers(Models *models, Editing_File *file, Edit edit){ } internal void -edit_single(Models *models, Editing_File *file, Interval_i64 range, String_Const_u8 string, Edit_Behaviors behaviors){ +edit_single(Thread_Context *tctx, Models *models, Editing_File *file, Interval_i64 range, String_Const_u8 string, Edit_Behaviors behaviors){ Edit edit = {}; edit.text = string; edit.range = range; @@ -188,7 +188,7 @@ edit_single(Models *models, Editing_File *file, Interval_i64 range, String_Const Assert(edit.range.first <= edit.range.one_past_last); Assert(edit.range.one_past_last <= buffer_size(buffer)); - Scratch_Block scratch(models->tctx, Scratch_Share); + Scratch_Block scratch(tctx, Scratch_Share); // NOTE(allen): history update if (!behaviors.do_not_post_to_history){ @@ -223,19 +223,25 @@ edit_single(Models *models, Editing_File *file, Interval_i64 range, String_Const buffer_remeasure_starts(scratch, buffer, Ii64(line_start, line_end + 1), line_shift, shift_amount); // NOTE(allen): cursor fixing - edit_fix_markers(models, file, edit); + edit_fix_markers(tctx, models, file, edit); // NOTE(allen): edit range hook if (models->buffer_edit_range != 0){ Interval_i64 new_range = Ii64(edit.range.first, edit.range.first + edit.text.size); - models->buffer_edit_range(&models->app_links, file->id, new_range, original_text); + Application_Links app = {}; + app.tctx = tctx;; + app.cmd_context = models; + models->buffer_edit_range(&app, file->id, new_range, original_text); } } internal void -file_end_file(Models *models, Editing_File *file){ +file_end_file(Thread_Context *tctx, Models *models, Editing_File *file){ if (models->end_buffer != 0){ - models->end_buffer(&models->app_links, file->id); + Application_Links app = {}; + app.tctx = tctx; + app.cmd_context = models; + models->end_buffer(&app, file->id); } Lifetime_Allocator *lifetime_allocator = &models->lifetime_allocator; lifetime_free_object(lifetime_allocator, file->lifetime_object); @@ -243,7 +249,7 @@ file_end_file(Models *models, Editing_File *file){ } internal void -edit__apply_record_forward(Models *models, Editing_File *file, Record *record, Edit_Behaviors behaviors_prototype){ +edit__apply_record_forward(Thread_Context *tctx, Models *models, Editing_File *file, Record *record, Edit_Behaviors behaviors_prototype){ // NOTE(allen): // NOTE(allen): // NOTE(allen): // NOTE(allen): // NOTE(allen): // Whenever you change this also change the backward version! @@ -252,7 +258,7 @@ edit__apply_record_forward(Models *models, Editing_File *file, Record *record, E { String_Const_u8 str = record->single.forward_text; Interval_i64 range = Ii64(record->single.first, record->single.first + record->single.backward_text.size); - edit_single(models, file, range, str, behaviors_prototype); + edit_single(tctx, models, file, range, str, behaviors_prototype); }break; case RecordKind_Group: @@ -262,7 +268,7 @@ edit__apply_record_forward(Models *models, Editing_File *file, Record *record, E node != sentinel; node = node->next){ Record *sub_record = CastFromMember(Record, node, node); - edit__apply_record_forward(models, file, sub_record, behaviors_prototype); + edit__apply_record_forward(tctx, models, file, sub_record, behaviors_prototype); } }break; @@ -274,7 +280,7 @@ edit__apply_record_forward(Models *models, Editing_File *file, Record *record, E } internal void -edit__apply_record_backward(Models *models, Editing_File *file, Record *record, Edit_Behaviors behaviors_prototype){ +edit__apply_record_backward(Thread_Context *tctx, Models *models, Editing_File *file, Record *record, Edit_Behaviors behaviors_prototype){ // NOTE(allen): // NOTE(allen): // NOTE(allen): // NOTE(allen): // NOTE(allen): // Whenever you change this also change the forward version! @@ -283,7 +289,7 @@ edit__apply_record_backward(Models *models, Editing_File *file, Record *record, { String_Const_u8 str = record->single.backward_text; Interval_i64 range = Ii64(record->single.first, record->single.first + record->single.forward_text.size); - edit_single(models, file, range, str, behaviors_prototype); + edit_single(tctx, models, file, range, str, behaviors_prototype); }break; case RecordKind_Group: @@ -293,7 +299,7 @@ edit__apply_record_backward(Models *models, Editing_File *file, Record *record, node != sentinel; node = node->prev){ Record *sub_record = CastFromMember(Record, node, node); - edit__apply_record_backward(models, file, sub_record, behaviors_prototype); + edit__apply_record_backward(tctx, models, file, sub_record, behaviors_prototype); } }break; @@ -305,7 +311,7 @@ edit__apply_record_backward(Models *models, Editing_File *file, Record *record, } internal void -edit_change_current_history_state(Models *models, Editing_File *file, i32 target_index){ +edit_change_current_history_state(Thread_Context *tctx, Models *models, Editing_File *file, i32 target_index){ History *history = &file->state.history; if (history->activated && file->state.current_record_index != target_index){ Assert(0 <= target_index && target_index <= history->record_count); @@ -323,13 +329,13 @@ edit_change_current_history_state(Models *models, Editing_File *file, i32 target current += 1; record = CastFromMember(Record, node, record->node.next); Assert(record != dummy_record); - edit__apply_record_forward(models, file, record, behaviors_prototype); + edit__apply_record_forward(tctx, models, file, record, behaviors_prototype); } while (current != target_index); } else{ do{ Assert(record != dummy_record); - edit__apply_record_backward(models, file, record, behaviors_prototype); + edit__apply_record_backward(tctx, models, file, record, behaviors_prototype); current -= 1; record = CastFromMember(Record, node, record->node.prev); } while (current != target_index); @@ -340,7 +346,7 @@ edit_change_current_history_state(Models *models, Editing_File *file, i32 target } internal b32 -edit_merge_history_range(Models *models, Editing_File *file, History_Record_Index first_index, History_Record_Index last_index, Record_Merge_Flag flags){ +edit_merge_history_range(Thread_Context *tctx, Models *models, Editing_File *file, History_Record_Index first_index, History_Record_Index last_index, Record_Merge_Flag flags){ b32 result = false; History *history = &file->state.history; if (history_is_activated(history)){ @@ -354,13 +360,13 @@ edit_merge_history_range(Models *models, Editing_File *file, History_Record_Inde switch (in_range_handler){ case RecordMergeFlag_StateInRange_MoveStateForward: { - edit_change_current_history_state(models, file, last_index); + edit_change_current_history_state(tctx, models, file, last_index); current_index = last_index; }break; case RecordMergeFlag_StateInRange_MoveStateBackward: { - edit_change_current_history_state(models, file, first_index); + edit_change_current_history_state(tctx, models, file, first_index); current_index = first_index; }break; @@ -370,7 +376,7 @@ edit_merge_history_range(Models *models, Editing_File *file, History_Record_Inde }break; } } - Scratch_Block scratch(models->tctx, Scratch_Share); + Scratch_Block scratch(tctx, Scratch_Share); history_merge_records(scratch, history, first_index, last_index); if (current_index >= last_index){ current_index -= (last_index - first_index); @@ -385,7 +391,7 @@ edit_merge_history_range(Models *models, Editing_File *file, History_Record_Inde } internal b32 -edit_batch(Models *models, Editing_File *file, Batch_Edit *batch, Edit_Behaviors behaviors){ +edit_batch(Thread_Context *tctx, Models *models, Editing_File *file, Batch_Edit *batch, Edit_Behaviors behaviors){ b32 result = true; if (batch != 0){ History_Record_Index start_index = 0; @@ -405,7 +411,7 @@ edit_batch(Models *models, Editing_File *file, Batch_Edit *batch, Edit_Behaviors if (0 <= edit_range.first && edit_range.first <= edit_range.one_past_last && edit_range.one_past_last <= size){ - edit_single(models, file, edit_range, insert_string, behaviors); + edit_single(tctx, models, file, edit_range, insert_string, behaviors); shift += replace_range_shift(edit_range, insert_string.size); } else{ @@ -417,7 +423,7 @@ edit_batch(Models *models, Editing_File *file, Batch_Edit *batch, Edit_Behaviors if (history_is_activated(&file->state.history)){ History_Record_Index last_index = file->state.current_record_index; if (start_index + 1 < last_index){ - edit_merge_history_range(models, file, start_index + 1, last_index, RecordMergeFlag_StateInRange_ErrorOut); + edit_merge_history_range(tctx, models, file, start_index + 1, last_index, RecordMergeFlag_StateInRange_ErrorOut); } } } @@ -427,14 +433,14 @@ edit_batch(Models *models, Editing_File *file, Batch_Edit *batch, Edit_Behaviors //////////////////////////////// internal Editing_File* -create_file(Models *models, String_Const_u8 file_name, Buffer_Create_Flag flags){ +create_file(Thread_Context *tctx, Models *models, String_Const_u8 file_name, Buffer_Create_Flag flags){ Editing_File *result = 0; if (file_name.size > 0){ Working_Set *working_set = &models->working_set; Heap *heap = &models->heap; - Scratch_Block scratch(models->tctx); + Scratch_Block scratch(tctx); Editing_File *file = 0; b32 do_empty_buffer = false; @@ -487,9 +493,9 @@ create_file(Models *models, String_Const_u8 file_name, Buffer_Create_Flag flags) file_bind_file_name(working_set, file, string_from_file_name(&canon)); } String_Const_u8 front = string_front_of_path(file_name); - buffer_bind_name(models, scratch, working_set, file, front); + buffer_bind_name(tctx, models, scratch, working_set, file, front); File_Attributes attributes = {}; - file_create_from_string(models, file, SCu8(""), attributes); + file_create_from_string(tctx, models, file, SCu8(""), attributes); result = file; } } @@ -511,8 +517,8 @@ create_file(Models *models, String_Const_u8 file_name, Buffer_Create_Flag flags) if (file != 0){ file_bind_file_name(working_set, file, string_from_file_name(&canon)); String_Const_u8 front = string_front_of_path(file_name); - buffer_bind_name(models, scratch, working_set, file, front); - file_create_from_string(models, file, SCu8(buffer, (i32)attributes.size), attributes); + buffer_bind_name(tctx, models, scratch, working_set, file, front); + file_create_from_string(tctx, models, file, SCu8(buffer, (i32)attributes.size), attributes); result = file; } } @@ -537,7 +543,7 @@ create_file(Models *models, String_Const_u8 file_name, Buffer_Create_Flag flags) i64 size = buffer_size(&file->state.buffer); if (size > 0){ Edit_Behaviors behaviors = {}; - edit_single(models, file, Ii64(0, size), string_u8_litexpr(""), behaviors); + edit_single(tctx, models, file, Ii64(0, size), string_u8_litexpr(""), behaviors); if (has_canon_name){ buffer_is_for_new_file = true; } @@ -547,7 +553,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->new_file != 0){ - models->new_file(&models->app_links, file->id); + Application_Links app = {}; + app.tctx = tctx; + app.cmd_context = models; + models->new_file(&app, file->id); } } diff --git a/4ed_file.cpp b/4ed_file.cpp index 43b436bb..825904cd 100644 --- a/4ed_file.cpp +++ b/4ed_file.cpp @@ -137,7 +137,7 @@ file_name_terminate(Editing_File_Name *name){ // TODO(allen): file_name should be String_Const_u8 internal b32 -save_file_to_name(Models *models, Editing_File *file, u8 *file_name){ +save_file_to_name(Thread_Context *tctx, Models *models, Editing_File *file, u8 *file_name){ b32 result = false; b32 using_actual_file_name = false; @@ -149,13 +149,16 @@ save_file_to_name(Models *models, Editing_File *file, u8 *file_name){ if (file_name != 0){ if (models->save_file != 0){ - models->save_file(&models->app_links, file->id); + Application_Links app = {}; + app.tctx = tctx; + app.cmd_context = models; + models->save_file(&app, file->id); } Gap_Buffer *buffer = &file->state.buffer; b32 dos_write_mode = file->settings.dos_write_mode; - Scratch_Block scratch(models->tctx, Scratch_Share); + Scratch_Block scratch(tctx, Scratch_Share); if (!using_actual_file_name){ String_Const_u8 s_file_name = SCu8(file_name); @@ -181,8 +184,8 @@ save_file_to_name(Models *models, Editing_File *file, u8 *file_name){ } internal b32 -save_file(Models *models, Editing_File *file){ - return(save_file_to_name(models, file, 0)); +save_file(Thread_Context *tctx, Models *models, Editing_File *file){ + return(save_file_to_name(tctx, models, file, 0)); } //////////////////////////////// @@ -206,8 +209,7 @@ file_compute_cursor(Editing_File *file, Buffer_Seek seek){ //////////////////////////////// internal void -file_create_from_string(Models *models, Editing_File *file, String_Const_u8 val, File_Attributes attributes){ - Thread_Context *tctx = models->tctx; +file_create_from_string(Thread_Context *tctx, Models *models, Editing_File *file, String_Const_u8 val, File_Attributes attributes){ Scratch_Block scratch(tctx, Scratch_Share); Base_Allocator *allocator = tctx->allocator; @@ -225,7 +227,7 @@ file_create_from_string(Models *models, Editing_File *file, String_Const_u8 val, buffer_measure_starts(scratch, &file->state.buffer); file->lifetime_object = lifetime_alloc_object(&models->lifetime_allocator, DynamicWorkspace_Buffer, file); - history_init(models, &file->state.history); + history_init(tctx, models, &file->state.history); file->state.cached_layouts_arena = make_arena(allocator); file->state.line_layout_table = make_table_Data_u64(allocator, 500); @@ -245,12 +247,15 @@ file_create_from_string(Models *models, Editing_File *file, String_Const_u8 val, //////////////////////////////// if (models->begin_buffer != 0){ - models->begin_buffer(&models->app_links, file->id); + Application_Links app = {}; + app.tctx = tctx; + app.cmd_context = models; + models->begin_buffer(&app, file->id); } } internal void -file_free(Models *models, Editing_File *file){ +file_free(Thread_Context *tctx, Models *models, Editing_File *file){ Lifetime_Allocator *lifetime_allocator = &models->lifetime_allocator; Working_Set *working_set = &models->working_set; @@ -262,7 +267,7 @@ file_free(Models *models, Editing_File *file){ base_free(buffer->allocator, buffer->line_starts); } - history_free(models, &file->state.history); + history_free(tctx, &file->state.history); linalloc_clear(&file->state.cached_layouts_arena); table_free(&file->state.line_layout_table); @@ -288,7 +293,7 @@ file_get_managed_scope(Editing_File *file){ //////////////////////////////// internal Buffer_Layout_Item_List -file_get_line_layout(Models *models, Editing_File *file, f32 width, Face *face, i64 line_number){ +file_get_line_layout(Thread_Context *tctx, Models *models, Editing_File *file, f32 width, Face *face, i64 line_number){ Buffer_Layout_Item_List result = {}; i64 line_count = buffer_line_count(&file->state.buffer); @@ -312,7 +317,7 @@ file_get_line_layout(Models *models, Editing_File *file, f32 width, Face *face, else{ list = push_array(&file->state.cached_layouts_arena, Buffer_Layout_Item_List, 1); Interval_i64 line_range = buffer_get_pos_range_from_line_number(&file->state.buffer, line_number); - *list = buffer_layout(models->tctx, &file->state.cached_layouts_arena, + *list = buffer_layout(tctx, &file->state.cached_layouts_arena, &file->state.buffer, line_range, face, width); key_data = push_data_copy(&file->state.cached_layouts_arena, key_data); table_insert(&file->state.line_layout_table, key_data, (u64)PtrAsInt(list)); @@ -330,7 +335,7 @@ file_clear_layout_cache(Editing_File *file){ } internal Line_Shift_Vertical -file_line_shift_y(Models *models, Editing_File *file, f32 width, Face *face, i64 line_number, f32 y_delta){ +file_line_shift_y(Thread_Context *tctx, Models *models, Editing_File *file, f32 width, Face *face, i64 line_number, f32 y_delta){ Line_Shift_Vertical result = {}; f32 line_y = 0.f; @@ -350,7 +355,7 @@ file_line_shift_y(Models *models, Editing_File *file, f32 width, Face *face, i64 line_number = 1; break; } - Buffer_Layout_Item_List line = file_get_line_layout(models, file, width, face, line_number); + Buffer_Layout_Item_List line = file_get_line_layout(tctx, models, file, width, face, line_number); line_y -= line.height; } if (!has_result){ @@ -363,7 +368,7 @@ file_line_shift_y(Models *models, Editing_File *file, f32 width, Face *face, i64 b32 has_result = false; i64 line_count = buffer_line_count(&file->state.buffer); for (;;line_number += 1){ - Buffer_Layout_Item_List line = file_get_line_layout(models, file, width, face, line_number); + Buffer_Layout_Item_List line = file_get_line_layout(tctx, models, file, width, face, line_number); f32 next_y = line_y + line.height; if (y_delta < next_y){ has_result = true; @@ -386,12 +391,12 @@ file_line_shift_y(Models *models, Editing_File *file, f32 width, Face *face, i64 } internal f32 -file_line_y_difference(Models *models, Editing_File *file, f32 width, Face *face, i64 line_a, i64 line_b){ +file_line_y_difference(Thread_Context *tctx, Models *models, Editing_File *file, f32 width, Face *face, i64 line_a, i64 line_b){ f32 result = 0.f; if (line_a != line_b){ Interval_i64 line_range = Ii64(line_a, line_b); for (i64 i = line_range.min; i < line_range.max; i += 1){ - Buffer_Layout_Item_List line = file_get_line_layout(models, file, width, face, i); + Buffer_Layout_Item_List line = file_get_line_layout(tctx, models, file, width, face, i); result += line.height; } if (line_a < line_b){ @@ -402,25 +407,25 @@ file_line_y_difference(Models *models, Editing_File *file, f32 width, Face *face } internal i64 -file_pos_at_relative_xy(Models *models, Editing_File *file, f32 width, Face *face, i64 base_line, Vec2_f32 relative_xy){ - Line_Shift_Vertical shift = file_line_shift_y(models, file, width, face, base_line, relative_xy.y); +file_pos_at_relative_xy(Thread_Context *tctx, Models *models, Editing_File *file, f32 width, Face *face, i64 base_line, Vec2_f32 relative_xy){ + Line_Shift_Vertical shift = file_line_shift_y(tctx, models, file, width, face, base_line, relative_xy.y); relative_xy.y -= shift.y_delta; - Buffer_Layout_Item_List line = file_get_line_layout(models, file, width, face, shift.line); + Buffer_Layout_Item_List line = file_get_line_layout(tctx, models, file, width, face, shift.line); return(buffer_layout_nearest_pos_to_xy(line, relative_xy)); } internal Vec2_f32 -file_relative_xy_of_pos(Models *models, Editing_File *file, f32 width, Face *face, i64 base_line, i64 pos){ +file_relative_xy_of_pos(Thread_Context *tctx, Models *models, Editing_File *file, f32 width, Face *face, i64 base_line, i64 pos){ i64 line_number = buffer_get_line_index(&file->state.buffer, pos) + 1; - Buffer_Layout_Item_List line = file_get_line_layout(models, file, width, face, line_number); + Buffer_Layout_Item_List line = file_get_line_layout(tctx, models, file, width, face, line_number); Vec2_f32 result = buffer_layout_xy_center_of_pos(line, pos); - result.y += file_line_y_difference(models, file, width, face, line_number, base_line); + result.y += file_line_y_difference(tctx, models, file, width, face, line_number, base_line); return(result); } internal Buffer_Point -file_normalize_buffer_point(Models *models, Editing_File *file, f32 width, Face *face, Buffer_Point point){ - Line_Shift_Vertical shift = file_line_shift_y(models, file, width, face, point.line_number, point.pixel_shift.y); +file_normalize_buffer_point(Thread_Context *tctx, Models *models, Editing_File *file, f32 width, Face *face, Buffer_Point point){ + Line_Shift_Vertical shift = file_line_shift_y(tctx, models, file, width, face, point.line_number, point.pixel_shift.y); point.line_number = shift.line; point.pixel_shift.y -= shift.y_delta; point.pixel_shift.x = clamp_bot(0.f, point.pixel_shift.x); @@ -429,15 +434,15 @@ file_normalize_buffer_point(Models *models, Editing_File *file, f32 width, Face } internal Vec2_f32 -file_buffer_point_difference(Models *models, Editing_File *file, f32 width, Face *face, Buffer_Point a, Buffer_Point b){ - f32 y_difference = file_line_y_difference(models, file, width, face, a.line_number, b.line_number); +file_buffer_point_difference(Thread_Context *tctx, Models *models, Editing_File *file, f32 width, Face *face, Buffer_Point a, Buffer_Point b){ + f32 y_difference = file_line_y_difference(tctx, models, file, width, face, a.line_number, b.line_number); Vec2_f32 result = a.pixel_shift - b.pixel_shift; result.y += y_difference; return(result); } internal Line_Shift_Character -file_line_shift_characters(Models *models, Editing_File *file, f32 width, Face *face, i64 line_number, i64 character_delta){ +file_line_shift_characters(Thread_Context *tctx, Models *models, Editing_File *file, f32 width, Face *face, i64 line_number, i64 character_delta){ Line_Shift_Character result = {}; i64 line_character = 0; @@ -457,7 +462,7 @@ file_line_shift_characters(Models *models, Editing_File *file, f32 width, Face * line_number = 1; break; } - Buffer_Layout_Item_List line = file_get_line_layout(models, file, width, face, line_number); + Buffer_Layout_Item_List line = file_get_line_layout(tctx, models, file, width, face, line_number); line_character -= line.character_count; } if (!has_result){ @@ -470,7 +475,7 @@ file_line_shift_characters(Models *models, Editing_File *file, f32 width, Face * b32 has_result = false; i64 line_count = buffer_line_count(&file->state.buffer); for (;;line_number += 1){ - Buffer_Layout_Item_List line = file_get_line_layout(models, file, width, face, line_number); + Buffer_Layout_Item_List line = file_get_line_layout(tctx, models, file, width, face, line_number); i64 next_character = line_character + line.character_count; if (character_delta < next_character){ has_result = true; @@ -493,12 +498,12 @@ file_line_shift_characters(Models *models, Editing_File *file, f32 width, Face * } internal i64 -file_line_character_difference(Models *models, Editing_File *file, f32 width, Face *face, i64 line_a, i64 line_b){ +file_line_character_difference(Thread_Context *tctx, Models *models, Editing_File *file, f32 width, Face *face, i64 line_a, i64 line_b){ i64 result = 0; if (line_a != line_b){ Interval_i64 line_range = Ii64(line_a, line_b); for (i64 i = line_range.min; i < line_range.max; i += 1){ - Buffer_Layout_Item_List line = file_get_line_layout(models, file, width, face, i); + Buffer_Layout_Item_List line = file_get_line_layout(tctx, models, file, width, face, i); result += line.character_count; } if (line_a < line_b){ @@ -509,19 +514,19 @@ file_line_character_difference(Models *models, Editing_File *file, f32 width, Fa } internal i64 -file_pos_from_relative_character(Models *models, Editing_File *file, f32 width, Face *face, i64 base_line, i64 relative_character){ - Line_Shift_Character shift = file_line_shift_characters(models, file, width, face, base_line, relative_character); +file_pos_from_relative_character(Thread_Context *tctx, Models *models, Editing_File *file, f32 width, Face *face, i64 base_line, i64 relative_character){ + Line_Shift_Character shift = file_line_shift_characters(tctx, models, file, width, face, base_line, relative_character); relative_character -= shift.character_delta; - Buffer_Layout_Item_List line = file_get_line_layout(models, file, width, face, shift.line); + Buffer_Layout_Item_List line = file_get_line_layout(tctx, models, file, width, face, shift.line); return(buffer_layout_get_pos_at_character(line, relative_character)); } internal i64 -file_relative_character_from_pos(Models *models, Editing_File *file, f32 width, Face *face, i64 base_line, i64 pos){ +file_relative_character_from_pos(Thread_Context *tctx, Models *models, Editing_File *file, f32 width, Face *face, i64 base_line, i64 pos){ i64 line_number = buffer_get_line_index(&file->state.buffer, pos) + 1; - Buffer_Layout_Item_List line = file_get_line_layout(models, file, width, face, line_number); + Buffer_Layout_Item_List line = file_get_line_layout(tctx, models, file, width, face, line_number); i64 result = buffer_layout_character_from_pos(line, pos); - result += file_line_character_difference(models, file, width, face, line_number, base_line); + result += file_line_character_difference(tctx, models, file, width, face, line_number, base_line); return(result); } diff --git a/4ed_history.cpp b/4ed_history.cpp index 1cceeaf4..d18e84b1 100644 --- a/4ed_history.cpp +++ b/4ed_history.cpp @@ -129,9 +129,8 @@ global_history_adjust_edit_grouping_counter(Global_History *global_history, i32 } internal void -history_init(Models *models, History *history){ +history_init(Thread_Context *tctx, Models *models, History *history){ history->activated = true; - Thread_Context *tctx = models->tctx; history->arena = reserve_arena(tctx, KB(32)); heap_init(&history->heap, tctx->allocator); history->heap_wrapper = base_allocator_on_heap(&history->heap); @@ -147,9 +146,9 @@ history_is_activated(History *history){ } internal void -history_free(Models *models, History *history){ +history_free(Thread_Context *tctx, History *history){ if (history->activated){ - release_arena(models, history->arena); + release_arena(tctx, history->arena); heap_free_all(&history->heap); block_zero_struct(history); } diff --git a/4ed_log.cpp b/4ed_log.cpp index 51f3d45c..de9eee94 100644 --- a/4ed_log.cpp +++ b/4ed_log.cpp @@ -31,10 +31,10 @@ log_string(String_Const_u8 str){ } internal void -output_file_append(Models *models, Editing_File *file, String_Const_u8 value); +output_file_append(Thread_Context *tctx, Models *models, Editing_File *file, String_Const_u8 value); internal b32 -log_flush(Models *models){ +log_flush(Thread_Context *tctx, Models *models){ b32 result = false; system_mutex_acquire(global_log.mutex); @@ -42,7 +42,7 @@ log_flush(Models *models){ if (global_log.list.total_size > 0){ String_Const_u8 text = string_list_flatten(&global_log.arena, global_log.list); - output_file_append(models, models->log_buffer, text); + output_file_append(tctx, models, models->log_buffer, text); result = true; } linalloc_clear(&global_log.arena); diff --git a/4ed_text_layout.cpp b/4ed_text_layout.cpp index 1e72bd8b..1057d534 100644 --- a/4ed_text_layout.cpp +++ b/4ed_text_layout.cpp @@ -10,10 +10,10 @@ // TOP internal void -text_layout_init(Models *models, Text_Layout_Container *container){ +text_layout_init(Thread_Context *tctx, Text_Layout_Container *container){ block_zero_struct(container); - container->node_arena = reserve_arena(models->tctx); - container->table = make_table_u64_u64(models->tctx->allocator, 20); + container->node_arena = reserve_arena(tctx); + container->table = make_table_u64_u64(tctx->allocator, 20); } internal Text_Layout* @@ -29,8 +29,8 @@ text_layout_new__alloc_layout(Text_Layout_Container *container){ } internal void -text_layout_release(Models *models, Text_Layout_Container *container, Text_Layout *layout){ - release_arena(models->tctx, layout->arena); +text_layout_release(Thread_Context *tctx, Models *models, Text_Layout_Container *container, Text_Layout *layout){ + release_arena(tctx, layout->arena); sll_stack_push(container->free_nodes, layout); } @@ -65,14 +65,14 @@ text_layout_get(Text_Layout_Container *container, Text_Layout_ID id){ } internal b32 -text_layout_erase(Models *models, Text_Layout_Container *container, Text_Layout_ID id){ +text_layout_erase(Thread_Context *tctx, Models *models, Text_Layout_Container *container, Text_Layout_ID id){ b32 result = false; Table_Lookup lookup = table_lookup(&container->table, id); if (lookup.found_match){ u64 ptr_val = 0; table_read(&container->table, lookup, &ptr_val); Text_Layout *ptr = (Text_Layout*)IntAsPtr(ptr_val); - text_layout_release(models, container, ptr); + text_layout_release(tctx, models, container, ptr); table_erase(&container->table, lookup); result = true; } @@ -82,7 +82,7 @@ text_layout_erase(Models *models, Text_Layout_Container *container, Text_Layout_ //////////////////////////////// internal void -text_layout_render(Models *models, Text_Layout *layout){ +text_layout_render(Thread_Context *tctx, Models *models, Text_Layout *layout){ Editing_File *file = imp_get_file(models, layout->buffer_id); if (file != 0){ Render_Target *target = models->target; @@ -98,7 +98,7 @@ text_layout_render(Models *models, Text_Layout *layout){ i64 line_number = layout->visible_line_number_range.min; i64 line_number_last = layout->visible_line_number_range.max; for (;line_number <= line_number_last; line_number += 1){ - Buffer_Layout_Item_List line = file_get_line_layout(models, file, width, face, line_number); + Buffer_Layout_Item_List line = file_get_line_layout(tctx, models, file, width, face, line_number); for (Buffer_Layout_Item_Block *block = line.first; block != 0; block = block->next){ diff --git a/4ed_view.cpp b/4ed_view.cpp index abfe0973..c3a98040 100644 --- a/4ed_view.cpp +++ b/4ed_view.cpp @@ -148,12 +148,15 @@ view_set_edit_pos(View *view, File_Edit_Positions edit_pos){ //////////////////////////////// internal Rect_f32 -view_get_buffer_rect(Models *models, View *view){ +view_get_buffer_rect(Thread_Context *tctx, Models *models, View *view){ Rect_f32 region = Rf32(view->panel->rect_full); if (models->buffer_region != 0){ Rect_f32 rect = region; Rect_f32 sub_region = Rf32(V2(0, 0), rect_dim(rect)); - sub_region = models->buffer_region(&models->app_links, view_get_id(&models->live_set, view), sub_region); + Application_Links app = {}; + app.tctx = tctx; + app.cmd_context = models; + sub_region = models->buffer_region(&app, view_get_id(&models->live_set, view), sub_region); region.p0 = rect.p0 + sub_region.p0; region.p1 = rect.p0 + sub_region.p1; region.x1 = clamp_top(region.x1, rect.x1); @@ -165,112 +168,112 @@ view_get_buffer_rect(Models *models, View *view){ } internal f32 -view_width(Models *models, View *view){ - return(rect_width(view_get_buffer_rect(models, view))); +view_width(Thread_Context *tctx, Models *models, View *view){ + return(rect_width(view_get_buffer_rect(tctx, models, view))); } internal f32 -view_height(Models *models, View *view){ - return(rect_height(view_get_buffer_rect(models, view))); +view_height(Thread_Context *tctx, Models *models, View *view){ + return(rect_height(view_get_buffer_rect(tctx, models, view))); } //////////////////////////////// internal Buffer_Layout_Item_List -view_get_line_layout(Models *models, View *view, i64 line_number){ +view_get_line_layout(Thread_Context *tctx, Models *models, View *view, i64 line_number){ Editing_File *file = view->file; Face *face = file_get_face(models, file); - f32 width = view_width(models, view); - return(file_get_line_layout(models, file, width, face, line_number)); + f32 width = view_width(tctx, models, view); + return(file_get_line_layout(tctx, models, file, width, face, line_number)); } internal Line_Shift_Vertical -view_line_shift_y(Models *models, View *view, i64 line_number, f32 y_delta){ +view_line_shift_y(Thread_Context *tctx, Models *models, View *view, i64 line_number, f32 y_delta){ Editing_File *file = view->file; Face *face = file_get_face(models, file); - f32 width = view_width(models, view); - return(file_line_shift_y(models, file, width, face, line_number, y_delta)); + f32 width = view_width(tctx, models, view); + return(file_line_shift_y(tctx, models, file, width, face, line_number, y_delta)); } internal f32 -view_line_y_difference(Models *models, View *view, i64 line_a, i64 line_b){ +view_line_y_difference(Thread_Context *tctx, Models *models, View *view, i64 line_a, i64 line_b){ Editing_File *file = view->file; Face *face = file_get_face(models, file); - f32 width = view_width(models, view); - return(file_line_y_difference(models, file, width, face, line_a, line_b)); + f32 width = view_width(tctx, models, view); + return(file_line_y_difference(tctx, models, file, width, face, line_a, line_b)); } internal i64 -view_pos_at_relative_xy(Models *models, View *view, i64 base_line, Vec2_f32 relative_xy){ +view_pos_at_relative_xy(Thread_Context *tctx, Models *models, View *view, i64 base_line, Vec2_f32 relative_xy){ Editing_File *file = view->file; Face *face = file_get_face(models, file); - f32 width = view_width(models, view); - return(file_pos_at_relative_xy(models, file, width, face, base_line, relative_xy)); + f32 width = view_width(tctx, models, view); + return(file_pos_at_relative_xy(tctx, models, file, width, face, base_line, relative_xy)); } internal Vec2_f32 -view_relative_xy_of_pos(Models *models, View *view, i64 base_line, i64 pos){ +view_relative_xy_of_pos(Thread_Context *tctx, Models *models, View *view, i64 base_line, i64 pos){ Editing_File *file = view->file; Face *face = file_get_face(models, file); - f32 width = view_width(models, view); - return(file_relative_xy_of_pos(models, file, width, face, base_line, pos)); + f32 width = view_width(tctx, models, view); + return(file_relative_xy_of_pos(tctx, models, file, width, face, base_line, pos)); } internal Buffer_Point -view_normalize_buffer_point(Models *models, View *view, Buffer_Point point){ +view_normalize_buffer_point(Thread_Context *tctx, Models *models, View *view, Buffer_Point point){ Editing_File *file = view->file; Face *face = file_get_face(models, file); - f32 width = view_width(models, view); - return(file_normalize_buffer_point(models, file, width, face, point)); + f32 width = view_width(tctx, models, view); + return(file_normalize_buffer_point(tctx, models, file, width, face, point)); } internal Vec2_f32 -view_buffer_point_difference(Models *models, View *view, Buffer_Point a, Buffer_Point b){ +view_buffer_point_difference(Thread_Context *tctx, Models *models, View *view, Buffer_Point a, Buffer_Point b){ Editing_File *file = view->file; Face *face = file_get_face(models, file); - f32 width = view_width(models, view); - return(file_buffer_point_difference(models, file, width, face, a, b)); + f32 width = view_width(tctx, models, view); + return(file_buffer_point_difference(tctx, models, file, width, face, a, b)); } internal Buffer_Point -view_move_buffer_point(Models *models, View *view, Buffer_Point buffer_point, Vec2_f32 delta){ +view_move_buffer_point(Thread_Context *tctx, Models *models, View *view, Buffer_Point buffer_point, Vec2_f32 delta){ delta += buffer_point.pixel_shift; - Line_Shift_Vertical shift = view_line_shift_y(models, view, buffer_point.line_number, delta.y); + Line_Shift_Vertical shift = view_line_shift_y(tctx, models, view, buffer_point.line_number, delta.y); buffer_point.line_number = shift.line; buffer_point.pixel_shift = V2f32(delta.x, delta.y - shift.y_delta); return(buffer_point); } internal Line_Shift_Character -view_line_shift_characters(Models *models, View *view, i64 line_number, i64 character_delta){ +view_line_shift_characters(Thread_Context *tctx, Models *models, View *view, i64 line_number, i64 character_delta){ Editing_File *file = view->file; Face *face = file_get_face(models, file); - f32 width = view_width(models, view); - return(file_line_shift_characters(models, file, width, face, line_number, character_delta)); + f32 width = view_width(tctx, models, view); + return(file_line_shift_characters(tctx, models, file, width, face, line_number, character_delta)); } internal i64 -view_line_character_difference(Models *models, View *view, i64 line_a, i64 line_b){ +view_line_character_difference(Thread_Context *tctx, Models *models, View *view, i64 line_a, i64 line_b){ Editing_File *file = view->file; Face *face = file_get_face(models, file); - f32 width = view_width(models, view); - return(file_line_character_difference(models, file, width, face, line_a, line_b)); + f32 width = view_width(tctx, models, view); + return(file_line_character_difference(tctx, models, file, width, face, line_a, line_b)); } internal i64 -view_pos_from_relative_character(Models *models, View *view, i64 base_line, i64 relative_character){ +view_pos_from_relative_character(Thread_Context *tctx, Models *models, View *view, i64 base_line, i64 relative_character){ Editing_File *file = view->file; Face *face = file_get_face(models, file); - f32 width = view_width(models, view); - return(file_pos_from_relative_character(models, file, width, face, base_line, relative_character)); + f32 width = view_width(tctx, models, view); + return(file_pos_from_relative_character(tctx, models, file, width, face, base_line, relative_character)); } internal i64 -view_relative_character_from_pos(Models *models, View *view, i64 base_line, i64 pos){ +view_relative_character_from_pos(Thread_Context *tctx, Models *models, View *view, i64 base_line, i64 pos){ Editing_File *file = view->file; Face *face = file_get_face(models, file); - f32 width = view_width(models, view); - return(file_relative_character_from_pos(models, file, width, face, base_line, pos)); + f32 width = view_width(tctx, models, view); + return(file_relative_character_from_pos(tctx, models, file, width, face, base_line, pos)); } internal Buffer_Cursor @@ -282,14 +285,14 @@ view_compute_cursor(View *view, Buffer_Seek seek){ //////////////////////////////// internal b32 -view_move_view_to_cursor(Models *models, View *view, Buffer_Scroll *scroll){ +view_move_view_to_cursor(Thread_Context *tctx, Models *models, View *view, Buffer_Scroll *scroll){ Editing_File *file = view->file; Face *face = file_get_face(models, file); - Rect_f32 rect = view_get_buffer_rect(models, view); + Rect_f32 rect = view_get_buffer_rect(tctx, models, view); Vec2_f32 view_dim = rect_dim(rect); File_Edit_Positions edit_pos = view_get_edit_pos(view); - Vec2_f32 p = file_relative_xy_of_pos(models, file, view_dim.x, face, scroll->target.line_number, + Vec2_f32 p = file_relative_xy_of_pos(tctx, models, file, view_dim.x, face, scroll->target.line_number, edit_pos.cursor_pos); p -= scroll->target.pixel_shift; @@ -310,7 +313,7 @@ view_move_view_to_cursor(Models *models, View *view, Buffer_Scroll *scroll){ target_p_relative.x = (p.x + typical_advance*1.5f) - view_dim.x; } scroll->target.pixel_shift += target_p_relative; - scroll->target = view_normalize_buffer_point(models, view, scroll->target); + scroll->target = view_normalize_buffer_point(tctx, models, view, scroll->target); scroll->target.pixel_shift.x = f32_round32(scroll->target.pixel_shift.x); scroll->target.pixel_shift.y = f32_round32(scroll->target.pixel_shift.y); @@ -318,13 +321,13 @@ view_move_view_to_cursor(Models *models, View *view, Buffer_Scroll *scroll){ } internal b32 -view_move_cursor_to_view(Models *models, View *view, Buffer_Scroll scroll, i64 *pos_in_out, f32 preferred_x){ +view_move_cursor_to_view(Thread_Context *tctx, Models *models, View *view, Buffer_Scroll scroll, i64 *pos_in_out, f32 preferred_x){ Editing_File *file = view->file; Face *face = file_get_face(models, file); - Rect_f32 rect = view_get_buffer_rect(models, view); + Rect_f32 rect = view_get_buffer_rect(tctx, models, view); Vec2_f32 view_dim = rect_dim(rect); - Vec2_f32 p = file_relative_xy_of_pos(models, file, view_dim.x, face, scroll.target.line_number, *pos_in_out); + Vec2_f32 p = file_relative_xy_of_pos(tctx, models, file, view_dim.x, face, scroll.target.line_number, *pos_in_out); p -= scroll.target.pixel_shift; f32 line_height = face->line_height; @@ -343,7 +346,7 @@ view_move_cursor_to_view(Models *models, View *view, Buffer_Scroll scroll, i64 * b32 result = false; if (adjusted_y){ p += scroll.target.pixel_shift; - *pos_in_out = file_pos_at_relative_xy(models, file, view_dim.x, face, scroll.target.line_number, p); + *pos_in_out = file_pos_at_relative_xy(tctx, models, file, view_dim.x, face, scroll.target.line_number, p); result = true; } @@ -351,33 +354,33 @@ view_move_cursor_to_view(Models *models, View *view, Buffer_Scroll scroll, i64 * } internal void -view_set_cursor(Models *models, View *view, i64 pos){ +view_set_cursor(Thread_Context *tctx, Models *models, View *view, i64 pos){ File_Edit_Positions edit_pos = view_get_edit_pos(view); file_edit_positions_set_cursor(&edit_pos, pos); view_set_edit_pos(view, edit_pos); Buffer_Scroll scroll = edit_pos.scroll; - if (view_move_view_to_cursor(models, view, &scroll)){ + if (view_move_view_to_cursor(tctx, models, view, &scroll)){ edit_pos.scroll = scroll; view_set_edit_pos(view, edit_pos); } } internal void -view_set_scroll(Models *models, View *view, Buffer_Scroll scroll){ +view_set_scroll(Thread_Context *tctx, Models *models, View *view, Buffer_Scroll scroll){ File_Edit_Positions edit_pos = view_get_edit_pos(view); file_edit_positions_set_scroll(&edit_pos, scroll); view_set_edit_pos(view, edit_pos); - if (view_move_cursor_to_view(models, view, edit_pos.scroll, &edit_pos.cursor_pos, view->preferred_x)){ + if (view_move_cursor_to_view(tctx, models, view, edit_pos.scroll, &edit_pos.cursor_pos, view->preferred_x)){ view_set_edit_pos(view, edit_pos); } } internal void -view_set_cursor_and_scroll(Models *models, View *view, i64 pos, Buffer_Scroll scroll){ +view_set_cursor_and_scroll(Thread_Context *tctx, Models *models, View *view, i64 pos, Buffer_Scroll scroll){ File_Edit_Positions edit_pos = view_get_edit_pos(view); file_edit_positions_set_cursor(&edit_pos, pos); Buffer_Cursor cursor = view_compute_cursor(view, seek_pos(pos)); - Vec2_f32 p = view_relative_xy_of_pos(models, view, cursor.line, pos); + Vec2_f32 p = view_relative_xy_of_pos(tctx, models, view, cursor.line, pos); view->preferred_x = p.x; file_edit_positions_set_scroll(&edit_pos, scroll); edit_pos.last_set_type = EditPos_None; @@ -397,7 +400,7 @@ view_post_paste_effect(View *view, f32 seconds, i64 start, i64 size, u32 color){ //////////////////////////////// internal void -view_set_file(Models *models, View *view, Editing_File *file){ +view_set_file(Thread_Context *tctx, Models *models, View *view, Editing_File *file){ Assert(file != 0); Editing_File *old_file = view->file; @@ -412,7 +415,7 @@ view_set_file(Models *models, View *view, Editing_File *file){ view_set_edit_pos(view, edit_pos); view->mark = edit_pos.cursor_pos; Buffer_Cursor cursor = view_compute_cursor(view, seek_pos(edit_pos.cursor_pos)); - Vec2_f32 p = view_relative_xy_of_pos(models, view, cursor.line, edit_pos.cursor_pos); + Vec2_f32 p = view_relative_xy_of_pos(tctx, models, view, cursor.line, edit_pos.cursor_pos); view->preferred_x = p.x; models->layout.panel_state_dirty = true; @@ -463,20 +466,6 @@ view_current_context(View *view){ //////////////////////////////// -internal App_Coroutine_State -get_co_state(Application_Links *app){ - App_Coroutine_State state = {}; - state.co = app->current_coroutine; - state.type = app->type_coroutine; - return(state); -} - -internal void -restore_co_state(Application_Links *app, App_Coroutine_State state){ - app->current_coroutine = state.co; - app->type_coroutine = state.type; -} - internal Coroutine* co_handle_request(Models *models, Coroutine *co, Co_Out *out){ Coroutine *result = 0; @@ -503,17 +492,11 @@ co_handle_request(Models *models, Coroutine *co, Co_Out *out){ } internal Coroutine* -co_run(Models *models, App_Coroutine_Purpose purpose, Coroutine *co, - Co_In *in, Co_Out *out){ - Application_Links *app = &models->app_links; - App_Coroutine_State prev_state = get_co_state(app); - app->current_coroutine = co; - app->type_coroutine = purpose; +co_run(Thread_Context *tctx, Models *models, Coroutine *co, Co_In *in, Co_Out *out){ Coroutine *result = coroutine_run(&models->coroutines, co, in, out); for (;result != 0 && out->request != CoRequest_None;){ result = co_handle_request(models, result, out); } - restore_co_state(app, prev_state); return(result); } @@ -523,15 +506,18 @@ view_event_context_base__inner(Coroutine *coroutine){ Models *models = in->models; Custom_Command_Function *event_context_base = in->event_context_base; Assert(event_context_base != 0); - event_context_base(&models->app_links); + Application_Links app = {}; + app.tctx = coroutine->tctx; + app.cmd_context = models; + event_context_base(&app); } function void -view_init(Models *models, View *view, Editing_File *initial_buffer, +view_init(Thread_Context *tctx, Models *models, View *view, Editing_File *initial_buffer, Custom_Command_Function *event_context_base){ - view_set_file(models, view, initial_buffer); + view_set_file(tctx, models, view, initial_buffer); - view->node_arena = reserve_arena(models->tctx); + view->node_arena = reserve_arena(tctx); View_Context first_ctx = {}; first_ctx.render_caller = models->render_caller; @@ -543,7 +529,7 @@ view_init(Models *models, View *view, Editing_File *initial_buffer, Co_In in = {}; in.models = models; in.event_context_base = event_context_base; - view->co = co_run(models, Co_View, view->co, &in, &view->co_out); + view->co = co_run(tctx, models, view->co, &in, &view->co_out); // TODO(allen): deal with this kind of problem! Assert(view->co != 0); } @@ -572,25 +558,28 @@ view_check_co_exited(Models *models, View *view){ } internal void -co_single_abort(Models *models, View *view){ +co_single_abort(Thread_Context *tctx, Models *models, View *view){ Coroutine *co = view->co; Co_In in = {}; in.user_input.abort = true; - view->co = co_run(models, Co_View, co, &in, &view->co_out); + view->co = co_run(tctx, models, co, &in, &view->co_out); view_check_co_exited(models, view); } internal void -co_full_abort(Models *models, View *view){ +co_full_abort(Thread_Context *tctx, Models *models, View *view){ Coroutine *co = view->co; Co_In in = {}; in.user_input.abort = true; for (u32 j = 0; j < 100 && co != 0; ++j){ - co = co_run(models, Co_View, co, &in, &view->co_out); + co = co_run(tctx, models, co, &in, &view->co_out); } if (co != 0){ #define M "SERIOUS ERROR: full stack abort did not complete" - print_message(&models->app_links, string_u8_litexpr(M)); + Application_Links app = {}; + app.tctx = tctx; + app.cmd_context = models; + print_message(&app, string_u8_litexpr(M)); #undef M } view->co = 0; @@ -598,7 +587,7 @@ co_full_abort(Models *models, View *view){ } function b32 -co_send_event(Models *models, View *view, Input_Event *event){ +co_send_event(Thread_Context *tctx, Models *models, View *view, Input_Event *event){ b32 event_was_handled = false; Coroutine *co = view->co; @@ -613,7 +602,7 @@ co_send_event(Models *models, View *view, Input_Event *event){ in.user_input.event = *event; in.user_input.abort = ((abort_flags & event_flags) != 0); begin_handling_input(models, &in.user_input); - view->co = co_run(models, Co_View, view->co, &in, &view->co_out); + view->co = co_run(tctx, models, view->co, &in, &view->co_out); view_check_co_exited(models, view); if (!HasFlag(event_flags, EventProperty_Animate)){ models->animate_next_frame = true; @@ -625,52 +614,52 @@ co_send_event(Models *models, View *view, Input_Event *event){ } function b32 -co_send_core_event(Models *models, View *view, Core_Code code, String_Const_u8 string){ +co_send_core_event(Thread_Context *tctx, Models *models, View *view, Core_Code code, String_Const_u8 string){ Input_Event event = {}; event.kind = InputEventKind_Core; event.core.code = code; event.core.string = string; - return(co_send_event(models, view, &event)); + return(co_send_event(tctx, models, view, &event)); } function b32 -co_send_core_event(Models *models, View *view, Core_Code code, Buffer_ID id){ +co_send_core_event(Thread_Context *tctx, Models *models, View *view, Core_Code code, Buffer_ID id){ Input_Event event = {}; event.kind = InputEventKind_Core; event.core.code = code; event.core.id = id; - return(co_send_event(models, view, &event)); + return(co_send_event(tctx, models, view, &event)); } function b32 -co_send_core_event(Models *models, View *view, Core_Code code){ - return(co_send_core_event(models, view, code, SCu8())); +co_send_core_event(Thread_Context *tctx, Models *models, View *view, Core_Code code){ + return(co_send_core_event(tctx, models, view, code, SCu8())); } function b32 -co_send_event(Models *models, Input_Event *event){ +co_send_event(Thread_Context *tctx, Models *models, Input_Event *event){ Panel *active_panel = models->layout.active_panel; View *view = active_panel->view; - return(co_send_event(models, view, event)); + return(co_send_event(tctx, models, view, event)); } function b32 -co_send_core_event(Models *models, Core_Code code, String_Const_u8 string){ +co_send_core_event(Thread_Context *tctx, Models *models, Core_Code code, String_Const_u8 string){ Panel *active_panel = models->layout.active_panel; View *view = active_panel->view; - return(co_send_core_event(models, view, code, string)); + return(co_send_core_event(tctx, models, view, code, string)); } function b32 -co_send_core_event(Models *models, Core_Code code, Buffer_ID buffer_id){ +co_send_core_event(Thread_Context *tctx, Models *models, Core_Code code, Buffer_ID buffer_id){ Panel *active_panel = models->layout.active_panel; View *view = active_panel->view; - return(co_send_core_event(models, view, code, buffer_id)); + return(co_send_core_event(tctx, models, view, code, buffer_id)); } function b32 -co_send_core_event(Models *models, Core_Code code){ - return(co_send_core_event(models, code, SCu8())); +co_send_core_event(Thread_Context *tctx, Models *models, Core_Code code){ + return(co_send_core_event(tctx, models, code, SCu8())); } //////////////////////////////// @@ -691,7 +680,7 @@ file_is_viewed(Layout *layout, Editing_File *file){ } internal void -adjust_views_looking_at_file_to_new_cursor(Models *models, Editing_File *file){ +adjust_views_looking_at_file_to_new_cursor(Thread_Context *tctx, Models *models, Editing_File *file){ Layout *layout = &models->layout; for (Panel *panel = layout_get_first_open_panel(layout); panel != 0; @@ -699,7 +688,7 @@ adjust_views_looking_at_file_to_new_cursor(Models *models, Editing_File *file){ View *view = panel->view; if (view->file == file){ File_Edit_Positions edit_pos = view_get_edit_pos(view); - view_set_cursor(models, view, edit_pos.cursor_pos); + view_set_cursor(tctx, models, view, edit_pos.cursor_pos); } } } diff --git a/4ed_working_set.cpp b/4ed_working_set.cpp index ed9ed573..cb5adcfd 100644 --- a/4ed_working_set.cpp +++ b/4ed_working_set.cpp @@ -381,7 +381,7 @@ buffer_unbind_name_low_level(Working_Set *working_set, Editing_File *file){ } internal void -buffer_bind_name(Models *models, Arena *scratch, Working_Set *working_set, Editing_File *file, String_Const_u8 base_name){ +buffer_bind_name(Thread_Context *tctx, Models *models, Arena *scratch, Working_Set *working_set, Editing_File *file, String_Const_u8 base_name){ Temp_Memory temp = begin_temp(scratch); // List of conflict files. @@ -445,7 +445,10 @@ buffer_bind_name(Models *models, Arena *scratch, Working_Set *working_set, Editi // Get user's resolution data. if (models->buffer_name_resolver != 0){ - models->buffer_name_resolver(&models->app_links, conflicts, conflict_count); + Application_Links app = {}; + app.tctx = tctx; + app.cmd_context = models; + models->buffer_name_resolver(&app, conflicts, conflict_count); } // Re-bind all of the files diff --git a/custom/4coder_async_tasks.cpp b/custom/4coder_async_tasks.cpp index 9ae53ece..b4f88b09 100644 --- a/custom/4coder_async_tasks.cpp +++ b/custom/4coder_async_tasks.cpp @@ -4,19 +4,126 @@ // TOP -Application_Links *dummy_async_app = 0; +global Async_System async_system = {}; + +function Async_Node* +async_pop_node(void){ + system_mutex_acquire(async_system.mutex); + for (;async_system.task_count == 0;){ + system_condition_variable_wait(async_system.cv, async_system.mutex); + } + Async_Node *node = async_system.task_first; + sll_queue_pop(async_system.task_first, async_system.task_last); + async_system.task_count -= 1; + system_mutex_release(async_system.mutex); + node->next = 0; + return(node); +} + +function Async_Task +async_push_node(Async_Task_Function_Type *func, Data data){ + Async_Task result = async_system.task_id_counter; + async_system.task_id_counter += 1; + + system_mutex_acquire(async_system.mutex); + Async_Node *node = async_system.free_nodes; + if (node == 0){ + node = push_array(&async_system.node_arena, Async_Node, 1); + } + else{ + sll_stack_pop(async_system.free_nodes); + } + node->task = result; + node->thread = 0; + node->func = func; + node->data.data = (u8*)heap_allocate(&async_system.node_heap, data.size); + block_copy(node->data.data, data.data, data.size); + node->data.size = data.size; + sll_queue_push(async_system.task_first, async_system.task_last, node); + async_system.task_count += 1; + system_condition_variable_signal(async_system.cv); + system_mutex_release(async_system.mutex); + + return(result); +} + +function void +async_free_node(Async_Node *node){ + system_mutex_acquire(async_system.mutex); + heap_free(&async_system.node_heap, node->data.data); + sll_stack_push(async_system.free_nodes, node); + system_mutex_release(async_system.mutex); +} + +function void +async_task_thread(void *thread_ptr){ + Base_Allocator *allocator = get_base_allocator_system(); + + Thread_Context_Extra_Info tctx_info = {}; + tctx_info.async_thread = thread_ptr; + + Thread_Context tctx_ = {}; + Thread_Context *tctx = &tctx_; + thread_ctx_init(tctx, ThreadKind_AsyncTasks, allocator, allocator); + + Async_Thread *thread = (Async_Thread*)thread_ptr; + + Application_Links app = {}; + app.tctx = tctx; + app.cmd_context = async_system.cmd_context; + Async_Context ctx = {&app, thread}; + + for (;;){ + Async_Node *node = async_pop_node(); + node->thread = thread; + thread->node = node; + thread->task = node->task; + node->func(&ctx, node->data); + thread->node = 0; + thread->task = 0; + async_free_node(node); + } +} + +function Async_Node* +async_get_pending_node(Async_Task task){ + Async_Node *result = 0; + for (Async_Node *node = async_system.task_first; + node != 0; + node = node->next){ + if (node->task == task){ + result = node; + break; + } + } + return(result); +} + +function Async_Node* +async_get_running_node(Async_Task task){ + Async_Node *result = 0; + if (async_system.thread.task == task){ + + } + return(result); +} + +//////////////////////////////// function void async_task_handler_init(Application_Links *app){ - //NotImplemented; - dummy_async_app = app; + block_zero_struct(&async_system); + async_system.cmd_context = app->cmd_context; + async_system.node_arena = make_arena_system(KB(4)); + heap_init(&async_system.node_heap, &async_system.node_arena); + async_system.mutex = system_mutex_make(); + async_system.cv = system_condition_variable_make(); + async_system.thread.thread = system_thread_launch(async_task_thread, &async_system.thread); } function Async_Task async_task_no_dep(Async_Task_Function_Type *func, Data data){ - //NotImplemented; - func(dummy_async_app, data); - return(0); + return(async_push_node(func, data)); } function Async_Task @@ -26,22 +133,36 @@ async_task_single_dep(Async_Task_Function_Type *func, Data data, Async_Task depe function b32 async_task_is_pending(Async_Task task){ - NotImplemented; + system_mutex_acquire(async_system.mutex); + Async_Node *node = async_get_pending_node(task); + system_mutex_release(async_system.mutex); + return(node != 0); } function b32 async_task_is_running(Async_Task task){ - NotImplemented; + system_mutex_acquire(async_system.mutex); + Async_Node *node = async_get_running_node(task); + system_mutex_release(async_system.mutex); + return(node != 0); } function b32 async_task_is_running_or_pending(Async_Task task){ - NotImplemented; + system_mutex_acquire(async_system.mutex); + Async_Node *node = async_get_pending_node(task); + if (node != 0){ + node = async_get_running_node(task); + } + system_mutex_release(async_system.mutex); + return(node != 0); } function void async_task_cancel(Async_Task task){ + system_mutex_acquire(async_system.mutex); NotImplemented; + system_mutex_release(async_system.mutex); } function void diff --git a/custom/4coder_async_tasks.h b/custom/4coder_async_tasks.h index 8dae24f8..ab1d4ac9 100644 --- a/custom/4coder_async_tasks.h +++ b/custom/4coder_async_tasks.h @@ -7,10 +7,44 @@ #if !defined(FCODER_ASYNC_TASKS_H) #define FCODER_ASYNC_TASKS_H -typedef void Async_Task_Function_Type(Application_Links *app, Data data); - +typedef void Async_Task_Function_Type(struct Async_Context *actx, Data data); typedef u64 Async_Task; +struct Async_Thread{ + System_Thread thread; + struct Async_Node *node; + Async_Task task; +}; + +struct Async_Node{ + Async_Node *next; + Async_Task task; + Async_Thread *thread; + Async_Task_Function_Type *func; + Data data; +}; + +struct Async_System{ + void *cmd_context; + + Heap node_heap; + Arena node_arena; + System_Mutex mutex; + System_Condition_Variable cv; + Async_Task task_id_counter; + Async_Node *free_nodes; + Async_Node *task_first; + Async_Node *task_last; + i32 task_count; + + Async_Thread thread; +}; + +struct Async_Context{ + Application_Links *app; + Async_Thread *thread; +}; + #endif // BOTTOM diff --git a/custom/4coder_base_types.h b/custom/4coder_base_types.h index 6b3ae3af..4e5f83a0 100644 --- a/custom/4coder_base_types.h +++ b/custom/4coder_base_types.h @@ -478,7 +478,7 @@ union SNode{ #define sll_stack_pop_(h) h=h=h->next #define sll_queue_push_multiple_(f,l,ff,ll) if(ll){if(f){l->next=ff;}else{f=ff;}l=ll;l->next=0;} #define sll_queue_push_(f,l,n) sll_queue_push_multiple_(f,l,n,n) -#define sll_queue_pop_(f,l) if (f==l) { f=l=0; } else { f->next=0;f=f->next; } +#define sll_queue_pop_(f,l) if (f==l) { f=l=0; } else { f=f->next; } #define sll_stack_push(h,n) (sll_stack_push_((h),(n))) #define sll_stack_pop(h) (sll_stack_pop_((h))) @@ -1188,6 +1188,8 @@ struct Thread_Context{ Profile_Record *prof_first; Profile_Record *prof_last; i32 prof_record_count; + + void *user_data; }; typedef i32 Scratch_Share_Code; diff --git a/custom/4coder_default_hooks.cpp b/custom/4coder_default_hooks.cpp index bc883130..8ba19564 100644 --- a/custom/4coder_default_hooks.cpp +++ b/custom/4coder_default_hooks.cpp @@ -539,7 +539,8 @@ BUFFER_NAME_RESOLVER_SIG(default_buffer_name_resolution){ } function void -do_full_lex_async__inner(Application_Links *app, Buffer_ID buffer_id){ +do_full_lex_async__inner(Async_Context *actx, Buffer_ID buffer_id){ + Application_Links *app = actx->app; Thread_Context *tctx = get_thread_context(app); Scratch_Block scratch(tctx); @@ -564,10 +565,10 @@ do_full_lex_async__inner(Application_Links *app, Buffer_ID buffer_id){ } function void -do_full_lex_async(Application_Links *app, Data data){ +do_full_lex_async(Async_Context *actx, Data data){ if (data.size == sizeof(Buffer_ID)){ Buffer_ID buffer = *(Buffer_ID*)data.data; - do_full_lex_async__inner(app, buffer); + do_full_lex_async__inner(actx, buffer); } } diff --git a/custom/4coder_types.h b/custom/4coder_types.h index 07403dae..a063dd4e 100644 --- a/custom/4coder_types.h +++ b/custom/4coder_types.h @@ -13,11 +13,13 @@ #endif +struct Thread_Context_Extra_Info{ + void *coroutine; + void *async_thread; +}; struct Application_Links{ + Thread_Context *tctx; void *cmd_context; - void *current_thread; - void *current_coroutine; - i32 type_coroutine; }; typedef void Custom_Layer_Init_Type(Application_Links *app); void custom_layer_init(Application_Links *app); diff --git a/platform_win32/win32_4ed.cpp b/platform_win32/win32_4ed.cpp index 803ecf07..933185d8 100644 --- a/platform_win32/win32_4ed.cpp +++ b/platform_win32/win32_4ed.cpp @@ -1681,7 +1681,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS Scratch_Block scratch(win32vars.tctx, Scratch_Share); String_Const_u8 curdir = system_get_path(scratch, SystemPath_CurrentDirectory); curdir = string_mod_replace_character(curdir, '\\', '/'); - app.init(&target, base_ptr, win32vars.clipboard_contents, curdir, custom); + app.init(win32vars.tctx, &target, base_ptr, win32vars.clipboard_contents, curdir, custom); } // @@ -1871,7 +1871,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS // NOTE(allen): Application Core Update Application_Step_Result result = {}; if (app.step != 0){ - result = app.step(&target, base_ptr, &input); + result = app.step(win32vars.tctx, &target, base_ptr, &input); } else{ //LOG("app.step == 0 -- skipping\n");