From afbde90d9e8fe24ecc252763e479e5fd7ad7a932 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Fri, 30 Oct 2015 22:33:13 -0400 Subject: [PATCH] multi-gap buffer --- 4ed.cpp | 40 ++- 4ed_color_view.cpp | 6 +- 4ed_file_view.cpp | 379 ++++++++++------------------- 4ed_meta.h | 2 +- buffer/4coder_buffer_abstract.cpp | 70 +++++- buffer/4coder_gap_buffer.cpp | 82 ++++++- buffer/4coder_golden_array.cpp | 98 +++++--- buffer/4coder_multi_gap_buffer.cpp | 165 +++++++++++++ buffer/4coder_shared.cpp | 40 ++- win32_4ed.cpp | 24 +- 10 files changed, 596 insertions(+), 310 deletions(-) create mode 100644 buffer/4coder_multi_gap_buffer.cpp diff --git a/4ed.cpp b/4ed.cpp index 638e13f3..c41a24ad 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -123,7 +123,7 @@ globalvar Application_Links app_links; #define REQ_VIEW(n) View *n = command->view; if (!n) return #define REQ_FILE_VIEW(n) File_View *n = view_to_file_view(command->view); if (!n) return -#define REQ_FILE(n,v) Editing_File *n = (v)->file; if (!n || !n->buffer.data || n->is_dummy) return +#define REQ_FILE(n,v) Editing_File *n = (v)->file; if (!n || !buffer_good(&n->buffer) || n->is_dummy) return #define REQ_COLOR_VIEW(n) Color_View *n = view_to_color_view(command->view); if (!n) return #define REQ_DBG_VIEW(n) Debug_View *n = view_to_debug_view(command->view); if (!n) return @@ -215,6 +215,7 @@ COMMAND_DECL(write_character){ } COMMAND_DECL(seek_whitespace_right){ +#if BUFFER_EXPERIMENT_SCALPEL <= 1 ProfileMomentFunction(); REQ_FILE_VIEW(view); REQ_FILE(file, view); @@ -222,9 +223,11 @@ COMMAND_DECL(seek_whitespace_right){ i32 pos = buffer_seek_whitespace_right(&file->buffer, view->cursor.pos); view_cursor_move(view, pos); +#endif } COMMAND_DECL(seek_whitespace_left){ +#if BUFFER_EXPERIMENT_SCALPEL <= 1 ProfileMomentFunction(); REQ_FILE_VIEW(view); REQ_FILE(file, view); @@ -232,24 +235,29 @@ COMMAND_DECL(seek_whitespace_left){ i32 pos = buffer_seek_whitespace_left(&file->buffer, view->cursor.pos); view_cursor_move(view, pos); +#endif } COMMAND_DECL(seek_whitespace_up){ +#if BUFFER_EXPERIMENT_SCALPEL <= 1 ProfileMomentFunction(); REQ_FILE_VIEW(view); REQ_FILE(file, view); i32 pos = buffer_seek_whitespace_up(&file->buffer, view->cursor.pos); view_cursor_move(view, pos); +#endif } COMMAND_DECL(seek_whitespace_down){ +#if BUFFER_EXPERIMENT_SCALPEL <= 1 ProfileMomentFunction(); REQ_FILE_VIEW(view); REQ_FILE(file, view); i32 pos = buffer_seek_whitespace_down(&file->buffer, view->cursor.pos); view_cursor_move(view, pos); +#endif } internal i32 @@ -304,7 +312,7 @@ COMMAND_DECL(seek_token_right){ } COMMAND_DECL(seek_white_or_token_right){ -#if BUFFER_EXPERIMENT_SCALPEL +#if BUFFER_EXPERIMENT_SCALPEL <= 0 ProfileMomentFunction(); REQ_FILE_VIEW(view); REQ_FILE(file, view); @@ -320,7 +328,7 @@ COMMAND_DECL(seek_white_or_token_right){ } COMMAND_DECL(seek_white_or_token_left){ -#if BUFFER_EXPERIMENT_SCALPEL +#if BUFFER_EXPERIMENT_SCALPEL <= 0 ProfileMomentFunction(); REQ_FILE_VIEW(view); REQ_FILE(file, view); @@ -336,24 +344,29 @@ COMMAND_DECL(seek_white_or_token_left){ } COMMAND_DECL(seek_alphanumeric_right){ +#if BUFFER_EXPERIMENT_SCALPEL <= 1 ProfileMomentFunction(); REQ_FILE_VIEW(view); REQ_FILE(file, view); i32 pos = buffer_seek_alphanumeric_right(&file->buffer, view->cursor.pos); view_cursor_move(view, pos); +#endif } COMMAND_DECL(seek_alphanumeric_left){ +#if BUFFER_EXPERIMENT_SCALPEL <= 1 ProfileMomentFunction(); REQ_FILE_VIEW(view); REQ_FILE(file, view); i32 pos = buffer_seek_alphanumeric_left(&file->buffer, view->cursor.pos); view_cursor_move(view, pos); +#endif } COMMAND_DECL(seek_alphanumeric_or_camel_right){ +#if BUFFER_EXPERIMENT_SCALPEL <= 1 ProfileMomentFunction(); REQ_FILE_VIEW(view); REQ_FILE(file, view); @@ -361,9 +374,11 @@ COMMAND_DECL(seek_alphanumeric_or_camel_right){ i32 an_pos = buffer_seek_alphanumeric_right(&file->buffer, view->cursor.pos); i32 pos = buffer_seek_alphanumeric_or_camel_right(&file->buffer, view->cursor.pos, an_pos); view_cursor_move(view, pos); +#endif } COMMAND_DECL(seek_alphanumeric_or_camel_left){ +#if BUFFER_EXPERIMENT_SCALPEL <= 1 ProfileMomentFunction(); REQ_FILE_VIEW(view); REQ_FILE(file, view); @@ -371,6 +386,7 @@ COMMAND_DECL(seek_alphanumeric_or_camel_left){ i32 an_pos = buffer_seek_alphanumeric_left(&file->buffer, view->cursor.pos); i32 pos = buffer_seek_alphanumeric_or_camel_left(&file->buffer, view->cursor.pos, an_pos); view_cursor_move(view, pos); +#endif } COMMAND_DECL(search){ @@ -690,7 +706,7 @@ app_open_file(App_Vars *vars, General_Memory *general, Panel *panel, new_view->map = app_get_map(vars, target_file->base_map_id); -#if BUFFER_EXPERIMENT_SCALPEL +#if BUFFER_EXPERIMENT_SCALPEL <= 0 if (created_file && target_file->tokens_exist) file_first_lex_parallel(general, target_file); #endif @@ -766,7 +782,7 @@ COMMAND_DECL(reopen){ *file = temp_file; file->source_path.str = file->source_path_; file->live_name.str = file->live_name_; -#if BUFFER_EXPERIMENT_SCALPEL +#if BUFFER_EXPERIMENT_SCALPEL <= 0 if (file->tokens_exist) file_first_lex_parallel(&mem->general, file); #endif @@ -920,7 +936,7 @@ COMMAND_DECL(toggle_show_whitespace){ } COMMAND_DECL(toggle_tokens){ -#if BUFFER_EXPERIMENT_SCALPEL +#if BUFFER_EXPERIMENT_SCALPEL <= 0 ProfileMomentFunction(); REQ_FILE_VIEW(view); REQ_FILE(file, view); @@ -938,6 +954,7 @@ COMMAND_DECL(toggle_tokens){ internal void case_change_range(Mem_Options *mem, File_View *view, Editing_File *file, u8 a, u8 z, u8 char_delta){ +#if BUFFER_EXPERIMENT_SCALPEL <= 0 Range range = get_range(view->cursor.pos, view->mark); if (range.start < range.end){ Edit_Step step = {}; @@ -958,11 +975,10 @@ case_change_range(Mem_Options *mem, File_View *view, Editing_File *file, } } -#if BUFFER_EXPERIMENT_SCALPEL if (file->token_stack.tokens) file_relex_parallel(mem, file, range.start, range.end, 0); -#endif } +#endif } COMMAND_DECL(to_uppercase){ @@ -1452,7 +1468,7 @@ COMMAND_DECL(set_settings){ switch (p){ case par_lex_as_cpp_file: { -#if BUFFER_EXPERIMENT_SCALPEL +#if BUFFER_EXPERIMENT_SCALPEL <= 0 int v = dynamic_to_bool(¶m->param.value); if (file->tokens_exist){ if (!v) file_kill_tokens(&mem->general, file); @@ -1572,7 +1588,7 @@ extern "C"{ if (view){ Editing_File *file = view->file; if (file && !file->is_dummy){ -#if BUFFER_EXPERIMENT_SCALPEL +#if BUFFER_EXPERIMENT_SCALPEL <= 0 Working_Set *working_set = cmd->working_set; buffer.file_id = (int)(file - working_set->files); buffer.size = file->buffer.size; @@ -2943,7 +2959,7 @@ app_step(Thread_Context *thread, Key_Codes *codes, view_set_file(file_view, file.file, style, vars->hooks[hook_open_file], &command_data, app_links); new_view->map = app_get_map(vars, file.file->base_map_id); -#if BUFFER_EXPERIMENT_SCALPEL +#if BUFFER_EXPERIMENT_SCALPEL <= 0 if (file.file->tokens_exist) file_first_lex_parallel(general, file.file); #endif }break; @@ -3058,7 +3074,7 @@ app_step(Thread_Context *thread, Key_Codes *codes, Editing_File *file = vars->working_set.files; for (i32 i = vars->working_set.file_index_count; i > 0; --i, ++file){ - if (file->buffer.data && !file->is_dummy){ + if (buffer_good(&file->buffer) && !file->is_dummy){ file_measure_widths(&vars->mem.general, file, vars->style.font); } } diff --git a/4ed_color_view.cpp b/4ed_color_view.cpp index 3178a951..fcd46532 100644 --- a/4ed_color_view.cpp +++ b/4ed_color_view.cpp @@ -1111,13 +1111,14 @@ step_draw_adjusting(Color_View *color_view, i32_Rect rect, View_Message message, internal void update_highlighting(Color_View *color_view){ - Style *style = color_view->main_style; File_View *file_view = color_view->hot_file_view; if (!file_view){ color_view->highlight = {}; return; } - + +#if BUFFER_EXPERIMENT_SCALPEL <= 0 + Style *style = color_view->main_style; Editing_File *file = file_view->file; i32 pos = view_get_cursor_pos(file_view); char c = file->buffer.data[pos]; @@ -1181,6 +1182,7 @@ update_highlighting(Color_View *color_view){ color_view->highlight.ids[2] = 0; color_view->highlight.ids[3] = 0; } +#endif } internal bool32 diff --git a/4ed_file_view.cpp b/4ed_file_view.cpp index fe011150..8923a699 100644 --- a/4ed_file_view.cpp +++ b/4ed_file_view.cpp @@ -11,13 +11,17 @@ #include "buffer/4coder_shared.cpp" -#if BUFFER_EXPERIMENT_SCALPEL +#if BUFFER_EXPERIMENT_SCALPEL == 0 #include "buffer/4coder_golden_array.cpp" #define Buffer_Type Buffer -#else +#elif BUFFER_EXPERIMENT_SCALPEL == 1 #include "buffer/4coder_gap_buffer.cpp" #define Buffer_Type Gap_Buffer +#else +#include "buffer/4coder_multi_gap_buffer.cpp" +#define Buffer_Type Multi_Gap_Buffer #endif + #include "buffer/4coder_buffer_abstract.cpp" struct Range{ @@ -1118,6 +1122,7 @@ file_synchronize_times(Editing_File *file, u8 *filename){ internal bool32 file_save(Partition *part, Editing_File *file, u8 *filename){ bool32 result = 0; +#if BUFFER_EXPERIMENT_SCALPEL <= 1 Temp_Memory temp = begin_temp_memory(part); i32 max = partition_remaining(part); if (file->dos_write_mode){ @@ -1134,6 +1139,7 @@ file_save(Partition *part, Editing_File *file, u8 *filename){ } end_temp_memory(temp); file_synchronize_times(file, filename); +#endif return result; } @@ -1149,7 +1155,11 @@ file_save_and_set_names(Partition *part, Editing_File *file, u8 *filename){ inline i32 file_count_newlines(Editing_File *file, i32 start, i32 end){ +#if BUFFER_EXPERIMENT_SCALPEL <= 1 i32 count = buffer_count_newlines(&file->buffer, start, end); +#else + i32 count = 0; +#endif return count; } @@ -1173,6 +1183,7 @@ enum File_Bubble_Type{ internal i32 file_grow_starts_as_needed(General_Memory *general, Editing_File *file, i32 additional_lines){ bool32 result = GROW_NOT_NEEDED; +#if BUFFER_EXPERIMENT_SCALPEL <= 1 i32 max = file->buffer.line_max; i32 count = file->buffer.line_count; i32 target_lines = count + additional_lines; @@ -1190,11 +1201,13 @@ file_grow_starts_as_needed(General_Memory *general, Editing_File *file, i32 addi result = GROW_FAILED; } } +#endif return result; } internal void file_measure_starts(General_Memory *general, Editing_File *file){ +#if BUFFER_EXPERIMENT_SCALPEL <= 1 ProfileMomentFunction(); if (!file->buffer.line_starts){ i32 max = file->buffer.line_max = Kbytes(1); @@ -1220,18 +1233,21 @@ file_measure_starts(General_Memory *general, Editing_File *file){ file->buffer.line_max = max; } file->buffer.line_count = state.count; +#endif } internal void file_remeasure_starts(General_Memory *general, Editing_File *file, i32 line_start, i32 line_end, i32 line_shift, i32 character_shift){ +#if BUFFER_EXPERIMENT_SCALPEL <= 1 ProfileMomentFunction(); Assert(file->buffer.line_starts); file_grow_starts_as_needed(general, file, line_shift); buffer_remeasure_starts(&file->buffer, line_start, line_end, line_shift, character_shift); +#endif } struct Opaque_Font_Advance{ @@ -1249,6 +1265,7 @@ get_opaque_font_advance(Font *font){ internal void file_grow_widths_as_needed(General_Memory *general, Editing_File *file){ +#if BUFFER_EXPERIMENT_SCALPEL <= 1 i32 line_count = file->buffer.line_count; if (line_count > file->buffer.widths_max){ i32 new_max = LargeRoundUp(line_count, Kbytes(1)); @@ -1262,26 +1279,31 @@ file_grow_widths_as_needed(General_Memory *general, Editing_File *file){ } file->buffer.widths_max = new_max; } +#endif } internal void file_measure_widths(General_Memory *general, Editing_File *file, Font *font){ +#if BUFFER_EXPERIMENT_SCALPEL <= 1 ProfileMomentFunction(); file_grow_widths_as_needed(general, file); Opaque_Font_Advance opad = get_opaque_font_advance(font); buffer_measure_widths(&file->buffer, opad.data, opad.stride); +#endif } internal void file_remeasure_widths(General_Memory *general, Editing_File *file, Font *font, i32 line_start, i32 line_end, i32 line_shift){ +#if BUFFER_EXPERIMENT_SCALPEL <= 1 ProfileMomentFunction(); file_grow_widths_as_needed(general, file); Opaque_Font_Advance opad = get_opaque_font_advance(font); buffer_remeasure_widths(&file->buffer, opad.data, opad.stride, line_start, line_end, line_shift); +#endif } inline i32 @@ -1293,8 +1315,9 @@ view_wrapped_line_span(real32 line_width, real32 max_width){ internal i32 view_compute_lowest_line(File_View *view){ - i32 last_line = view->line_count - 1; i32 lowest_line = 0; +#if BUFFER_EXPERIMENT_SCALPEL <= 1 + i32 last_line = view->line_count - 1; if (last_line > 0){ if (view->unwrapped_lines){ lowest_line = last_line; @@ -1313,11 +1336,13 @@ view_compute_lowest_line(File_View *view){ lowest_line += line_span - 1; } } +#endif return lowest_line; } internal void view_measure_wraps(General_Memory *general, File_View *view){ +#if BUFFER_EXPERIMENT_SCALPEL <= 1 ProfileMomentFunction(); Editing_File *file = view->file; i32 line_count = file->buffer.line_count; @@ -1340,23 +1365,35 @@ view_measure_wraps(General_Memory *general, File_View *view){ buffer_measure_wrap_y(&file->buffer, view->line_wrap_y, line_height, max_width); view->line_count = line_count; +#endif +} + +internal void* +alloc_for_buffer(void *context, int *size){ + *size = LargeRoundUp(*size, Kbytes(4)); + void *data = general_memory_allocate((General_Memory*)context, *size, BUBBLE_BUFFER); + return data; } internal void file_create_from_string(General_Memory *general, Editing_File *file, u8 *filename, Font *font, String val){ - i32 request_size = LargeRoundUp(1+val.size*2, Kbytes(64)); - u8 *data = (u8*)general_memory_allocate(general, request_size, BUBBLE_BUFFER); - - // TODO(allen): if we didn't get the memory what is going on? - // request_size too large? - // need to expand general memory allocator's base pool? - // need to release least recently used target? - Assert(data); - *file = {}; - file->buffer.data = (char*)data; - file->buffer.max = request_size; +#if BUFFER_EXPERIMENT_SCALPEL <= 2 + + Buffer_Init_Type init = buffer_begin_init(&file->buffer, val.str, val.size); + for (; buffer_init_need_more(&init); ){ + i32 page_size = buffer_init_page_size(&init); + page_size = LargeRoundUp(page_size, Kbytes(4)); + void *data = general_memory_allocate(general, page_size, BUBBLE_BUFFER); + buffer_init_provide_page(&init, data, page_size); + } + i32 init_success = buffer_end_init(&init); + Assert(init_success); + +#if 0 buffer_initialize(&file->buffer, val.str, val.size); +#endif +#endif file_synchronize_times(file, filename); file_init_strings(file); @@ -1367,7 +1404,8 @@ file_create_from_string(General_Memory *general, Editing_File *file, u8 *filenam file_measure_starts(general, file); file_measure_widths(general, file, font); file->font = font; - + + i32 request_size = Kbytes(64); file->undo.undo.max = request_size; file->undo.undo.strings = (u8*)general_memory_allocate(general, request_size, BUBBLE_UNDO_STRING); file->undo.undo.edit_max = request_size / sizeof(Edit_Step); @@ -1451,9 +1489,11 @@ file_close(General_Memory *general, Editing_File *file){ if (file->token_stack.tokens){ general_memory_free(general, file->token_stack.tokens); } +#if BUFFER_EXPERIMENT_SCALPEL <= 1 general_memory_free(general, file->buffer.data); general_memory_free(general, file->buffer.line_starts); general_memory_free(general, file->buffer.line_widths); +#endif general_memory_free(general, file->undo.undo.strings); general_memory_free(general, file->undo.undo.edits); @@ -1475,7 +1515,7 @@ struct Shift_Information{ i32 start, end, amount; }; -#if BUFFER_EXPERIMENT_SCALPEL +#if BUFFER_EXPERIMENT_SCALPEL <= 0 internal JOB_CALLBACK(job_full_lex){ Editing_File *file = (Editing_File*)data[0]; @@ -1553,7 +1593,7 @@ file_kill_tokens(General_Memory *general, Editing_File *file){ file->token_stack = {}; } -#if BUFFER_EXPERIMENT_SCALPEL +#if BUFFER_EXPERIMENT_SCALPEL <= 0 internal void file_first_lex_parallel(General_Memory *general, Editing_File *file){ Assert(file->token_stack.tokens == 0); @@ -1659,6 +1699,7 @@ file_relex_parallel(Mem_Options *mem, Editing_File *file, internal bool32 file_grow_as_needed(General_Memory *general, Editing_File *file, i32 additional_size){ bool32 result = 1; +#if BUFFER_EXPERIMENT_SCALPEL <= 1 i32 size = buffer_size(&file->buffer); i32 target_size = size + additional_size + 1; if (target_size >= file->buffer.max){ @@ -1669,6 +1710,7 @@ file_grow_as_needed(General_Memory *general, Editing_File *file, i32 additional_ void *old_data = buffer_relocate(&file->buffer, new_data, request_size); general_memory_free(general, old_data); } +#endif return result; } @@ -1746,6 +1788,7 @@ struct Edit_Spec{ Edit_Step step; }; +#if BUFFER_EXPERIMENT_SCALPEL <= 1 internal Edit_Step* file_post_undo(General_Memory *general, Editing_File *file, Edit_Step step, bool32 do_merge, bool32 can_merge){ @@ -1809,9 +1852,9 @@ file_post_undo(General_Memory *general, Editing_File *file, result = undo->edits + (undo->edit_count++); *result = inv_step; } - return result; } +#endif inline void undo_stack_pop(Edit_Stack *stack){ @@ -1821,6 +1864,7 @@ undo_stack_pop(Edit_Stack *stack){ } } +#if BUFFER_EXPERIMENT_SCALPEL <= 1 internal void file_post_redo(General_Memory *general, Editing_File *file, Edit_Step step){ Edit_Stack *redo = &file->undo.redo; @@ -1857,6 +1901,7 @@ file_post_redo(General_Memory *general, Editing_File *file, Edit_Step step){ redo->edits[redo->edit_count++] = inv_step; } } +#endif inline void file_post_history_block(Editing_File *file, i32 pos){ @@ -1880,6 +1925,7 @@ file_unpost_history_block(Editing_File *file){ file->undo.history_head_block = old_head->prev_block; } +#if BUFFER_EXPERIMENT_SCALPEL <= 1 internal Edit_Step* file_post_history(General_Memory *general, Editing_File *file, Edit_Step step, bool32 do_merge, bool32 can_merge){ @@ -1949,37 +1995,47 @@ file_post_history(General_Memory *general, Editing_File *file, return result; } +#endif inline Full_Cursor view_compute_cursor_from_pos(File_View *view, i32 pos){ +#if BUFFER_EXPERIMENT_SCALPEL <= 1 Editing_File *file = view->file; Style *style = view->style; Font *font = style->font; real32 max_width = view_compute_width(view); Opaque_Font_Advance opad = get_opaque_font_advance(font); - + return buffer_cursor_from_pos(&file->buffer, pos, view->line_wrap_y, max_width, (real32)font->height, opad.data, opad.stride); +#else + return view->cursor; +#endif } inline Full_Cursor view_compute_cursor_from_unwrapped_xy(File_View *view, real32 seek_x, real32 seek_y, bool32 round_down = 0){ +#if BUFFER_EXPERIMENT_SCALPEL <= 1 Editing_File *file = view->file; Style *style = view->style; Font *font = style->font; real32 max_width = view_compute_width(view); Opaque_Font_Advance opad = get_opaque_font_advance(font); - + return buffer_cursor_from_unwrapped_xy(&file->buffer, seek_x, seek_y, round_down, view->line_wrap_y, max_width, (real32)font->height, opad.data, opad.stride); +#else + return view->cursor; +#endif } inline Full_Cursor view_compute_cursor_from_wrapped_xy(File_View *view, real32 seek_x, real32 seek_y, bool32 round_down = 0){ +#if BUFFER_EXPERIMENT_SCALPEL <= 1 Editing_File *file = view->file; Style *style = view->style; Font *font = style->font; @@ -1989,6 +2045,9 @@ view_compute_cursor_from_wrapped_xy(File_View *view, real32 seek_x, real32 seek_ return buffer_cursor_from_wrapped_xy(&file->buffer, seek_x, seek_y, round_down, view->line_wrap_y, max_width, (real32)font->height, opad.data, opad.stride); +#else + return view->cursor; +#endif } inline Full_Cursor @@ -2212,6 +2271,7 @@ enum History_Mode{ internal void view_update_history_before_edit(Mem_Options *mem, Editing_File *file, Edit_Step step, u8 *str, History_Mode history_mode){ +#if BUFFER_EXPERIMENT_SCALPEL <= 1 General_Memory *general = &mem->general; #if FRED_SLOW @@ -2376,6 +2436,7 @@ view_update_history_before_edit(Mem_Options *mem, Editing_File *file, Edit_Step } if (history_mode == hist_normal) file->undo.edit_history_cursor = file->undo.history.edit_count; +#endif } inline b32 @@ -2409,20 +2470,21 @@ view_do_single_edit(Mem_Options *mem, File_View *view, Editing_File *file, // NOTE(allen): fixing stuff beforewards???? view_update_history_before_edit(mem, file, spec.step, spec.str, history_mode); file_pre_edit_maintenance(file); - + +#if BUFFER_EXPERIMENT_SCALPEL <= 1 // NOTE(allen): actual text replacement General_Memory *general = &mem->general; - + i32 start = spec.step.edit.start; i32 end = spec.step.edit.end; - char *str = (char*)spec.str; AllowLocal(str); + char *str = (char*)spec.str; i32 str_len = spec.step.edit.len; - + i32 shift_amount = 0; while (buffer_replace_range(&file->buffer, start, end, str, str_len, &shift_amount)) file_grow_as_needed(general, file, shift_amount); -#if BUFFER_EXPERIMENT_SCALPEL +#if BUFFER_EXPERIMENT_SCALPEL <= 0 // NOTE(allen): fixing stuff afterwards if (file->tokens_exist) file_relex_parallel(mem, file, start, end, shift_amount); @@ -2484,11 +2546,13 @@ view_do_single_edit(Mem_Options *mem, File_View *view, Editing_File *file, } end_temp_memory(cursor_temp); +#endif } internal void view_do_white_batch_edit(Mem_Options *mem, File_View *view, Editing_File *file, Editing_Layout *layout, Edit_Spec spec, History_Mode history_mode){ +#if BUFFER_EXPERIMENT_SCALPEL <= 1 Assert(file); ProfileMomentFunction(); @@ -2580,6 +2644,7 @@ view_do_white_batch_edit(Mem_Options *mem, File_View *view, Editing_File *file, } end_temp_memory(cursor_temp); } +#endif } inline void @@ -2704,7 +2769,7 @@ view_history_step(Mem_Options *mem, Editing_Layout *layout, File_View *view, His // TODO(allen): should these still be view operations? internal i32 view_find_end_of_line(File_View *view, i32 pos){ -#if BUFFER_EXPERIMENT_SCALPEL +#if BUFFER_EXPERIMENT_SCALPEL <= 0 Editing_File *file = view->file; char *data = file->buffer.data; while (pos < file->buffer.size && data[pos] != '\n') ++pos; @@ -2715,7 +2780,7 @@ view_find_end_of_line(File_View *view, i32 pos){ internal i32 view_find_beginning_of_line(File_View *view, i32 pos){ -#if BUFFER_EXPERIMENT_SCALPEL +#if BUFFER_EXPERIMENT_SCALPEL <= 0 Editing_File *file = view->file; char *data = file->buffer.data; if (pos > 0){ @@ -2729,7 +2794,7 @@ view_find_beginning_of_line(File_View *view, i32 pos){ internal i32 view_find_beginning_of_next_line(File_View *view, i32 pos){ -#if BUFFER_EXPERIMENT_SCALPEL +#if BUFFER_EXPERIMENT_SCALPEL <= 0 Editing_File *file = view->file; char *data = file->buffer.data; while (pos < file->buffer.size && @@ -2833,11 +2898,13 @@ working_set_lookup_file(Working_Set *working_set, String string){ internal void clipboard_copy(General_Memory *general, Working_Set *working, Range range, Editing_File *file){ +#if BUFFER_EXPERIMENT_SCALPEL <= 1 i32 size = range.end - range.start; String *dest = working_set_next_clipboard_string(general, working, size); buffer_stringify(&file->buffer, range.start, range.end, dest->str); dest->size = size; system_post_clipboard(*dest); +#endif } internal Edit_Spec @@ -2845,6 +2912,7 @@ view_compute_whitespace_edit(Mem_Options *mem, Editing_File *file, Buffer_Edit *edits, char *str_base, i32 str_size, Buffer_Edit *inverse_array, char *inv_str, i32 inv_max, i32 edit_count){ +#if BUFFER_EXPERIMENT_SCALPEL <= 1 General_Memory *general = &mem->general; i32 inv_str_pos = 0; @@ -2867,12 +2935,16 @@ view_compute_whitespace_edit(Mem_Options *mem, Editing_File *file, spec.step.special_type = 1; spec.step.child_count = edit_count; spec.step.inverse_child_count = edit_count; +#else + Edit_Spec spec = {}; +#endif return spec; } internal void view_clean_whitespace(Mem_Options *mem, File_View *view, Editing_Layout *layout){ +#if BUFFER_EXPERIMENT_SCALPEL <= 1 Editing_File *file = view->file; Assert(file && !file->is_dummy); Partition *part = &mem->part; @@ -2926,12 +2998,13 @@ view_clean_whitespace(Mem_Options *mem, File_View *view, Editing_Layout *layout) } end_temp_memory(temp); +#endif } internal void view_auto_tab_tokens(Mem_Options *mem, File_View *view, Editing_Layout *layout, i32 start, i32 end, b32 empty_blank_lines){ -#if BUFFER_EXPERIMENT_SCALPEL +#if BUFFER_EXPERIMENT_SCALPEL <= 0 Editing_File *file = view->file; Assert(file && !file->is_dummy); Partition *part = &mem->part; @@ -3654,12 +3727,13 @@ draw_file_view(Thread_Context *thread, View *view_, i32_Rect rect, bool32 is_act bar.rect = rect; bar.rect.y1 = bar.rect.y0 + font->height + 2; rect.y0 += font->height + 2; - + +#if BUFFER_EXPERIMENT_SCALPEL <= 1 i32 max_x = rect.x1 - rect.x0; i32 max_y = rect.y1 - rect.y0 + font->height; - Assert(file && file->buffer.data && !file->is_dummy); - + Assert(file && buffer_good(&file->buffer) && !file->is_dummy); + Opaque_Font_Advance opad = get_opaque_font_advance(font); b32 tokens_use = file->tokens_complete && (file->token_stack.count > 0); Cpp_Token_Stack token_stack = file->token_stack; @@ -3670,7 +3744,7 @@ draw_file_view(Thread_Context *thread, View *view_, i32_Rect rect, bool32 is_act partition_align(part, 4); i32 max = partition_remaining(part) / sizeof(Buffer_Render_Item); Buffer_Render_Item *items = push_array(part, Buffer_Render_Item, max); - + i32 count; buffer_get_render_data(&file->buffer, view->line_wrap_y, items, max, &count, (real32)rect.x0, (real32)rect.y0, view->scroll_x, view->scroll_y, !view->unwrapped_lines, @@ -3756,184 +3830,6 @@ draw_file_view(Thread_Context *thread, View *view_, i32_Rect rect, bool32 is_act } end_temp_memory(temp); - -#if 0 - - i32 size = (i32)file->buffer.size; - u8 *data = (u8*)file->buffer.data; - - Full_Cursor start_cursor; - start_cursor = view_compute_cursor_from_xy(view, 0, view->scroll_y); - view->scroll_y_cursor = start_cursor; - - i32 start_character = start_cursor.pos; - - real32 shift_x = rect.x0 - view->scroll_x; - real32 shift_y = rect.y0 - view->scroll_y; - if (view->unwrapped_lines) shift_y += start_cursor.unwrapped_y; - else shift_y += start_cursor.wrapped_y; - - real32 pos_x = 0; - real32 pos_y = 0; - - u32 highlight_color = 0; - u32 main_color = style->main.default_color; - i32 token_i = 0; - - if (tokens_use){ - Cpp_Get_Token_Result result = cpp_get_token(&token_stack, start_character); - token_i = result.token_index; - - main_color = *style_get_color(style, token_stack.tokens[token_i]); - ++token_i; - } - - data[size] = 0; - for (i32 i = start_character; i <= size; ++i){ - u8 to_render; - to_render = data[i]; - - real32 ch_width = font_get_glyph_width(font, to_render); - real32 ch_advance = measure_character(opad.data, opad.stride, to_render); - - if (!view->unwrapped_lines && pos_x + ch_advance > max_x){ - pos_x = 0; - pos_y += font->height; - } - - u32 fade_color = 0xFFFF00FF; - real32 fade_amount = 0.f; - if (view->paste_effect.tick_down > 0 && - view->paste_effect.start <= i && i < view->paste_effect.end){ - fade_color = view->paste_effect.color; - fade_amount = (real32)(view->paste_effect.tick_down) / view->paste_effect.tick_max; - } - - highlight_color = 0; - if (tokens_use){ - Cpp_Token current_token = token_stack.tokens[token_i-1]; - - if (token_i < token_stack.count){ - if (i >= token_stack.tokens[token_i].start){ - main_color = - *style_get_color(style, token_stack.tokens[token_i]); - current_token = token_stack.tokens[token_i]; - ++token_i; - } - else if (i >= current_token.start + current_token.size){ - main_color = 0xFFFFFFFF; - } - } - - if (current_token.type == CPP_TOKEN_JUNK && - i >= current_token.start && i <= current_token.start + current_token.size){ - highlight_color = style->main.highlight_junk_color; - } - } - if (highlight_color == 0 && view->show_whitespace && char_is_whitespace(data[i])){ - highlight_color = style->main.highlight_white_color; - } - - i32 cursor_mode = 0; - if (view->show_temp_highlight){ - if (view->temp_highlight.pos <= i && i < view->temp_highlight_end_pos) - cursor_mode = 2; - } - else{ - if (view->cursor.pos == i) - cursor_mode = 1; - } - - real32_Rect cursor_rect = - real32XYWH(shift_x + pos_x, shift_y + pos_y, - 1 + ch_width, (real32)font->height); - - if (to_render == '\t' || to_render == 0){ - cursor_rect.x1 = cursor_rect.x0 + font->chardata[' '].xadvance; - } - - if (highlight_color != 0){ - real32_Rect highlight_rect = cursor_rect; - highlight_rect.x0 += 1; - draw_rectangle(target, highlight_rect, highlight_color); - } - - u32 cursor_color = 0; - switch (cursor_mode){ - case 1: - cursor_color = style->main.cursor_color; break; - case 2: - cursor_color = style->main.highlight_color; break; - } - - if (is_active){ - if (cursor_color & 0xFF000000) draw_rectangle(target, cursor_rect, cursor_color); - } - else{ - if (cursor_color & 0xFF000000)draw_rectangle_outline(target, cursor_rect, cursor_color); - } - if (i == view->mark){ - draw_rectangle_outline(target, cursor_rect, style->main.mark_color); - } - - u32 char_color = main_color; - u32 special_char_color = main_color; - if (to_render == '\r'){ - special_char_color = char_color = style->main.special_character_color; - } - if (is_active){ - switch (cursor_mode){ - case 1: - char_color = style->main.at_cursor_color; break; - case 2: - special_char_color = char_color = style->main.at_highlight_color; break; - } - } - - char_color = color_blend(char_color, fade_amount, fade_color); - special_char_color = color_blend(special_char_color, fade_amount, fade_color); - - if (to_render == '\r'){ - font_draw_glyph(target, font, '\\', - shift_x + pos_x, - shift_y + pos_y, - char_color); - pos_x += font_get_glyph_width(font, '\\'); - - real32 cw = font_get_glyph_width(font, 'r'); - draw_rectangle(target, - real32XYWH(shift_x + pos_x, - shift_y + pos_y, - cw, (real32)font->height), - highlight_color); - font_draw_glyph(target, font, 'r', - shift_x + pos_x, - shift_y + pos_y, - special_char_color); - pos_x += cw; - } - - else if (to_render == '\n'){ - pos_x = 0; - pos_y += font->height; - } - - else if (font->glyphs[to_render].exists){ - font_draw_glyph(target, font, to_render, - shift_x + pos_x, - shift_y + pos_y, - char_color); - pos_x += ch_width; - } - - else{ - pos_x += ch_width; - } - - if (pos_y > max_y){ - break; - } - } #endif if (view->widget.type != FWIDG_NONE){ @@ -4089,7 +3985,7 @@ HANDLE_COMMAND_SIG(handle_command_file_view){ case FWIDG_SEARCH: { -#if BUFFER_EXPERIMENT_SCALPEL +#if BUFFER_EXPERIMENT_SCALPEL <= 1 String *string = &file_view->isearch.str; Single_Line_Input_Step result = app_single_line_input_step(codes, key, string); @@ -4100,72 +3996,61 @@ HANDLE_COMMAND_SIG(handle_command_file_view){ bool32 step_forward = 0; bool32 step_backward = 0; - if (binding.function == command_search){ - step_forward = 1; - } - if (binding.function == command_rsearch){ - step_backward = 1; - } + if (binding.function == command_search) step_forward = 1; + if (binding.function == command_rsearch) step_backward = 1; i32 start_pos = file_view->isearch.pos; if (step_forward){ if (file_view->isearch.reverse){ - start_pos = file_view->temp_highlight.pos - 1; + start_pos = file_view->temp_highlight.pos + 1; file_view->isearch.pos = start_pos; file_view->isearch.reverse = 0; + step_forward = 0; } } if (step_backward){ if (!file_view->isearch.reverse){ - start_pos = file_view->temp_highlight.pos + 1; + start_pos = file_view->temp_highlight.pos - 1; file_view->isearch.pos = start_pos; file_view->isearch.reverse = 1; + step_backward = 0; } } - - String file_string = make_string(file->buffer.data, file->buffer.size); + + Temp_Memory temp = begin_temp_memory(&view->mem->part); + char *spare = push_array(&view->mem->part, char, string->size); + + i32 size = buffer_size(&file->buffer); i32 pos; - if (file_view->isearch.reverse){ - if (result.hit_backspace){ - start_pos = file_view->temp_highlight.pos + 1; - file_view->isearch.pos = start_pos; - } - else{ - pos = rfind_substr(file_string, start_pos - 1, *string); + if (!result.hit_backspace){ + if (file_view->isearch.reverse){ + pos = buffer_rfind_string(&file->buffer, start_pos - 1, string->str, string->size, spare); if (pos >= 0){ - if (step_backward){ // TODO(allen): this if and it's mirror are suspicious + if (step_backward){ file_view->isearch.pos = pos; start_pos = pos; - pos = rfind_substr(file_string, start_pos - 1, *string); - if (pos == -1){ - pos = start_pos; - } + pos = buffer_rfind_string(&file->buffer, start_pos - 1, string->str, string->size, spare); + if (pos == -1) pos = start_pos; } view_set_temp_highlight(file_view, pos, pos+string->size); } } - } - - else{ - if (result.hit_backspace){ - start_pos = file_view->temp_highlight.pos - 1; - file_view->isearch.pos = start_pos; - } + else{ - pos = find_substr(file_string, start_pos + 1, *string); - if (pos < file->buffer.size){ + pos = buffer_find_string(&file->buffer, start_pos + 1, string->str, string->size, spare); + if (pos < size){ if (step_forward){ file_view->isearch.pos = pos; start_pos = pos; - pos = find_substr(file_string, start_pos + 1, *string); - if (pos == file->buffer.size){ - pos = start_pos; - } + pos = buffer_find_string(&file->buffer, start_pos + 1, string->str, string->size, spare); + if (pos == size) pos = start_pos; } view_set_temp_highlight(file_view, pos, pos+string->size); } } } + + end_temp_memory(temp); } if (result.hit_newline || result.hit_ctrl_newline){ diff --git a/4ed_meta.h b/4ed_meta.h index 40c2f4ba..f852729c 100644 --- a/4ed_meta.h +++ b/4ed_meta.h @@ -77,7 +77,7 @@ _OutDbgStr(u8*); #endif #if FRED_SLOW -# define Assert(c) if(!(c)){*(int*)0 = 0;} +# define Assert(c) assert(c) #else # define Assert(c) #endif diff --git a/buffer/4coder_buffer_abstract.cpp b/buffer/4coder_buffer_abstract.cpp index 6a0b39f5..6e235e7b 100644 --- a/buffer/4coder_buffer_abstract.cpp +++ b/buffer/4coder_buffer_abstract.cpp @@ -13,9 +13,11 @@ // TOP +#define Buffer_Init_Type cat_4tech(Buffer_Type, _Init) #define Buffer_Stringify_Type cat_4tech(Buffer_Type, _Stringify_Loop) #define Buffer_Backify_Type cat_4tech(Buffer_Type, _Backify_Loop) +#if BUFFER_EXPERIMENT_SCALPEL <= 1 inline_4tech void buffer_stringify(Buffer_Type *buffer, int start, int end, char *out){ for (Buffer_Stringify_Type loop = buffer_stringify_loop(buffer, start, end, end - start); @@ -364,8 +366,8 @@ buffer_seek_alphanumeric_or_camel_left_end: } internal_4tech int -buffer_find_hard_start(Buffer_Type *buffer, int line_start, int *all_whitespace, int *all_space, - int *preferred_indent, int tab_width){ +buffer_find_hard_start(Buffer_Type *buffer, int line_start, int *all_whitespace, + int *all_space, int *preferred_indent, int tab_width){ Buffer_Stringify_Type loop; char *data; int size, end; @@ -403,6 +405,69 @@ buffer_find_hard_start_end: return(result); } +internal_4tech int +buffer_find_string(Buffer_Type *buffer, int start_pos, char *str, int len, char *spare){ + Buffer_Stringify_Type loop; + char *data; + int size, end; + int pos; + + size = buffer_size(buffer); + + pos = start_pos; + if (len > 0){ + for (loop = buffer_stringify_loop(buffer, start_pos, size - len + 1, size); + buffer_stringify_good(&loop); + buffer_stringify_next(&loop)){ + end = loop.size + loop.absolute_pos; + data = loop.data - loop.absolute_pos; + for (; pos < end; ++pos){ + if (*str == data[pos]){ + buffer_stringify(buffer, pos, pos + len, spare); + if (is_match(str, spare, len)) + goto buffer_find_string_end; + } + } + } + } + +buffer_find_string_end: + if (pos >= size - len + 1) pos = size; + return(pos); +} + +internal_4tech int +buffer_rfind_string(Buffer_Type *buffer, int start_pos, char *str, int len, char *spare){ + Buffer_Backify_Type loop; + char *data; + int end, size; + int pos; + + size = buffer_size(buffer); + + pos = start_pos; + if (pos > size - len) pos = size - len; + + if (len > 0){ + for (loop = buffer_backify_loop(buffer, start_pos, 0, size); + buffer_backify_good(&loop); + buffer_backify_next(&loop)){ + end = loop.absolute_pos; + data = loop.data - loop.absolute_pos; + for (; pos >= end; --pos){ + if (*str == data[pos]){ + buffer_stringify(buffer, pos, pos + len, spare); + if (is_match(str, spare, len)) + goto buffer_rfind_string_end; + } + } + } + } + +buffer_rfind_string_end: + return(pos); +} + typedef struct{ int i; int count; @@ -1058,6 +1123,7 @@ buffer_get_render_data_end: assert_4tech(item_i <= max); *count = item_i; } +#endif #ifndef NON_ABSTRACT_4TECH #define NON_ABSTRACT_4TECH 1 diff --git a/buffer/4coder_gap_buffer.cpp b/buffer/4coder_gap_buffer.cpp index 30404486..4a34cef4 100644 --- a/buffer/4coder_gap_buffer.cpp +++ b/buffer/4coder_gap_buffer.cpp @@ -24,6 +24,13 @@ typedef struct{ int widths_max; } Gap_Buffer; +inline_4tech int +buffer_good(Gap_Buffer *buffer){ + int good; + good = (buffer->data != 0); + return(good); +} + inline_4tech int buffer_size(Gap_Buffer *buffer){ int size; @@ -31,7 +38,79 @@ buffer_size(Gap_Buffer *buffer){ return(size); } -inline_4tech void +typedef struct{ + Gap_Buffer *buffer; + char *data; + int size; +} Gap_Buffer_Init; + +internal_4tech Gap_Buffer_Init +buffer_begin_init(Gap_Buffer *buffer, char *data, int size){ + Gap_Buffer_Init init; + init.buffer = buffer; + init.data = data; + init.size = size; + return(init); +} + +internal_4tech int +buffer_init_need_more(Gap_Buffer_Init *init){ + int result; + result = 1; + if (init->buffer->data) result = 0; + return(result); +} + +internal_4tech int +buffer_init_page_size(Gap_Buffer_Init *init){ + int result; + result = init->size * 2; + return(result); +} + +internal_4tech void +buffer_init_provide_page(Gap_Buffer_Init *init, void *page, int page_size){ + Gap_Buffer *buffer; + buffer = init->buffer; + buffer->data = (char*)page; + buffer->max = page_size; +} + +internal_4tech int +buffer_end_init(Gap_Buffer_Init *init){ + Gap_Buffer *buffer; + int osize1, size1, size2, size; + int result; + + result = 0; + buffer = init->buffer; + size = init->size; + if (buffer->data){ + if (buffer->max >= init->size){ + size2 = size >> 1; + size1 = osize1 = size - size2; + + if (size1 > 0){ + size1 = eol_convert_in(buffer->data, init->data, size1); + if (size2 > 0){ + size2 = eol_convert_in(buffer->data + size1, init->data + osize1, size2); + } + } + + buffer->size1 = size1; + buffer->size2 = size2; + buffer->gap_size = buffer->max - size1 - size2; + memmove_4tech(buffer->data + size1 + buffer->gap_size, buffer->data + size1, size2); + + result = 1; + } + } + + return(result); +} + +#if 0 +internal_4tech void buffer_initialize(Gap_Buffer *buffer, char *data, int size){ int osize1, size1, size2; @@ -51,6 +130,7 @@ buffer_initialize(Gap_Buffer *buffer, char *data, int size){ buffer->gap_size = buffer->max - size1 - size2; memmove_4tech(buffer->data + size1 + buffer->gap_size, buffer->data + size1, size2); } +#endif internal_4tech void* buffer_relocate(Gap_Buffer *buffer, char *new_data, int new_max){ diff --git a/buffer/4coder_golden_array.cpp b/buffer/4coder_golden_array.cpp index b84c6f1c..622d8025 100644 --- a/buffer/4coder_golden_array.cpp +++ b/buffer/4coder_golden_array.cpp @@ -24,16 +24,81 @@ typedef struct{ int widths_max; } Buffer; +inline_4tech int +buffer_good(Buffer *buffer){ + int good; + good = (buffer->data != 0); + return(good); +} + inline_4tech int buffer_size(Buffer *buffer){ return buffer->size; } +typedef struct{ + Buffer *buffer; + char *data; + int size; +} Buffer_Init; + +internal_4tech Buffer_Init +buffer_begin_init(Buffer *buffer, char *data, int size){ + Buffer_Init init; + init.buffer = buffer; + init.data = data; + init.size = size; + return(init); +} + +inline_4tech int +buffer_init_need_more(Buffer_Init *init){ + int result; + result = 1; + if (init->buffer->data) result = 0; + return(result); +} + +inline_4tech int +buffer_init_page_size(Buffer_Init *init){ + int result; + result = init->size * 2; + return(result); +} + +inline_4tech void +buffer_init_provide_page(Buffer_Init *init, void *page, int page_size){ + Buffer *buffer; + buffer = init->buffer; + buffer->data = (char*)page; + buffer->max = page_size; +} + +internal_4tech int +buffer_end_init(Buffer_Init *init){ + Buffer *buffer; + int result; + + result = 0; + buffer = init->buffer; + if (buffer->data){ + if (buffer->max >= init->size){ + buffer->size = eol_convert_in(buffer->data, init->data, init->size); + result = 1; + } + } + + return(result); +} + +#if 0 internal_4tech void buffer_initialize(Buffer *buffer, char *data, int size){ + assert_4tech(buffer->data); assert_4tech(size <= buffer->max); buffer->size = eol_convert_in(buffer->data, data, size); } +#endif internal_4tech void* buffer_relocate(Buffer *buffer, char *new_data, int new_max){ @@ -192,38 +257,5 @@ buffer_batch_edit_step(Buffer_Batch_State *state, Buffer *buffer, Buffer_Edit *s return(result); } -#if 0 -internal_4tech int -buffer_find_hard_start(Buffer *buffer, int line_start, int *all_whitespace, int *all_space, - int *preferred_indent, int tab_width){ - char *data; - int size; - int result; - char c; - - *all_space = 1; - *preferred_indent = 0; - - data = buffer->data; - size = buffer->size; - - tab_width -= 1; - - for (result = line_start; result < size; ++result){ - c = data[result]; - if (c == '\n' || c == 0){ - *all_whitespace = 1; - break; - } - if (c >= '!' && c <= '~') break; - if (c == '\t') *preferred_indent += tab_width; - if (c != ' ') *all_space = 0; - *preferred_indent += 1; - } - - return(result); -} -#endif - // BOTTOM diff --git a/buffer/4coder_multi_gap_buffer.cpp b/buffer/4coder_multi_gap_buffer.cpp new file mode 100644 index 00000000..3c7f37ab --- /dev/null +++ b/buffer/4coder_multi_gap_buffer.cpp @@ -0,0 +1,165 @@ +/* + * Mr. 4th Dimention - Allen Webster + * Four Tech + * + * public domain -- no warranty is offered or implied; use this code at your own risk + * + * 30.10.2015 + * + * Buffer data object + * type - Multi Gap Buffer + * + * This scheme was originally introduced to me by Martin Cohen, + * who calls it a "Fixed Width Gap Buffer". + * + */ + +// TOP + +typedef struct{ + char *data; + int size1, gap_size, size2; + int start_pos; +} Fixed_Width_Gap_Buffer; + +#define fixed_width_buffer_size Kbytes(8) +#define fixed_width_buffer_half_size Kbytes(4) + +typedef struct{ + Fixed_Width_Gap_Buffer *gaps; + int chunk_count; + int chunk_max; + int size; +} Multi_Gap_Buffer; + +inline_4tech int +buffer_good(Multi_Gap_Buffer *buffer){ + int good; + good = (buffer->gaps != 0); + return(good); +} + +inline_4tech int +buffer_size(Multi_Gap_Buffer *buffer){ + int size; + size = buffer->size; + return(size); +} + +typedef struct{ + Multi_Gap_Buffer *buffer; + char *data; + int size; + int chunk_i; + int chunk_count; +} Multi_Gap_Buffer_Init; + + +internal_4tech Multi_Gap_Buffer_Init +buffer_begin_init(Multi_Gap_Buffer *buffer, char *data, int size){ + Multi_Gap_Buffer_Init init; + init.buffer = buffer; + init.data = data; + init.size = size; + init.chunk_i = 0; + init.chunk_count = div_ceil_4tech(size, fixed_width_buffer_half_size); + return(init); +} + +internal_4tech int +buffer_init_need_more(Multi_Gap_Buffer_Init *init){ + int result; + result = 1; + if (init->buffer->gaps && init->chunk_i == init->chunk_count) + result = 0; + return(result); +} + +internal_4tech int +buffer_init_page_size(Multi_Gap_Buffer_Init *init){ + Multi_Gap_Buffer *buffer; + int result; + buffer = init->buffer; + if (buffer->gaps) result = fixed_width_buffer_size; + else result = init->chunk_count * 2 * sizeof(*buffer->gaps); + return(result); +} + +internal_4tech void +buffer_init_provide_page(Multi_Gap_Buffer_Init *init, void *page, int page_size){ + Multi_Gap_Buffer *buffer; + buffer = init->buffer; + + if (buffer->gaps){ + assert_4tech(page_size >= fixed_width_buffer_size); + buffer->gaps[init->chunk_i].data = (char*)page; + ++init->chunk_i; + } + else{ + buffer->gaps = (Fixed_Width_Gap_Buffer*)page; + buffer->chunk_max = page_size / sizeof(*buffer->gaps); + } +} + +internal_4tech int +buffer_end_init(Multi_Gap_Buffer_Init *init){ + Multi_Gap_Buffer *buffer; + Fixed_Width_Gap_Buffer *gap; + int result; + int i, count; + char *data; + int pos, size, total_size, start_pos; + int osize1, size1, size2; + + result = 0; + buffer = init->buffer; + if (buffer->gaps){ + if (buffer->chunk_max >= div_ceil_4tech(init->size, fixed_width_buffer_half_size)){ + buffer->chunk_count = init->chunk_count; + result = 1; + + data = init->data; + total_size = init->size; + gap = buffer->gaps; + count = init->chunk_count; + size = fixed_width_buffer_half_size; + pos = 0; + start_pos = 0; + + for (i = 0; i < count; ++i, ++gap, pos += size){ + if (pos + size > total_size) size = total_size - pos; + + if (gap->data){ + size2 = size >> 1; + size1 = osize1 = size - size2; + + if (size1 > 0){ + size1 = eol_convert_in(gap->data, data + pos, size1); + if (size2 > 0){ + size2 = eol_convert_in(gap->data + size1, data + pos + osize1, size2); + } + } + + gap->size1 = size1; + gap->size2 = size2; + gap->gap_size = fixed_width_buffer_size - size1 - size2; + memmove_4tech(gap->data + size1 + gap->gap_size, gap->data + size1, size2); + + gap->start_pos = start_pos; + start_pos += size1 + size2; + } + else{ + result = 0; + break; + } + } + buffer->size = start_pos; + } + } + + return(result); +} + +// BOTTOM + + diff --git a/buffer/4coder_shared.cpp b/buffer/4coder_shared.cpp index a2bcadc3..2685c0c6 100644 --- a/buffer/4coder_shared.cpp +++ b/buffer/4coder_shared.cpp @@ -12,18 +12,43 @@ // TOP -#ifndef defines_4tech +#ifndef inline_4tech #define inline_4tech inline +#endif + +#ifndef internal_4tech #define internal_4tech static +#endif + +#ifndef memset_4tech #define memset_4tech memset +#endif + +#ifndef memcpy_4tech #define memcpy_4tech memcpy +#endif + +#ifndef memmove_4tech #define memmove_4tech memmove -#define defines_4tech 1 +#endif + +#ifndef debug_4tech #define debug_4tech(x) x +#endif + +#ifndef assert_4tech #define assert_4tech assert +#endif +#ifndef ceil_4tech #define ceil_4tech CEIL32 +#endif +#ifndef div_ceil_4tech +#define div_ceil_4tech DIVCEIL32 +#endif + +#ifndef cat_4tech #define cat_4tech_(a,b) a##b #define cat_4tech(a,b) cat_4tech_(a,b) #endif @@ -397,5 +422,16 @@ is_lower(char c){ return (c >= 'a' && c <= 'z'); } +internal_4tech int +is_match(char *a, char *b, int len){ + int result; + + result = 1; + for (;len > 0; --len, ++a, ++b) + if (*a != *b) { result = 0; break; } + + return(result); +} + // BOTTOM diff --git a/win32_4ed.cpp b/win32_4ed.cpp index e064086c..c5780b46 100644 --- a/win32_4ed.cpp +++ b/win32_4ed.cpp @@ -13,24 +13,28 @@ // Fix the OwnDC thing. // +#ifdef FRED_NOT_PACKAGE + +#define FRED_INTERNAL 1 +#define FRED_SLOW 1 + #define FRED_PRINT_DEBUG 1 #define FRED_PRINT_DEBUG_FILE_LINE 0 #define FRED_PROFILING 1 #define FRED_PROFILING_OS 0 #define FRED_FULL_ERRORS 0 -#ifndef FRED_SLOW -#define FRED_SLOW 0 #else -#undef FRED_SLOW -#define FRED_SLOW 1 -#endif -#ifndef FRED_INTERNAL +#define FRED_SLOW 0 #define FRED_INTERNAL 0 -#else -#undef FRED_INTERNAL -#define FRED_INTERNAL 1 + +#define FRED_PRINT_DEBUG 0 +#define FRED_PRINT_DEBUG_FILE_LINE 0 +#define FRED_PROFILING 0 +#define FRED_PROFILING_OS 0 +#define FRED_FULL_ERRORS 0 + #endif #define SOFTWARE_RENDER 0 @@ -54,7 +58,7 @@ #define FPS 30 #define FRAME_TIME (1000000 / FPS) -#define BUFFER_EXPERIMENT_SCALPEL 0 +#define BUFFER_EXPERIMENT_SCALPEL 2 #include "4ed_meta.h"