Async system setup WITHOUT cancelation working yet

This commit is contained in:
Allen Webster 2019-10-21 21:10:29 -07:00
parent a5a07c16f8
commit c7f69d26a0
23 changed files with 531 additions and 414 deletions

81
4ed.cpp
View File

@ -10,14 +10,14 @@
// TOP // TOP
internal void 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); i64 end = buffer_size(&file->state.buffer);
Edit_Behaviors behaviors = {}; Edit_Behaviors behaviors = {};
edit_single(models, file, Ii64(end), value, behaviors); edit_single(tctx, models, file, Ii64(end), value, behaviors);
} }
internal void 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); Assert(file != 0);
i64 pos = buffer_size(&file->state.buffer); i64 pos = buffer_size(&file->state.buffer);
Layout *layout = &models->layout; Layout *layout = &models->layout;
@ -28,7 +28,7 @@ file_cursor_to_end(Models *models, Editing_File *file){
if (view->file != file){ if (view->file != file){
continue; continue;
} }
view_set_cursor(models, view, pos); view_set_cursor(tctx, models, view, pos);
view->mark = pos; view->mark = pos;
} }
} }
@ -281,12 +281,12 @@ init_command_line_settings(App_Settings *settings, Plat_Settings *plat_settings,
//////////////////////////////// ////////////////////////////////
internal Models* internal Models*
models_init(Thread_Context *tctx){ models_init(void){
Arena *arena = reserve_arena(tctx); Arena arena = make_arena_system();
Models *models = push_array_zero(arena, Models, 1); Models *models = push_array_zero(&arena, Models, 1);
models->tctx = tctx; models->arena_ = arena;
models->arena = arena; models->arena = &models->arena_;
heap_init(&models->heap, tctx->allocator); heap_init(&models->heap, get_base_allocator_system());
return(models); return(models);
} }
@ -306,7 +306,7 @@ app_get_logger(void){
} }
App_Read_Command_Line_Sig(app_read_command_line){ App_Read_Command_Line_Sig(app_read_command_line){
Models *models = models_init(tctx); Models *models = models_init();
App_Settings *settings = &models->settings; App_Settings *settings = &models->settings;
block_zero_struct(settings); block_zero_struct(settings);
if (argc > 1){ if (argc > 1){
@ -322,7 +322,6 @@ App_Init_Sig(app_init){
models->keep_playing = true; models->keep_playing = true;
models->config_api = api; models->config_api = api;
models->app_links.cmd_context = models;
API_VTable_custom custom_vtable = {}; API_VTable_custom custom_vtable = {};
custom_api_fill_vtable(&custom_vtable); custom_api_fill_vtable(&custom_vtable);
@ -330,7 +329,11 @@ App_Init_Sig(app_init){
system_api_fill_vtable(&system_vtable); system_api_fill_vtable(&system_vtable);
Custom_Layer_Init_Type *custom_init = api.init_apis(&custom_vtable, &system_vtable); Custom_Layer_Init_Type *custom_init = api.init_apis(&custom_vtable, &system_vtable);
Assert(custom_init != 0); 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 // NOTE(allen): coroutines
coroutine_system_init(&models->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); managed_ids_init(tctx->allocator, &models->managed_id_set);
lifetime_allocator_init(models->tctx->allocator, &models->lifetime_allocator); lifetime_allocator_init(tctx->allocator, &models->lifetime_allocator);
dynamic_workspace_init(&models->lifetime_allocator, DynamicWorkspace_Global, 0, &models->dynamic_workspace); dynamic_workspace_init(&models->lifetime_allocator, DynamicWorkspace_Global, 0, &models->dynamic_workspace);
// NOTE(allen): file setup // NOTE(allen): file setup
@ -371,7 +374,7 @@ App_Init_Sig(app_init){
// NOTE(allen): // NOTE(allen):
global_history_init(&models->global_history); global_history_init(&models->global_history);
text_layout_init(models, &models->text_layouts); text_layout_init(tctx, &models->text_layouts);
// NOTE(allen): clipboard setup // NOTE(allen): clipboard setup
models->working_set.clipboard_max_size = ArrayCount(models->working_set.clipboards); models->working_set.clipboard_max_size = ArrayCount(models->working_set.clipboards);
@ -412,17 +415,17 @@ App_Init_Sig(app_init){
Heap *heap = &models->heap; Heap *heap = &models->heap;
for (i32 i = 0; i < ArrayCount(init_files); ++i){ for (i32 i = 0; i < ArrayCount(init_files); ++i){
Editing_File *file = working_set_allocate_file(&models->working_set, &models->lifetime_allocator); 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){ if (init_files[i].ptr != 0){
*init_files[i].ptr = file; *init_files[i].ptr = file;
} }
File_Attributes attributes = {}; 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){ if (init_files[i].read_only){
file->settings.read_only = true; file->settings.read_only = true;
history_free(models, &file->state.history); history_free(tctx, &file->state.history);
} }
file->settings.never_kill = true; file->settings.never_kill = true;
@ -433,12 +436,12 @@ App_Init_Sig(app_init){
{ {
Panel *panel = layout_initialize(arena, &models->layout); Panel *panel = layout_initialize(arena, &models->layout);
View *new_view = live_set_alloc_view(&models->lifetime_allocator, &models->live_set, panel); 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 // NOTE(allen): miscellaneous init
hot_directory_init(arena, &models->hot_directory, current_directory); 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(); models->period_wakeup_timer = system_wake_up_timer_create();
} }
@ -446,7 +449,7 @@ App_Step_Sig(app_step){
Models *models = (Models*)base_ptr; Models *models = (Models*)base_ptr;
Mutex_Lock file_order_lock(models->working_set.mutex); 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->next_animate_delay = max_u32;
models->animate_next_frame = false; 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); 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); dest->size = eol_convert_in((char*)dest->str, (char*)clipboard.str, (i32)clipboard.size);
if (input->clipboard_changed){ 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 (system_cli_update_step(cli, dest, max, &amount)){
if (file != 0 && amount > 0){ if (file != 0 && amount > 0){
amount = eol_in_place_convert_in(dest, amount); 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; edited_file = true;
} }
} }
@ -507,7 +510,7 @@ App_Step_Sig(app_step){
if (system_cli_end_update(cli)){ if (system_cli_end_update(cli)){
if (file != 0){ if (file != 0){
String_Const_u8 str = push_u8_stringf(scratch, "exited with code %d", cli->exit); 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; edited_file = true;
} }
processes_to_free[processes_to_free_count++] = child_process; 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){ 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.code = CoreCode_Startup;
event.core.flag_strings = flags; event.core.flag_strings = flags;
event.core.file_names = file_names; event.core.file_names = file_names;
co_send_event(models, &event); co_send_event(tctx, models, &event);
} }
// NOTE(allen): consume event stream // NOTE(allen): consume event stream
@ -689,7 +692,7 @@ App_Step_Sig(app_step){
case EventConsume_ClickChangeView: case EventConsume_ClickChangeView:
{ {
// NOTE(allen): run deactivate command // 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; layout->active_panel = mouse_panel;
models->animate_next_frame = true; models->animate_next_frame = true;
@ -697,14 +700,14 @@ App_Step_Sig(app_step){
view = active_panel->view; view = active_panel->view;
// NOTE(allen): run activate command // 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; event_was_handled = true;
}break; }break;
case EventConsume_CustomCommand: case EventConsume_CustomCommand:
{ {
event_was_handled = co_send_event(models, view, event); event_was_handled = co_send_event(tctx, models, view, event);
}break; }break;
} }
}break; }break;
@ -745,7 +748,10 @@ App_Step_Sig(app_step){
if (models->layout.panel_state_dirty){ if (models->layout.panel_state_dirty){
models->layout.panel_state_dirty = false; models->layout.panel_state_dirty = false;
if (models->buffer_viewer_update != 0){ 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)){ panel = layout_get_next_open_panel(layout, panel)){
View *view = panel->view; View *view = panel->view;
File_Edit_Positions edit_pos = view_get_edit_pos(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); block_zero_struct(&edit_pos.scroll.target);
view_set_edit_pos(view, edit_pos); 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); Editing_File *file = CastFromMember(Editing_File, external_mod_node, node);
dll_remove(node); dll_remove(node);
block_zero_struct(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; models->keep_playing = false;
} }
if (!models->keep_playing){ 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; models->keep_playing = true;
} }
} }
@ -836,7 +842,10 @@ App_Step_Sig(app_step){
if (ctx != 0){ if (ctx != 0){
Render_Caller_Function *render_caller = ctx->ctx.render_caller; Render_Caller_Function *render_caller = ctx->ctx.render_caller;
if (render_caller != 0){ 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 // NOTE(allen): flush the log
log_flush(models); log_flush(tctx, models);
// NOTE(allen): set the app_result // NOTE(allen): set the app_result
Application_Step_Result app_result = {}; Application_Step_Result app_result = {};

6
4ed.h
View File

@ -47,7 +47,8 @@ struct Custom_API{
}; };
#define App_Init_Sig(name) \ #define App_Init_Sig(name) \
void name(Render_Target *target, \ void name(Thread_Context *tctx, \
Render_Target *target, \
void *base_ptr, \ void *base_ptr, \
String_Const_u8 clipboard,\ String_Const_u8 clipboard,\
String_Const_u8 current_directory,\ String_Const_u8 current_directory,\
@ -77,7 +78,8 @@ struct Application_Step_Input{
}; };
#define App_Step_Sig(name) Application_Step_Result \ #define App_Step_Sig(name) Application_Step_Result \
name(Render_Target *target, \ name(Thread_Context *tctx, \
Render_Target *target, \
void *base_ptr, \ void *base_ptr, \
Application_Step_Input *input) Application_Step_Input *input)

View File

@ -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

View File

@ -45,7 +45,9 @@ api_check_view(View *view, Access_Flag access){
function b32 function b32
is_running_coroutine(Application_Links *app){ 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 api(custom) function b32
@ -73,25 +75,13 @@ global_get_screen_rectangle(Application_Links *app){
api(custom) function Thread_Context* api(custom) function Thread_Context*
get_thread_context(Application_Links *app){ get_thread_context(Application_Links *app){
Thread_Context *tctx = 0; return(app->tctx);
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);
} }
api(custom) function b32 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){ 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; 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 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); i64 size = buffer_size(&file->state.buffer);
if (0 <= range.first && range.first <= range.one_past_last && range.one_past_last <= size){ if (0 <= range.first && range.first <= range.one_past_last && range.one_past_last <= size){
Edit_Behaviors behaviors = {}; Edit_Behaviors behaviors = {};
edit_single(models, file, range, string, behaviors); edit_single(app->tctx, models, file, range, string, behaviors);
result = true; result = true;
} }
} }
@ -261,7 +251,7 @@ buffer_batch_edit(Application_Links *app, Buffer_ID buffer_id, Batch_Edit *batch
b32 result = false; b32 result = false;
if (api_check_buffer(file)){ if (api_check_buffer(file)){
Edit_Behaviors behaviors = {}; Edit_Behaviors behaviors = {};
result = edit_batch(models, file, batch, behaviors); result = edit_batch(app->tctx, models, file, batch, behaviors);
} }
return(result); return(result);
} }
@ -373,7 +363,7 @@ buffer_line_y_difference(Application_Links *app, Buffer_ID buffer_id, f32 width,
if (api_check_buffer(file)){ if (api_check_buffer(file)){
Face *face = font_set_face_from_id(&models->font_set, face_id); Face *face = font_set_face_from_id(&models->font_set, face_id);
if (face != 0){ 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); 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)){ if (api_check_buffer(file)){
Face *face = font_set_face_from_id(&models->font_set, face_id); Face *face = font_set_face_from_id(&models->font_set, face_id);
if (face != 0){ 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); 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)){ if (api_check_buffer(file)){
Face *face = font_set_face_from_id(&models->font_set, face_id); Face *face = font_set_face_from_id(&models->font_set, face_id);
if (face != 0){ 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); 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)){ if (api_check_buffer(file)){
Face *face = font_set_face_from_id(&models->font_set, face_id); Face *face = font_set_face_from_id(&models->font_set, face_id);
if (face != 0){ 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); return(result);
@ -431,7 +421,7 @@ buffer_relative_character_from_pos(Application_Links *app, Buffer_ID buffer_id,
if (api_check_buffer(file)){ if (api_check_buffer(file)){
Face *face = font_set_face_from_id(&models->font_set, face_id); Face *face = font_set_face_from_id(&models->font_set, face_id);
if (face != 0){ 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); return(result);
@ -446,7 +436,7 @@ buffer_pos_from_relative_character(Application_Links *app, Buffer_ID buffer_id,
if (api_check_buffer(file)){ if (api_check_buffer(file)){
Face *face = font_set_face_from_id(&models->font_set, face_id); Face *face = font_set_face_from_id(&models->font_set, face_id);
if (face != 0){ 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); 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); View *view = imp_get_view(models, view_id);
f32 result = {}; f32 result = {};
if (api_check_view(view)){ 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); 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); View *view = imp_get_view(models, view_id);
Line_Shift_Vertical result = {}; Line_Shift_Vertical result = {};
if (api_check_view(view)){ 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); 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); View *view = imp_get_view(models, view_id);
i64 result = -1; i64 result = -1;
if (api_check_view(view)){ 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); 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); View *view = imp_get_view(models, view_id);
Vec2_f32 result = {}; Vec2_f32 result = {};
if (api_check_view(view)){ 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); 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); View *view = imp_get_view(models, view_id);
i64 result = {}; i64 result = {};
if (api_check_view(view)){ 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); 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); View *view = imp_get_view(models, view_id);
i64 result = {}; i64 result = {};
if (api_check_view(view)){ 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); return(result);
} }
@ -693,12 +683,12 @@ buffer_set_setting(Application_Links *app, Buffer_ID buffer_id, Buffer_Setting_I
{ {
if (value){ if (value){
if (!history_is_activated(&file->state.history)){ if (!history_is_activated(&file->state.history)){
history_init(models, &file->state.history); history_init(app->tctx, models, &file->state.history);
} }
} }
else{ else{
if (history_is_activated(&file->state.history)){ if (history_is_activated(&file->state.history)){
history_free(models, &file->state.history); history_free(app->tctx, &file->state.history);
} }
} }
}break; }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); Editing_File *file = imp_get_file(models, buffer_id);
b32 result = false; b32 result = false;
if (api_check_buffer(file)){ if (api_check_buffer(file)){
file_end_file(models, file); file_end_file(app->tctx, models, file);
result = true; result = true;
} }
return(result); 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) create_buffer(Application_Links *app, String_Const_u8 file_name, Buffer_Create_Flag flags)
{ {
Models *models = (Models*)app->cmd_context; 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; Buffer_ID result = 0;
if (new_file != 0){ if (new_file != 0){
result = new_file->id; 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){ 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); 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; result = true;
} }
} }
@ -787,15 +778,16 @@ buffer_kill(Application_Links *app, Buffer_ID buffer_id, Buffer_Kill_Flag flags)
if (!file->settings.never_kill){ if (!file->settings.never_kill){
b32 needs_to_save = file_needs_save(file); b32 needs_to_save = file_needs_save(file);
if (!needs_to_save || (flags & BufferKill_AlwaysKill) != 0){ if (!needs_to_save || (flags & BufferKill_AlwaysKill) != 0){
Thread_Context *tctx = app->tctx;
if (models->end_buffer != 0){ 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); buffer_unbind_name_low_level(working_set, file);
if (file->canon.name_size != 0){ if (file->canon.name_size != 0){
buffer_unbind_file(working_set, file); buffer_unbind_file(working_set, file);
} }
file_free(models, file); file_free(tctx, models, file);
working_set_free_file(&models->heap, working_set, file); working_set_free_file(&models->heap, working_set, file);
Layout *layout = &models->layout; 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); Assert(file_node != order);
view->file = 0; view->file = 0;
Editing_File *new_file = CastFromMember(Editing_File, touch_node, file_node); 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; file_node = file_node->next;
if (file_node == order){ if (file_node == order){
file_node = file_node->next; 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) buffer_reopen(Application_Links *app, Buffer_ID buffer_id, Buffer_Reopen_Flag flags)
{ {
Models *models = (Models*)app->cmd_context; 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); Editing_File *file = imp_get_file(models, buffer_id);
Buffer_Reopen_Result result = BufferReopenResult_Failed; Buffer_Reopen_Result result = BufferReopenResult_Failed;
if (api_check_buffer(file)){ 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; Working_Set *working_set = &models->working_set;
file_free(models, file); file_free(tctx, models, file);
working_set_file_default_settings(working_set, 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){ 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; vptrs[i]->file = file;
i64 line = line_numbers[i]; i64 line = line_numbers[i];
i64 col = column_numbers[i]; i64 col = column_numbers[i];
Buffer_Cursor cursor = file_compute_cursor(file, seek_line_col(line, col)); 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; result = BufferReopenResult_Reopened;
} }
@ -919,7 +912,7 @@ api(custom) function File_Attributes
get_file_attributes(Application_Links *app, String_Const_u8 file_name) get_file_attributes(Application_Links *app, String_Const_u8 file_name)
{ {
Models *models = (Models*)app->cmd_context; 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)); 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; Live_Views *live_set = &models->live_set;
View *new_view = live_set_alloc_view(&models->lifetime_allocator, View *new_view = live_set_alloc_view(&models->lifetime_allocator,
live_set, new_panel); 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); models->view_event_handler);
result = true; 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); View *view = imp_get_view(models, view_id);
Rect_f32 result = {}; Rect_f32 result = {};
if (api_check_view(view)){ if (api_check_view(view)){
result = view_get_buffer_rect(models, view); result = view_get_buffer_rect(app->tctx, models, view);
} }
return(result); return(result);
} }
@ -1466,7 +1459,7 @@ view_set_cursor(Application_Links *app, View_ID view_id, Buffer_Seek seek)
Assert(file != 0); Assert(file != 0);
if (api_check_buffer(file)){ if (api_check_buffer(file)){
Buffer_Cursor cursor = file_compute_cursor(file, seek); 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; result = true;
} }
} }
@ -1481,15 +1474,16 @@ view_set_buffer_scroll(Application_Links *app, View_ID view_id, Buffer_Scroll sc
b32 result = false; b32 result = false;
View *view = imp_get_view(models, view_id); View *view = imp_get_view(models, view_id);
if (api_check_view(view)){ if (api_check_view(view)){
scroll.position = view_normalize_buffer_point(models, view, scroll.position); Thread_Context *tctx = app->tctx;
scroll.target = view_normalize_buffer_point(models, view, scroll.target); 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.x = f32_round32(scroll.target.pixel_shift.x);
scroll.target.pixel_shift.y = f32_round32(scroll.target.pixel_shift.y); 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); 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); scroll.target.pixel_shift.y = clamp(0.f, scroll.target.pixel_shift.y, line.height);
if (rule == SetBufferScroll_SnapCursorIntoView){ if (rule == SetBufferScroll_SnapCursorIntoView){
view_set_scroll(models, view, scroll); view_set_scroll(tctx, models, view, scroll);
} }
else{ else{
File_Edit_Positions edit_pos = view_get_edit_pos(view); 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); Editing_File *file = working_set_get_file(&models->working_set, buffer_id);
if (api_check_buffer(file)){ if (api_check_buffer(file)){
if (file != view->file){ if (file != view->file){
view_set_file(models, view, file); view_set_file(app->tctx, models, view, file);
if (!(flags & SetBuffer_KeepOriginalGUI)){ if (!(flags & SetBuffer_KeepOriginalGUI)){
//view_quit_ui(models, view); //view_quit_ui(models, view);
// TODO(allen): back to base context // 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; Models *models = (Models*)app->cmd_context;
Lifetime_Allocator *lifetime_allocator = &models->lifetime_allocator; 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 // TODO(allen): revisit this
struct Node_Ptr{ 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) get_next_input(Application_Links *app, Event_Property get_properties, Event_Property abort_properties)
{ {
Models *models = (Models*)app->cmd_context; 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 = {}; User_Input result = {};
if (app->type_coroutine == Co_View){ if (tctx_info->coroutine != 0){
Coroutine *coroutine = (Coroutine*)app->current_coroutine; Coroutine *coroutine = (Coroutine*)tctx_info->coroutine;
if (coroutine != 0){ if (coroutine != 0){
Co_Out *out = (Co_Out*)coroutine->out; Co_Out *out = (Co_Out*)coroutine->out;
out->request = CoRequest_None; out->request = CoRequest_None;
@ -2213,8 +2209,8 @@ print_message(Application_Links *app, String_Const_u8 message)
Editing_File *file = models->message_buffer; Editing_File *file = models->message_buffer;
b32 result = false; b32 result = false;
if (file != 0){ if (file != 0){
output_file_append(models, file, message); output_file_append(app->tctx, models, file, message);
file_cursor_to_end(models, file); file_cursor_to_end(app->tctx, models, file);
result = true; result = true;
} }
return(result); 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)){ if (api_check_buffer(file) && history_is_activated(&file->state.history)){
i32 max_index = history_get_record_count(&file->state.history); i32 max_index = history_get_record_count(&file->state.history);
if (0 <= index && index <= max_index){ 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; 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); Editing_File *file = imp_get_file(models, buffer_id);
b32 result = false; b32 result = false;
if (api_check_buffer(file)){ 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); return(result);
} }
@ -2502,9 +2498,11 @@ api(custom) function Face_ID
try_create_new_face(Application_Links *app, Face_Description *description) try_create_new_face(Application_Links *app, Face_Description *description)
{ {
Models *models = (Models*)app->cmd_context; 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; Face_ID result = 0;
if (is_running_coroutine(app)){ if (tctx_info != 0 && tctx_info->coroutine != 0){
Coroutine *coroutine = (Coroutine*)app->current_coroutine; Coroutine *coroutine = (Coroutine*)tctx_info->coroutine;
Assert(coroutine != 0); Assert(coroutine != 0);
Co_Out *out = (Co_Out*)coroutine->out; Co_Out *out = (Co_Out*)coroutine->out;
out->request = CoRequest_NewFontFace; 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; Co_In *in = (Co_In*)coroutine->in;
result = in->face_id; result = in->face_id;
} }
else if (tctx_info != 0){
// This API does nothing when called from an async thread.
}
else{ else{
Face *new_face = font_set_new_face(&models->font_set, description); Face *new_face = font_set_new_face(&models->font_set, description);
result = new_face->id; result = new_face->id;
@ -2524,9 +2525,11 @@ api(custom) function b32
try_modify_face(Application_Links *app, Face_ID id, Face_Description *description) try_modify_face(Application_Links *app, Face_ID id, Face_Description *description)
{ {
Models *models = (Models*)app->cmd_context; 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; b32 result = false;
if (is_running_coroutine(app)){ if (tctx_info != 0 && tctx_info->coroutine != 0){
Coroutine *coroutine = (Coroutine*)app->current_coroutine; Coroutine *coroutine = (Coroutine*)tctx_info->coroutine;
Assert(coroutine != 0); Assert(coroutine != 0);
Co_Out *out = (Co_Out*)coroutine->out; Co_Out *out = (Co_Out*)coroutine->out;
out->request = CoRequest_ModifyFace; 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; Co_In *in = (Co_In*)coroutine->in;
result = in->success; result = in->success;
} }
else if (tctx_info != 0){
// This API does nothing when called from an async thread.
}
else{ else{
result = font_set_modify_face(&models->font_set, id, description); 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); Editing_File *file = imp_get_file(models, buffer_id);
Text_Layout_ID result = {}; Text_Layout_ID result = {};
if (api_check_buffer(file)){ if (api_check_buffer(file)){
Scratch_Block scratch(app); Thread_Context *tctx = app->tctx;
Arena *arena = reserve_arena(models->tctx); Scratch_Block scratch(tctx);
Arena *arena = reserve_arena(tctx);
Face *face = file_get_face(models, file); Face *face = file_get_face(models, file);
Gap_Buffer *buffer = &file->state.buffer; 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; f32 y = -buffer_point.pixel_shift.y;
for (;line_number <= line_count; for (;line_number <= line_count;
line_number += 1){ 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; f32 next_y = y + line.height;
if (next_y >= dim.y){ if (next_y >= dim.y){
break; 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;; for (i64 line_number_it = layout->visible_line_number_range.first;;
line_number_it += 1){ 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; result.max += line.height;
if (line_number_it == line_number){ if (line_number_it == line_number){
break; break;
@ -2816,7 +2823,7 @@ text_layout_character_on_screen(Application_Links *app, Text_Layout_ID layout_id
Buffer_Layout_Item_List line = {}; Buffer_Layout_Item_List line = {};
for (i64 line_number_it = layout->visible_line_number_range.first;; for (i64 line_number_it = layout->visible_line_number_range.first;;
line_number_it += 1){ 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){ if (line_number_it == line_number){
break; break;
} }
@ -2874,7 +2881,7 @@ paint_text_color(Application_Links *app, Text_Layout_ID layout_id, Interval_i64
api(custom) function b32 api(custom) function b32
text_layout_free(Application_Links *app, Text_Layout_ID text_layout_id){ text_layout_free(Application_Links *app, Text_Layout_ID text_layout_id){
Models *models = (Models*)app->cmd_context; 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 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; Models *models = (Models*)app->cmd_context;
Text_Layout *layout = text_layout_get(&models->text_layouts, layout_id); Text_Layout *layout = text_layout_get(&models->text_layouts, layout_id);
if (layout != 0 && models->target != 0){ if (layout != 0 && models->target != 0){
text_layout_render(models, layout); text_layout_render(app->tctx, models, layout);
} }
} }

View File

@ -35,8 +35,7 @@ enum App_State{
}; };
struct Models{ struct Models{
Thread_Context *tctx; Arena arena_;
Arena *arena; Arena *arena;
Heap heap; Heap heap;
@ -50,8 +49,6 @@ struct Models{
Child_Process_Container child_processes; Child_Process_Container child_processes;
Custom_API config_api; Custom_API config_api;
Application_Links app_links;
Render_Caller_Function *render_caller; Render_Caller_Function *render_caller;
Delta_Rule_Function *delta_rule; Delta_Rule_Function *delta_rule;
umem delta_rule_memory_size; umem delta_rule_memory_size;
@ -141,15 +138,6 @@ struct Consumption_Record{
char consumer[32]; char consumer[32];
}; };
typedef i32 App_Coroutine_Purpose;
enum{
Co_View,
};
struct App_Coroutine_State{
void *co;
i32 type;
};
struct File_Init{ struct File_Init{
String_Const_u8 name; String_Const_u8 name;
Editing_File **ptr; Editing_File **ptr;

View File

@ -79,7 +79,6 @@
#define DYNAMIC_LINK_API #define DYNAMIC_LINK_API
#include "generated/font_api.cpp" #include "generated/font_api.cpp"
#include "4ed_allocator_models.cpp"
#include "4ed_log.cpp" #include "4ed_log.cpp"
#include "4ed_coroutine.cpp" #include "4ed_coroutine.cpp"
#include "4ed_mem.cpp" #include "4ed_mem.cpp"

View File

@ -98,9 +98,9 @@ child_process_lookup_return_code(Child_Process_Container *container, Child_Proce
//////////////////////////////// ////////////////////////////////
internal b32 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; 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 path_n = push_string_copy(scratch, path);
String_Const_u8 command_n = push_string_copy(scratch, command); String_Const_u8 command_n = push_string_copy(scratch, command);
CLI_Handles cli_handles = {}; CLI_Handles cli_handles = {};

View File

@ -30,9 +30,13 @@ internal void
coroutine_main(void *ptr){ coroutine_main(void *ptr){
Coroutine *me = (Coroutine*)ptr; Coroutine *me = (Coroutine*)ptr;
Thread_Context_Extra_Info tctx_info = {};
tctx_info.coroutine = me;
Thread_Context tctx_ = {}; Thread_Context tctx_ = {};
thread_ctx_init(&tctx_, ThreadKind_MainCoroutine, thread_ctx_init(&tctx_, ThreadKind_MainCoroutine,
get_base_allocator_system(), get_base_allocator_system()); get_base_allocator_system(), get_base_allocator_system());
tctx_.user_data = &tctx_info;
me->tctx = &tctx_; me->tctx = &tctx_;
// NOTE(allen): Init handshake // NOTE(allen): Init handshake

View File

@ -67,6 +67,7 @@ internal void
lifetime_allocator_init(Base_Allocator *base_allocator, Lifetime_Allocator *lifetime_allocator){ lifetime_allocator_init(Base_Allocator *base_allocator, Lifetime_Allocator *lifetime_allocator){
block_zero_struct(lifetime_allocator); block_zero_struct(lifetime_allocator);
lifetime_allocator->allocator = base_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_table = make_table_Data_u64(base_allocator, 100);
lifetime_allocator->key_check_table = make_table_u64_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); 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* internal Lifetime_Object*
lifetime_alloc_object(Lifetime_Allocator *lifetime_allocator, i32 user_type, void *user_back_ptr){ 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){ if (object == 0){
i32 new_object_count = 256; object = push_array(&lifetime_allocator->node_arena, Lifetime_Object, 1);
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; else{
object = lifetime_allocator->free_objects.first; 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); block_zero_struct(object);
dynamic_workspace_init(lifetime_allocator, user_type, user_back_ptr, &object->workspace); dynamic_workspace_init(lifetime_allocator, user_type, user_back_ptr, &object->workspace);
return(object); return(object);
} }
@ -313,7 +303,7 @@ internal void
lifetime_free_object(Lifetime_Allocator *lifetime_allocator, Lifetime_Object *lifetime_object){ lifetime_free_object(Lifetime_Allocator *lifetime_allocator, Lifetime_Object *lifetime_object){
lifetime__object_free_all_keys(lifetime_allocator, lifetime_object); lifetime__object_free_all_keys(lifetime_allocator, lifetime_object);
dynamic_workspace_free(lifetime_allocator, &lifetime_object->workspace); 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 internal void

View File

@ -98,19 +98,14 @@ struct Lifetime_Key_Ref_Node{
struct Lifetime_Key *keys[lifetime_key_reference_per_node]; struct Lifetime_Key *keys[lifetime_key_reference_per_node];
}; };
struct Lifetime_Object{ union Lifetime_Object{
union{
struct{
Lifetime_Object *next; Lifetime_Object *next;
Lifetime_Object *prev;
};
struct{ struct{
Lifetime_Key_Ref_Node *key_node_first; Lifetime_Key_Ref_Node *key_node_first;
Lifetime_Key_Ref_Node *key_node_last; Lifetime_Key_Ref_Node *key_node_last;
i32 key_count; i32 key_count;
Dynamic_Workspace workspace; Dynamic_Workspace workspace;
}; };
};
}; };
struct Lifetime_Key{ struct Lifetime_Key{
@ -120,7 +115,7 @@ struct Lifetime_Key{
Lifetime_Key *prev; Lifetime_Key *prev;
}; };
struct{ struct{
struct Lifetime_Object **members; Lifetime_Object **members;
i32 count; i32 count;
Dynamic_Workspace dynamic_workspace; Dynamic_Workspace dynamic_workspace;
}; };
@ -136,12 +131,6 @@ struct Lifetime_Key_Ref_Node_List{
i32 count; i32 count;
}; };
struct Lifetime_Object_List{
Lifetime_Object *first;
Lifetime_Object *last;
i32 count;
};
struct Lifetime_Key_List{ struct Lifetime_Key_List{
Lifetime_Key *first; Lifetime_Key *first;
Lifetime_Key *last; Lifetime_Key *last;
@ -150,8 +139,9 @@ struct Lifetime_Key_List{
struct Lifetime_Allocator{ struct Lifetime_Allocator{
Base_Allocator *allocator; Base_Allocator *allocator;
Arena node_arena;
Lifetime_Key_Ref_Node_List free_key_references; Lifetime_Key_Ref_Node_List free_key_references;
Lifetime_Object_List free_objects; Lifetime_Object *free_objects;
Lifetime_Key_List free_keys; Lifetime_Key_List free_keys;
Table_Data_u64 key_table; Table_Data_u64 key_table;
Table_u64_u64 key_check_table; Table_u64_u64 key_check_table;

View File

@ -70,7 +70,7 @@ edit_fix_markers__compute_scroll_y(i32 line_height, i32 old_y_val, f32 new_y_val
} }
internal void 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; Layout *layout = &models->layout;
Lifetime_Object *file_lifetime_object = file->lifetime_object; 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; 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 *cursors = push_array(scratch, Cursor_With_Index, cursor_max);
Cursor_With_Index *r_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; i64 cursor_pos = cursors[cursor_count++].pos;
view->mark = cursors[cursor_count++].pos; view->mark = cursors[cursor_count++].pos;
File_Edit_Positions edit_pos = view_get_edit_pos(view); 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 // 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 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 edit = {};
edit.text = string; edit.text = string;
edit.range = range; 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.first <= edit.range.one_past_last);
Assert(edit.range.one_past_last <= buffer_size(buffer)); 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 // NOTE(allen): history update
if (!behaviors.do_not_post_to_history){ 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); buffer_remeasure_starts(scratch, buffer, Ii64(line_start, line_end + 1), line_shift, shift_amount);
// NOTE(allen): cursor fixing // NOTE(allen): cursor fixing
edit_fix_markers(models, file, edit); edit_fix_markers(tctx, models, file, edit);
// NOTE(allen): edit range hook // NOTE(allen): edit range hook
if (models->buffer_edit_range != 0){ if (models->buffer_edit_range != 0){
Interval_i64 new_range = Ii64(edit.range.first, edit.range.first + edit.text.size); 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 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){ 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_Allocator *lifetime_allocator = &models->lifetime_allocator;
lifetime_free_object(lifetime_allocator, file->lifetime_object); lifetime_free_object(lifetime_allocator, file->lifetime_object);
@ -243,7 +249,7 @@ file_end_file(Models *models, Editing_File *file){
} }
internal void 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): // NOTE(allen): // NOTE(allen): // NOTE(allen): // NOTE(allen): // NOTE(allen):
// Whenever you change this also change the backward version! // 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; String_Const_u8 str = record->single.forward_text;
Interval_i64 range = Ii64(record->single.first, record->single.first + record->single.backward_text.size); 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; }break;
case RecordKind_Group: case RecordKind_Group:
@ -262,7 +268,7 @@ edit__apply_record_forward(Models *models, Editing_File *file, Record *record, E
node != sentinel; node != sentinel;
node = node->next){ node = node->next){
Record *sub_record = CastFromMember(Record, node, node); 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; }break;
@ -274,7 +280,7 @@ edit__apply_record_forward(Models *models, Editing_File *file, Record *record, E
} }
internal void 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): // NOTE(allen): // NOTE(allen): // NOTE(allen): // NOTE(allen): // NOTE(allen):
// Whenever you change this also change the forward version! // 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; String_Const_u8 str = record->single.backward_text;
Interval_i64 range = Ii64(record->single.first, record->single.first + record->single.forward_text.size); 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; }break;
case RecordKind_Group: case RecordKind_Group:
@ -293,7 +299,7 @@ edit__apply_record_backward(Models *models, Editing_File *file, Record *record,
node != sentinel; node != sentinel;
node = node->prev){ node = node->prev){
Record *sub_record = CastFromMember(Record, node, node); 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; }break;
@ -305,7 +311,7 @@ edit__apply_record_backward(Models *models, Editing_File *file, Record *record,
} }
internal void 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; History *history = &file->state.history;
if (history->activated && file->state.current_record_index != target_index){ if (history->activated && file->state.current_record_index != target_index){
Assert(0 <= target_index && target_index <= history->record_count); 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; current += 1;
record = CastFromMember(Record, node, record->node.next); record = CastFromMember(Record, node, record->node.next);
Assert(record != dummy_record); 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); } while (current != target_index);
} }
else{ else{
do{ do{
Assert(record != dummy_record); 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; current -= 1;
record = CastFromMember(Record, node, record->node.prev); record = CastFromMember(Record, node, record->node.prev);
} while (current != target_index); } while (current != target_index);
@ -340,7 +346,7 @@ edit_change_current_history_state(Models *models, Editing_File *file, i32 target
} }
internal b32 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; b32 result = false;
History *history = &file->state.history; History *history = &file->state.history;
if (history_is_activated(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){ switch (in_range_handler){
case RecordMergeFlag_StateInRange_MoveStateForward: 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; current_index = last_index;
}break; }break;
case RecordMergeFlag_StateInRange_MoveStateBackward: 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; current_index = first_index;
}break; }break;
@ -370,7 +376,7 @@ edit_merge_history_range(Models *models, Editing_File *file, History_Record_Inde
}break; }break;
} }
} }
Scratch_Block scratch(models->tctx, Scratch_Share); Scratch_Block scratch(tctx, Scratch_Share);
history_merge_records(scratch, history, first_index, last_index); history_merge_records(scratch, history, first_index, last_index);
if (current_index >= last_index){ if (current_index >= last_index){
current_index -= (last_index - first_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 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; b32 result = true;
if (batch != 0){ if (batch != 0){
History_Record_Index start_index = 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 && if (0 <= edit_range.first &&
edit_range.first <= edit_range.one_past_last && edit_range.first <= edit_range.one_past_last &&
edit_range.one_past_last <= size){ 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); shift += replace_range_shift(edit_range, insert_string.size);
} }
else{ else{
@ -417,7 +423,7 @@ edit_batch(Models *models, Editing_File *file, Batch_Edit *batch, Edit_Behaviors
if (history_is_activated(&file->state.history)){ if (history_is_activated(&file->state.history)){
History_Record_Index last_index = file->state.current_record_index; History_Record_Index last_index = file->state.current_record_index;
if (start_index + 1 < last_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* 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; Editing_File *result = 0;
if (file_name.size > 0){ if (file_name.size > 0){
Working_Set *working_set = &models->working_set; Working_Set *working_set = &models->working_set;
Heap *heap = &models->heap; Heap *heap = &models->heap;
Scratch_Block scratch(models->tctx); Scratch_Block scratch(tctx);
Editing_File *file = 0; Editing_File *file = 0;
b32 do_empty_buffer = false; 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)); file_bind_file_name(working_set, file, string_from_file_name(&canon));
} }
String_Const_u8 front = string_front_of_path(file_name); String_Const_u8 front = string_front_of_path(file_name);
buffer_bind_name(models, scratch, working_set, file, front); buffer_bind_name(tctx, models, scratch, working_set, file, front);
File_Attributes attributes = {}; File_Attributes attributes = {};
file_create_from_string(models, file, SCu8(""), attributes); file_create_from_string(tctx, models, file, SCu8(""), attributes);
result = file; result = file;
} }
} }
@ -511,8 +517,8 @@ create_file(Models *models, String_Const_u8 file_name, Buffer_Create_Flag flags)
if (file != 0){ if (file != 0){
file_bind_file_name(working_set, file, string_from_file_name(&canon)); file_bind_file_name(working_set, file, string_from_file_name(&canon));
String_Const_u8 front = string_front_of_path(file_name); String_Const_u8 front = string_front_of_path(file_name);
buffer_bind_name(models, scratch, working_set, file, front); buffer_bind_name(tctx, models, scratch, working_set, file, front);
file_create_from_string(models, file, SCu8(buffer, (i32)attributes.size), attributes); file_create_from_string(tctx, models, file, SCu8(buffer, (i32)attributes.size), attributes);
result = file; 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); i64 size = buffer_size(&file->state.buffer);
if (size > 0){ if (size > 0){
Edit_Behaviors behaviors = {}; 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){ if (has_canon_name){
buffer_is_for_new_file = true; 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 && if (file != 0 && buffer_is_for_new_file &&
!HasFlag(flags, BufferCreate_SuppressNewFileHook) && !HasFlag(flags, BufferCreate_SuppressNewFileHook) &&
models->new_file != 0){ 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);
} }
} }

View File

@ -137,7 +137,7 @@ file_name_terminate(Editing_File_Name *name){
// TODO(allen): file_name should be String_Const_u8 // TODO(allen): file_name should be String_Const_u8
internal b32 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 result = false;
b32 using_actual_file_name = 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 (file_name != 0){
if (models->save_file != 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; Gap_Buffer *buffer = &file->state.buffer;
b32 dos_write_mode = file->settings.dos_write_mode; 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){ if (!using_actual_file_name){
String_Const_u8 s_file_name = SCu8(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 internal b32
save_file(Models *models, Editing_File *file){ save_file(Thread_Context *tctx, Models *models, Editing_File *file){
return(save_file_to_name(models, file, 0)); return(save_file_to_name(tctx, models, file, 0));
} }
//////////////////////////////// ////////////////////////////////
@ -206,8 +209,7 @@ file_compute_cursor(Editing_File *file, Buffer_Seek seek){
//////////////////////////////// ////////////////////////////////
internal void internal void
file_create_from_string(Models *models, Editing_File *file, String_Const_u8 val, File_Attributes attributes){ file_create_from_string(Thread_Context *tctx, Models *models, Editing_File *file, String_Const_u8 val, File_Attributes attributes){
Thread_Context *tctx = models->tctx;
Scratch_Block scratch(tctx, Scratch_Share); Scratch_Block scratch(tctx, Scratch_Share);
Base_Allocator *allocator = tctx->allocator; 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); buffer_measure_starts(scratch, &file->state.buffer);
file->lifetime_object = lifetime_alloc_object(&models->lifetime_allocator, DynamicWorkspace_Buffer, file); 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.cached_layouts_arena = make_arena(allocator);
file->state.line_layout_table = make_table_Data_u64(allocator, 500); 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){ 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 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; Lifetime_Allocator *lifetime_allocator = &models->lifetime_allocator;
Working_Set *working_set = &models->working_set; 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); 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); linalloc_clear(&file->state.cached_layouts_arena);
table_free(&file->state.line_layout_table); table_free(&file->state.line_layout_table);
@ -288,7 +293,7 @@ file_get_managed_scope(Editing_File *file){
//////////////////////////////// ////////////////////////////////
internal Buffer_Layout_Item_List 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 = {}; Buffer_Layout_Item_List result = {};
i64 line_count = buffer_line_count(&file->state.buffer); 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{ else{
list = push_array(&file->state.cached_layouts_arena, Buffer_Layout_Item_List, 1); 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); 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); &file->state.buffer, line_range, face, width);
key_data = push_data_copy(&file->state.cached_layouts_arena, key_data); key_data = push_data_copy(&file->state.cached_layouts_arena, key_data);
table_insert(&file->state.line_layout_table, key_data, (u64)PtrAsInt(list)); 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 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 = {}; Line_Shift_Vertical result = {};
f32 line_y = 0.f; 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; line_number = 1;
break; 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; line_y -= line.height;
} }
if (!has_result){ 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; b32 has_result = false;
i64 line_count = buffer_line_count(&file->state.buffer); i64 line_count = buffer_line_count(&file->state.buffer);
for (;;line_number += 1){ 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; f32 next_y = line_y + line.height;
if (y_delta < next_y){ if (y_delta < next_y){
has_result = true; has_result = true;
@ -386,12 +391,12 @@ file_line_shift_y(Models *models, Editing_File *file, f32 width, Face *face, i64
} }
internal f32 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; f32 result = 0.f;
if (line_a != line_b){ if (line_a != line_b){
Interval_i64 line_range = Ii64(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){ 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; result += line.height;
} }
if (line_a < line_b){ if (line_a < line_b){
@ -402,25 +407,25 @@ file_line_y_difference(Models *models, Editing_File *file, f32 width, Face *face
} }
internal i64 internal i64
file_pos_at_relative_xy(Models *models, Editing_File *file, f32 width, Face *face, i64 base_line, Vec2_f32 relative_xy){ 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(models, file, width, face, base_line, relative_xy.y); Line_Shift_Vertical shift = file_line_shift_y(tctx, models, file, width, face, base_line, relative_xy.y);
relative_xy.y -= shift.y_delta; 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)); return(buffer_layout_nearest_pos_to_xy(line, relative_xy));
} }
internal Vec2_f32 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; 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); 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); return(result);
} }
internal Buffer_Point internal Buffer_Point
file_normalize_buffer_point(Models *models, Editing_File *file, f32 width, Face *face, Buffer_Point point){ 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(models, file, width, face, point.line_number, point.pixel_shift.y); 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.line_number = shift.line;
point.pixel_shift.y -= shift.y_delta; point.pixel_shift.y -= shift.y_delta;
point.pixel_shift.x = clamp_bot(0.f, point.pixel_shift.x); 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 internal Vec2_f32
file_buffer_point_difference(Models *models, Editing_File *file, f32 width, Face *face, Buffer_Point a, Buffer_Point b){ 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(models, file, width, face, a.line_number, b.line_number); 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; Vec2_f32 result = a.pixel_shift - b.pixel_shift;
result.y += y_difference; result.y += y_difference;
return(result); return(result);
} }
internal Line_Shift_Character 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 = {}; Line_Shift_Character result = {};
i64 line_character = 0; i64 line_character = 0;
@ -457,7 +462,7 @@ file_line_shift_characters(Models *models, Editing_File *file, f32 width, Face *
line_number = 1; line_number = 1;
break; 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; line_character -= line.character_count;
} }
if (!has_result){ if (!has_result){
@ -470,7 +475,7 @@ file_line_shift_characters(Models *models, Editing_File *file, f32 width, Face *
b32 has_result = false; b32 has_result = false;
i64 line_count = buffer_line_count(&file->state.buffer); i64 line_count = buffer_line_count(&file->state.buffer);
for (;;line_number += 1){ 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; i64 next_character = line_character + line.character_count;
if (character_delta < next_character){ if (character_delta < next_character){
has_result = true; has_result = true;
@ -493,12 +498,12 @@ file_line_shift_characters(Models *models, Editing_File *file, f32 width, Face *
} }
internal i64 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; i64 result = 0;
if (line_a != line_b){ if (line_a != line_b){
Interval_i64 line_range = Ii64(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){ 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; result += line.character_count;
} }
if (line_a < line_b){ if (line_a < line_b){
@ -509,19 +514,19 @@ file_line_character_difference(Models *models, Editing_File *file, f32 width, Fa
} }
internal i64 internal i64
file_pos_from_relative_character(Models *models, Editing_File *file, f32 width, Face *face, i64 base_line, i64 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(models, file, width, face, base_line, relative_character); Line_Shift_Character shift = file_line_shift_characters(tctx, models, file, width, face, base_line, relative_character);
relative_character -= shift.character_delta; 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)); return(buffer_layout_get_pos_at_character(line, relative_character));
} }
internal i64 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; 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); 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); return(result);
} }

View File

@ -129,9 +129,8 @@ global_history_adjust_edit_grouping_counter(Global_History *global_history, i32
} }
internal void internal void
history_init(Models *models, History *history){ history_init(Thread_Context *tctx, Models *models, History *history){
history->activated = true; history->activated = true;
Thread_Context *tctx = models->tctx;
history->arena = reserve_arena(tctx, KB(32)); history->arena = reserve_arena(tctx, KB(32));
heap_init(&history->heap, tctx->allocator); heap_init(&history->heap, tctx->allocator);
history->heap_wrapper = base_allocator_on_heap(&history->heap); history->heap_wrapper = base_allocator_on_heap(&history->heap);
@ -147,9 +146,9 @@ history_is_activated(History *history){
} }
internal void internal void
history_free(Models *models, History *history){ history_free(Thread_Context *tctx, History *history){
if (history->activated){ if (history->activated){
release_arena(models, history->arena); release_arena(tctx, history->arena);
heap_free_all(&history->heap); heap_free_all(&history->heap);
block_zero_struct(history); block_zero_struct(history);
} }

View File

@ -31,10 +31,10 @@ log_string(String_Const_u8 str){
} }
internal void 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 internal b32
log_flush(Models *models){ log_flush(Thread_Context *tctx, Models *models){
b32 result = false; b32 result = false;
system_mutex_acquire(global_log.mutex); system_mutex_acquire(global_log.mutex);
@ -42,7 +42,7 @@ log_flush(Models *models){
if (global_log.list.total_size > 0){ if (global_log.list.total_size > 0){
String_Const_u8 text = string_list_flatten(&global_log.arena, global_log.list); 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; result = true;
} }
linalloc_clear(&global_log.arena); linalloc_clear(&global_log.arena);

View File

@ -10,10 +10,10 @@
// TOP // TOP
internal void 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); block_zero_struct(container);
container->node_arena = reserve_arena(models->tctx); container->node_arena = reserve_arena(tctx);
container->table = make_table_u64_u64(models->tctx->allocator, 20); container->table = make_table_u64_u64(tctx->allocator, 20);
} }
internal Text_Layout* internal Text_Layout*
@ -29,8 +29,8 @@ text_layout_new__alloc_layout(Text_Layout_Container *container){
} }
internal void internal void
text_layout_release(Models *models, Text_Layout_Container *container, Text_Layout *layout){ text_layout_release(Thread_Context *tctx, Models *models, Text_Layout_Container *container, Text_Layout *layout){
release_arena(models->tctx, layout->arena); release_arena(tctx, layout->arena);
sll_stack_push(container->free_nodes, layout); sll_stack_push(container->free_nodes, layout);
} }
@ -65,14 +65,14 @@ text_layout_get(Text_Layout_Container *container, Text_Layout_ID id){
} }
internal b32 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; b32 result = false;
Table_Lookup lookup = table_lookup(&container->table, id); Table_Lookup lookup = table_lookup(&container->table, id);
if (lookup.found_match){ if (lookup.found_match){
u64 ptr_val = 0; u64 ptr_val = 0;
table_read(&container->table, lookup, &ptr_val); table_read(&container->table, lookup, &ptr_val);
Text_Layout *ptr = (Text_Layout*)IntAsPtr(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); table_erase(&container->table, lookup);
result = true; result = true;
} }
@ -82,7 +82,7 @@ text_layout_erase(Models *models, Text_Layout_Container *container, Text_Layout_
//////////////////////////////// ////////////////////////////////
internal void 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); Editing_File *file = imp_get_file(models, layout->buffer_id);
if (file != 0){ if (file != 0){
Render_Target *target = models->target; 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 = layout->visible_line_number_range.min;
i64 line_number_last = layout->visible_line_number_range.max; i64 line_number_last = layout->visible_line_number_range.max;
for (;line_number <= line_number_last; line_number += 1){ 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; for (Buffer_Layout_Item_Block *block = line.first;
block != 0; block != 0;
block = block->next){ block = block->next){

View File

@ -148,12 +148,15 @@ view_set_edit_pos(View *view, File_Edit_Positions edit_pos){
//////////////////////////////// ////////////////////////////////
internal Rect_f32 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); Rect_f32 region = Rf32(view->panel->rect_full);
if (models->buffer_region != 0){ if (models->buffer_region != 0){
Rect_f32 rect = region; Rect_f32 rect = region;
Rect_f32 sub_region = Rf32(V2(0, 0), rect_dim(rect)); 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.p0 = rect.p0 + sub_region.p0;
region.p1 = rect.p0 + sub_region.p1; region.p1 = rect.p0 + sub_region.p1;
region.x1 = clamp_top(region.x1, rect.x1); region.x1 = clamp_top(region.x1, rect.x1);
@ -165,112 +168,112 @@ view_get_buffer_rect(Models *models, View *view){
} }
internal f32 internal f32
view_width(Models *models, View *view){ view_width(Thread_Context *tctx, Models *models, View *view){
return(rect_width(view_get_buffer_rect(models, view))); return(rect_width(view_get_buffer_rect(tctx, models, view)));
} }
internal f32 internal f32
view_height(Models *models, View *view){ view_height(Thread_Context *tctx, Models *models, View *view){
return(rect_height(view_get_buffer_rect(models, view))); return(rect_height(view_get_buffer_rect(tctx, models, view)));
} }
//////////////////////////////// ////////////////////////////////
internal Buffer_Layout_Item_List 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; Editing_File *file = view->file;
Face *face = file_get_face(models, file); Face *face = file_get_face(models, file);
f32 width = view_width(models, view); f32 width = view_width(tctx, models, view);
return(file_get_line_layout(models, file, width, face, line_number)); return(file_get_line_layout(tctx, models, file, width, face, line_number));
} }
internal Line_Shift_Vertical 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; Editing_File *file = view->file;
Face *face = file_get_face(models, file); Face *face = file_get_face(models, file);
f32 width = view_width(models, view); f32 width = view_width(tctx, models, view);
return(file_line_shift_y(models, file, width, face, line_number, y_delta)); return(file_line_shift_y(tctx, models, file, width, face, line_number, y_delta));
} }
internal f32 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; Editing_File *file = view->file;
Face *face = file_get_face(models, file); Face *face = file_get_face(models, file);
f32 width = view_width(models, view); f32 width = view_width(tctx, models, view);
return(file_line_y_difference(models, file, width, face, line_a, line_b)); return(file_line_y_difference(tctx, models, file, width, face, line_a, line_b));
} }
internal i64 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; Editing_File *file = view->file;
Face *face = file_get_face(models, file); Face *face = file_get_face(models, file);
f32 width = view_width(models, view); f32 width = view_width(tctx, models, view);
return(file_pos_at_relative_xy(models, file, width, face, base_line, relative_xy)); return(file_pos_at_relative_xy(tctx, models, file, width, face, base_line, relative_xy));
} }
internal Vec2_f32 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; Editing_File *file = view->file;
Face *face = file_get_face(models, file); Face *face = file_get_face(models, file);
f32 width = view_width(models, view); f32 width = view_width(tctx, models, view);
return(file_relative_xy_of_pos(models, file, width, face, base_line, pos)); return(file_relative_xy_of_pos(tctx, models, file, width, face, base_line, pos));
} }
internal Buffer_Point 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; Editing_File *file = view->file;
Face *face = file_get_face(models, file); Face *face = file_get_face(models, file);
f32 width = view_width(models, view); f32 width = view_width(tctx, models, view);
return(file_normalize_buffer_point(models, file, width, face, point)); return(file_normalize_buffer_point(tctx, models, file, width, face, point));
} }
internal Vec2_f32 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; Editing_File *file = view->file;
Face *face = file_get_face(models, file); Face *face = file_get_face(models, file);
f32 width = view_width(models, view); f32 width = view_width(tctx, models, view);
return(file_buffer_point_difference(models, file, width, face, a, b)); return(file_buffer_point_difference(tctx, models, file, width, face, a, b));
} }
internal Buffer_Point 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; 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.line_number = shift.line;
buffer_point.pixel_shift = V2f32(delta.x, delta.y - shift.y_delta); buffer_point.pixel_shift = V2f32(delta.x, delta.y - shift.y_delta);
return(buffer_point); return(buffer_point);
} }
internal Line_Shift_Character 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; Editing_File *file = view->file;
Face *face = file_get_face(models, file); Face *face = file_get_face(models, file);
f32 width = view_width(models, view); f32 width = view_width(tctx, models, view);
return(file_line_shift_characters(models, file, width, face, line_number, character_delta)); return(file_line_shift_characters(tctx, models, file, width, face, line_number, character_delta));
} }
internal i64 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; Editing_File *file = view->file;
Face *face = file_get_face(models, file); Face *face = file_get_face(models, file);
f32 width = view_width(models, view); f32 width = view_width(tctx, models, view);
return(file_line_character_difference(models, file, width, face, line_a, line_b)); return(file_line_character_difference(tctx, models, file, width, face, line_a, line_b));
} }
internal i64 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; Editing_File *file = view->file;
Face *face = file_get_face(models, file); Face *face = file_get_face(models, file);
f32 width = view_width(models, view); f32 width = view_width(tctx, models, view);
return(file_pos_from_relative_character(models, file, width, face, base_line, relative_character)); return(file_pos_from_relative_character(tctx, models, file, width, face, base_line, relative_character));
} }
internal i64 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; Editing_File *file = view->file;
Face *face = file_get_face(models, file); Face *face = file_get_face(models, file);
f32 width = view_width(models, view); f32 width = view_width(tctx, models, view);
return(file_relative_character_from_pos(models, file, width, face, base_line, pos)); return(file_relative_character_from_pos(tctx, models, file, width, face, base_line, pos));
} }
internal Buffer_Cursor internal Buffer_Cursor
@ -282,14 +285,14 @@ view_compute_cursor(View *view, Buffer_Seek seek){
//////////////////////////////// ////////////////////////////////
internal b32 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; Editing_File *file = view->file;
Face *face = file_get_face(models, 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 view_dim = rect_dim(rect);
File_Edit_Positions edit_pos = view_get_edit_pos(view); 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); edit_pos.cursor_pos);
p -= scroll->target.pixel_shift; 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; target_p_relative.x = (p.x + typical_advance*1.5f) - view_dim.x;
} }
scroll->target.pixel_shift += target_p_relative; 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.x = f32_round32(scroll->target.pixel_shift.x);
scroll->target.pixel_shift.y = f32_round32(scroll->target.pixel_shift.y); 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 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; Editing_File *file = view->file;
Face *face = file_get_face(models, 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 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; p -= scroll.target.pixel_shift;
f32 line_height = face->line_height; 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; b32 result = false;
if (adjusted_y){ if (adjusted_y){
p += scroll.target.pixel_shift; 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; result = true;
} }
@ -351,33 +354,33 @@ view_move_cursor_to_view(Models *models, View *view, Buffer_Scroll scroll, i64 *
} }
internal void 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 edit_pos = view_get_edit_pos(view);
file_edit_positions_set_cursor(&edit_pos, pos); file_edit_positions_set_cursor(&edit_pos, pos);
view_set_edit_pos(view, edit_pos); view_set_edit_pos(view, edit_pos);
Buffer_Scroll scroll = edit_pos.scroll; 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; edit_pos.scroll = scroll;
view_set_edit_pos(view, edit_pos); view_set_edit_pos(view, edit_pos);
} }
} }
internal void 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 edit_pos = view_get_edit_pos(view);
file_edit_positions_set_scroll(&edit_pos, scroll); file_edit_positions_set_scroll(&edit_pos, scroll);
view_set_edit_pos(view, edit_pos); 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); view_set_edit_pos(view, edit_pos);
} }
} }
internal void 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 edit_pos = view_get_edit_pos(view);
file_edit_positions_set_cursor(&edit_pos, pos); file_edit_positions_set_cursor(&edit_pos, pos);
Buffer_Cursor cursor = view_compute_cursor(view, seek_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; view->preferred_x = p.x;
file_edit_positions_set_scroll(&edit_pos, scroll); file_edit_positions_set_scroll(&edit_pos, scroll);
edit_pos.last_set_type = EditPos_None; 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 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); Assert(file != 0);
Editing_File *old_file = view->file; 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_set_edit_pos(view, edit_pos);
view->mark = edit_pos.cursor_pos; view->mark = edit_pos.cursor_pos;
Buffer_Cursor cursor = view_compute_cursor(view, seek_pos(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; view->preferred_x = p.x;
models->layout.panel_state_dirty = true; 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* internal Coroutine*
co_handle_request(Models *models, Coroutine *co, Co_Out *out){ co_handle_request(Models *models, Coroutine *co, Co_Out *out){
Coroutine *result = 0; Coroutine *result = 0;
@ -503,17 +492,11 @@ co_handle_request(Models *models, Coroutine *co, Co_Out *out){
} }
internal Coroutine* internal Coroutine*
co_run(Models *models, App_Coroutine_Purpose purpose, Coroutine *co, co_run(Thread_Context *tctx, Models *models, Coroutine *co, Co_In *in, Co_Out *out){
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;
Coroutine *result = coroutine_run(&models->coroutines, co, in, out); Coroutine *result = coroutine_run(&models->coroutines, co, in, out);
for (;result != 0 && out->request != CoRequest_None;){ for (;result != 0 && out->request != CoRequest_None;){
result = co_handle_request(models, result, out); result = co_handle_request(models, result, out);
} }
restore_co_state(app, prev_state);
return(result); return(result);
} }
@ -523,15 +506,18 @@ view_event_context_base__inner(Coroutine *coroutine){
Models *models = in->models; Models *models = in->models;
Custom_Command_Function *event_context_base = in->event_context_base; Custom_Command_Function *event_context_base = in->event_context_base;
Assert(event_context_base != 0); 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 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){ 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 = {}; View_Context first_ctx = {};
first_ctx.render_caller = models->render_caller; first_ctx.render_caller = models->render_caller;
@ -543,7 +529,7 @@ view_init(Models *models, View *view, Editing_File *initial_buffer,
Co_In in = {}; Co_In in = {};
in.models = models; in.models = models;
in.event_context_base = event_context_base; 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! // TODO(allen): deal with this kind of problem!
Assert(view->co != 0); Assert(view->co != 0);
} }
@ -572,25 +558,28 @@ view_check_co_exited(Models *models, View *view){
} }
internal void internal void
co_single_abort(Models *models, View *view){ co_single_abort(Thread_Context *tctx, Models *models, View *view){
Coroutine *co = view->co; Coroutine *co = view->co;
Co_In in = {}; Co_In in = {};
in.user_input.abort = true; 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); view_check_co_exited(models, view);
} }
internal void internal void
co_full_abort(Models *models, View *view){ co_full_abort(Thread_Context *tctx, Models *models, View *view){
Coroutine *co = view->co; Coroutine *co = view->co;
Co_In in = {}; Co_In in = {};
in.user_input.abort = true; in.user_input.abort = true;
for (u32 j = 0; j < 100 && co != 0; ++j){ 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){ if (co != 0){
#define M "SERIOUS ERROR: full stack abort did not complete" #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 #undef M
} }
view->co = 0; view->co = 0;
@ -598,7 +587,7 @@ co_full_abort(Models *models, View *view){
} }
function b32 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; b32 event_was_handled = false;
Coroutine *co = view->co; 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.event = *event;
in.user_input.abort = ((abort_flags & event_flags) != 0); in.user_input.abort = ((abort_flags & event_flags) != 0);
begin_handling_input(models, &in.user_input); 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); view_check_co_exited(models, view);
if (!HasFlag(event_flags, EventProperty_Animate)){ if (!HasFlag(event_flags, EventProperty_Animate)){
models->animate_next_frame = true; models->animate_next_frame = true;
@ -625,52 +614,52 @@ co_send_event(Models *models, View *view, Input_Event *event){
} }
function b32 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 = {}; Input_Event event = {};
event.kind = InputEventKind_Core; event.kind = InputEventKind_Core;
event.core.code = code; event.core.code = code;
event.core.string = string; event.core.string = string;
return(co_send_event(models, view, &event)); return(co_send_event(tctx, models, view, &event));
} }
function b32 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 = {}; Input_Event event = {};
event.kind = InputEventKind_Core; event.kind = InputEventKind_Core;
event.core.code = code; event.core.code = code;
event.core.id = id; event.core.id = id;
return(co_send_event(models, view, &event)); return(co_send_event(tctx, models, view, &event));
} }
function b32 function b32
co_send_core_event(Models *models, View *view, Core_Code code){ co_send_core_event(Thread_Context *tctx, Models *models, View *view, Core_Code code){
return(co_send_core_event(models, view, code, SCu8())); return(co_send_core_event(tctx, models, view, code, SCu8()));
} }
function b32 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; Panel *active_panel = models->layout.active_panel;
View *view = active_panel->view; View *view = active_panel->view;
return(co_send_event(models, view, event)); return(co_send_event(tctx, models, view, event));
} }
function b32 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; Panel *active_panel = models->layout.active_panel;
View *view = active_panel->view; 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 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; Panel *active_panel = models->layout.active_panel;
View *view = active_panel->view; 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 function b32
co_send_core_event(Models *models, Core_Code code){ co_send_core_event(Thread_Context *tctx, Models *models, Core_Code code){
return(co_send_core_event(models, code, SCu8())); return(co_send_core_event(tctx, models, code, SCu8()));
} }
//////////////////////////////// ////////////////////////////////
@ -691,7 +680,7 @@ file_is_viewed(Layout *layout, Editing_File *file){
} }
internal void 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; Layout *layout = &models->layout;
for (Panel *panel = layout_get_first_open_panel(layout); for (Panel *panel = layout_get_first_open_panel(layout);
panel != 0; panel != 0;
@ -699,7 +688,7 @@ adjust_views_looking_at_file_to_new_cursor(Models *models, Editing_File *file){
View *view = panel->view; View *view = panel->view;
if (view->file == file){ if (view->file == file){
File_Edit_Positions edit_pos = view_get_edit_pos(view); 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);
} }
} }
} }

