Dumb merge

master
Allen Webster 2019-10-22 12:52:31 -07:00
commit b807950233
46 changed files with 4759 additions and 3846 deletions

112
4ed.cpp
View File

@ -7,17 +7,18 @@
*
*/
// TOP
internal void
output_file_append(Models *models, Editing_File *file, String_Const_u8 value){
output_file_append(Thread_Context *tctx, Models *models, Editing_File *file, String_Const_u8 value){
i64 end = buffer_size(&file->state.buffer);
Edit_Behaviors behaviors = {};
edit_single(models, file, Ii64(end), value, behaviors);
edit_single(tctx, models, file, Ii64(end), value, behaviors);
}
internal void
file_cursor_to_end(Models *models, Editing_File *file){
file_cursor_to_end(Thread_Context *tctx, Models *models, Editing_File *file){
Assert(file != 0);
i64 pos = buffer_size(&file->state.buffer);
Layout *layout = &models->layout;
@ -28,7 +29,7 @@ file_cursor_to_end(Models *models, Editing_File *file){
if (view->file != file){
continue;
}
view_set_cursor(models, view, pos);
view_set_cursor(tctx, models, view, pos);
view->mark = pos;
}
}
@ -281,12 +282,12 @@ init_command_line_settings(App_Settings *settings, Plat_Settings *plat_settings,
////////////////////////////////
internal Models*
models_init(Thread_Context *tctx){
Arena *arena = reserve_arena(tctx);
Models *models = push_array_zero(arena, Models, 1);
models->tctx = tctx;
models->arena = arena;
heap_init(&models->heap, tctx->allocator);
models_init(void){
Arena arena = make_arena_system();
Models *models = push_array_zero(&arena, Models, 1);
models->arena_ = arena;
models->arena = &models->arena_;
heap_init(&models->heap, get_base_allocator_system());
return(models);
}
@ -306,7 +307,7 @@ app_get_logger(void){
}
App_Read_Command_Line_Sig(app_read_command_line){
Models *models = models_init(tctx);
Models *models = models_init();
App_Settings *settings = &models->settings;
block_zero_struct(settings);
if (argc > 1){
@ -322,7 +323,6 @@ App_Init_Sig(app_init){
models->keep_playing = true;
models->config_api = api;
models->app_links.cmd_context = models;
API_VTable_custom custom_vtable = {};
custom_api_fill_vtable(&custom_vtable);
@ -330,7 +330,11 @@ App_Init_Sig(app_init){
system_api_fill_vtable(&system_vtable);
Custom_Layer_Init_Type *custom_init = api.init_apis(&custom_vtable, &system_vtable);
Assert(custom_init != 0);
custom_init(&models->app_links);
Application_Links app = {};
app.tctx = tctx;
app.cmd_context = models;
custom_init(&app);
// NOTE(allen): coroutines
coroutine_system_init(&models->coroutines);
@ -360,8 +364,8 @@ App_Init_Sig(app_init){
}
}
managed_ids_init(models->tctx->allocator, &models->managed_id_set);
lifetime_allocator_init(models->tctx->allocator, &models->lifetime_allocator);
managed_ids_init(tctx->allocator, &models->managed_id_set);
lifetime_allocator_init(tctx->allocator, &models->lifetime_allocator);
dynamic_workspace_init(&models->lifetime_allocator, DynamicWorkspace_Global, 0, &models->dynamic_workspace);
// NOTE(allen): file setup
@ -371,7 +375,7 @@ App_Init_Sig(app_init){
// NOTE(allen):
global_history_init(&models->global_history);
text_layout_init(models, &models->text_layouts);
text_layout_init(tctx, &models->text_layouts);
// NOTE(allen): clipboard setup
models->working_set.clipboard_max_size = ArrayCount(models->working_set.clipboards);
@ -412,17 +416,17 @@ App_Init_Sig(app_init){
Heap *heap = &models->heap;
for (i32 i = 0; i < ArrayCount(init_files); ++i){
Editing_File *file = working_set_allocate_file(&models->working_set, &models->lifetime_allocator);
buffer_bind_name(models, arena, &models->working_set, file, init_files[i].name);
buffer_bind_name(tctx, models, arena, &models->working_set, file, init_files[i].name);
if (init_files[i].ptr != 0){
*init_files[i].ptr = file;
}
File_Attributes attributes = {};
file_create_from_string(models, file, SCu8(), attributes);
file_create_from_string(tctx, models, file, SCu8(), attributes);
if (init_files[i].read_only){
file->settings.read_only = true;
history_free(models, &file->state.history);
history_free(tctx, &file->state.history);
}
file->settings.never_kill = true;
@ -433,12 +437,12 @@ App_Init_Sig(app_init){
{
Panel *panel = layout_initialize(arena, &models->layout);
View *new_view = live_set_alloc_view(&models->lifetime_allocator, &models->live_set, panel);
view_init(models, new_view, models->scratch_buffer, models->view_event_handler);
view_init(tctx, models, new_view, models->scratch_buffer, models->view_event_handler);
}
// NOTE(allen): miscellaneous init
hot_directory_init(arena, &models->hot_directory, current_directory);
child_process_container_init(models->tctx->allocator, &models->child_processes);
child_process_container_init(tctx->allocator, &models->child_processes);
models->period_wakeup_timer = system_wake_up_timer_create();
}
@ -446,7 +450,7 @@ App_Step_Sig(app_step){
Models *models = (Models*)base_ptr;
Mutex_Lock file_order_lock(models->working_set.mutex);
Scratch_Block scratch(models->tctx, Scratch_Share);
Scratch_Block scratch(tctx, Scratch_Share);
models->next_animate_delay = max_u32;
models->animate_next_frame = false;
@ -462,7 +466,7 @@ App_Step_Sig(app_step){
String_Const_u8 *dest = working_set_next_clipboard_string(&models->heap, &models->working_set, clipboard.size);
dest->size = eol_convert_in((char*)dest->str, (char*)clipboard.str, (i32)clipboard.size);
if (input->clipboard_changed){
co_send_core_event(models, CoreCode_NewClipboardContents, *dest);
co_send_core_event(tctx, models, CoreCode_NewClipboardContents, *dest);
}
}
@ -499,7 +503,7 @@ App_Step_Sig(app_step){
if (system_cli_update_step(cli, dest, max, &amount)){
if (file != 0 && amount > 0){
amount = eol_in_place_convert_in(dest, amount);
output_file_append(models, file, SCu8(dest, amount));
output_file_append(tctx, models, file, SCu8(dest, amount));
edited_file = true;
}
}
@ -507,7 +511,7 @@ App_Step_Sig(app_step){
if (system_cli_end_update(cli)){
if (file != 0){
String_Const_u8 str = push_u8_stringf(scratch, "exited with code %d", cli->exit);
output_file_append(models, file, str);
output_file_append(tctx, models, file, str);
edited_file = true;
}
processes_to_free[processes_to_free_count++] = child_process;
@ -515,7 +519,7 @@ App_Step_Sig(app_step){
}
if (child_process->cursor_at_end && file != 0){
file_cursor_to_end(models, file);
file_cursor_to_end(tctx, models, file);
}
}
@ -639,7 +643,7 @@ App_Step_Sig(app_step){
event.core.code = CoreCode_Startup;
event.core.flag_strings = flags;
event.core.file_names = file_names;
co_send_event(models, &event);
co_send_event(tctx, models, &event);
}
// NOTE(allen): consume event stream
@ -689,7 +693,7 @@ App_Step_Sig(app_step){
case EventConsume_ClickChangeView:
{
// NOTE(allen): run deactivate command
co_send_core_event(models, view, CoreCode_ClickDeactivateView);
co_send_core_event(tctx, models, view, CoreCode_ClickDeactivateView);
layout->active_panel = mouse_panel;
models->animate_next_frame = true;
@ -697,14 +701,14 @@ App_Step_Sig(app_step){
view = active_panel->view;
// NOTE(allen): run activate command
co_send_core_event(models, view, CoreCode_ClickActivateView);
co_send_core_event(tctx, models, view, CoreCode_ClickActivateView);
event_was_handled = true;
}break;
case EventConsume_CustomCommand:
{
event_was_handled = co_send_event(models, view, event);
event_was_handled = co_send_event(tctx, models, view, event);
}break;
}
}break;
@ -745,7 +749,10 @@ App_Step_Sig(app_step){
if (models->layout.panel_state_dirty){
models->layout.panel_state_dirty = false;
if (models->buffer_viewer_update != 0){
models->buffer_viewer_update(&models->app_links);
Application_Links app = {};
app.tctx = tctx;
app.cmd_context = models;
models->buffer_viewer_update(&app);
}
}
@ -769,42 +776,12 @@ App_Step_Sig(app_step){
panel = layout_get_next_open_panel(layout, panel)){
View *view = panel->view;
File_Edit_Positions edit_pos = view_get_edit_pos(view);
edit_pos.scroll.position = view_normalize_buffer_point(models, view, edit_pos.scroll.target);
edit_pos.scroll.position = view_normalize_buffer_point(tctx, models, view, edit_pos.scroll.target);
block_zero_struct(&edit_pos.scroll.target);
view_set_edit_pos(view, edit_pos);
}
}
#if 0
// NOTE(allen): apply pending smooth deltas
{
Delta_Rule_Function *delta_rule = models->delta_rule;
for (Panel *panel = layout_get_first_open_panel(layout);
panel != 0;
panel = layout_get_next_open_panel(layout, panel)){
View *view = panel->view;
View_ID view_id = view_get_id(&models->live_set, view);
b32 new_target = (b32)view->new_scroll_target;
File_Edit_Positions edit_pos = view_get_edit_pos(view);
Vec2_f32 pending = view_buffer_point_difference(models, view,
edit_pos.scroll.target, edit_pos.scroll.position);
if (!near_zero(pending, 0.5f)){
Vec2_f32 partial = scroll_rule(pending, view_id, new_target, animation_dt);
edit_pos.scroll.position = view_move_buffer_point(models, view,
edit_pos.scroll.position, partial);
view_set_edit_pos(view, edit_pos);
models->animate_next_frame = true;
}
else{
edit_pos.scroll.position = edit_pos.scroll.target;
view_set_edit_pos(view, edit_pos);
}
}
}
#endif
// NOTE(allen): hook for files reloaded
{
Working_Set *working_set = &models->working_set;
@ -817,7 +794,7 @@ App_Step_Sig(app_step){
Editing_File *file = CastFromMember(Editing_File, external_mod_node, node);
dll_remove(node);
block_zero_struct(node);
co_send_core_event(models, CoreCode_FileExternallyModified, file->id);
co_send_core_event(tctx, models, CoreCode_FileExternallyModified, file->id);
}
}
}
@ -827,7 +804,7 @@ App_Step_Sig(app_step){
models->keep_playing = false;
}
if (!models->keep_playing){
if (co_send_core_event(models, CoreCode_TryExit)){
if (co_send_core_event(tctx, models, CoreCode_TryExit)){
models->keep_playing = true;
}
}
@ -866,7 +843,10 @@ App_Step_Sig(app_step){
if (ctx != 0){
Render_Caller_Function *render_caller = ctx->ctx.render_caller;
if (render_caller != 0){
render_caller(&models->app_links, frame, view_get_id(live_views, view));
Application_Links app = {};
app.tctx = tctx;
app.cmd_context = models;
render_caller(&app, frame, view_get_id(live_views, view));
}
}
}
@ -876,7 +856,7 @@ App_Step_Sig(app_step){
}
// NOTE(allen): flush the log
log_flush(models);
log_flush(tctx, models);
// NOTE(allen): set the app_result
Application_Step_Result app_result = {};

6
4ed.h
View File

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

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
is_running_coroutine(Application_Links *app){
return(app->current_coroutine != 0);
Thread_Context *tctx = app->tctx;
Thread_Context_Extra_Info *info = (Thread_Context_Extra_Info*)tctx->user_data;
return(info->coroutine != 0);
}
api(custom) function b32
@ -73,22 +75,13 @@ global_get_screen_rectangle(Application_Links *app){
api(custom) function Thread_Context*
get_thread_context(Application_Links *app){
Thread_Context *tctx = 0;
if (app->current_coroutine == 0){
Models *models = (Models*)app->cmd_context;
tctx = models->tctx;
}
else{
Coroutine *coroutine = (Coroutine*)app->current_coroutine;
tctx = coroutine->tctx;
}
return(tctx);
return(app->tctx);
}
api(custom) function b32
create_child_process(Application_Links *app, String_Const_u8 path, String_Const_u8 command, Child_Process_ID *child_process_id_out){
Models *models = (Models*)app->cmd_context;
return(child_process_call(models, path, command, child_process_id_out));
return(child_process_call(app->tctx, models, path, command, child_process_id_out));
}
api(custom) function b32
@ -243,7 +236,7 @@ buffer_replace_range(Application_Links *app, Buffer_ID buffer_id, Range_i64 rang
i64 size = buffer_size(&file->state.buffer);
if (0 <= range.first && range.first <= range.one_past_last && range.one_past_last <= size){
Edit_Behaviors behaviors = {};
edit_single(models, file, range, string, behaviors);
edit_single(app->tctx, models, file, range, string, behaviors);
result = true;
}
}
@ -258,7 +251,7 @@ buffer_batch_edit(Application_Links *app, Buffer_ID buffer_id, Batch_Edit *batch
b32 result = false;
if (api_check_buffer(file)){
Edit_Behaviors behaviors = {};
result = edit_batch(models, file, batch, behaviors);
result = edit_batch(app->tctx, models, file, batch, behaviors);
}
return(result);
}
@ -370,7 +363,7 @@ buffer_line_y_difference(Application_Links *app, Buffer_ID buffer_id, f32 width,
if (api_check_buffer(file)){
Face *face = font_set_face_from_id(&models->font_set, face_id);
if (face != 0){
result = file_line_y_difference(models, file, width, face, line_a, line_b);
result = file_line_y_difference(app->tctx, models, file, width, face, line_a, line_b);
}
}
return(result);
@ -384,7 +377,7 @@ buffer_line_shift_y(Application_Links *app, Buffer_ID buffer_id, f32 width, Face
if (api_check_buffer(file)){
Face *face = font_set_face_from_id(&models->font_set, face_id);
if (face != 0){
result = file_line_shift_y(models, file, width, face, line, y_shift);
result = file_line_shift_y(app->tctx, models, file, width, face, line, y_shift);
}
}
return(result);
@ -398,7 +391,7 @@ buffer_pos_at_relative_xy(Application_Links *app, Buffer_ID buffer_id, f32 width
if (api_check_buffer(file)){
Face *face = font_set_face_from_id(&models->font_set, face_id);
if (face != 0){
result = file_pos_at_relative_xy(models, file, width, face, base_line, relative_xy);
result = file_pos_at_relative_xy(app->tctx, models, file, width, face, base_line, relative_xy);
}
}
return(result);
@ -413,7 +406,7 @@ buffer_relative_xy_of_pos(Application_Links *app, Buffer_ID buffer_id, f32 width
if (api_check_buffer(file)){
Face *face = font_set_face_from_id(&models->font_set, face_id);
if (face != 0){
result = file_relative_xy_of_pos(models, file, width, face, base_line, pos);
result = file_relative_xy_of_pos(app->tctx, models, file, width, face, base_line, pos);
}
}
return(result);
@ -428,7 +421,7 @@ buffer_relative_character_from_pos(Application_Links *app, Buffer_ID buffer_id,
if (api_check_buffer(file)){
Face *face = font_set_face_from_id(&models->font_set, face_id);
if (face != 0){
result = file_relative_character_from_pos(models, file, width, face, base_line, pos);
result = file_relative_character_from_pos(app->tctx, models, file, width, face, base_line, pos);
}
}
return(result);
@ -443,7 +436,7 @@ buffer_pos_from_relative_character(Application_Links *app, Buffer_ID buffer_id,
if (api_check_buffer(file)){
Face *face = font_set_face_from_id(&models->font_set, face_id);
if (face != 0){
result = file_pos_from_relative_character(models, file, width, face, base_line, relative_character);
result = file_pos_from_relative_character(app->tctx, models, file, width, face, base_line, relative_character);
}
}
return(result);
@ -457,7 +450,7 @@ view_line_y_difference(Application_Links *app, View_ID view_id, i64 line_a, i64
View *view = imp_get_view(models, view_id);
f32 result = {};
if (api_check_view(view)){
result = view_line_y_difference(models, view, line_a, line_b);
result = view_line_y_difference(app->tctx, models, view, line_a, line_b);
}
return(result);
}
@ -468,7 +461,7 @@ view_line_shift_y(Application_Links *app, View_ID view_id, i64 line, f32 y_shift
View *view = imp_get_view(models, view_id);
Line_Shift_Vertical result = {};
if (api_check_view(view)){
result = view_line_shift_y(models, view, line, y_shift);
result = view_line_shift_y(app->tctx, models, view, line, y_shift);
}
return(result);
}
@ -479,7 +472,7 @@ view_pos_at_relative_xy(Application_Links *app, View_ID view_id, i64 base_line,
View *view = imp_get_view(models, view_id);
i64 result = -1;
if (api_check_view(view)){
result = view_pos_at_relative_xy(models, view, base_line, relative_xy);
result = view_pos_at_relative_xy(app->tctx, models, view, base_line, relative_xy);
}
return(result);
}
@ -490,7 +483,7 @@ view_relative_xy_of_pos(Application_Links *app, View_ID view_id, i64 base_line,
View *view = imp_get_view(models, view_id);
Vec2_f32 result = {};
if (api_check_view(view)){
result = view_relative_xy_of_pos(models, view, base_line, pos);
result = view_relative_xy_of_pos(app->tctx, models, view, base_line, pos);
}
return(result);
}
@ -501,7 +494,7 @@ view_relative_character_from_pos(Application_Links *app, View_ID view_id, i64 b
View *view = imp_get_view(models, view_id);
i64 result = {};
if (api_check_view(view)){
result = view_relative_character_from_pos(models, view, base_line, pos);
result = view_relative_character_from_pos(app->tctx, models, view, base_line, pos);
}
return(result);
}
@ -512,7 +505,7 @@ view_pos_from_relative_character(Application_Links *app, View_ID view_id, i64 b
View *view = imp_get_view(models, view_id);
i64 result = {};
if (api_check_view(view)){
result = view_pos_from_relative_character(models, view, base_line, character);
result = view_pos_from_relative_character(app->tctx, models, view, base_line, character);
}
return(result);
}
@ -690,12 +683,12 @@ buffer_set_setting(Application_Links *app, Buffer_ID buffer_id, Buffer_Setting_I
{
if (value){
if (!history_is_activated(&file->state.history)){
history_init(models, &file->state.history);
history_init(app->tctx, models, &file->state.history);
}
}
else{
if (history_is_activated(&file->state.history)){
history_free(models, &file->state.history);
history_free(app->tctx, &file->state.history);
}
}
}break;
@ -729,7 +722,7 @@ buffer_send_end_signal(Application_Links *app, Buffer_ID buffer_id)
Editing_File *file = imp_get_file(models, buffer_id);
b32 result = false;
if (api_check_buffer(file)){
file_end_file(models, file);
file_end_file(app->tctx, models, file);
result = true;
}
return(result);
@ -739,7 +732,7 @@ api(custom) function Buffer_ID
create_buffer(Application_Links *app, String_Const_u8 file_name, Buffer_Create_Flag flags)
{
Models *models = (Models*)app->cmd_context;
Editing_File *new_file = create_file(models, file_name, flags);
Editing_File *new_file = create_file(app->tctx, models, file_name, flags);
Buffer_ID result = 0;
if (new_file != 0){
result = new_file->id;
@ -763,9 +756,10 @@ buffer_save(Application_Links *app, Buffer_ID buffer_id, String_Const_u8 file_na
}
if (!skip_save){
Scratch_Block scratch(models->tctx, Scratch_Share);
Thread_Context *tctx = app->tctx;
Scratch_Block scratch(app->tctx, Scratch_Share);
String_Const_u8 name = push_string_copy(scratch, file_name);
save_file_to_name(models, file, name.str);
save_file_to_name(tctx, models, file, name.str);
result = true;
}
}
@ -784,15 +778,16 @@ buffer_kill(Application_Links *app, Buffer_ID buffer_id, Buffer_Kill_Flag flags)
if (!file->settings.never_kill){
b32 needs_to_save = file_needs_save(file);
if (!needs_to_save || (flags & BufferKill_AlwaysKill) != 0){
Thread_Context *tctx = app->tctx;
if (models->end_buffer != 0){
models->end_buffer(&models->app_links, file->id);
models->end_buffer(app, file->id);
}
buffer_unbind_name_low_level(working_set, file);
if (file->canon.name_size != 0){
buffer_unbind_file(working_set, file);
}
file_free(models, file);
file_free(tctx, models, file);
working_set_free_file(&models->heap, working_set, file);
Layout *layout = &models->layout;
@ -807,7 +802,7 @@ buffer_kill(Application_Links *app, Buffer_ID buffer_id, Buffer_Kill_Flag flags)
Assert(file_node != order);
view->file = 0;
Editing_File *new_file = CastFromMember(Editing_File, touch_node, file_node);
view_set_file(models, view, new_file);
view_set_file(tctx, models, view, new_file);
file_node = file_node->next;
if (file_node == order){
file_node = file_node->next;
@ -833,7 +828,8 @@ api(custom) function Buffer_Reopen_Result
buffer_reopen(Application_Links *app, Buffer_ID buffer_id, Buffer_Reopen_Flag flags)
{
Models *models = (Models*)app->cmd_context;
Scratch_Block scratch(models->tctx, Scratch_Share);
Thread_Context *tctx = app->tctx;
Scratch_Block scratch(tctx, Scratch_Share);
Editing_File *file = imp_get_file(models, buffer_id);
Buffer_Reopen_Result result = BufferReopenResult_Failed;
if (api_check_buffer(file)){
@ -872,18 +868,18 @@ buffer_reopen(Application_Links *app, Buffer_ID buffer_id, Buffer_Reopen_Flag fl
}
Working_Set *working_set = &models->working_set;
file_free(models, file);
file_free(tctx, models, file);
working_set_file_default_settings(working_set, file);
file_create_from_string(models, file, SCu8(file_memory, attributes.size), attributes);
file_create_from_string(tctx, models, file, SCu8(file_memory, attributes.size), attributes);
for (i32 i = 0; i < vptr_count; ++i){
view_set_file(models, vptrs[i], file);
view_set_file(tctx, models, vptrs[i], file);
vptrs[i]->file = file;
i64 line = line_numbers[i];
i64 col = column_numbers[i];
Buffer_Cursor cursor = file_compute_cursor(file, seek_line_col(line, col));
view_set_cursor(models, vptrs[i], cursor.pos);
view_set_cursor(tctx, models, vptrs[i], cursor.pos);
}
result = BufferReopenResult_Reopened;
}
@ -916,7 +912,7 @@ api(custom) function File_Attributes
get_file_attributes(Application_Links *app, String_Const_u8 file_name)
{
Models *models = (Models*)app->cmd_context;
Scratch_Block scratch(models->tctx, Scratch_Share);
Scratch_Block scratch(app->tctx, Scratch_Share);
return(system_quick_file_attributes(scratch, file_name));
}
@ -1169,7 +1165,7 @@ panel_split(Application_Links *app, Panel_ID panel_id, Dimension split_dim){
Live_Views *live_set = &models->live_set;
View *new_view = live_set_alloc_view(&models->lifetime_allocator,
live_set, new_panel);
view_init(models, new_view, models->scratch_buffer,
view_init(app->tctx, models, new_view, models->scratch_buffer,
models->view_event_handler);
result = true;
}
@ -1318,7 +1314,7 @@ view_get_buffer_region(Application_Links *app, View_ID view_id){
View *view = imp_get_view(models, view_id);
Rect_f32 result = {};
if (api_check_view(view)){
result = view_get_buffer_rect(models, view);
result = view_get_buffer_rect(app->tctx, models, view);
}
return(result);
}
@ -1463,7 +1459,7 @@ view_set_cursor(Application_Links *app, View_ID view_id, Buffer_Seek seek)
Assert(file != 0);
if (api_check_buffer(file)){
Buffer_Cursor cursor = file_compute_cursor(file, seek);
view_set_cursor(models, view, cursor.pos);
view_set_cursor(app->tctx, models, view, cursor.pos);
result = true;
}
}
@ -1478,15 +1474,16 @@ view_set_buffer_scroll(Application_Links *app, View_ID view_id, Buffer_Scroll sc
b32 result = false;
View *view = imp_get_view(models, view_id);
if (api_check_view(view)){
scroll.position = view_normalize_buffer_point(models, view, scroll.position);
scroll.target = view_normalize_buffer_point(models, view, scroll.target);
Thread_Context *tctx = app->tctx;
scroll.position = view_normalize_buffer_point(tctx, models, view, scroll.position);
scroll.target = view_normalize_buffer_point(tctx, models, view, scroll.target);
scroll.target.pixel_shift.x = f32_round32(scroll.target.pixel_shift.x);
scroll.target.pixel_shift.y = f32_round32(scroll.target.pixel_shift.y);
scroll.target.pixel_shift.x = clamp_bot(0.f, scroll.target.pixel_shift.x);
Buffer_Layout_Item_List line = view_get_line_layout(models, view, scroll.target.line_number);
Buffer_Layout_Item_List line = view_get_line_layout(tctx, models, view, scroll.target.line_number);
scroll.target.pixel_shift.y = clamp(0.f, scroll.target.pixel_shift.y, line.height);
if (rule == SetBufferScroll_SnapCursorIntoView){
view_set_scroll(models, view, scroll);
view_set_scroll(tctx, models, view, scroll);
}
else{
File_Edit_Positions edit_pos = view_get_edit_pos(view);
@ -1533,7 +1530,7 @@ view_set_buffer(Application_Links *app, View_ID view_id, Buffer_ID buffer_id, Se
Editing_File *file = working_set_get_file(&models->working_set, buffer_id);
if (api_check_buffer(file)){
if (file != view->file){
view_set_file(models, view, file);
view_set_file(app->tctx, models, view, file);
if (!(flags & SetBuffer_KeepOriginalGUI)){
//view_quit_ui(models, view);
// TODO(allen): back to base context
@ -1704,7 +1701,7 @@ get_managed_scope_with_multiple_dependencies(Application_Links *app, Managed_Sco
Models *models = (Models*)app->cmd_context;
Lifetime_Allocator *lifetime_allocator = &models->lifetime_allocator;
Scratch_Block scratch(models->tctx, Scratch_Share);
Scratch_Block scratch(app->tctx, Scratch_Share);
// TODO(allen): revisit this
struct Node_Ptr{
@ -2026,9 +2023,11 @@ api(custom) function User_Input
get_next_input(Application_Links *app, Event_Property get_properties, Event_Property abort_properties)
{
Models *models = (Models*)app->cmd_context;
Thread_Context *tctx = app->tctx;
Thread_Context_Extra_Info *tctx_info = (Thread_Context_Extra_Info*)tctx->user_data;
User_Input result = {};
if (app->type_coroutine == Co_View){
Coroutine *coroutine = (Coroutine*)app->current_coroutine;
if (tctx_info->coroutine != 0){
Coroutine *coroutine = (Coroutine*)tctx_info->coroutine;
if (coroutine != 0){
Co_Out *out = (Co_Out*)coroutine->out;
out->request = CoRequest_None;
@ -2210,8 +2209,8 @@ print_message(Application_Links *app, String_Const_u8 message)
Editing_File *file = models->message_buffer;
b32 result = false;
if (file != 0){
output_file_append(models, file, message);
file_cursor_to_end(models, file);
output_file_append(app->tctx, models, file, message);
file_cursor_to_end(app->tctx, models, file);
result = true;
}
return(result);
@ -2382,7 +2381,7 @@ buffer_history_set_current_state_index(Application_Links *app, Buffer_ID buffer_
if (api_check_buffer(file) && history_is_activated(&file->state.history)){
i32 max_index = history_get_record_count(&file->state.history);
if (0 <= index && index <= max_index){
edit_change_current_history_state(models, file, index);
edit_change_current_history_state(app->tctx, models, file, index);
result = true;
}
}
@ -2395,7 +2394,7 @@ buffer_history_merge_record_range(Application_Links *app, Buffer_ID buffer_id, H
Editing_File *file = imp_get_file(models, buffer_id);
b32 result = false;
if (api_check_buffer(file)){
result = edit_merge_history_range(models, file, first_index, last_index, flags);
result = edit_merge_history_range(app->tctx, models, file, first_index, last_index, flags);
}
return(result);
}
@ -2499,9 +2498,11 @@ api(custom) function Face_ID
try_create_new_face(Application_Links *app, Face_Description *description)
{
Models *models = (Models*)app->cmd_context;
Thread_Context *tctx = app->tctx;
Thread_Context_Extra_Info *tctx_info = (Thread_Context_Extra_Info*)tctx->user_data;
Face_ID result = 0;
if (is_running_coroutine(app)){
Coroutine *coroutine = (Coroutine*)app->current_coroutine;
if (tctx_info != 0 && tctx_info->coroutine != 0){
Coroutine *coroutine = (Coroutine*)tctx_info->coroutine;
Assert(coroutine != 0);
Co_Out *out = (Co_Out*)coroutine->out;
out->request = CoRequest_NewFontFace;
@ -2510,6 +2511,9 @@ try_create_new_face(Application_Links *app, Face_Description *description)
Co_In *in = (Co_In*)coroutine->in;
result = in->face_id;
}
else if (tctx_info != 0){
// This API does nothing when called from an async thread.
}
else{
Face *new_face = font_set_new_face(&models->font_set, description);
result = new_face->id;
@ -2521,9 +2525,11 @@ api(custom) function b32
try_modify_face(Application_Links *app, Face_ID id, Face_Description *description)
{
Models *models = (Models*)app->cmd_context;
Thread_Context *tctx = app->tctx;
Thread_Context_Extra_Info *tctx_info = (Thread_Context_Extra_Info*)tctx->user_data;
b32 result = false;
if (is_running_coroutine(app)){
Coroutine *coroutine = (Coroutine*)app->current_coroutine;
if (tctx_info != 0 && tctx_info->coroutine != 0){
Coroutine *coroutine = (Coroutine*)tctx_info->coroutine;
Assert(coroutine != 0);
Co_Out *out = (Co_Out*)coroutine->out;
out->request = CoRequest_ModifyFace;
@ -2533,6 +2539,9 @@ try_modify_face(Application_Links *app, Face_ID id, Face_Description *descriptio
Co_In *in = (Co_In*)coroutine->in;
result = in->success;
}
else if (tctx_info != 0){
// This API does nothing when called from an async thread.
}
else{
result = font_set_modify_face(&models->font_set, id, description);
}
@ -2686,8 +2695,9 @@ text_layout_create(Application_Links *app, Buffer_ID buffer_id, Rect_f32 rect, B
Editing_File *file = imp_get_file(models, buffer_id);
Text_Layout_ID result = {};
if (api_check_buffer(file)){
Scratch_Block scratch(app);
Arena *arena = reserve_arena(models->tctx);
Thread_Context *tctx = app->tctx;
Scratch_Block scratch(tctx);
Arena *arena = reserve_arena(tctx);
Face *face = file_get_face(models, file);
Gap_Buffer *buffer = &file->state.buffer;
@ -2699,7 +2709,7 @@ text_layout_create(Application_Links *app, Buffer_ID buffer_id, Rect_f32 rect, B
f32 y = -buffer_point.pixel_shift.y;
for (;line_number <= line_count;
line_number += 1){
Buffer_Layout_Item_List line = file_get_line_layout(models, file, dim.x, face, line_number);
Buffer_Layout_Item_List line = file_get_line_layout(tctx, models, file, dim.x, face, line_number);
f32 next_y = y + line.height;
if (next_y >= dim.y){
break;
@ -2772,7 +2782,7 @@ text_layout_line_on_screen(Application_Links *app, Text_Layout_ID layout_id, i64
for (i64 line_number_it = layout->visible_line_number_range.first;;
line_number_it += 1){
Buffer_Layout_Item_List line = file_get_line_layout(models, file, width, face, line_number_it);
Buffer_Layout_Item_List line = file_get_line_layout(app->tctx, models, file, width, face, line_number_it);
result.max += line.height;
if (line_number_it == line_number){
break;
@ -2813,7 +2823,7 @@ text_layout_character_on_screen(Application_Links *app, Text_Layout_ID layout_id
Buffer_Layout_Item_List line = {};
for (i64 line_number_it = layout->visible_line_number_range.first;;
line_number_it += 1){
line = file_get_line_layout(models, file, width, face, line_number_it);
line = file_get_line_layout(app->tctx, models, file, width, face, line_number_it);
if (line_number_it == line_number){
break;
}
@ -2871,7 +2881,7 @@ paint_text_color(Application_Links *app, Text_Layout_ID layout_id, Interval_i64
api(custom) function b32
text_layout_free(Application_Links *app, Text_Layout_ID text_layout_id){
Models *models = (Models*)app->cmd_context;
return(text_layout_erase(models, &models->text_layouts, text_layout_id));
return(text_layout_erase(app->tctx, models, &models->text_layouts, text_layout_id));
}
api(custom) function void
@ -2879,7 +2889,7 @@ draw_text_layout(Application_Links *app, Text_Layout_ID layout_id){
Models *models = (Models*)app->cmd_context;
Text_Layout *layout = text_layout_get(&models->text_layouts, layout_id);
if (layout != 0 && models->target != 0){
text_layout_render(models, layout);
text_layout_render(app->tctx, models, layout);
}
}

View File

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

View File

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

View File

@ -98,9 +98,9 @@ child_process_lookup_return_code(Child_Process_Container *container, Child_Proce
////////////////////////////////
internal b32
child_process_call(Models *models, String_Const_u8 path, String_Const_u8 command, Child_Process_ID *id_out){
child_process_call(Thread_Context *tctx, Models *models, String_Const_u8 path, String_Const_u8 command, Child_Process_ID *id_out){
b32 result = false;
Scratch_Block scratch(&models->app_links);
Scratch_Block scratch(tctx);
String_Const_u8 path_n = push_string_copy(scratch, path);
String_Const_u8 command_n = push_string_copy(scratch, command);
CLI_Handles cli_handles = {};

View File

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

View File

@ -67,6 +67,7 @@ internal void
lifetime_allocator_init(Base_Allocator *base_allocator, Lifetime_Allocator *lifetime_allocator){
block_zero_struct(lifetime_allocator);
lifetime_allocator->allocator = base_allocator;
lifetime_allocator->node_arena = make_arena(base_allocator, KB(4));
lifetime_allocator->key_table = make_table_Data_u64(base_allocator, 100);
lifetime_allocator->key_check_table = make_table_u64_u64(base_allocator, 100);
lifetime_allocator->scope_id_to_scope_ptr_table = make_table_u64_u64(base_allocator, 100);
@ -250,26 +251,15 @@ lifetime__object_add_key(Lifetime_Allocator *lifetime_allocator, Lifetime_Object
internal Lifetime_Object*
lifetime_alloc_object(Lifetime_Allocator *lifetime_allocator, i32 user_type, void *user_back_ptr){
Lifetime_Object *object = lifetime_allocator->free_objects.first;
Lifetime_Object *object = lifetime_allocator->free_objects;
if (object == 0){
i32 new_object_count = 256;
umem new_memory_size = new_object_count*sizeof(Lifetime_Object);
Data new_memory = base_allocate(lifetime_allocator->allocator, new_memory_size);
Lifetime_Object *new_objects = (Lifetime_Object*)new_memory.data;
Lifetime_Object *new_object_ptr = new_objects;
for (i32 i = 0; i < new_object_count; i += 1, new_object_ptr += 1){
zdll_push_back(lifetime_allocator->free_objects.first, lifetime_allocator->free_objects.last, new_object_ptr);
}
lifetime_allocator->free_objects.count += new_object_count;
object = lifetime_allocator->free_objects.first;
object = push_array(&lifetime_allocator->node_arena, Lifetime_Object, 1);
}
else{
sll_stack_pop(lifetime_allocator->free_objects);
}
zdll_remove(lifetime_allocator->free_objects.first, lifetime_allocator->free_objects.last, object);
lifetime_allocator->free_objects.count -= 1;
block_zero_struct(object);
dynamic_workspace_init(lifetime_allocator, user_type, user_back_ptr, &object->workspace);
return(object);
}
@ -313,7 +303,7 @@ internal void
lifetime_free_object(Lifetime_Allocator *lifetime_allocator, Lifetime_Object *lifetime_object){
lifetime__object_free_all_keys(lifetime_allocator, lifetime_object);
dynamic_workspace_free(lifetime_allocator, &lifetime_object->workspace);
zdll_push_back(lifetime_allocator->free_objects.first, lifetime_allocator->free_objects.last, lifetime_object);
sll_stack_push(lifetime_allocator->free_objects, lifetime_object);
}
internal void

View File

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

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
edit_fix_markers(Models *models, Editing_File *file, Edit edit){
edit_fix_markers(Thread_Context *tctx, Models *models, Editing_File *file, Edit edit){
Layout *layout = &models->layout;
Lifetime_Object *file_lifetime_object = file->lifetime_object;
@ -97,7 +97,7 @@ edit_fix_markers(Models *models, Editing_File *file, Edit edit){
}
cursor_max += total_marker_count;
Scratch_Block scratch(models->tctx, Scratch_Share);
Scratch_Block scratch(tctx, Scratch_Share);
Cursor_With_Index *cursors = push_array(scratch, Cursor_With_Index, cursor_max);
Cursor_With_Index *r_cursors = push_array(scratch, Cursor_With_Index, cursor_max);
@ -155,7 +155,7 @@ edit_fix_markers(Models *models, Editing_File *file, Edit edit){
i64 cursor_pos = cursors[cursor_count++].pos;
view->mark = cursors[cursor_count++].pos;
File_Edit_Positions edit_pos = view_get_edit_pos(view);
view_set_cursor_and_scroll(models, view, cursor_pos, edit_pos.scroll);
view_set_cursor_and_scroll(tctx, models, view, cursor_pos, edit_pos.scroll);
// TODO(allen): read a cursor for the current scroll line
}
}
@ -178,7 +178,7 @@ edit_fix_markers(Models *models, Editing_File *file, Edit edit){
}
internal void
edit_single(Models *models, Editing_File *file, Interval_i64 range, String_Const_u8 string, Edit_Behaviors behaviors){
edit_single(Thread_Context *tctx, Models *models, Editing_File *file, Interval_i64 range, String_Const_u8 string, Edit_Behaviors behaviors){
Edit edit = {};
edit.text = string;
edit.range = range;
@ -188,7 +188,7 @@ edit_single(Models *models, Editing_File *file, Interval_i64 range, String_Const
Assert(edit.range.first <= edit.range.one_past_last);
Assert(edit.range.one_past_last <= buffer_size(buffer));
Scratch_Block scratch(models->tctx, Scratch_Share);
Scratch_Block scratch(tctx, Scratch_Share);
// NOTE(allen): history update
if (!behaviors.do_not_post_to_history){
@ -223,19 +223,25 @@ edit_single(Models *models, Editing_File *file, Interval_i64 range, String_Const
buffer_remeasure_starts(scratch, buffer, Ii64(line_start, line_end + 1), line_shift, shift_amount);
// NOTE(allen): cursor fixing
edit_fix_markers(models, file, edit);
edit_fix_markers(tctx, models, file, edit);
// NOTE(allen): edit range hook
if (models->buffer_edit_range != 0){
Interval_i64 new_range = Ii64(edit.range.first, edit.range.first + edit.text.size);
models->buffer_edit_range(&models->app_links, file->id, new_range, original_text);
Application_Links app = {};
app.tctx = tctx;;
app.cmd_context = models;
models->buffer_edit_range(&app, file->id, new_range, original_text);
}
}
internal void
file_end_file(Models *models, Editing_File *file){
file_end_file(Thread_Context *tctx, Models *models, Editing_File *file){
if (models->end_buffer != 0){
models->end_buffer(&models->app_links, file->id);
Application_Links app = {};
app.tctx = tctx;
app.cmd_context = models;
models->end_buffer(&app, file->id);
}
Lifetime_Allocator *lifetime_allocator = &models->lifetime_allocator;
lifetime_free_object(lifetime_allocator, file->lifetime_object);
@ -243,7 +249,7 @@ file_end_file(Models *models, Editing_File *file){
}
internal void
edit__apply_record_forward(Models *models, Editing_File *file, Record *record, Edit_Behaviors behaviors_prototype){
edit__apply_record_forward(Thread_Context *tctx, Models *models, Editing_File *file, Record *record, Edit_Behaviors behaviors_prototype){
// NOTE(allen): // NOTE(allen): // NOTE(allen): // NOTE(allen): // NOTE(allen):
// Whenever you change this also change the backward version!
@ -252,7 +258,7 @@ edit__apply_record_forward(Models *models, Editing_File *file, Record *record, E
{
String_Const_u8 str = record->single.forward_text;
Interval_i64 range = Ii64(record->single.first, record->single.first + record->single.backward_text.size);
edit_single(models, file, range, str, behaviors_prototype);
edit_single(tctx, models, file, range, str, behaviors_prototype);
}break;
case RecordKind_Group:
@ -262,7 +268,7 @@ edit__apply_record_forward(Models *models, Editing_File *file, Record *record, E
node != sentinel;
node = node->next){
Record *sub_record = CastFromMember(Record, node, node);
edit__apply_record_forward(models, file, sub_record, behaviors_prototype);
edit__apply_record_forward(tctx, models, file, sub_record, behaviors_prototype);
}
}break;
@ -274,7 +280,7 @@ edit__apply_record_forward(Models *models, Editing_File *file, Record *record, E
}
internal void
edit__apply_record_backward(Models *models, Editing_File *file, Record *record, Edit_Behaviors behaviors_prototype){
edit__apply_record_backward(Thread_Context *tctx, Models *models, Editing_File *file, Record *record, Edit_Behaviors behaviors_prototype){
// NOTE(allen): // NOTE(allen): // NOTE(allen): // NOTE(allen): // NOTE(allen):
// Whenever you change this also change the forward version!
@ -283,7 +289,7 @@ edit__apply_record_backward(Models *models, Editing_File *file, Record *record,
{
String_Const_u8 str = record->single.backward_text;
Interval_i64 range = Ii64(record->single.first, record->single.first + record->single.forward_text.size);
edit_single(models, file, range, str, behaviors_prototype);
edit_single(tctx, models, file, range, str, behaviors_prototype);
}break;
case RecordKind_Group:
@ -293,7 +299,7 @@ edit__apply_record_backward(Models *models, Editing_File *file, Record *record,
node != sentinel;
node = node->prev){
Record *sub_record = CastFromMember(Record, node, node);
edit__apply_record_backward(models, file, sub_record, behaviors_prototype);
edit__apply_record_backward(tctx, models, file, sub_record, behaviors_prototype);
}
}break;
@ -305,7 +311,7 @@ edit__apply_record_backward(Models *models, Editing_File *file, Record *record,
}
internal void
edit_change_current_history_state(Models *models, Editing_File *file, i32 target_index){
edit_change_current_history_state(Thread_Context *tctx, Models *models, Editing_File *file, i32 target_index){
History *history = &file->state.history;
if (history->activated && file->state.current_record_index != target_index){
Assert(0 <= target_index && target_index <= history->record_count);
@ -323,13 +329,13 @@ edit_change_current_history_state(Models *models, Editing_File *file, i32 target
current += 1;
record = CastFromMember(Record, node, record->node.next);
Assert(record != dummy_record);
edit__apply_record_forward(models, file, record, behaviors_prototype);
edit__apply_record_forward(tctx, models, file, record, behaviors_prototype);
} while (current != target_index);
}
else{
do{
Assert(record != dummy_record);
edit__apply_record_backward(models, file, record, behaviors_prototype);
edit__apply_record_backward(tctx, models, file, record, behaviors_prototype);
current -= 1;
record = CastFromMember(Record, node, record->node.prev);
} while (current != target_index);
@ -340,7 +346,7 @@ edit_change_current_history_state(Models *models, Editing_File *file, i32 target
}
internal b32
edit_merge_history_range(Models *models, Editing_File *file, History_Record_Index first_index, History_Record_Index last_index, Record_Merge_Flag flags){
edit_merge_history_range(Thread_Context *tctx, Models *models, Editing_File *file, History_Record_Index first_index, History_Record_Index last_index, Record_Merge_Flag flags){
b32 result = false;
History *history = &file->state.history;
if (history_is_activated(history)){
@ -354,13 +360,13 @@ edit_merge_history_range(Models *models, Editing_File *file, History_Record_Inde
switch (in_range_handler){
case RecordMergeFlag_StateInRange_MoveStateForward:
{
edit_change_current_history_state(models, file, last_index);
edit_change_current_history_state(tctx, models, file, last_index);
current_index = last_index;
}break;
case RecordMergeFlag_StateInRange_MoveStateBackward:
{
edit_change_current_history_state(models, file, first_index);
edit_change_current_history_state(tctx, models, file, first_index);
current_index = first_index;
}break;
@ -370,7 +376,7 @@ edit_merge_history_range(Models *models, Editing_File *file, History_Record_Inde
}break;
}
}
Scratch_Block scratch(models->tctx, Scratch_Share);
Scratch_Block scratch(tctx, Scratch_Share);
history_merge_records(scratch, history, first_index, last_index);
if (current_index >= last_index){
current_index -= (last_index - first_index);
@ -385,7 +391,7 @@ edit_merge_history_range(Models *models, Editing_File *file, History_Record_Inde
}
internal b32
edit_batch(Models *models, Editing_File *file, Batch_Edit *batch, Edit_Behaviors behaviors){
edit_batch(Thread_Context *tctx, Models *models, Editing_File *file, Batch_Edit *batch, Edit_Behaviors behaviors){
b32 result = true;
if (batch != 0){
History_Record_Index start_index = 0;
@ -405,7 +411,7 @@ edit_batch(Models *models, Editing_File *file, Batch_Edit *batch, Edit_Behaviors
if (0 <= edit_range.first &&
edit_range.first <= edit_range.one_past_last &&
edit_range.one_past_last <= size){
edit_single(models, file, edit_range, insert_string, behaviors);
edit_single(tctx, models, file, edit_range, insert_string, behaviors);
shift += replace_range_shift(edit_range, insert_string.size);
}
else{
@ -417,7 +423,7 @@ edit_batch(Models *models, Editing_File *file, Batch_Edit *batch, Edit_Behaviors
if (history_is_activated(&file->state.history)){
History_Record_Index last_index = file->state.current_record_index;
if (start_index + 1 < last_index){
edit_merge_history_range(models, file, start_index + 1, last_index, RecordMergeFlag_StateInRange_ErrorOut);
edit_merge_history_range(tctx, models, file, start_index + 1, last_index, RecordMergeFlag_StateInRange_ErrorOut);
}
}
}
@ -427,14 +433,14 @@ edit_batch(Models *models, Editing_File *file, Batch_Edit *batch, Edit_Behaviors
////////////////////////////////
internal Editing_File*
create_file(Models *models, String_Const_u8 file_name, Buffer_Create_Flag flags){
create_file(Thread_Context *tctx, Models *models, String_Const_u8 file_name, Buffer_Create_Flag flags){
Editing_File *result = 0;
if (file_name.size > 0){
Working_Set *working_set = &models->working_set;
Heap *heap = &models->heap;
Scratch_Block scratch(models->tctx);
Scratch_Block scratch(tctx);
Editing_File *file = 0;
b32 do_empty_buffer = false;
@ -487,9 +493,9 @@ create_file(Models *models, String_Const_u8 file_name, Buffer_Create_Flag flags)
file_bind_file_name(working_set, file, string_from_file_name(&canon));
}
String_Const_u8 front = string_front_of_path(file_name);
buffer_bind_name(models, scratch, working_set, file, front);
buffer_bind_name(tctx, models, scratch, working_set, file, front);
File_Attributes attributes = {};
file_create_from_string(models, file, SCu8(""), attributes);
file_create_from_string(tctx, models, file, SCu8(""), attributes);
result = file;
}
}
@ -511,8 +517,8 @@ create_file(Models *models, String_Const_u8 file_name, Buffer_Create_Flag flags)
if (file != 0){
file_bind_file_name(working_set, file, string_from_file_name(&canon));
String_Const_u8 front = string_front_of_path(file_name);
buffer_bind_name(models, scratch, working_set, file, front);
file_create_from_string(models, file, SCu8(buffer, (i32)attributes.size), attributes);
buffer_bind_name(tctx, models, scratch, working_set, file, front);
file_create_from_string(tctx, models, file, SCu8(buffer, (i32)attributes.size), attributes);
result = file;
}
}
@ -537,7 +543,7 @@ create_file(Models *models, String_Const_u8 file_name, Buffer_Create_Flag flags)
i64 size = buffer_size(&file->state.buffer);
if (size > 0){
Edit_Behaviors behaviors = {};
edit_single(models, file, Ii64(0, size), string_u8_litexpr(""), behaviors);
edit_single(tctx, models, file, Ii64(0, size), string_u8_litexpr(""), behaviors);
if (has_canon_name){
buffer_is_for_new_file = true;
}
@ -547,7 +553,10 @@ create_file(Models *models, String_Const_u8 file_name, Buffer_Create_Flag flags)
if (file != 0 && buffer_is_for_new_file &&
!HasFlag(flags, BufferCreate_SuppressNewFileHook) &&
models->new_file != 0){
models->new_file(&models->app_links, file->id);
Application_Links app = {};
app.tctx = tctx;
app.cmd_context = models;
models->new_file(&app, file->id);
}
}

View File

@ -137,7 +137,7 @@ file_name_terminate(Editing_File_Name *name){
// TODO(allen): file_name should be String_Const_u8
internal b32
save_file_to_name(Models *models, Editing_File *file, u8 *file_name){
save_file_to_name(Thread_Context *tctx, Models *models, Editing_File *file, u8 *file_name){
b32 result = false;
b32 using_actual_file_name = false;
@ -149,13 +149,16 @@ save_file_to_name(Models *models, Editing_File *file, u8 *file_name){
if (file_name != 0){
if (models->save_file != 0){
models->save_file(&models->app_links, file->id);
Application_Links app = {};
app.tctx = tctx;
app.cmd_context = models;
models->save_file(&app, file->id);
}
Gap_Buffer *buffer = &file->state.buffer;
b32 dos_write_mode = file->settings.dos_write_mode;
Scratch_Block scratch(models->tctx, Scratch_Share);
Scratch_Block scratch(tctx, Scratch_Share);
if (!using_actual_file_name){
String_Const_u8 s_file_name = SCu8(file_name);
@ -181,8 +184,8 @@ save_file_to_name(Models *models, Editing_File *file, u8 *file_name){
}
internal b32
save_file(Models *models, Editing_File *file){
return(save_file_to_name(models, file, 0));
save_file(Thread_Context *tctx, Models *models, Editing_File *file){
return(save_file_to_name(tctx, models, file, 0));
}
////////////////////////////////
@ -206,8 +209,7 @@ file_compute_cursor(Editing_File *file, Buffer_Seek seek){
////////////////////////////////
internal void
file_create_from_string(Models *models, Editing_File *file, String_Const_u8 val, File_Attributes attributes){
Thread_Context *tctx = models->tctx;
file_create_from_string(Thread_Context *tctx, Models *models, Editing_File *file, String_Const_u8 val, File_Attributes attributes){
Scratch_Block scratch(tctx, Scratch_Share);
Base_Allocator *allocator = tctx->allocator;
@ -225,7 +227,7 @@ file_create_from_string(Models *models, Editing_File *file, String_Const_u8 val,
buffer_measure_starts(scratch, &file->state.buffer);
file->lifetime_object = lifetime_alloc_object(&models->lifetime_allocator, DynamicWorkspace_Buffer, file);
history_init(models, &file->state.history);
history_init(tctx, models, &file->state.history);
file->state.cached_layouts_arena = make_arena(allocator);
file->state.line_layout_table = make_table_Data_u64(allocator, 500);
@ -245,12 +247,15 @@ file_create_from_string(Models *models, Editing_File *file, String_Const_u8 val,
////////////////////////////////
if (models->begin_buffer != 0){
models->begin_buffer(&models->app_links, file->id);
Application_Links app = {};
app.tctx = tctx;
app.cmd_context = models;
models->begin_buffer(&app, file->id);
}
}
internal void
file_free(Models *models, Editing_File *file){
file_free(Thread_Context *tctx, Models *models, Editing_File *file){
Lifetime_Allocator *lifetime_allocator = &models->lifetime_allocator;
Working_Set *working_set = &models->working_set;
@ -262,7 +267,7 @@ file_free(Models *models, Editing_File *file){
base_free(buffer->allocator, buffer->line_starts);
}
history_free(models, &file->state.history);
history_free(tctx, &file->state.history);
linalloc_clear(&file->state.cached_layouts_arena);
table_free(&file->state.line_layout_table);
@ -288,7 +293,7 @@ file_get_managed_scope(Editing_File *file){
////////////////////////////////
internal Buffer_Layout_Item_List
file_get_line_layout(Models *models, Editing_File *file, f32 width, Face *face, i64 line_number){
file_get_line_layout(Thread_Context *tctx, Models *models, Editing_File *file, f32 width, Face *face, i64 line_number){
Buffer_Layout_Item_List result = {};
i64 line_count = buffer_line_count(&file->state.buffer);
@ -312,7 +317,7 @@ file_get_line_layout(Models *models, Editing_File *file, f32 width, Face *face,
else{
list = push_array(&file->state.cached_layouts_arena, Buffer_Layout_Item_List, 1);
Interval_i64 line_range = buffer_get_pos_range_from_line_number(&file->state.buffer, line_number);
*list = buffer_layout(models->tctx, &file->state.cached_layouts_arena,
*list = buffer_layout(tctx, &file->state.cached_layouts_arena,
&file->state.buffer, line_range, face, width);
key_data = push_data_copy(&file->state.cached_layouts_arena, key_data);
table_insert(&file->state.line_layout_table, key_data, (u64)PtrAsInt(list));
@ -330,7 +335,7 @@ file_clear_layout_cache(Editing_File *file){
}
internal Line_Shift_Vertical
file_line_shift_y(Models *models, Editing_File *file, f32 width, Face *face, i64 line_number, f32 y_delta){
file_line_shift_y(Thread_Context *tctx, Models *models, Editing_File *file, f32 width, Face *face, i64 line_number, f32 y_delta){
Line_Shift_Vertical result = {};
f32 line_y = 0.f;
@ -350,7 +355,7 @@ file_line_shift_y(Models *models, Editing_File *file, f32 width, Face *face, i64
line_number = 1;
break;
}
Buffer_Layout_Item_List line = file_get_line_layout(models, file, width, face, line_number);
Buffer_Layout_Item_List line = file_get_line_layout(tctx, models, file, width, face, line_number);
line_y -= line.height;
}
if (!has_result){
@ -363,7 +368,7 @@ file_line_shift_y(Models *models, Editing_File *file, f32 width, Face *face, i64
b32 has_result = false;
i64 line_count = buffer_line_count(&file->state.buffer);
for (;;line_number += 1){
Buffer_Layout_Item_List line = file_get_line_layout(models, file, width, face, line_number);
Buffer_Layout_Item_List line = file_get_line_layout(tctx, models, file, width, face, line_number);
f32 next_y = line_y + line.height;
if (y_delta < next_y){
has_result = true;
@ -386,12 +391,12 @@ file_line_shift_y(Models *models, Editing_File *file, f32 width, Face *face, i64
}
internal f32
file_line_y_difference(Models *models, Editing_File *file, f32 width, Face *face, i64 line_a, i64 line_b){
file_line_y_difference(Thread_Context *tctx, Models *models, Editing_File *file, f32 width, Face *face, i64 line_a, i64 line_b){
f32 result = 0.f;
if (line_a != line_b){
Interval_i64 line_range = Ii64(line_a, line_b);
for (i64 i = line_range.min; i < line_range.max; i += 1){
Buffer_Layout_Item_List line = file_get_line_layout(models, file, width, face, i);
Buffer_Layout_Item_List line = file_get_line_layout(tctx, models, file, width, face, i);
result += line.height;
}
if (line_a < line_b){
@ -402,25 +407,25 @@ file_line_y_difference(Models *models, Editing_File *file, f32 width, Face *face
}
internal i64
file_pos_at_relative_xy(Models *models, Editing_File *file, f32 width, Face *face, i64 base_line, Vec2_f32 relative_xy){
Line_Shift_Vertical shift = file_line_shift_y(models, file, width, face, base_line, relative_xy.y);
file_pos_at_relative_xy(Thread_Context *tctx, Models *models, Editing_File *file, f32 width, Face *face, i64 base_line, Vec2_f32 relative_xy){
Line_Shift_Vertical shift = file_line_shift_y(tctx, models, file, width, face, base_line, relative_xy.y);
relative_xy.y -= shift.y_delta;
Buffer_Layout_Item_List line = file_get_line_layout(models, file, width, face, shift.line);
Buffer_Layout_Item_List line = file_get_line_layout(tctx, models, file, width, face, shift.line);
return(buffer_layout_nearest_pos_to_xy(line, relative_xy));
}
internal Vec2_f32
file_relative_xy_of_pos(Models *models, Editing_File *file, f32 width, Face *face, i64 base_line, i64 pos){
file_relative_xy_of_pos(Thread_Context *tctx, Models *models, Editing_File *file, f32 width, Face *face, i64 base_line, i64 pos){
i64 line_number = buffer_get_line_index(&file->state.buffer, pos) + 1;
Buffer_Layout_Item_List line = file_get_line_layout(models, file, width, face, line_number);
Buffer_Layout_Item_List line = file_get_line_layout(tctx, models, file, width, face, line_number);
Vec2_f32 result = buffer_layout_xy_center_of_pos(line, pos);
result.y += file_line_y_difference(models, file, width, face, line_number, base_line);
result.y += file_line_y_difference(tctx, models, file, width, face, line_number, base_line);
return(result);
}
internal Buffer_Point
file_normalize_buffer_point(Models *models, Editing_File *file, f32 width, Face *face, Buffer_Point point){
Line_Shift_Vertical shift = file_line_shift_y(models, file, width, face, point.line_number, point.pixel_shift.y);
file_normalize_buffer_point(Thread_Context *tctx, Models *models, Editing_File *file, f32 width, Face *face, Buffer_Point point){
Line_Shift_Vertical shift = file_line_shift_y(tctx, models, file, width, face, point.line_number, point.pixel_shift.y);
point.line_number = shift.line;
point.pixel_shift.y -= shift.y_delta;
point.pixel_shift.x = clamp_bot(0.f, point.pixel_shift.x);
@ -429,15 +434,15 @@ file_normalize_buffer_point(Models *models, Editing_File *file, f32 width, Face
}
internal Vec2_f32
file_buffer_point_difference(Models *models, Editing_File *file, f32 width, Face *face, Buffer_Point a, Buffer_Point b){
f32 y_difference = file_line_y_difference(models, file, width, face, a.line_number, b.line_number);
file_buffer_point_difference(Thread_Context *tctx, Models *models, Editing_File *file, f32 width, Face *face, Buffer_Point a, Buffer_Point b){
f32 y_difference = file_line_y_difference(tctx, models, file, width, face, a.line_number, b.line_number);
Vec2_f32 result = a.pixel_shift - b.pixel_shift;
result.y += y_difference;
return(result);
}
internal Line_Shift_Character
file_line_shift_characters(Models *models, Editing_File *file, f32 width, Face *face, i64 line_number, i64 character_delta){
file_line_shift_characters(Thread_Context *tctx, Models *models, Editing_File *file, f32 width, Face *face, i64 line_number, i64 character_delta){
Line_Shift_Character result = {};
i64 line_character = 0;
@ -457,7 +462,7 @@ file_line_shift_characters(Models *models, Editing_File *file, f32 width, Face *
line_number = 1;
break;
}
Buffer_Layout_Item_List line = file_get_line_layout(models, file, width, face, line_number);
Buffer_Layout_Item_List line = file_get_line_layout(tctx, models, file, width, face, line_number);
line_character -= line.character_count;
}
if (!has_result){
@ -470,7 +475,7 @@ file_line_shift_characters(Models *models, Editing_File *file, f32 width, Face *
b32 has_result = false;
i64 line_count = buffer_line_count(&file->state.buffer);
for (;;line_number += 1){
Buffer_Layout_Item_List line = file_get_line_layout(models, file, width, face, line_number);
Buffer_Layout_Item_List line = file_get_line_layout(tctx, models, file, width, face, line_number);
i64 next_character = line_character + line.character_count;
if (character_delta < next_character){
has_result = true;
@ -493,12 +498,12 @@ file_line_shift_characters(Models *models, Editing_File *file, f32 width, Face *
}
internal i64
file_line_character_difference(Models *models, Editing_File *file, f32 width, Face *face, i64 line_a, i64 line_b){
file_line_character_difference(Thread_Context *tctx, Models *models, Editing_File *file, f32 width, Face *face, i64 line_a, i64 line_b){
i64 result = 0;
if (line_a != line_b){
Interval_i64 line_range = Ii64(line_a, line_b);
for (i64 i = line_range.min; i < line_range.max; i += 1){
Buffer_Layout_Item_List line = file_get_line_layout(models, file, width, face, i);
Buffer_Layout_Item_List line = file_get_line_layout(tctx, models, file, width, face, i);
result += line.character_count;
}
if (line_a < line_b){
@ -509,19 +514,19 @@ file_line_character_difference(Models *models, Editing_File *file, f32 width, Fa
}
internal i64
file_pos_from_relative_character(Models *models, Editing_File *file, f32 width, Face *face, i64 base_line, i64 relative_character){
Line_Shift_Character shift = file_line_shift_characters(models, file, width, face, base_line, relative_character);
file_pos_from_relative_character(Thread_Context *tctx, Models *models, Editing_File *file, f32 width, Face *face, i64 base_line, i64 relative_character){
Line_Shift_Character shift = file_line_shift_characters(tctx, models, file, width, face, base_line, relative_character);
relative_character -= shift.character_delta;
Buffer_Layout_Item_List line = file_get_line_layout(models, file, width, face, shift.line);
Buffer_Layout_Item_List line = file_get_line_layout(tctx, models, file, width, face, shift.line);
return(buffer_layout_get_pos_at_character(line, relative_character));
}
internal i64
file_relative_character_from_pos(Models *models, Editing_File *file, f32 width, Face *face, i64 base_line, i64 pos){
file_relative_character_from_pos(Thread_Context *tctx, Models *models, Editing_File *file, f32 width, Face *face, i64 base_line, i64 pos){
i64 line_number = buffer_get_line_index(&file->state.buffer, pos) + 1;
Buffer_Layout_Item_List line = file_get_line_layout(models, file, width, face, line_number);
Buffer_Layout_Item_List line = file_get_line_layout(tctx, models, file, width, face, line_number);
i64 result = buffer_layout_character_from_pos(line, pos);
result += file_line_character_difference(models, file, width, face, line_number, base_line);
result += file_line_character_difference(tctx, models, file, width, face, line_number, base_line);
return(result);
}

View File

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

View File

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

View File

@ -177,6 +177,16 @@ define_api(Arena *arena){
API_Call *call = api_call(arena, api, "thread_get_id", "i32");
}
{
API_Call *call = api_call(arena, api, "acquire_global_frame_mutex", "void");
api_param(arena, call, "Thread_Context*", "tctx");
}
{
API_Call *call = api_call(arena, api, "release_global_frame_mutex", "void");
api_param(arena, call, "Thread_Context*", "tctx");
}
{
API_Call *call = api_call(arena, api, "mutex_make", "System_Mutex");
}

View File

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

View File

@ -148,12 +148,15 @@ view_set_edit_pos(View *view, File_Edit_Positions edit_pos){
////////////////////////////////
internal Rect_f32
view_get_buffer_rect(Models *models, View *view){
view_get_buffer_rect(Thread_Context *tctx, Models *models, View *view){
Rect_f32 region = Rf32(view->panel->rect_full);
if (models->buffer_region != 0){
Rect_f32 rect = region;
Rect_f32 sub_region = Rf32(V2(0, 0), rect_dim(rect));
sub_region = models->buffer_region(&models->app_links, view_get_id(&models->live_set, view), sub_region);
Application_Links app = {};
app.tctx = tctx;
app.cmd_context = models;
sub_region = models->buffer_region(&app, view_get_id(&models->live_set, view), sub_region);
region.p0 = rect.p0 + sub_region.p0;
region.p1 = rect.p0 + sub_region.p1;
region.x1 = clamp_top(region.x1, rect.x1);
@ -165,112 +168,112 @@ view_get_buffer_rect(Models *models, View *view){
}
internal f32
view_width(Models *models, View *view){
return(rect_width(view_get_buffer_rect(models, view)));
view_width(Thread_Context *tctx, Models *models, View *view){
return(rect_width(view_get_buffer_rect(tctx, models, view)));
}
internal f32
view_height(Models *models, View *view){
return(rect_height(view_get_buffer_rect(models, view)));
view_height(Thread_Context *tctx, Models *models, View *view){
return(rect_height(view_get_buffer_rect(tctx, models, view)));
}
////////////////////////////////
internal Buffer_Layout_Item_List
view_get_line_layout(Models *models, View *view, i64 line_number){
view_get_line_layout(Thread_Context *tctx, Models *models, View *view, i64 line_number){
Editing_File *file = view->file;
Face *face = file_get_face(models, file);
f32 width = view_width(models, view);
return(file_get_line_layout(models, file, width, face, line_number));
f32 width = view_width(tctx, models, view);
return(file_get_line_layout(tctx, models, file, width, face, line_number));
}
internal Line_Shift_Vertical
view_line_shift_y(Models *models, View *view, i64 line_number, f32 y_delta){
view_line_shift_y(Thread_Context *tctx, Models *models, View *view, i64 line_number, f32 y_delta){
Editing_File *file = view->file;
Face *face = file_get_face(models, file);
f32 width = view_width(models, view);
return(file_line_shift_y(models, file, width, face, line_number, y_delta));
f32 width = view_width(tctx, models, view);
return(file_line_shift_y(tctx, models, file, width, face, line_number, y_delta));
}
internal f32
view_line_y_difference(Models *models, View *view, i64 line_a, i64 line_b){
view_line_y_difference(Thread_Context *tctx, Models *models, View *view, i64 line_a, i64 line_b){
Editing_File *file = view->file;
Face *face = file_get_face(models, file);
f32 width = view_width(models, view);
return(file_line_y_difference(models, file, width, face, line_a, line_b));
f32 width = view_width(tctx, models, view);
return(file_line_y_difference(tctx, models, file, width, face, line_a, line_b));
}
internal i64
view_pos_at_relative_xy(Models *models, View *view, i64 base_line, Vec2_f32 relative_xy){
view_pos_at_relative_xy(Thread_Context *tctx, Models *models, View *view, i64 base_line, Vec2_f32 relative_xy){
Editing_File *file = view->file;
Face *face = file_get_face(models, file);
f32 width = view_width(models, view);
return(file_pos_at_relative_xy(models, file, width, face, base_line, relative_xy));
f32 width = view_width(tctx, models, view);
return(file_pos_at_relative_xy(tctx, models, file, width, face, base_line, relative_xy));
}
internal Vec2_f32
view_relative_xy_of_pos(Models *models, View *view, i64 base_line, i64 pos){
view_relative_xy_of_pos(Thread_Context *tctx, Models *models, View *view, i64 base_line, i64 pos){
Editing_File *file = view->file;
Face *face = file_get_face(models, file);
f32 width = view_width(models, view);
return(file_relative_xy_of_pos(models, file, width, face, base_line, pos));
f32 width = view_width(tctx, models, view);
return(file_relative_xy_of_pos(tctx, models, file, width, face, base_line, pos));
}
internal Buffer_Point
view_normalize_buffer_point(Models *models, View *view, Buffer_Point point){
view_normalize_buffer_point(Thread_Context *tctx, Models *models, View *view, Buffer_Point point){
Editing_File *file = view->file;
Face *face = file_get_face(models, file);
f32 width = view_width(models, view);
return(file_normalize_buffer_point(models, file, width, face, point));
f32 width = view_width(tctx, models, view);
return(file_normalize_buffer_point(tctx, models, file, width, face, point));
}
internal Vec2_f32
view_buffer_point_difference(Models *models, View *view, Buffer_Point a, Buffer_Point b){
view_buffer_point_difference(Thread_Context *tctx, Models *models, View *view, Buffer_Point a, Buffer_Point b){
Editing_File *file = view->file;
Face *face = file_get_face(models, file);
f32 width = view_width(models, view);
return(file_buffer_point_difference(models, file, width, face, a, b));
f32 width = view_width(tctx, models, view);
return(file_buffer_point_difference(tctx, models, file, width, face, a, b));
}
internal Buffer_Point
view_move_buffer_point(Models *models, View *view, Buffer_Point buffer_point, Vec2_f32 delta){
view_move_buffer_point(Thread_Context *tctx, Models *models, View *view, Buffer_Point buffer_point, Vec2_f32 delta){
delta += buffer_point.pixel_shift;
Line_Shift_Vertical shift = view_line_shift_y(models, view, buffer_point.line_number, delta.y);
Line_Shift_Vertical shift = view_line_shift_y(tctx, models, view, buffer_point.line_number, delta.y);
buffer_point.line_number = shift.line;
buffer_point.pixel_shift = V2f32(delta.x, delta.y - shift.y_delta);
return(buffer_point);
}
internal Line_Shift_Character
view_line_shift_characters(Models *models, View *view, i64 line_number, i64 character_delta){
view_line_shift_characters(Thread_Context *tctx, Models *models, View *view, i64 line_number, i64 character_delta){
Editing_File *file = view->file;
Face *face = file_get_face(models, file);
f32 width = view_width(models, view);
return(file_line_shift_characters(models, file, width, face, line_number, character_delta));
f32 width = view_width(tctx, models, view);
return(file_line_shift_characters(tctx, models, file, width, face, line_number, character_delta));
}
internal i64
view_line_character_difference(Models *models, View *view, i64 line_a, i64 line_b){
view_line_character_difference(Thread_Context *tctx, Models *models, View *view, i64 line_a, i64 line_b){
Editing_File *file = view->file;
Face *face = file_get_face(models, file);
f32 width = view_width(models, view);
return(file_line_character_difference(models, file, width, face, line_a, line_b));
f32 width = view_width(tctx, models, view);
return(file_line_character_difference(tctx, models, file, width, face, line_a, line_b));
}
internal i64
view_pos_from_relative_character(Models *models, View *view, i64 base_line, i64 relative_character){
view_pos_from_relative_character(Thread_Context *tctx, Models *models, View *view, i64 base_line, i64 relative_character){
Editing_File *file = view->file;
Face *face = file_get_face(models, file);
f32 width = view_width(models, view);
return(file_pos_from_relative_character(models, file, width, face, base_line, relative_character));
f32 width = view_width(tctx, models, view);
return(file_pos_from_relative_character(tctx, models, file, width, face, base_line, relative_character));
}
internal i64
view_relative_character_from_pos(Models *models, View *view, i64 base_line, i64 pos){
view_relative_character_from_pos(Thread_Context *tctx, Models *models, View *view, i64 base_line, i64 pos){
Editing_File *file = view->file;
Face *face = file_get_face(models, file);
f32 width = view_width(models, view);
return(file_relative_character_from_pos(models, file, width, face, base_line, pos));
f32 width = view_width(tctx, models, view);
return(file_relative_character_from_pos(tctx, models, file, width, face, base_line, pos));
}
internal Buffer_Cursor
@ -282,14 +285,14 @@ view_compute_cursor(View *view, Buffer_Seek seek){
////////////////////////////////
internal b32
view_move_view_to_cursor(Models *models, View *view, Buffer_Scroll *scroll){
view_move_view_to_cursor(Thread_Context *tctx, Models *models, View *view, Buffer_Scroll *scroll){
Editing_File *file = view->file;
Face *face = file_get_face(models, file);
Rect_f32 rect = view_get_buffer_rect(models, view);
Rect_f32 rect = view_get_buffer_rect(tctx, models, view);
Vec2_f32 view_dim = rect_dim(rect);
File_Edit_Positions edit_pos = view_get_edit_pos(view);
Vec2_f32 p = file_relative_xy_of_pos(models, file, view_dim.x, face, scroll->target.line_number,
Vec2_f32 p = file_relative_xy_of_pos(tctx, models, file, view_dim.x, face, scroll->target.line_number,
edit_pos.cursor_pos);
p -= scroll->target.pixel_shift;
@ -310,7 +313,7 @@ view_move_view_to_cursor(Models *models, View *view, Buffer_Scroll *scroll){
target_p_relative.x = (p.x + typical_advance*1.5f) - view_dim.x;
}
scroll->target.pixel_shift += target_p_relative;
scroll->target = view_normalize_buffer_point(models, view, scroll->target);
scroll->target = view_normalize_buffer_point(tctx, models, view, scroll->target);
scroll->target.pixel_shift.x = f32_round32(scroll->target.pixel_shift.x);
scroll->target.pixel_shift.y = f32_round32(scroll->target.pixel_shift.y);
@ -318,13 +321,13 @@ view_move_view_to_cursor(Models *models, View *view, Buffer_Scroll *scroll){
}
internal b32
view_move_cursor_to_view(Models *models, View *view, Buffer_Scroll scroll, i64 *pos_in_out, f32 preferred_x){
view_move_cursor_to_view(Thread_Context *tctx, Models *models, View *view, Buffer_Scroll scroll, i64 *pos_in_out, f32 preferred_x){
Editing_File *file = view->file;
Face *face = file_get_face(models, file);
Rect_f32 rect = view_get_buffer_rect(models, view);
Rect_f32 rect = view_get_buffer_rect(tctx, models, view);
Vec2_f32 view_dim = rect_dim(rect);
Vec2_f32 p = file_relative_xy_of_pos(models, file, view_dim.x, face, scroll.target.line_number, *pos_in_out);
Vec2_f32 p = file_relative_xy_of_pos(tctx, models, file, view_dim.x, face, scroll.target.line_number, *pos_in_out);
p -= scroll.target.pixel_shift;
f32 line_height = face->line_height;
@ -343,7 +346,7 @@ view_move_cursor_to_view(Models *models, View *view, Buffer_Scroll scroll, i64 *
b32 result = false;
if (adjusted_y){
p += scroll.target.pixel_shift;
*pos_in_out = file_pos_at_relative_xy(models, file, view_dim.x, face, scroll.target.line_number, p);
*pos_in_out = file_pos_at_relative_xy(tctx, models, file, view_dim.x, face, scroll.target.line_number, p);
result = true;
}
@ -351,33 +354,33 @@ view_move_cursor_to_view(Models *models, View *view, Buffer_Scroll scroll, i64 *
}
internal void
view_set_cursor(Models *models, View *view, i64 pos){
view_set_cursor(Thread_Context *tctx, Models *models, View *view, i64 pos){
File_Edit_Positions edit_pos = view_get_edit_pos(view);
file_edit_positions_set_cursor(&edit_pos, pos);
view_set_edit_pos(view, edit_pos);
Buffer_Scroll scroll = edit_pos.scroll;
if (view_move_view_to_cursor(models, view, &scroll)){
if (view_move_view_to_cursor(tctx, models, view, &scroll)){
edit_pos.scroll = scroll;
view_set_edit_pos(view, edit_pos);
}
}
internal void
view_set_scroll(Models *models, View *view, Buffer_Scroll scroll){
view_set_scroll(Thread_Context *tctx, Models *models, View *view, Buffer_Scroll scroll){
File_Edit_Positions edit_pos = view_get_edit_pos(view);
file_edit_positions_set_scroll(&edit_pos, scroll);
view_set_edit_pos(view, edit_pos);
if (view_move_cursor_to_view(models, view, edit_pos.scroll, &edit_pos.cursor_pos, view->preferred_x)){
if (view_move_cursor_to_view(tctx, models, view, edit_pos.scroll, &edit_pos.cursor_pos, view->preferred_x)){
view_set_edit_pos(view, edit_pos);
}
}
internal void
view_set_cursor_and_scroll(Models *models, View *view, i64 pos, Buffer_Scroll scroll){
view_set_cursor_and_scroll(Thread_Context *tctx, Models *models, View *view, i64 pos, Buffer_Scroll scroll){
File_Edit_Positions edit_pos = view_get_edit_pos(view);
file_edit_positions_set_cursor(&edit_pos, pos);
Buffer_Cursor cursor = view_compute_cursor(view, seek_pos(pos));
Vec2_f32 p = view_relative_xy_of_pos(models, view, cursor.line, pos);
Vec2_f32 p = view_relative_xy_of_pos(tctx, models, view, cursor.line, pos);
view->preferred_x = p.x;
file_edit_positions_set_scroll(&edit_pos, scroll);
edit_pos.last_set_type = EditPos_None;
@ -397,7 +400,7 @@ view_post_paste_effect(View *view, f32 seconds, i64 start, i64 size, u32 color){
////////////////////////////////
internal void
view_set_file(Models *models, View *view, Editing_File *file){
view_set_file(Thread_Context *tctx, Models *models, View *view, Editing_File *file){
Assert(file != 0);
Editing_File *old_file = view->file;
@ -412,7 +415,7 @@ view_set_file(Models *models, View *view, Editing_File *file){
view_set_edit_pos(view, edit_pos);
view->mark = edit_pos.cursor_pos;
Buffer_Cursor cursor = view_compute_cursor(view, seek_pos(edit_pos.cursor_pos));
Vec2_f32 p = view_relative_xy_of_pos(models, view, cursor.line, edit_pos.cursor_pos);
Vec2_f32 p = view_relative_xy_of_pos(tctx, models, view, cursor.line, edit_pos.cursor_pos);
view->preferred_x = p.x;
models->layout.panel_state_dirty = true;
@ -463,20 +466,6 @@ view_current_context(View *view){
////////////////////////////////
internal App_Coroutine_State
get_co_state(Application_Links *app){
App_Coroutine_State state = {};
state.co = app->current_coroutine;
state.type = app->type_coroutine;
return(state);
}
internal void
restore_co_state(Application_Links *app, App_Coroutine_State state){
app->current_coroutine = state.co;
app->type_coroutine = state.type;
}
internal Coroutine*
co_handle_request(Models *models, Coroutine *co, Co_Out *out){
Coroutine *result = 0;
@ -503,17 +492,11 @@ co_handle_request(Models *models, Coroutine *co, Co_Out *out){
}
internal Coroutine*
co_run(Models *models, App_Coroutine_Purpose purpose, Coroutine *co,
Co_In *in, Co_Out *out){
Application_Links *app = &models->app_links;
App_Coroutine_State prev_state = get_co_state(app);
app->current_coroutine = co;
app->type_coroutine = purpose;
co_run(Thread_Context *tctx, Models *models, Coroutine *co, Co_In *in, Co_Out *out){
Coroutine *result = coroutine_run(&models->coroutines, co, in, out);
for (;result != 0 && out->request != CoRequest_None;){
result = co_handle_request(models, result, out);
}
restore_co_state(app, prev_state);
return(result);
}
@ -523,15 +506,18 @@ view_event_context_base__inner(Coroutine *coroutine){
Models *models = in->models;
Custom_Command_Function *event_context_base = in->event_context_base;
Assert(event_context_base != 0);
event_context_base(&models->app_links);
Application_Links app = {};
app.tctx = coroutine->tctx;
app.cmd_context = models;
event_context_base(&app);
}
function void
view_init(Models *models, View *view, Editing_File *initial_buffer,
view_init(Thread_Context *tctx, Models *models, View *view, Editing_File *initial_buffer,
Custom_Command_Function *event_context_base){
view_set_file(models, view, initial_buffer);
view_set_file(tctx, models, view, initial_buffer);
view->node_arena = reserve_arena(models->tctx);
view->node_arena = reserve_arena(tctx);
View_Context first_ctx = {};
first_ctx.render_caller = models->render_caller;
@ -543,7 +529,7 @@ view_init(Models *models, View *view, Editing_File *initial_buffer,
Co_In in = {};
in.models = models;
in.event_context_base = event_context_base;
view->co = co_run(models, Co_View, view->co, &in, &view->co_out);
view->co = co_run(tctx, models, view->co, &in, &view->co_out);
// TODO(allen): deal with this kind of problem!
Assert(view->co != 0);
}
@ -572,25 +558,28 @@ view_check_co_exited(Models *models, View *view){
}
internal void
co_single_abort(Models *models, View *view){
co_single_abort(Thread_Context *tctx, Models *models, View *view){
Coroutine *co = view->co;
Co_In in = {};
in.user_input.abort = true;
view->co = co_run(models, Co_View, co, &in, &view->co_out);
view->co = co_run(tctx, models, co, &in, &view->co_out);
view_check_co_exited(models, view);
}
internal void
co_full_abort(Models *models, View *view){
co_full_abort(Thread_Context *tctx, Models *models, View *view){
Coroutine *co = view->co;
Co_In in = {};
in.user_input.abort = true;
for (u32 j = 0; j < 100 && co != 0; ++j){
co = co_run(models, Co_View, co, &in, &view->co_out);
co = co_run(tctx, models, co, &in, &view->co_out);
}
if (co != 0){
#define M "SERIOUS ERROR: full stack abort did not complete"
print_message(&models->app_links, string_u8_litexpr(M));
Application_Links app = {};
app.tctx = tctx;
app.cmd_context = models;
print_message(&app, string_u8_litexpr(M));
#undef M
}
view->co = 0;
@ -598,7 +587,7 @@ co_full_abort(Models *models, View *view){
}
function b32
co_send_event(Models *models, View *view, Input_Event *event){
co_send_event(Thread_Context *tctx, Models *models, View *view, Input_Event *event){
b32 event_was_handled = false;
Coroutine *co = view->co;
@ -613,7 +602,7 @@ co_send_event(Models *models, View *view, Input_Event *event){
in.user_input.event = *event;
in.user_input.abort = ((abort_flags & event_flags) != 0);
begin_handling_input(models, &in.user_input);
view->co = co_run(models, Co_View, view->co, &in, &view->co_out);
view->co = co_run(tctx, models, view->co, &in, &view->co_out);
view_check_co_exited(models, view);
if (!HasFlag(event_flags, EventProperty_Animate)){
models->animate_next_frame = true;
@ -625,52 +614,52 @@ co_send_event(Models *models, View *view, Input_Event *event){
}
function b32
co_send_core_event(Models *models, View *view, Core_Code code, String_Const_u8 string){
co_send_core_event(Thread_Context *tctx, Models *models, View *view, Core_Code code, String_Const_u8 string){
Input_Event event = {};
event.kind = InputEventKind_Core;
event.core.code = code;
event.core.string = string;
return(co_send_event(models, view, &event));
return(co_send_event(tctx, models, view, &event));
}
function b32
co_send_core_event(Models *models, View *view, Core_Code code, Buffer_ID id){
co_send_core_event(Thread_Context *tctx, Models *models, View *view, Core_Code code, Buffer_ID id){
Input_Event event = {};
event.kind = InputEventKind_Core;
event.core.code = code;
event.core.id = id;
return(co_send_event(models, view, &event));
return(co_send_event(tctx, models, view, &event));
}
function b32
co_send_core_event(Models *models, View *view, Core_Code code){
return(co_send_core_event(models, view, code, SCu8()));
co_send_core_event(Thread_Context *tctx, Models *models, View *view, Core_Code code){
return(co_send_core_event(tctx, models, view, code, SCu8()));
}
function b32
co_send_event(Models *models, Input_Event *event){
co_send_event(Thread_Context *tctx, Models *models, Input_Event *event){
Panel *active_panel = models->layout.active_panel;
View *view = active_panel->view;
return(co_send_event(models, view, event));
return(co_send_event(tctx, models, view, event));
}
function b32
co_send_core_event(Models *models, Core_Code code, String_Const_u8 string){
co_send_core_event(Thread_Context *tctx, Models *models, Core_Code code, String_Const_u8 string){
Panel *active_panel = models->layout.active_panel;
View *view = active_panel->view;
return(co_send_core_event(models, view, code, string));
return(co_send_core_event(tctx, models, view, code, string));
}
function b32
co_send_core_event(Models *models, Core_Code code, Buffer_ID buffer_id){
co_send_core_event(Thread_Context *tctx, Models *models, Core_Code code, Buffer_ID buffer_id){
Panel *active_panel = models->layout.active_panel;
View *view = active_panel->view;
return(co_send_core_event(models, view, code, buffer_id));
return(co_send_core_event(tctx, models, view, code, buffer_id));
}
function b32
co_send_core_event(Models *models, Core_Code code){
return(co_send_core_event(models, code, SCu8()));
co_send_core_event(Thread_Context *tctx, Models *models, Core_Code code){
return(co_send_core_event(tctx, models, code, SCu8()));
}
////////////////////////////////
@ -691,7 +680,7 @@ file_is_viewed(Layout *layout, Editing_File *file){
}
internal void
adjust_views_looking_at_file_to_new_cursor(Models *models, Editing_File *file){
adjust_views_looking_at_file_to_new_cursor(Thread_Context *tctx, Models *models, Editing_File *file){
Layout *layout = &models->layout;
for (Panel *panel = layout_get_first_open_panel(layout);
panel != 0;
@ -699,7 +688,7 @@ adjust_views_looking_at_file_to_new_cursor(Models *models, Editing_File *file){
View *view = panel->view;
if (view->file == file){
File_Edit_Positions edit_pos = view_get_edit_pos(view);
view_set_cursor(models, view, edit_pos.cursor_pos);
view_set_cursor(tctx, models, view, edit_pos.cursor_pos);
}
}
}

View File

@ -381,7 +381,7 @@ buffer_unbind_name_low_level(Working_Set *working_set, Editing_File *file){
}
internal void
buffer_bind_name(Models *models, Arena *scratch, Working_Set *working_set, Editing_File *file, String_Const_u8 base_name){
buffer_bind_name(Thread_Context *tctx, Models *models, Arena *scratch, Working_Set *working_set, Editing_File *file, String_Const_u8 base_name){
Temp_Memory temp = begin_temp(scratch);
// List of conflict files.
@ -445,7 +445,10 @@ buffer_bind_name(Models *models, Arena *scratch, Working_Set *working_set, Editi
// Get user's resolution data.
if (models->buffer_name_resolver != 0){
models->buffer_name_resolver(&models->app_links, conflicts, conflict_count);
Application_Links app = {};
app.tctx = tctx;
app.cmd_context = models;
models->buffer_name_resolver(&app, conflicts, conflict_count);
}
// Re-bind all of the files

View File

@ -0,0 +1,212 @@
/*
* 4coder_async_tasks.cpp - Implementation of the custom layer asynchronous task system.
*/
// TOP
// TODO(allen): put atomic wrappers in base type layer
#define atomic_write_b32(p,v) (*(p)=(v))
#define atomic_read_b32(p) (*(p))
global Async_System global_async_system = {};
function Async_Node*
async_pop_node(Async_System *async_system){
for (;async_system->task_count == 0;){
system_condition_variable_wait(async_system->cv, async_system->mutex);
}
Node *node = async_system->task_sent.next;
Assert(node != &async_system->task_sent);
dll_remove(node);
async_system->task_count -= 1;
Async_Node *a_node = CastFromMember(Async_Node, node, node);
a_node->next = 0;
return(a_node);
}
function Async_Task
async_push_node(Async_System *async_system, Async_Task_Function_Type *func, Data data){
Async_Task result = async_system->task_id_counter;
async_system->task_id_counter += 1;
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;
dll_insert_back(&async_system->task_sent, &node->node);
async_system->task_count += 1;
system_condition_variable_signal(async_system->cv);
return(result);
}
function void
async_free_node(Async_System *async_system, Async_Node *node){
heap_free(&async_system->node_heap, node->data.data);
sll_stack_push(async_system->free_nodes, node);
}
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;
Async_System *async_system = thread->async_system;
Application_Links app = {};
app.tctx = tctx;
app.cmd_context = async_system->cmd_context;
Async_Context ctx = {&app, thread};
for (;;){
system_mutex_acquire(async_system->mutex);
Async_Node *node = async_pop_node(async_system);
node->thread = thread;
thread->node = node;
thread->task = node->task;
thread->cancel_signal = false;
thread->join_signal = false;
system_mutex_release(async_system->mutex);
node->func(&ctx, node->data);
system_mutex_acquire(async_system->mutex);
if (thread->join_signal){
system_condition_variable_signal(async_system->join_cv);
}
node->thread = 0;
thread->node = 0;
thread->task = 0;
thread->cancel_signal = false;
thread->join_signal = false;
async_free_node(async_system, node);
system_mutex_release(async_system->mutex);
}
}
function Async_Node*
async_get_pending_node(Async_System *async_system, Async_Task task){
Async_Node *result = 0;
if (task != 0){
for (Node *node = async_system->task_sent.next;
node != &async_system->task_sent;
node = node->next){
Async_Node *a_node = CastFromMember(Async_Node, node, node);
if (a_node->task == task){
result = a_node;
break;
}
}
}
return(result);
}
function Async_Node*
async_get_running_node(Async_System *async_system, Async_Task task){
Async_Node *result = 0;
if (task != 0 && async_system->thread.task == task){
result = async_system->thread.node;
}
return(result);
}
////////////////////////////////
function void
async_task_handler_init(Application_Links *app, Async_System *async_system){
block_zero_struct(async_system);
async_system->cmd_context = app->cmd_context;
async_system->node_arena = make_arena_system(KB(4));
heap_init(&async_system->node_heap, &async_system->node_arena);
async_system->mutex = system_mutex_make();
async_system->cv = system_condition_variable_make();
async_system->join_cv = system_condition_variable_make();
dll_init_sentinel(&async_system->task_sent);
async_system->thread.async_system = async_system;
async_system->thread.thread = system_thread_launch(async_task_thread, &async_system->thread);
}
function Async_Task
async_task_no_dep(Async_System *async_system, Async_Task_Function_Type *func, Data data){
system_mutex_acquire(async_system->mutex);
Async_Task result = async_push_node(async_system, func, data);
system_mutex_release(async_system->mutex);
return(result);
}
function Async_Task
async_task_single_dep(Async_System *async_system, Async_Task_Function_Type *func, Data data, Async_Task dependency){
NotImplemented;
}
function b32
async_task_is_pending(Async_System *async_system, Async_Task task){
system_mutex_acquire(async_system->mutex);
Async_Node *node = async_get_pending_node(async_system, task);
system_mutex_release(async_system->mutex);
return(node != 0);
}
function b32
async_task_is_running(Async_System *async_system, Async_Task task){
system_mutex_acquire(async_system->mutex);
Async_Node *node = async_get_running_node(async_system, task);
system_mutex_release(async_system->mutex);
return(node != 0);
}
function b32
async_task_is_running_or_pending(Async_System *async_system, Async_Task task){
system_mutex_acquire(async_system->mutex);
Async_Node *node = async_get_pending_node(async_system, task);
if (node != 0){
node = async_get_running_node(async_system, task);
}
system_mutex_release(async_system->mutex);
return(node != 0);
}
function void
async_task_cancel(Async_System *async_system, Async_Task task){
system_mutex_acquire(async_system->mutex);
Async_Node *node = async_get_pending_node(async_system, task);
if (node != 0){
dll_remove(&node->node);
async_system->task_count -= 1;
async_free_node(async_system, node);
}
else{
node = async_get_running_node(async_system, task);
if (node != 0){
b32 *cancel_signal = &node->thread->cancel_signal;
atomic_write_b32(cancel_signal, true);
}
}
system_mutex_release(async_system->mutex);
}
function b32
async_check_canceled(Async_Context *actx){
b32 *cancel_signal = &actx->thread->cancel_signal;
b32 result = atomic_read_b32(cancel_signal);
return(result);
}
// BOTTOM

View File

@ -0,0 +1,57 @@
/*
* 4coder_async_tasks.cpp - Types for the custom layer asynchronous task system.
*/
// TOP
#if !defined(FCODER_ASYNC_TASKS_H)
#define FCODER_ASYNC_TASKS_H
typedef void Async_Task_Function_Type(struct Async_Context *actx, Data data);
typedef u64 Async_Task;
struct Async_Thread{
struct Async_System *async_system;
System_Thread thread;
struct Async_Node *node;
Async_Task task;
b32 cancel_signal;
b32 join_signal;
};
struct Async_Node{
union{
Async_Node *next;
Node node;
};
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;
System_Condition_Variable join_cv;
Async_Task task_id_counter;
Async_Node *free_nodes;
Node task_sent;
i32 task_count;
Async_Thread thread;
};
struct Async_Context{
Application_Links *app;
Async_Thread *thread;
};
#endif
// BOTTOM

View File

@ -311,6 +311,7 @@ get_indentation_array(Application_Links *app, Arena *arena, Buffer_ID buffer, Ra
internal b32
auto_indent_buffer(Application_Links *app, Buffer_ID buffer, Range_i64 pos, Indent_Flag flags, i32 tab_width, i32 indent_width){
ProfileScope(app, "auto indent buffer");
Managed_Scope scope = buffer_get_managed_scope(app, buffer);
Token_Array *tokens = scope_attachment(app, scope, attachment_tokens, Token_Array);

View File

@ -1203,6 +1203,7 @@ CUSTOM_DOC("Queries the user for a string, and incrementally replace every occur
function void
save_all_dirty_buffers_with_postfix(Application_Links *app, String_Const_u8 postfix){
ProfileScope(app, "save all dirty buffers");
Scratch_Block scratch(app);
for (Buffer_ID buffer = get_buffer_next(app, 0, Access_ReadWriteVisible);
buffer != 0;

View File

@ -2834,9 +2834,10 @@ end_temp(Temp_Memory temp){
////////////////////////////////
internal void
thread_ctx_init(Thread_Context *tctx, Base_Allocator *allocator,
thread_ctx_init(Thread_Context *tctx, Thread_Kind kind, Base_Allocator *allocator,
Base_Allocator *prof_allocator){
block_zero_struct(tctx);
tctx->kind = kind;
tctx->allocator = allocator;
tctx->node_arena = make_arena(allocator, KB(4), 8);

View File

@ -478,7 +478,7 @@ union SNode{
#define sll_stack_pop_(h) h=h=h->next
#define sll_queue_push_multiple_(f,l,ff,ll) if(ll){if(f){l->next=ff;}else{f=ff;}l=ll;l->next=0;}
#define sll_queue_push_(f,l,n) sll_queue_push_multiple_(f,l,n,n)
#define sll_queue_pop_(f,l) if (f==l) { f=l=0; } else { f->next=0;f=f->next; }
#define sll_queue_pop_(f,l) if (f==l) { f=l=0; } else { f=f->next; }
#define sll_stack_push(h,n) (sll_stack_push_((h),(n)))
#define sll_stack_pop(h) (sll_stack_pop_((h)))
@ -1168,7 +1168,15 @@ struct Profile_Global_List{
////////////////////////////////
typedef i32 Thread_Kind;
enum{
ThreadKind_Main,
ThreadKind_MainCoroutine,
ThreadKind_AsyncTasks,
};
struct Thread_Context{
Thread_Kind kind;
Base_Allocator *allocator;
Arena node_arena;
Arena_Node *free_arenas;
@ -1180,6 +1188,8 @@ struct Thread_Context{
Profile_Record *prof_first;
Profile_Record *prof_last;
i32 prof_record_count;
void *user_data;
};
typedef i32 Scratch_Share_Code;

File diff suppressed because it is too large Load Diff

View File

@ -19,6 +19,7 @@ custom_layer_init(Application_Links *app){
mapping_init(tctx, &framework_mapping);
setup_default_mapping(&framework_mapping);
global_prof_init();
async_task_handler_init(app, &global_async_system);
}
#endif

View File

@ -453,6 +453,7 @@ default_4coder_initialize(Application_Links *app, String_Const_u8_Array file_nam
buffer_map_id = managed_id_declare(app, SCu8("DEFAULT.buffer_map_id" ));
buffer_eol_setting = managed_id_declare(app, SCu8("DEFAULT.buffer_eol_setting"));
buffer_lex_task = managed_id_declare(app, SCu8("DEFAULT.buffer_lex_task"));
sticky_jump_marker_handle = managed_id_declare(app, SCu8("DEFAULT.sticky_jump_marker_handle"));
attachment_tokens = managed_id_declare(app, SCu8("DEFAULT.tokens"));

View File

@ -44,6 +44,7 @@ global Managed_ID view_call_next = 0;
global Managed_ID buffer_map_id = 0;
global Managed_ID buffer_eol_setting = 0;
global Managed_ID buffer_lex_task = 0;
global Managed_ID sticky_jump_marker_handle = 0;

View File

@ -92,7 +92,7 @@ CUSTOM_DOC("Input consumption loop for default view behavior")
Managed_Scope scope = view_get_managed_scope(app, view);
Custom_Command_Function** next_call = 0;
call_again:
next_call = scope_attachment(app, scope, view_call_next, Custom_Command_Function*);
*next_call = 0;
@ -140,7 +140,7 @@ CUSTOM_DOC("Input consumption loop for default view behavior")
}
next_call = scope_attachment(app, scope, view_call_next, Custom_Command_Function*);
if (*next_call != 0){
if (next_call != 0 && *next_call != 0){
binding.custom = *next_call;
goto call_again;
}
@ -539,24 +539,69 @@ BUFFER_NAME_RESOLVER_SIG(default_buffer_name_resolution){
}
function void
do_full_lex(Application_Links *app, Buffer_ID buffer_id){
Scratch_Block scratch(app);
String_Const_u8 contents = push_whole_buffer(app, scratch, buffer_id);
Token_List list = lex_full_input_cpp(scratch, contents);
do_full_lex_async__inner(Async_Context *actx, Buffer_ID buffer_id){
Application_Links *app = actx->app;
ProfileScope(app, "async lex");
Thread_Context *tctx = get_thread_context(app);
Scratch_Block scratch(tctx);
Managed_Scope scope = buffer_get_managed_scope(app, buffer_id);
Base_Allocator *allocator = managed_scope_allocator(app, scope);
Token_Array tokens = {};
tokens.tokens = base_array(allocator, Token, list.total_count);
tokens.count = list.total_count;
tokens.max = list.total_count;
token_fill_memory_from_list(tokens.tokens, &list);
String_Const_u8 contents = {};
{
ProfileBlock(app, "async lex contents (before mutex)");
system_acquire_global_frame_mutex(tctx);
ProfileBlock(app, "async lex contents (after mutex)");
contents = push_whole_buffer(app, scratch, buffer_id);
system_release_global_frame_mutex(tctx);
}
Token_Array *tokens_ptr = scope_attachment(app, scope, attachment_tokens, Token_Array);
block_copy_struct(tokens_ptr, &tokens);
Lex_State_Cpp state = {};
lex_full_input_cpp_init(&state, contents);
Token_List list = {};
b32 canceled = false;
for (;;){
ProfileBlock(app, "async lex block");
if (lex_full_input_cpp_breaks(scratch, &list, &state, 10000)){
break;
}
if (async_check_canceled(actx)){
canceled = true;
break;
}
}
if (!canceled){
ProfileBlock(app, "async lex save results (before mutex)");
system_acquire_global_frame_mutex(tctx);
ProfileBlock(app, "async lex save results (after mutex)");
Managed_Scope scope = buffer_get_managed_scope(app, buffer_id);
if (scope != 0){
Base_Allocator *allocator = managed_scope_allocator(app, scope);
Token_Array *tokens_ptr = scope_attachment(app, scope, attachment_tokens, Token_Array);
base_free(allocator, tokens_ptr->tokens);
Token_Array tokens = {};
tokens.tokens = base_array(allocator, Token, list.total_count);
tokens.count = list.total_count;
tokens.max = list.total_count;
token_fill_memory_from_list(tokens.tokens, &list);
block_copy_struct(tokens_ptr, &tokens);
}
system_release_global_frame_mutex(tctx);
}
}
function void
do_full_lex_async(Async_Context *actx, Data data){
if (data.size == sizeof(Buffer_ID)){
Buffer_ID buffer = *(Buffer_ID*)data.data;
do_full_lex_async__inner(actx, buffer);
}
}
BUFFER_HOOK_SIG(default_begin_buffer){
ProfileScope(app, "begin buffer");
b32 treat_as_code = false;
b32 lex_without_strings = false;
(void)(lex_without_strings);
@ -643,6 +688,7 @@ BUFFER_HOOK_SIG(default_begin_buffer){
first_call = false;
buffer_map_id = managed_id_declare(app, SCu8("DEFAULT.buffer_map_id"));
buffer_eol_setting = managed_id_declare(app, SCu8("DEFAULT.buffer_eol_setting"));
buffer_lex_task = managed_id_declare(app, SCu8("DEFAULT.buffer_lex_task"));
}
Command_Map_ID map_id = (treat_as_code)?(default_code_map):(mapid_file);
@ -672,10 +718,11 @@ BUFFER_HOOK_SIG(default_begin_buffer){
}
if (use_lexer){
do_full_lex(app, buffer_id);
ProfileBlock(app, "begin buffer kick off lexer");
Async_Task *lex_task_ptr = scope_attachment(app, scope, buffer_lex_task, Async_Task);
*lex_task_ptr = async_task_no_dep(&global_async_system, do_full_lex_async, make_data_struct(&buffer_id));
}
// no meaning for return
return(0);
}
@ -688,6 +735,7 @@ BUFFER_HOOK_SIG(default_new_file){
BUFFER_HOOK_SIG(default_file_save){
// buffer_id
ProfileScope(app, "default file save");
b32 is_virtual = false;
if (global_config.automatically_indent_text_on_save && is_virtual){
auto_indent_buffer(app, buffer_id, buffer_range(app, buffer_id));
@ -713,7 +761,6 @@ BUFFER_HOOK_SIG(default_file_save){
BUFFER_EDIT_RANGE_SIG(default_buffer_edit_range){
// buffer_id, range, text
ProfileScope(app, "default edit range");
Interval_i64 replace_range = Ii64(range.first, range.first + text.size);
@ -723,90 +770,83 @@ BUFFER_EDIT_RANGE_SIG(default_buffer_edit_range){
Scratch_Block scratch(app);
Managed_Scope scope = buffer_get_managed_scope(app, buffer_id);
Token_Array *ptr = scope_attachment(app, scope, attachment_tokens, Token_Array);
if (ptr != 0 && ptr->tokens != 0){
i64 token_index_first = token_relex_first(ptr, range.first, 1);
i64 token_index_resync_guess = token_relex_resync(ptr, range.one_past_last, 16);
Token *token_first = ptr->tokens + token_index_first;
Token *token_resync = ptr->tokens + token_index_resync_guess;
Interval_i64 relex_range = Ii64(token_first->pos,
token_resync->pos + token_resync->size + text_shift);
String_Const_u8 partial_text = push_buffer_range(app, scratch, buffer_id, relex_range);
Token_List relex_list = lex_full_input_cpp(scratch, partial_text);
if (relex_range.one_past_last < buffer_get_size(app, buffer_id)){
token_drop_eof(&relex_list);
}
Token_Relex relex = token_relex(relex_list, relex_range.first - text_shift,
ptr->tokens, token_index_first, token_index_resync_guess);
Base_Allocator *allocator = managed_scope_allocator(app, scope);
if (relex.successful_resync){
i64 token_index_resync = relex.first_resync_index;
Async_Task *lex_task_ptr = scope_attachment(app, scope, buffer_lex_task, Async_Task);
if (async_task_is_running_or_pending(&global_async_system, *lex_task_ptr)){
async_task_cancel(&global_async_system, *lex_task_ptr);
*lex_task_ptr = async_task_no_dep(&global_async_system, do_full_lex_async, make_data_struct(&buffer_id));
}
else{
Token_Array *ptr = scope_attachment(app, scope, attachment_tokens, Token_Array);
if (ptr != 0 && ptr->tokens != 0){
i64 token_index_first = token_relex_first(ptr, range.first, 1);
i64 token_index_resync_guess = token_relex_resync(ptr, range.one_past_last, 16);
Interval_i64 head = Ii64(0, token_index_first);
Interval_i64 replaced = Ii64(token_index_first, token_index_resync);
Interval_i64 tail = Ii64(token_index_resync, ptr->count);
i64 resynced_count = (token_index_resync_guess + 1) - token_index_resync;
i64 relexed_count = relex_list.total_count - resynced_count;
i64 tail_shift = relexed_count - (token_index_resync - token_index_first);
Token *token_first = ptr->tokens + token_index_first;
Token *token_resync = ptr->tokens + token_index_resync_guess;
i64 new_tokens_count = ptr->count + tail_shift;
Token *new_tokens = base_array(allocator, Token, new_tokens_count);
Interval_i64 relex_range = Ii64(token_first->pos,
token_resync->pos + token_resync->size + text_shift);
String_Const_u8 partial_text = push_buffer_range(app, scratch, buffer_id, relex_range);
Token *old_tokens = ptr->tokens;
block_copy_array_shift(new_tokens, old_tokens, head, 0);
token_fill_memory_from_list(new_tokens + replaced.first, &relex_list, relexed_count);
for (i64 i = 0, index = replaced.first; i < relexed_count; i += 1, index += 1){
new_tokens[index].pos += relex_range.first;
Token_List relex_list = lex_full_input_cpp(scratch, partial_text);
if (relex_range.one_past_last < buffer_get_size(app, buffer_id)){
token_drop_eof(&relex_list);
}
for (i64 i = tail.first; i < tail.one_past_last; i += 1){
old_tokens[i].pos += text_shift;
Base_Allocator *allocator = managed_scope_allocator(app, scope);
Token_Relex relex = token_relex(relex_list, relex_range.first - text_shift,
ptr->tokens, token_index_first, token_index_resync_guess);
if (relex.successful_resync){
i64 token_index_resync = relex.first_resync_index;
Interval_i64 head = Ii64(0, token_index_first);
Interval_i64 replaced = Ii64(token_index_first, token_index_resync);
Interval_i64 tail = Ii64(token_index_resync, ptr->count);
i64 resynced_count = (token_index_resync_guess + 1) - token_index_resync;
i64 relexed_count = relex_list.total_count - resynced_count;
i64 tail_shift = relexed_count - (token_index_resync - token_index_first);
i64 new_tokens_count = ptr->count + tail_shift;
Token *new_tokens = base_array(allocator, Token, new_tokens_count);
Token *old_tokens = ptr->tokens;
block_copy_array_shift(new_tokens, old_tokens, head, 0);
token_fill_memory_from_list(new_tokens + replaced.first, &relex_list, relexed_count);
for (i64 i = 0, index = replaced.first; i < relexed_count; i += 1, index += 1){
new_tokens[index].pos += relex_range.first;
}
for (i64 i = tail.first; i < tail.one_past_last; i += 1){
old_tokens[i].pos += text_shift;
}
block_copy_array_shift(new_tokens, ptr->tokens, tail, tail_shift);
base_free(allocator, ptr->tokens);
ptr->tokens = new_tokens;
ptr->count = new_tokens_count;
ptr->max = new_tokens_count;
}
block_copy_array_shift(new_tokens, ptr->tokens, tail, tail_shift);
base_free(allocator, ptr->tokens);
ptr->tokens = new_tokens;
ptr->count = new_tokens_count;
ptr->max = new_tokens_count;
}
else{
scratch.restore();
base_free(allocator, ptr->tokens);
do_full_lex(app, buffer_id);
}
#if 0
// NOTE(allen): Assert correctness of relex results. Enable this code
// to track down corruption of the token data.
{
String_Const_u8 full = push_whole_buffer(app, scratch, buffer_id);
Token_List list = lex_full_input_cpp(scratch, full);
Token_Array array = token_array_from_list(scratch, &list);
Assert(array.count == ptr->count);
Token *token_a = array.tokens;
Token *token_b = ptr->tokens;
for (i64 i = 0; i < array.count; i += 1, token_a += 1, token_b += 1){
Assert(block_match_struct(token_a, token_b));
else{
base_free(allocator, ptr->tokens);
block_zero_struct(ptr);
*lex_task_ptr = async_task_no_dep(&global_async_system, do_full_lex_async,
make_data_struct(&buffer_id));
}
}
#endif
}
// no meaning for return
return(0);
}
BUFFER_HOOK_SIG(default_end_file){
Scratch_Block scratch(app);
String_Const_u8 buffer_name = push_buffer_unique_name(app, scratch, buffer_id);
String_Const_u8 str = push_u8_stringf(scratch, "Ending file: %s\n", buffer_name.str);
print_message(app, str);
BUFFER_HOOK_SIG(default_end_buffer){
Managed_Scope scope = buffer_get_managed_scope(app, buffer_id);
Async_Task *lex_task_ptr = scope_attachment(app, scope, buffer_lex_task, Async_Task);
if (lex_task_ptr != 0){
async_task_cancel(&global_async_system, *lex_task_ptr);
}
// no meaning for return
return(0);
}
@ -829,7 +869,7 @@ set_all_default_hooks(Application_Links *app){
set_custom_hook(app, HookID_BufferNameResolver, default_buffer_name_resolution);
set_custom_hook(app, HookID_BeginBuffer, default_begin_buffer);
set_custom_hook(app, HookID_EndBuffer, end_file_close_jump_list);
set_custom_hook(app, HookID_EndBuffer, end_buffer_close_jump_list);
set_custom_hook(app, HookID_NewFile, default_new_file);
set_custom_hook(app, HookID_SaveFile, default_file_save);
set_custom_hook(app, HookID_BufferEditRange, default_buffer_edit_range);

View File

@ -26,6 +26,7 @@
#include "4coder_system_allocator.cpp"
#include "4coder_profile.h"
#include "4coder_async_tasks.h"
#include "4coder_token.h"
#include "generated/lexer_cpp.h"
#include "4coder_string_match.h"
@ -64,6 +65,7 @@
#include "4coder_log.cpp"
#include "4coder_hash_functions.cpp"
#include "4coder_table.cpp"
#include "4coder_async_tasks.cpp"
#include "4coder_string_match.cpp"
#include "4coder_buffer_seek_constructors.cpp"

View File

@ -648,21 +648,20 @@ draw_notepad_style_cursor_highlight(Application_Links *app, View_ID view_id,
function Rect_f32
get_tool_tip_box(Rect_f32 container, Vec2_f32 p, Vec2_f32 box_dims){
Rect_f32 box = {};
Vec2_f32 container_dims = rect_dim(container);
if (box_dims.x <= container_dims.x &&
box_dims.y <= container_dims.y){
p.x -= 6.f;
p.y += 22.f;
if (p.x + box_dims.x > container.x1){
p.x = container.x1 - box_dims.x;
}
if (p.y + box_dims.y > container.y1){
p.y = container.y1 - box_dims.y;
}
box = Rf32_xy_wh(p, box_dims);
box_dims.x = clamp_top(box_dims.x, container_dims.x);
box_dims.y = clamp_top(box_dims.y, container_dims.y);
Vec2_f32 q = p + V2f32(-20.f, 22.f);
if (q.x + box_dims.x > container.x1){
q.x = container.x1 - box_dims.x;
}
return(box);
if (q.y + box_dims.y > container.y1){
q.y = p.y - box_dims.y - 2.f;
if (q.y < container.y0){
q.y = (container.y0 + container.y1 - box_dims.y)*0.5f;
}
}
return(Rf32_xy_wh(q, box_dims));
}
// BOTTOM

View File

@ -7,6 +7,7 @@
function void
rewrite_lines_to_crlf(Application_Links *app, Buffer_ID buffer){
ProfileScope(app, "rewrite lines to crlf");
Scratch_Block scratch(app);
i64 size = buffer_get_size(app, buffer);
@ -51,6 +52,7 @@ rewrite_lines_to_crlf(Application_Links *app, Buffer_ID buffer){
function void
rewrite_lines_to_lf(Application_Links *app, Buffer_ID buffer){
ProfileScope(app, "rewrite lines to lf");
Scratch_Block scratch(app);
Batch_Edit *first = 0;

View File

@ -597,13 +597,13 @@ CUSTOM_DOC("If the buffer in the active view is writable, inserts a character, o
// End File Hook
//
BUFFER_HOOK_SIG(default_end_file);
BUFFER_HOOK_SIG(end_file_close_jump_list){
BUFFER_HOOK_SIG(default_end_buffer);
BUFFER_HOOK_SIG(end_buffer_close_jump_list){
Marker_List *list = get_marker_list_for_buffer(buffer_id);
if (list != 0){
delete_marker_list(list);
}
default_end_file(app, buffer_id);
default_end_buffer(app, buffer_id);
return(0);
}

View File

@ -85,8 +85,6 @@ profile_parse_record(Arena *arena, Profile_Inspection *insp,
slot = profile_parse_get_slot(arena, insp, location, name);
}
else if (record->id == id){
String_Const_u8 close_location = record->location;
String_Const_u8 close_name = record->name;
slot = profile_parse_get_slot(arena, insp, location, name);
node->time.max = record->time;
node->closed = true;
@ -227,6 +225,7 @@ profile_render(Application_Links *app, Frame_Info frame_info, View_ID view){
f32 x_half_padding = x_padding*0.5f;
inspect->tab_id_hovered = ProfileInspectTab_None;
block_zero_struct(&inspect->full_name_hovered);
block_zero_struct(&inspect->location_jump_hovered);
// NOTE(allen): tabs
@ -275,12 +274,14 @@ profile_render(Application_Links *app, Frame_Info frame_info, View_ID view){
node = node->next){
Range_f32 y = If32_size(y_pos, block_height);
i32 name_width = 30;
b32 name_too_long = false;
i32 name_width = 45;
Fancy_String_List list = {};
if (node->name.size > name_width){
push_fancy_stringf(scratch, &list, fancy_id(Stag_Pop1),
"%.*s... ",
name_width - 3, node->name.str);
name_too_long = true;
}
else{
push_fancy_stringf(scratch, &list, fancy_id(Stag_Pop1),
@ -295,7 +296,7 @@ profile_render(Application_Links *app, Frame_Info frame_info, View_ID view){
}
else{
push_fancy_stringf(scratch, &list, fancy_id(Stag_Pop2),
"%11.8fs ",
"%11.9fs ",
((f32)node->total_time)/1000000.f);
}
@ -309,6 +310,9 @@ profile_render(Application_Links *app, Frame_Info frame_info, View_ID view){
Rect_f32 box = Rf32(x, y);
int_color margin = Stag_Margin;
if (rect_contains_point(box, m_p)){
if (name_too_long){
inspect->full_name_hovered = node->name;
}
inspect->location_jump_hovered = node->location;
margin = Stag_Margin_Hover;
}
@ -349,24 +353,51 @@ profile_render(Application_Links *app, Frame_Info frame_info, View_ID view){
}break;
}
if (inspect->tab_id_hovered != ProfileInspectTab_None){
if (!rect_contains_point(region, m_p)){
// NOTE(allen): don't draw tool tip when the mouse doesn't hover in our view
}
else if (inspect->tab_id_hovered != ProfileInspectTab_None){
// NOTE(allen): no tool tip for tabs
}
else if (inspect->location_jump_hovered.size > 0){
draw_set_clip(app, region);
else{
i32 line_count = 0;
Fancy_String_List list[2] = {};
Fancy_Color color = fancy_rgba(1.f, 1.f, 1.f, 0.5f);
Fancy_String_List list = {};
push_fancy_stringf(scratch, &list, fancy_rgba(1.f, 1.f, 1.f, 0.5f),
"jump to: '%.*s'",
string_expand(inspect->location_jump_hovered));
f32 width = get_fancy_string_advance(app, face_id, list.first);
Vec2_f32 dims = V2f32(width + x_padding, line_height + 2.f);
Rect_f32 box = get_tool_tip_box(region, m_p, dims);
if (rect_area(box) > 0.f){
f32 width = 0.f;
if (inspect->full_name_hovered.size > 0){
line_count += 1;
push_fancy_stringf(scratch, &list[0], color, "%.*s",
string_expand(inspect->full_name_hovered));
f32 l_width = get_fancy_string_advance(app, face_id, list[0].first);
width = max(width, l_width);
}
if (inspect->location_jump_hovered.size > 0){
line_count += 1;
push_fancy_stringf(scratch, &list[1], color, "jump to: '%.*s'",
string_expand(inspect->location_jump_hovered));
f32 l_width = get_fancy_string_advance(app, face_id, list[1].first);
width = max(width, l_width);
}
if (line_count > 0){
Vec2_f32 dims = V2f32(width + x_padding, line_count*line_height + 2.f);
Rect_f32 box = get_tool_tip_box(region, m_p, dims);
draw_set_clip(app, box);
draw_rectangle(app, box, 6.f, 0x80000000);
draw_fancy_string(app, face_id, list.first,
V2f32(box.x0 + x_half_padding, box.y0 + 1.f),
0, 0);
f32 y = box.y0 + 1.f;
if (inspect->full_name_hovered.size > 0){
draw_fancy_string(app, face_id, list[0].first,
V2f32(box.x0 + x_half_padding, y),
0, 0);
y += line_height;
}
if (inspect->location_jump_hovered.size > 0){
draw_fancy_string(app, face_id, list[1].first,
V2f32(box.x0 + x_half_padding, y),
0, 0);
}
}
}
}

View File

@ -62,6 +62,7 @@ struct Profile_Inspection{
Profile_Inspection_Tab tab_id;
Profile_Inspection_Tab tab_id_hovered;
String_Const_u8 full_name_hovered;
String_Const_u8 location_jump_hovered;
};

View File

@ -138,6 +138,7 @@ open_all_files_in_directory_pattern_match(Application_Links *app,
Project_File_Pattern_Array whitelist,
Project_File_Pattern_Array blacklist,
u32 flags){
ProfileScope(app, "open all files in directory pattern");
Scratch_Block scratch(app);
String_Const_u8 directory = dir;
if (!character_is_slash(string_get_character(directory, directory.size - 1))){
@ -937,6 +938,7 @@ CUSTOM_DOC("Works as open_all_code but also runs in all subdirectories.")
CUSTOM_COMMAND_SIG(load_project)
CUSTOM_DOC("Looks for a project.4coder file in the current directory and tries to load it. Looks in parent directories until a project file is found or there are no more parents.")
{
ProfileScope(app, "load project");
save_all_dirty_buffers(app);
set_current_project_from_nearest_project_file(app);
}
@ -944,6 +946,7 @@ CUSTOM_DOC("Looks for a project.4coder file in the current directory and tries t
CUSTOM_COMMAND_SIG(project_fkey_command)
CUSTOM_DOC("Run an 'fkey command' configured in a project.4coder file. Determines the index of the 'fkey command' by which function key or numeric key was pressed to trigger the command.")
{
ProfileScope(app, "project fkey command");
User_Input input = get_current_input(app);
b32 got_ind = false;
i32 ind = 0;

View File

@ -334,7 +334,6 @@ word_complete_it_release(Word_Complete_Iterator *it){
end_temp(it->arena_restore);
table_clear(&it->already_used_table);
}
block_zero_struct(it);
}
function Word_Complete_State
@ -418,6 +417,7 @@ CUSTOM_DOC("Iteratively tries completing the word to the left of the cursor with
ProfileBlock(app, "word complete state init");
word_complete_it_release(&state.it);
block_zero_struct(&state);
i64 pos = view_get_cursor_pos(app, view);

View File

@ -13,10 +13,13 @@
#endif
struct Thread_Context_Extra_Info{
void *coroutine;
void *async_thread;
};
struct Application_Links{
Thread_Context *tctx;
void *cmd_context;
void *current_coroutine;
i32 type_coroutine;
};
typedef void Custom_Layer_Init_Type(Application_Links *app);
void custom_layer_init(Application_Links *app);
@ -373,14 +376,14 @@ STRUCT Theme_Color{
//int_color colors[Stag_COUNT];
//};
TYPEDEF u32 Face_ID;
typedef u32 Face_ID;
STRUCT Font_Load_Location{
struct Font_Load_Location{
String_Const_u8 file_name;
b32 in_4coder_font_folder;
};
STRUCT Face_Load_Parameters{
struct Face_Load_Parameters{
u32 pt_size;
b32 bold;
b32 italic;
@ -388,7 +391,7 @@ STRUCT Face_Load_Parameters{
b32 hinting;
};
STRUCT Face_Description{
struct Face_Description{
Font_Load_Location font;
Face_Load_Parameters parameters;
};

View File

@ -330,42 +330,42 @@ static Command_Metadata fcoder_metacmd_table[211] = {
{ PROC_LINKS(query_replace, 0), false, "query_replace", 13, "Queries the user for two strings, and incrementally replaces every occurence of the first string with the second string.", 120, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1150 },
{ PROC_LINKS(query_replace_identifier, 0), false, "query_replace_identifier", 24, "Queries the user for a string, and incrementally replace every occurence of the word or token found at the cursor with the specified string.", 140, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1171 },
{ PROC_LINKS(query_replace_selection, 0), false, "query_replace_selection", 23, "Queries the user for a string, and incrementally replace every occurence of the string found in the selected range with the specified string.", 141, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1187 },
{ PROC_LINKS(save_all_dirty_buffers, 0), false, "save_all_dirty_buffers", 22, "Saves all buffers marked dirty (showing the '*' indicator).", 59, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1222 },
{ PROC_LINKS(delete_file_query, 0), false, "delete_file_query", 17, "Deletes the file of the current buffer if 4coder has the appropriate access rights. Will ask the user for confirmation first.", 125, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1247 },
{ PROC_LINKS(save_to_query, 0), false, "save_to_query", 13, "Queries the user for a file name and saves the contents of the current buffer, altering the buffer's name too.", 110, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1291 },
{ PROC_LINKS(rename_file_query, 0), false, "rename_file_query", 17, "Queries the user for a new name and renames the file of the current buffer, altering the buffer's name too.", 107, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1324 },
{ PROC_LINKS(make_directory_query, 0), false, "make_directory_query", 20, "Queries the user for a name and creates a new directory with the given name.", 76, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1362 },
{ PROC_LINKS(move_line_up, 0), false, "move_line_up", 12, "Swaps the line under the cursor with the line above it, and moves the cursor up with it.", 88, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1396 },
{ PROC_LINKS(move_line_down, 0), false, "move_line_down", 14, "Swaps the line under the cursor with the line below it, and moves the cursor down with it.", 90, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1402 },
{ PROC_LINKS(duplicate_line, 0), false, "duplicate_line", 14, "Create a copy of the line on which the cursor sits.", 51, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1408 },
{ PROC_LINKS(delete_line, 0), false, "delete_line", 11, "Delete the line the on which the cursor sits.", 45, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1422 },
{ PROC_LINKS(open_file_in_quotes, 0), false, "open_file_in_quotes", 19, "Reads a filename from surrounding '\"' characters and attempts to open the corresponding file.", 94, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1487 },
{ PROC_LINKS(open_matching_file_cpp, 0), false, "open_matching_file_cpp", 22, "If the current file is a *.cpp or *.h, attempts to open the corresponding *.h or *.cpp file in the other view.", 110, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1519 },
{ PROC_LINKS(view_buffer_other_panel, 0), false, "view_buffer_other_panel", 23, "Set the other non-active panel to view the buffer that the active panel views, and switch to that panel.", 104, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1532 },
{ PROC_LINKS(swap_buffers_between_panels, 0), false, "swap_buffers_between_panels", 27, "Set the other non-active panel to view the buffer that the active panel views, and switch to that panel.", 104, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1544 },
{ PROC_LINKS(kill_buffer, 0), false, "kill_buffer", 11, "Kills the current buffer.", 25, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1578 },
{ PROC_LINKS(save, 0), false, "save", 4, "Saves the current buffer.", 25, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1586 },
{ PROC_LINKS(reopen, 0), false, "reopen", 6, "Reopen the current buffer from the hard drive.", 46, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1596 },
{ PROC_LINKS(undo, 0), false, "undo", 4, "Advances backwards through the undo history of the current buffer.", 66, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1825 },
{ PROC_LINKS(redo, 0), false, "redo", 4, "Advances forwards through the undo history of the current buffer.", 65, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1838 },
{ PROC_LINKS(undo_all_buffers, 0), false, "undo_all_buffers", 16, "Advances backward through the undo history in the buffer containing the most recent regular edit.", 97, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1852 },
{ PROC_LINKS(redo_all_buffers, 0), false, "redo_all_buffers", 16, "Advances forward through the undo history in the buffer containing the most recent regular edit.", 96, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1923 },
{ PROC_LINKS(open_in_other, 0), false, "open_in_other", 13, "Interactively opens a file in the other panel.", 46, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 2024 },
{ PROC_LINKS(default_file_externally_modified, 0), false, "default_file_externally_modified", 32, "Notes the external modification of attached files by printing a message.", 72, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 2031 },
{ PROC_LINKS(set_eol_mode_to_crlf, 0), false, "set_eol_mode_to_crlf", 20, "Puts the buffer in crlf line ending mode.", 41, "w:\\4ed\\code\\custom\\4coder_eol.cpp", 33, 80 },
{ PROC_LINKS(set_eol_mode_to_lf, 0), false, "set_eol_mode_to_lf", 18, "Puts the buffer in lf line ending mode.", 39, "w:\\4ed\\code\\custom\\4coder_eol.cpp", 33, 91 },
{ PROC_LINKS(set_eol_mode_to_binary, 0), false, "set_eol_mode_to_binary", 22, "Puts the buffer in bin line ending mode.", 40, "w:\\4ed\\code\\custom\\4coder_eol.cpp", 33, 102 },
{ PROC_LINKS(set_eol_mode_from_contents, 0), false, "set_eol_mode_from_contents", 26, "Sets the buffer's line ending mode to match the contents of the buffer.", 71, "w:\\4ed\\code\\custom\\4coder_eol.cpp", 33, 113 },
{ PROC_LINKS(save_all_dirty_buffers, 0), false, "save_all_dirty_buffers", 22, "Saves all buffers marked dirty (showing the '*' indicator).", 59, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1223 },
{ PROC_LINKS(delete_file_query, 0), false, "delete_file_query", 17, "Deletes the file of the current buffer if 4coder has the appropriate access rights. Will ask the user for confirmation first.", 125, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1248 },
{ PROC_LINKS(save_to_query, 0), false, "save_to_query", 13, "Queries the user for a file name and saves the contents of the current buffer, altering the buffer's name too.", 110, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1292 },
{ PROC_LINKS(rename_file_query, 0), false, "rename_file_query", 17, "Queries the user for a new name and renames the file of the current buffer, altering the buffer's name too.", 107, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1325 },
{ PROC_LINKS(make_directory_query, 0), false, "make_directory_query", 20, "Queries the user for a name and creates a new directory with the given name.", 76, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1363 },
{ PROC_LINKS(move_line_up, 0), false, "move_line_up", 12, "Swaps the line under the cursor with the line above it, and moves the cursor up with it.", 88, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1397 },
{ PROC_LINKS(move_line_down, 0), false, "move_line_down", 14, "Swaps the line under the cursor with the line below it, and moves the cursor down with it.", 90, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1403 },
{ PROC_LINKS(duplicate_line, 0), false, "duplicate_line", 14, "Create a copy of the line on which the cursor sits.", 51, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1409 },
{ PROC_LINKS(delete_line, 0), false, "delete_line", 11, "Delete the line the on which the cursor sits.", 45, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1423 },
{ PROC_LINKS(open_file_in_quotes, 0), false, "open_file_in_quotes", 19, "Reads a filename from surrounding '\"' characters and attempts to open the corresponding file.", 94, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1488 },
{ PROC_LINKS(open_matching_file_cpp, 0), false, "open_matching_file_cpp", 22, "If the current file is a *.cpp or *.h, attempts to open the corresponding *.h or *.cpp file in the other view.", 110, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1520 },
{ PROC_LINKS(view_buffer_other_panel, 0), false, "view_buffer_other_panel", 23, "Set the other non-active panel to view the buffer that the active panel views, and switch to that panel.", 104, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1533 },
{ PROC_LINKS(swap_buffers_between_panels, 0), false, "swap_buffers_between_panels", 27, "Set the other non-active panel to view the buffer that the active panel views, and switch to that panel.", 104, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1545 },
{ PROC_LINKS(kill_buffer, 0), false, "kill_buffer", 11, "Kills the current buffer.", 25, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1579 },
{ PROC_LINKS(save, 0), false, "save", 4, "Saves the current buffer.", 25, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1587 },
{ PROC_LINKS(reopen, 0), false, "reopen", 6, "Reopen the current buffer from the hard drive.", 46, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1597 },
{ PROC_LINKS(undo, 0), false, "undo", 4, "Advances backwards through the undo history of the current buffer.", 66, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1826 },
{ PROC_LINKS(redo, 0), false, "redo", 4, "Advances forwards through the undo history of the current buffer.", 65, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1839 },
{ PROC_LINKS(undo_all_buffers, 0), false, "undo_all_buffers", 16, "Advances backward through the undo history in the buffer containing the most recent regular edit.", 97, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1853 },
{ PROC_LINKS(redo_all_buffers, 0), false, "redo_all_buffers", 16, "Advances forward through the undo history in the buffer containing the most recent regular edit.", 96, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1924 },
{ PROC_LINKS(open_in_other, 0), false, "open_in_other", 13, "Interactively opens a file in the other panel.", 46, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 2025 },
{ PROC_LINKS(default_file_externally_modified, 0), false, "default_file_externally_modified", 32, "Notes the external modification of attached files by printing a message.", 72, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 2032 },
{ PROC_LINKS(set_eol_mode_to_crlf, 0), false, "set_eol_mode_to_crlf", 20, "Puts the buffer in crlf line ending mode.", 41, "w:\\4ed\\code\\custom\\4coder_eol.cpp", 33, 82 },
{ PROC_LINKS(set_eol_mode_to_lf, 0), false, "set_eol_mode_to_lf", 18, "Puts the buffer in lf line ending mode.", 39, "w:\\4ed\\code\\custom\\4coder_eol.cpp", 33, 93 },
{ PROC_LINKS(set_eol_mode_to_binary, 0), false, "set_eol_mode_to_binary", 22, "Puts the buffer in bin line ending mode.", 40, "w:\\4ed\\code\\custom\\4coder_eol.cpp", 33, 104 },
{ PROC_LINKS(set_eol_mode_from_contents, 0), false, "set_eol_mode_from_contents", 26, "Sets the buffer's line ending mode to match the contents of the buffer.", 71, "w:\\4ed\\code\\custom\\4coder_eol.cpp", 33, 115 },
{ PROC_LINKS(interactive_switch_buffer, 0), true, "interactive_switch_buffer", 25, "Interactively switch to an open buffer.", 39, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 477 },
{ PROC_LINKS(interactive_kill_buffer, 0), true, "interactive_kill_buffer", 23, "Interactively kill an open buffer.", 34, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 496 },
{ PROC_LINKS(interactive_open_or_new, 0), true, "interactive_open_or_new", 23, "Interactively open a file out of the file system.", 49, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 567 },
{ PROC_LINKS(interactive_new, 0), true, "interactive_new", 15, "Interactively creates a new file.", 33, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 606 },
{ PROC_LINKS(interactive_open, 0), true, "interactive_open", 16, "Interactively opens a file.", 27, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 639 },
{ PROC_LINKS(command_lister, 0), true, "command_lister", 14, "Opens an interactive list of all registered commands.", 53, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 702 },
{ PROC_LINKS(auto_indent_whole_file, 0), false, "auto_indent_whole_file", 22, "Audo-indents the entire current buffer.", 39, "w:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 367 },
{ PROC_LINKS(auto_indent_line_at_cursor, 0), false, "auto_indent_line_at_cursor", 26, "Auto-indents the line on which the cursor sits.", 47, "w:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 376 },
{ PROC_LINKS(auto_indent_range, 0), false, "auto_indent_range", 17, "Auto-indents the range between the cursor and the mark.", 55, "w:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 386 },
{ PROC_LINKS(write_text_and_auto_indent, 0), false, "write_text_and_auto_indent", 26, "Inserts text and auto-indents the line on which the cursor sits if any of the text contains 'layout punctuation' such as ;:{}()[]# and new lines.", 145, "w:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 396 },
{ PROC_LINKS(auto_indent_whole_file, 0), false, "auto_indent_whole_file", 22, "Audo-indents the entire current buffer.", 39, "w:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 368 },
{ PROC_LINKS(auto_indent_line_at_cursor, 0), false, "auto_indent_line_at_cursor", 26, "Auto-indents the line on which the cursor sits.", 47, "w:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 377 },
{ PROC_LINKS(auto_indent_range, 0), false, "auto_indent_range", 17, "Auto-indents the range between the cursor and the mark.", 55, "w:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 387 },
{ PROC_LINKS(write_text_and_auto_indent, 0), false, "write_text_and_auto_indent", 26, "Inserts text and auto-indents the line on which the cursor sits if any of the text contains 'layout punctuation' such as ;:{}()[]# and new lines.", 145, "w:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 397 },
{ PROC_LINKS(list_all_locations, 0), false, "list_all_locations", 18, "Queries the user for a string and lists all exact case-sensitive matches found in all open buffers.", 99, "w:\\4ed\\code\\custom\\4coder_search.cpp", 36, 166 },
{ PROC_LINKS(list_all_substring_locations, 0), false, "list_all_substring_locations", 28, "Queries the user for a string and lists all case-sensitive substring matches found in all open buffers.", 103, "w:\\4ed\\code\\custom\\4coder_search.cpp", 36, 172 },
{ PROC_LINKS(list_all_locations_case_insensitive, 0), false, "list_all_locations_case_insensitive", 35, "Queries the user for a string and lists all exact case-insensitive matches found in all open buffers.", 101, "w:\\4ed\\code\\custom\\4coder_search.cpp", 36, 178 },
@ -376,7 +376,7 @@ static Command_Metadata fcoder_metacmd_table[211] = {
{ PROC_LINKS(list_all_locations_of_selection_case_insensitive, 0), false, "list_all_locations_of_selection_case_insensitive", 48, "Reads the string in the selected range and lists all exact case-insensitive mathces in all open buffers.", 104, "w:\\4ed\\code\\custom\\4coder_search.cpp", 36, 208 },
{ PROC_LINKS(list_all_locations_of_type_definition, 0), false, "list_all_locations_of_type_definition", 37, "Queries user for string, lists all locations of strings that appear to define a type whose name matches the input string.", 121, "w:\\4ed\\code\\custom\\4coder_search.cpp", 36, 214 },
{ PROC_LINKS(list_all_locations_of_type_definition_of_identifier, 0), false, "list_all_locations_of_type_definition_of_identifier", 51, "Reads a token or word under the cursor and lists all locations of strings that appear to define a type whose name matches it.", 125, "w:\\4ed\\code\\custom\\4coder_search.cpp", 36, 222 },
{ PROC_LINKS(word_complete, 0), false, "word_complete", 13, "Iteratively tries completing the word to the left of the cursor with other words in open buffers that have the same prefix string.", 130, "w:\\4ed\\code\\custom\\4coder_search.cpp", 36, 392 },
{ PROC_LINKS(word_complete, 0), false, "word_complete", 13, "Iteratively tries completing the word to the left of the cursor with other words in open buffers that have the same prefix string.", 130, "w:\\4ed\\code\\custom\\4coder_search.cpp", 36, 391 },
{ PROC_LINKS(goto_jump_at_cursor, 0), false, "goto_jump_at_cursor", 19, "If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in another view and changes the active panel to the view containing the jump.", 187, "w:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 346 },
{ PROC_LINKS(goto_jump_at_cursor_same_panel, 0), false, "goto_jump_at_cursor_same_panel", 30, "If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in this view, losing the compilation output or jump list.", 167, "w:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 373 },
{ PROC_LINKS(goto_next_jump, 0), false, "goto_next_jump", 14, "If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, skipping sub jump locations.", 123, "w:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 462 },
@ -401,17 +401,17 @@ static Command_Metadata fcoder_metacmd_table[211] = {
{ PROC_LINKS(build_in_build_panel, 0), false, "build_in_build_panel", 20, "Looks for a build.bat, build.sh, or makefile in the current and parent directories. Runs the first that it finds and prints the output to *compilation*. Puts the *compilation* buffer in a panel at the footer of the current view.", 230, "w:\\4ed\\code\\custom\\4coder_build_commands.cpp", 44, 163 },
{ PROC_LINKS(close_build_panel, 0), false, "close_build_panel", 17, "If the special build panel is open, closes it.", 46, "w:\\4ed\\code\\custom\\4coder_build_commands.cpp", 44, 178 },
{ PROC_LINKS(change_to_build_panel, 0), false, "change_to_build_panel", 21, "If the special build panel is open, makes the build panel the active panel.", 75, "w:\\4ed\\code\\custom\\4coder_build_commands.cpp", 44, 184 },
{ PROC_LINKS(close_all_code, 0), false, "close_all_code", 14, "Closes any buffer with a filename ending with an extension configured to be recognized as a code file type.", 107, "w:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 917 },
{ PROC_LINKS(open_all_code, 0), false, "open_all_code", 13, "Open all code in the current directory. File types are determined by extensions. An extension is considered code based on the extensions specified in 4coder.config.", 164, "w:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 923 },
{ PROC_LINKS(open_all_code_recursive, 0), false, "open_all_code_recursive", 23, "Works as open_all_code but also runs in all subdirectories.", 59, "w:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 929 },
{ PROC_LINKS(load_project, 0), false, "load_project", 12, "Looks for a project.4coder file in the current directory and tries to load it. Looks in parent directories until a project file is found or there are no more parents.", 167, "w:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 937 },
{ PROC_LINKS(project_fkey_command, 0), false, "project_fkey_command", 20, "Run an 'fkey command' configured in a project.4coder file. Determines the index of the 'fkey command' by which function key or numeric key was pressed to trigger the command.", 175, "w:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 944 },
{ PROC_LINKS(project_go_to_root_directory, 0), false, "project_go_to_root_directory", 28, "Changes 4coder's hot directory to the root directory of the currently loaded project. With no loaded project nothing hapepns.", 125, "w:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 969 },
{ PROC_LINKS(setup_new_project, 0), false, "setup_new_project", 17, "Queries the user for several configuration options and initializes a new 4coder project with build scripts for every OS.", 120, "w:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 1303 },
{ PROC_LINKS(setup_build_bat, 0), false, "setup_build_bat", 15, "Queries the user for several configuration options and initializes a new build batch script.", 92, "w:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 1310 },
{ PROC_LINKS(setup_build_sh, 0), false, "setup_build_sh", 14, "Queries the user for several configuration options and initializes a new build shell script.", 92, "w:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 1316 },
{ PROC_LINKS(setup_build_bat_and_sh, 0), false, "setup_build_bat_and_sh", 22, "Queries the user for several configuration options and initializes a new build batch script.", 92, "w:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 1322 },
{ PROC_LINKS(project_command_lister, 0), false, "project_command_lister", 22, "Open a lister of all commands in the currently loaded project.", 62, "w:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 1338 },
{ PROC_LINKS(close_all_code, 0), false, "close_all_code", 14, "Closes any buffer with a filename ending with an extension configured to be recognized as a code file type.", 107, "w:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 918 },
{ PROC_LINKS(open_all_code, 0), false, "open_all_code", 13, "Open all code in the current directory. File types are determined by extensions. An extension is considered code based on the extensions specified in 4coder.config.", 164, "w:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 924 },
{ PROC_LINKS(open_all_code_recursive, 0), false, "open_all_code_recursive", 23, "Works as open_all_code but also runs in all subdirectories.", 59, "w:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 930 },
{ PROC_LINKS(load_project, 0), false, "load_project", 12, "Looks for a project.4coder file in the current directory and tries to load it. Looks in parent directories until a project file is found or there are no more parents.", 167, "w:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 938 },
{ PROC_LINKS(project_fkey_command, 0), false, "project_fkey_command", 20, "Run an 'fkey command' configured in a project.4coder file. Determines the index of the 'fkey command' by which function key or numeric key was pressed to trigger the command.", 175, "w:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 946 },
{ PROC_LINKS(project_go_to_root_directory, 0), false, "project_go_to_root_directory", 28, "Changes 4coder's hot directory to the root directory of the currently loaded project. With no loaded project nothing hapepns.", 125, "w:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 972 },
{ PROC_LINKS(setup_new_project, 0), false, "setup_new_project", 17, "Queries the user for several configuration options and initializes a new 4coder project with build scripts for every OS.", 120, "w:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 1306 },
{ PROC_LINKS(setup_build_bat, 0), false, "setup_build_bat", 15, "Queries the user for several configuration options and initializes a new build batch script.", 92, "w:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 1313 },
{ PROC_LINKS(setup_build_sh, 0), false, "setup_build_sh", 14, "Queries the user for several configuration options and initializes a new build shell script.", 92, "w:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 1319 },
{ PROC_LINKS(setup_build_bat_and_sh, 0), false, "setup_build_bat_and_sh", 22, "Queries the user for several configuration options and initializes a new build batch script.", 92, "w:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 1325 },
{ PROC_LINKS(project_command_lister, 0), false, "project_command_lister", 22, "Open a lister of all commands in the currently loaded project.", 62, "w:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 1341 },
{ PROC_LINKS(list_all_functions_current_buffer, 0), false, "list_all_functions_current_buffer", 33, "Creates a jump list of lines of the current buffer that appear to define or declare functions.", 94, "w:\\4ed\\code\\custom\\4coder_function_list.cpp", 43, 267 },
{ PROC_LINKS(list_all_functions_current_buffer_lister, 0), false, "list_all_functions_current_buffer_lister", 40, "Creates a lister of locations that look like function definitions and declarations in the buffer.", 97, "w:\\4ed\\code\\custom\\4coder_function_list.cpp", 43, 277 },
{ PROC_LINKS(list_all_functions_all_buffers, 0), false, "list_all_functions_all_buffers", 30, "Creates a jump list of lines from all buffers that appear to define or declare functions.", 89, "w:\\4ed\\code\\custom\\4coder_function_list.cpp", 43, 289 },
@ -441,7 +441,7 @@ static Command_Metadata fcoder_metacmd_table[211] = {
{ PROC_LINKS(miblo_decrement_time_stamp, 0), false, "miblo_decrement_time_stamp", 26, "Decrement a time stamp under the cursor by one second. (format [m]m:ss or h:mm:ss", 81, "w:\\4ed\\code\\custom\\4coder_miblo_numbers.cpp", 43, 237 },
{ PROC_LINKS(miblo_increment_time_stamp_minute, 0), false, "miblo_increment_time_stamp_minute", 33, "Increment a time stamp under the cursor by one minute. (format [m]m:ss or h:mm:ss", 81, "w:\\4ed\\code\\custom\\4coder_miblo_numbers.cpp", 43, 243 },
{ PROC_LINKS(miblo_decrement_time_stamp_minute, 0), false, "miblo_decrement_time_stamp_minute", 33, "Decrement a time stamp under the cursor by one minute. (format [m]m:ss or h:mm:ss", 81, "w:\\4ed\\code\\custom\\4coder_miblo_numbers.cpp", 43, 249 },
{ PROC_LINKS(profile_inspect, 0), true, "profile_inspect", 15, "Inspect all currently collected profiling information in 4coder's self profiler.", 80, "w:\\4ed\\code\\custom\\4coder_profile_inspect.cpp", 45, 377 },
{ PROC_LINKS(profile_inspect, 0), true, "profile_inspect", 15, "Inspect all currently collected profiling information in 4coder's self profiler.", 80, "w:\\4ed\\code\\custom\\4coder_profile_inspect.cpp", 45, 408 },
{ PROC_LINKS(default_startup, 0), false, "default_startup", 15, "Default command for responding to a startup event", 49, "w:\\4ed\\code\\custom\\4coder_default_hooks.cpp", 43, 7 },
{ PROC_LINKS(default_try_exit, 0), false, "default_try_exit", 16, "Default command for responding to a try-exit event", 50, "w:\\4ed\\code\\custom\\4coder_default_hooks.cpp", 43, 21 },
};

File diff suppressed because it is too large Load Diff

View File

@ -29,6 +29,8 @@ vtable->thread_launch = system_thread_launch;
vtable->thread_join = system_thread_join;
vtable->thread_free = system_thread_free;
vtable->thread_get_id = system_thread_get_id;
vtable->acquire_global_frame_mutex = system_acquire_global_frame_mutex;
vtable->release_global_frame_mutex = system_release_global_frame_mutex;
vtable->mutex_make = system_mutex_make;
vtable->mutex_acquire = system_mutex_acquire;
vtable->mutex_release = system_mutex_release;
@ -77,6 +79,8 @@ system_thread_launch = vtable->thread_launch;
system_thread_join = vtable->thread_join;
system_thread_free = vtable->thread_free;
system_thread_get_id = vtable->thread_get_id;
system_acquire_global_frame_mutex = vtable->acquire_global_frame_mutex;
system_release_global_frame_mutex = vtable->release_global_frame_mutex;
system_mutex_make = vtable->mutex_make;
system_mutex_acquire = vtable->mutex_acquire;
system_mutex_release = vtable->mutex_release;

View File

@ -27,6 +27,8 @@
#define system_thread_join_sig() void system_thread_join(System_Thread thread)
#define system_thread_free_sig() void system_thread_free(System_Thread thread)
#define system_thread_get_id_sig() i32 system_thread_get_id(void)
#define system_acquire_global_frame_mutex_sig() void system_acquire_global_frame_mutex(Thread_Context* tctx)
#define system_release_global_frame_mutex_sig() void system_release_global_frame_mutex(Thread_Context* tctx)
#define system_mutex_make_sig() System_Mutex system_mutex_make(void)
#define system_mutex_acquire_sig() void system_mutex_acquire(System_Mutex mutex)
#define system_mutex_release_sig() void system_mutex_release(System_Mutex mutex)
@ -71,6 +73,8 @@ typedef System_Thread system_thread_launch_type(Thread_Function* proc, void* ptr
typedef void system_thread_join_type(System_Thread thread);
typedef void system_thread_free_type(System_Thread thread);
typedef i32 system_thread_get_id_type(void);
typedef void system_acquire_global_frame_mutex_type(Thread_Context* tctx);
typedef void system_release_global_frame_mutex_type(Thread_Context* tctx);
typedef System_Mutex system_mutex_make_type(void);
typedef void system_mutex_acquire_type(System_Mutex mutex);
typedef void system_mutex_release_type(System_Mutex mutex);
@ -116,6 +120,8 @@ system_thread_launch_type *thread_launch;
system_thread_join_type *thread_join;
system_thread_free_type *thread_free;
system_thread_get_id_type *thread_get_id;
system_acquire_global_frame_mutex_type *acquire_global_frame_mutex;
system_release_global_frame_mutex_type *release_global_frame_mutex;
system_mutex_make_type *mutex_make;
system_mutex_acquire_type *mutex_acquire;
system_mutex_release_type *mutex_release;
@ -162,6 +168,8 @@ internal System_Thread system_thread_launch(Thread_Function* proc, void* ptr);
internal void system_thread_join(System_Thread thread);
internal void system_thread_free(System_Thread thread);
internal i32 system_thread_get_id(void);
internal void system_acquire_global_frame_mutex(Thread_Context* tctx);
internal void system_release_global_frame_mutex(Thread_Context* tctx);
internal System_Mutex system_mutex_make(void);
internal void system_mutex_acquire(System_Mutex mutex);
internal void system_mutex_release(System_Mutex mutex);
@ -208,6 +216,8 @@ global system_thread_launch_type *system_thread_launch = 0;
global system_thread_join_type *system_thread_join = 0;
global system_thread_free_type *system_thread_free = 0;
global system_thread_get_id_type *system_thread_get_id = 0;
global system_acquire_global_frame_mutex_type *system_acquire_global_frame_mutex = 0;
global system_release_global_frame_mutex_type *system_release_global_frame_mutex = 0;
global system_mutex_make_type *system_mutex_make = 0;
global system_mutex_acquire_type *system_mutex_acquire = 0;
global system_mutex_release_type *system_mutex_release = 0;

View File

@ -27,6 +27,8 @@ api(system) function System_Thread thread_launch(Thread_Function* proc, void* pt
api(system) function void thread_join(System_Thread thread);
api(system) function void thread_free(System_Thread thread);
api(system) function i32 thread_get_id(void);
api(system) function void acquire_global_frame_mutex(Thread_Context* tctx);
api(system) function void release_global_frame_mutex(Thread_Context* tctx);
api(system) function System_Mutex mutex_make(void);
api(system) function void mutex_acquire(System_Mutex mutex);
api(system) function void mutex_release(System_Mutex mutex);

View File

@ -3258,7 +3258,7 @@ gen_flag_check__cont_flow(Flag *flag, b32 value, FILE *out){
if (value == 0){
fprintf(out, "!");
}
fprintf(out, "HasFlag(%.*s%d, 0x%x)", string_expand(flag->base_name), flag->index, flag->value);
fprintf(out, "HasFlag(state.%.*s%d, 0x%x)", string_expand(flag->base_name), flag->index, flag->value);
}
internal void
@ -3298,6 +3298,7 @@ gen_goto_state__cont_flow(State *state, Action_Context context, FILE *out){
}break;
case ActionContext_EndOfFile:
{
fprintf(out, "result = true;\n");
fprintf(out, "goto end;\n");
}break;
}
@ -3312,11 +3313,11 @@ internal void
gen_action__set_flag(Flag *flag, b32 value, FILE *out){
if (flag != 0){
if (value == 0){
fprintf(out, "%.*s%d &= ~(0x%x);\n",
fprintf(out, "state.%.*s%d &= ~(0x%x);\n",
string_expand(flag->base_name), flag->index, flag->value);
}
else{
fprintf(out, "%.*s%d |= 0x%x;\n",
fprintf(out, "state.%.*s%d |= 0x%x;\n",
string_expand(flag->base_name), flag->index, flag->value);
}
}
@ -3326,15 +3327,15 @@ internal void
gen_emit__fill_token_flags(Flag_Set flags, Flag_Bucket_Set bucket_set, FILE *out){
if (bucket_set.buckets[FlagBindProperty_Bound][FlagResetRule_AutoZero].count > 0){
if (bucket_set.buckets[FlagBindProperty_Bound][FlagResetRule_KeepState].count > 0){
fprintf(out, "token.flags = flag_ZB0 | flags_KB0;\n");
fprintf(out, "token.flags = state.flag_ZB0 | state.flags_KB0;\n");
}
else{
fprintf(out, "token.flags = flags_ZB0;\n");
fprintf(out, "token.flags = state.flags_ZB0;\n");
}
}
else{
if (bucket_set.buckets[FlagBindProperty_Bound][FlagResetRule_KeepState].count > 0){
fprintf(out, "token.flags = flags_KB0;\n");
fprintf(out, "token.flags = state.flags_KB0;\n");
}
}
for (Flag *flag = flags.first;
@ -3390,25 +3391,25 @@ gen_SLOW_action_list__cont_flow(Arena *scratch, Token_Kind_Set tokens, Flag_Set
for (i32 i = 0; i < FlagBindProperty_COUNT; i += 1){
Flag_Bucket *bucket = &bucket_set.buckets[i][FlagResetRule_AutoZero];
for (i32 j = 0; j < bucket->number_of_variables; j += 1){
fprintf(out, "%.*s%d = 0;\n", string_expand(bucket->pretty_name), j);
fprintf(out, "state.%.*s%d = 0;\n", string_expand(bucket->pretty_name), j);
}
}
}break;
case ActionKind_DelimMarkFirst:
{
fprintf(out, "delim_first = ptr;\n");
fprintf(out, "state.delim_first = state.ptr;\n");
}break;
case ActionKind_DelimMarkOnePastLast:
{
fprintf(out, "delim_one_past_last = ptr;\n");
fprintf(out, "state.delim_one_past_last = state.ptr;\n");
}break;
case ActionKind_Consume:
{
if (context != ActionContext_EndOfFile){
fprintf(out, "ptr += 1;\n");
fprintf(out, "state.ptr += 1;\n");
}
else{
result_context = ActionContext_EndOfFile;
@ -3422,8 +3423,8 @@ gen_SLOW_action_list__cont_flow(Arena *scratch, Token_Kind_Set tokens, Flag_Set
fprintf(out, "{\n");
fprintf(out, "Token token = {};\n");
fprintf(out, "token.pos = (i64)(emit_ptr - input.str);\n");
fprintf(out, "token.size = (i64)(ptr - emit_ptr);\n");
fprintf(out, "token.pos = (i64)(state.emit_ptr - state.base);\n");
fprintf(out, "token.size = (i64)(state.ptr - state.emit_ptr);\n");
gen_emit__fill_token_flags(flags, bucket_set, out);
@ -3454,7 +3455,7 @@ gen_SLOW_action_list__cont_flow(Arena *scratch, Token_Kind_Set tokens, Flag_Set
fprintf(out, "Lexeme_Table_Lookup lookup = "
"lexeme_table_lookup(%.*s_hash_array, %.*s_key_array, "
"%.*s_value_array, %.*s_slot_count, %.*s_seed, "
"emit_ptr, token.size);\n",
"state.emit_ptr, token.size);\n",
string_expand(keywords->pretty_name),
string_expand(keywords->pretty_name),
string_expand(keywords->pretty_name),
@ -3478,7 +3479,7 @@ gen_SLOW_action_list__cont_flow(Arena *scratch, Token_Kind_Set tokens, Flag_Set
fprintf(out, "Lexeme_Table_Lookup lookup = "
"lexeme_table_lookup(%.*s_hash_array, %.*s_key_array, "
"%.*s_value_array, %.*s_slot_count, %.*s_seed, "
"delim_first, (delim_one_past_last - delim_first));\n",
"state.delim_first, (state.delim_one_past_last - state.delim_first));\n",
string_expand(keywords->pretty_name),
string_expand(keywords->pretty_name),
string_expand(keywords->pretty_name),
@ -3520,8 +3521,14 @@ gen_SLOW_action_list__cont_flow(Arena *scratch, Token_Kind_Set tokens, Flag_Set
fprintf(out, "}\n");
}
fprintf(out, "token_list_push(arena, &list, &token);\n");
fprintf(out, "emit_ptr = ptr;\n");
fprintf(out, "token_list_push(arena, list, &token);\n");
fprintf(out, "emit_counter += 1;\n");
if (context != ActionContext_EndOfFile){
fprintf(out, "if (emit_counter == max){\n");
fprintf(out, "goto end;\n");
fprintf(out, "}\n");
}
fprintf(out, "state.emit_ptr = state.ptr;\n");
fprintf(out, "}\n");
}break;
}
@ -3535,7 +3542,18 @@ gen_flag_declarations__cont_flow(Flag_Bucket *bucket, FILE *out){
i32 number_of_flag_variables = (bucket->count + max_bits - 1)/max_bits;
String_Const_u8 pretty_name = bucket->pretty_name;
for (i32 i = 0; i < number_of_flag_variables; i += 1){
fprintf(out, "u%d %.*s%d = 0;\n", max_bits, string_expand(pretty_name), i);
fprintf(out, "u%d %.*s%d;\n", max_bits, string_expand(pretty_name), i);
}
bucket->number_of_variables = number_of_flag_variables;
}
internal void
gen_flag_init__cont_flow(Flag_Bucket *bucket, FILE *out){
i32 max_bits = bucket->max_bits;
i32 number_of_flag_variables = (bucket->count + max_bits - 1)/max_bits;
String_Const_u8 pretty_name = bucket->pretty_name;
for (i32 i = 0; i < number_of_flag_variables; i += 1){
fprintf(out, "state_ptr->%.*s%d = 0;\n", string_expand(pretty_name), i);
}
bucket->number_of_variables = number_of_flag_variables;
}
@ -3664,23 +3682,43 @@ gen_contiguous_control_flow_lexer(Arena *scratch, Token_Kind_Set tokens, Lexer_M
}
}
fprintf(out, "internal Token_List\n");
fprintf(out, "lex_full_input_" LANG_NAME_LOWER_STR "(Arena *arena, String_Const_u8 input){\n");
fprintf(out, "Token_List list = {};\n");
fprintf(out, "struct Lex_State_" LANG_NAME_CAMEL_STR "{\n");
for (i32 i = 0; i < FlagBindProperty_COUNT; i += 1){
for (i32 j = 0; j < FlagResetRule_COUNT; j += 1){
gen_flag_declarations__cont_flow(&bucket_set.buckets[i][j], out);
}
}
fprintf(out, "u8 *base;\n");
fprintf(out, "u8 *delim_first;\n");
fprintf(out, "u8 *delim_one_past_last;\n");
fprintf(out, "u8 *emit_ptr;\n");
fprintf(out, "u8 *ptr;\n");
fprintf(out, "u8 *opl_ptr;\n");
fprintf(out, "};\n");
fprintf(out, "u8 *delim_first = input.str;\n");
fprintf(out, "u8 *delim_one_past_last = input.str;\n");
fprintf(out, "internal void\n");
fprintf(out, "lex_full_input_" LANG_NAME_LOWER_STR "_init(Lex_State_"
LANG_NAME_CAMEL_STR " *state_ptr, String_Const_u8 input){\n");
for (i32 i = 0; i < FlagBindProperty_COUNT; i += 1){
for (i32 j = 0; j < FlagResetRule_COUNT; j += 1){
gen_flag_init__cont_flow(&bucket_set.buckets[i][j], out);
}
}
fprintf(out, "state_ptr->base = input.str;\n");
fprintf(out, "state_ptr->delim_first = input.str;\n");
fprintf(out, "state_ptr->delim_one_past_last = input.str;\n");
fprintf(out, "state_ptr->emit_ptr = input.str;\n");
fprintf(out, "state_ptr->ptr = input.str;\n");
fprintf(out, "state_ptr->opl_ptr = input.str + input.size;\n");
fprintf(out, "}\n");
fprintf(out, "u8 *emit_ptr = input.str;\n");
fprintf(out, "u8 *ptr = input.str;\n");
fprintf(out, "u8 *opl_ptr = ptr + input.size;\n");
fprintf(out, "internal b32\n");
fprintf(out, "lex_full_input_" LANG_NAME_LOWER_STR "_breaks("
"Arena *arena, Token_List *list, Lex_State_" LANG_NAME_CAMEL_STR " *state_ptr, u64 max){\n");
fprintf(out, "b32 result = false;\n");
fprintf(out, "u64 emit_counter = 0;\n");
fprintf(out, "Lex_State_" LANG_NAME_CAMEL_STR " state;\n");
fprintf(out, "block_copy_struct(&state, state_ptr);\n");
for (State *state = model.states.first;
state != 0;
@ -3706,7 +3744,7 @@ gen_contiguous_control_flow_lexer(Arena *scratch, Token_Kind_Set tokens, Lexer_M
Transition *failure_trans = trans->next;
Assert(failure_trans->condition.kind == TransitionCaseKind_DelimMatchFail);
fprintf(out, "umem delim_length = delim_one_past_last - delim_first;\n");
fprintf(out, "umem delim_length = state.delim_one_past_last - state.delim_first;\n");
fprintf(out, "umem parse_length = 0;\n");
fprintf(out, "for (;;){\n");
{
@ -3718,7 +3756,7 @@ gen_contiguous_control_flow_lexer(Arena *scratch, Token_Kind_Set tokens, Lexer_M
gen_goto_dst_state__cont_flow(success_trans, ActionContext_Normal, out);
}
fprintf(out, "}\n");
fprintf(out, "if (ptr == opl_ptr){\n");
fprintf(out, "if (state.ptr == state.opl_ptr){\n");
{
gen_SLOW_action_list__cont_flow(scratch, tokens, model.flags, bucket_set,
failure_trans->activation_actions,
@ -3727,8 +3765,8 @@ gen_contiguous_control_flow_lexer(Arena *scratch, Token_Kind_Set tokens, Lexer_M
}
fprintf(out, "}\n");
fprintf(out, "if (*ptr == delim_first[parse_length]){\n");
fprintf(out, "ptr += 1;\n");
fprintf(out, "if (*state.ptr == state.delim_first[parse_length]){\n");
fprintf(out, "state.ptr += 1;\n");
fprintf(out, "parse_length += 1;\n");
fprintf(out, "}\n");
fprintf(out, "else{\n");
@ -3746,7 +3784,7 @@ gen_contiguous_control_flow_lexer(Arena *scratch, Token_Kind_Set tokens, Lexer_M
case TransitionCaseKind_ConditionSet:
{
{
fprintf(out, "if (ptr == opl_ptr){\n");
fprintf(out, "if (state.ptr == state.opl_ptr){\n");
for (;
trans != 0;
trans = trans->next){
@ -3773,7 +3811,7 @@ gen_contiguous_control_flow_lexer(Arena *scratch, Token_Kind_Set tokens, Lexer_M
Grouped_Input_Handler_List group_list = opt_grouped_input_handlers(scratch, trans);
fprintf(out, "switch (*ptr){\n");
fprintf(out, "switch (*state.ptr){\n");
for (Grouped_Input_Handler *group = group_list.first;
group != 0;
group = group->next){
@ -3823,6 +3861,16 @@ gen_contiguous_control_flow_lexer(Arena *scratch, Token_Kind_Set tokens, Lexer_M
}
fprintf(out, "end:;\n");
fprintf(out, "block_copy_struct(state_ptr, &state);\n");
fprintf(out, "return(result);\n");
fprintf(out, "}\n");
fprintf(out, "internal Token_List\n");
fprintf(out, "lex_full_input_" LANG_NAME_LOWER_STR "(Arena *arena, String_Const_u8 input){\n");
fprintf(out, "Lex_State_" LANG_NAME_CAMEL_STR " state = {};\n");
fprintf(out, "lex_full_input_" LANG_NAME_LOWER_STR "_init(&state, input);\n");
fprintf(out, "Token_List list = {};\n");
fprintf(out, "lex_full_input_" LANG_NAME_LOWER_STR "_breaks(arena, &list, &state, max_u64);\n");
fprintf(out, "return(list);\n");
fprintf(out, "}\n");

View File

@ -188,6 +188,8 @@ struct Win32_Vars{
CONDITION_VARIABLE thread_launch_cv;
b32 waiting_for_launch;
System_Mutex global_frame_mutex;
Log_Function *log_string;
};
@ -887,6 +889,20 @@ system_mutex_release_sig(){
}
}
internal
system_acquire_global_frame_mutex_sig(){
if (tctx->kind == ThreadKind_AsyncTasks){
system_mutex_acquire(win32vars.global_frame_mutex);
}
}
internal
system_release_global_frame_mutex_sig(){
if (tctx->kind == ThreadKind_AsyncTasks){
system_mutex_release(win32vars.global_frame_mutex);
}
}
internal
system_mutex_free_sig(){
Win32_Object *object = (Win32_Object*)handle_type_ptr(mutex);
@ -1440,7 +1456,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS
// NOTE(allen): context setup
Thread_Context _tctx = {};
thread_ctx_init(&_tctx, get_base_allocator_system(), get_base_allocator_system());
thread_ctx_init(&_tctx, ThreadKind_Main, get_base_allocator_system(), get_base_allocator_system());
block_zero_struct(&win32vars);
win32vars.tctx = &_tctx;
@ -1665,7 +1681,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS
Scratch_Block scratch(win32vars.tctx, Scratch_Share);
String_Const_u8 curdir = system_get_path(scratch, SystemPath_CurrentDirectory);
curdir = string_mod_replace_character(curdir, '\\', '/');
app.init(&target, base_ptr, win32vars.clipboard_contents, curdir, custom);
app.init(win32vars.tctx, &target, base_ptr, win32vars.clipboard_contents, curdir, custom);
}
//
@ -1684,6 +1700,9 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS
SetActiveWindow(win32vars.window_handle);
ShowWindow(win32vars.window_handle, SW_SHOW);
win32vars.global_frame_mutex = system_mutex_make();
system_mutex_acquire(win32vars.global_frame_mutex);
u64 timer_start = system_now_time();
MSG msg;
for (;keep_running;){
@ -1852,7 +1871,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS
// NOTE(allen): Application Core Update
Application_Step_Result result = {};
if (app.step != 0){
result = app.step(&target, base_ptr, &input);
result = app.step(win32vars.tctx, &target, base_ptr, &input);
}
else{
//LOG("app.step == 0 -- skipping\n");
@ -1921,6 +1940,8 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS
}
// NOTE(allen): sleep a bit to cool off :)
system_mutex_release(win32vars.global_frame_mutex);
u64 timer_end = system_now_time();
u64 end_target = timer_start + frame_useconds;
@ -1933,6 +1954,8 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS
}
timer_start = system_now_time();
system_mutex_acquire(win32vars.global_frame_mutex);
win32vars.first = false;
}

View File

@ -14,10 +14,13 @@ mode = "4coder";
// UI
use_scroll_bars = false;
use_file_bars = true;
use_line_highlight = true;
use_error_highlight = true;
use_jump_highlight = true;
use_scope_highlight = true;
use_paren_helper = true;
use_comment_keywords = true;
lister_whole_word_backspace_when_modified = false;
show_line_number_margins = false;
// Code Wrapping
treat_as_code = ".cpp.c.hpp.h.cc.cs.java.rs.glsl.m";