View File

@ -381,7 +381,7 @@ buffer_unbind_name_low_level(Working_Set *working_set, Editing_File *file){
} }
internal void 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); Temp_Memory temp = begin_temp(scratch);
// List of conflict files. // 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. // Get user's resolution data.
if (models->buffer_name_resolver != 0){ 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 // Re-bind all of the files

View File

@ -4,19 +4,126 @@
// TOP // 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 function void
async_task_handler_init(Application_Links *app){ async_task_handler_init(Application_Links *app){
//NotImplemented; block_zero_struct(&async_system);
dummy_async_app = app; 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 function Async_Task
async_task_no_dep(Async_Task_Function_Type *func, Data data){ async_task_no_dep(Async_Task_Function_Type *func, Data data){
//NotImplemented; return(async_push_node(func, data));
func(dummy_async_app, data);
return(0);
} }
function Async_Task function Async_Task
@ -26,22 +133,36 @@ async_task_single_dep(Async_Task_Function_Type *func, Data data, Async_Task depe
function b32 function b32
async_task_is_pending(Async_Task task){ 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 function b32
async_task_is_running(Async_Task task){ 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 function b32
async_task_is_running_or_pending(Async_Task task){ 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 function void
async_task_cancel(Async_Task task){ async_task_cancel(Async_Task task){
system_mutex_acquire(async_system.mutex);
NotImplemented; NotImplemented;
system_mutex_release(async_system.mutex);
} }
function void function void

View File

@ -7,10 +7,44 @@
#if !defined(FCODER_ASYNC_TASKS_H) #if !defined(FCODER_ASYNC_TASKS_H)
#define 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; 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 #endif
// BOTTOM // BOTTOM

View File

@ -478,7 +478,7 @@ union SNode{
#define sll_stack_pop_(h) h=h=h->next #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_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_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_push(h,n) (sll_stack_push_((h),(n)))
#define sll_stack_pop(h) (sll_stack_pop_((h))) #define sll_stack_pop(h) (sll_stack_pop_((h)))
@ -1188,6 +1188,8 @@ struct Thread_Context{
Profile_Record *prof_first; Profile_Record *prof_first;
Profile_Record *prof_last; Profile_Record *prof_last;
i32 prof_record_count; i32 prof_record_count;
void *user_data;
}; };
typedef i32 Scratch_Share_Code; typedef i32 Scratch_Share_Code;

View File

@ -539,7 +539,8 @@ BUFFER_NAME_RESOLVER_SIG(default_buffer_name_resolution){
} }
function void 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); Thread_Context *tctx = get_thread_context(app);
Scratch_Block scratch(tctx); Scratch_Block scratch(tctx);
@ -564,10 +565,10 @@ do_full_lex_async__inner(Application_Links *app, Buffer_ID buffer_id){
} }
function void 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)){ if (data.size == sizeof(Buffer_ID)){
Buffer_ID buffer = *(Buffer_ID*)data.data; Buffer_ID buffer = *(Buffer_ID*)data.data;
do_full_lex_async__inner(app, buffer); do_full_lex_async__inner(actx, buffer);
} }
} }

View File

@ -13,11 +13,13 @@
#endif #endif
struct Thread_Context_Extra_Info{
void *coroutine;
void *async_thread;
};
struct Application_Links{ struct Application_Links{
Thread_Context *tctx;
void *cmd_context; void *cmd_context;
void *current_thread;
void *current_coroutine;
i32 type_coroutine;
}; };
typedef void Custom_Layer_Init_Type(Application_Links *app); typedef void Custom_Layer_Init_Type(Application_Links *app);
void custom_layer_init(Application_Links *app); void custom_layer_init(Application_Links *app);

View File

@ -1681,7 +1681,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS
Scratch_Block scratch(win32vars.tctx, Scratch_Share); Scratch_Block scratch(win32vars.tctx, Scratch_Share);
String_Const_u8 curdir = system_get_path(scratch, SystemPath_CurrentDirectory); String_Const_u8 curdir = system_get_path(scratch, SystemPath_CurrentDirectory);
curdir = string_mod_replace_character(curdir, '\\', '/'); 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 // NOTE(allen): Application Core Update
Application_Step_Result result = {}; Application_Step_Result result = {};
if (app.step != 0){ if (app.step != 0){
result = app.step(&target, base_ptr, &input); result = app.step(win32vars.tctx, &target, base_ptr, &input);
} }
else{ else{
//LOG("app.step == 0 -- skipping\n"); //LOG("app.step == 0 -- skipping\n");