From 28b6132be57bde5645109e29893ac4122b53369b Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Thu, 22 Sep 2016 21:57:28 -0400 Subject: [PATCH] switched to better streaming API --- 4ed_file_view.cpp | 2 - buffer/4coder_buffer_abstract.cpp | 472 +++++++++++++++--------------- buffer/4coder_gap_buffer.cpp | 56 ++-- 3 files changed, 258 insertions(+), 272 deletions(-) diff --git a/4ed_file_view.cpp b/4ed_file_view.cpp index 8e313cd8..f37bbdcd 100644 --- a/4ed_file_view.cpp +++ b/4ed_file_view.cpp @@ -4882,8 +4882,6 @@ draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target } - Assert(count > 0); - i32 cursor_begin = 0, cursor_end = 0; u32 cursor_color = 0, at_cursor_color = 0; if (view->file_data.show_temp_highlight){ diff --git a/buffer/4coder_buffer_abstract.cpp b/buffer/4coder_buffer_abstract.cpp index 8688061b..66bfb829 100644 --- a/buffer/4coder_buffer_abstract.cpp +++ b/buffer/4coder_buffer_abstract.cpp @@ -11,33 +11,44 @@ // TOP #define Buffer_Init_Type cat_4tech(Buffer_Type, _Init) -#define Buffer_Stringify_Type cat_4tech(Buffer_Type, _Stringify_Loop) +#define Buffer_Stream_Type cat_4tech(Buffer_Type, _Stream) inline_4tech void buffer_stringify(Buffer_Type *buffer, i32 start, i32 end, char *out){ - for (Buffer_Stringify_Type loop = buffer_stringify_loop(buffer, start, end); - buffer_stringify_good(&loop); - buffer_stringify_next(&loop)){ - memcpy_4tech(out, loop.data, loop.size); - out += loop.size; + Buffer_Stream_Type stream = {0}; + + i32 i = start; + if (buffer_stringify_loop(&stream, buffer, i, end)){ + b32 still_looping = 0; + do{ + i32 size = stream.end - i; + memcpy_4tech(out, stream.data + i, size); + i = stream.end; + out += size; + still_looping = buffer_stringify_next(&stream); + }while(still_looping); } } internal_4tech i32 buffer_convert_out(Buffer_Type *buffer, char *dest, i32 max){ - Buffer_Stringify_Type loop; - i32 size, out_size, pos, result; - - size = buffer_size(buffer); + Buffer_Stream_Type stream = {0}; + i32 i = 0; + i32 size = buffer_size(buffer); assert_4tech(size + buffer->line_count <= max); - pos = 0; - for (loop = buffer_stringify_loop(buffer, 0, size); - buffer_stringify_good(&loop); - buffer_stringify_next(&loop)){ - result = eol_convert_out(dest + pos, max - pos, loop.data, loop.size, &out_size); - assert_4tech(result); - pos += out_size; + i32 pos = 0; + if (buffer_stringify_loop(&stream, buffer, 0, size)){ + b32 still_looping = 0; + do{ + i32 size = stream.end - i; + i32 out_size = 0; + i32 result = eol_convert_out(dest + pos, max - pos, stream.data + i, size, &out_size); + assert_4tech(result); + i = stream.end; + pos += out_size; + still_looping = buffer_stringify_next(&stream); + }while(still_looping); } return(pos); @@ -45,22 +56,22 @@ buffer_convert_out(Buffer_Type *buffer, char *dest, i32 max){ internal_4tech i32 buffer_count_newlines(Buffer_Type *buffer, i32 start, i32 end){ - Buffer_Stringify_Type loop; - i32 i; - i32 count; + Buffer_Stream_Type stream = {0}; + i32 i = start; + i32 count = 0; assert_4tech(0 <= start); assert_4tech(start <= end); assert_4tech(end <= buffer_size(buffer)); - count = 0; - - for (loop = buffer_stringify_loop(buffer, start, end); - buffer_stringify_good(&loop); - buffer_stringify_next(&loop)){ - for (i = 0; i < loop.size; ++i){ - count += (loop.data[i] == '\n'); - } + if (buffer_stringify_loop(&stream, buffer, i, end)){ + b32 still_looping = 0; + do{ + for (; i < stream.end; ++i){ + count += (stream.data[i] == '\n'); + } + still_looping = buffer_stringify_next(&stream); + }while(still_looping); } return(count); @@ -77,32 +88,29 @@ typedef struct Buffer_Measure_Starts{ // and stores the size in the extra spot. internal_4tech i32 buffer_measure_starts(Buffer_Measure_Starts *state, Buffer_Type *buffer){ - Buffer_Stringify_Type loop = {0}; - char *data = 0; - i32 end = 0; + Buffer_Stream_Type stream = {0}; i32 size = buffer_size(buffer); i32 start = state->start, i = state->i; i32 *start_ptr = buffer->line_starts + state->count; i32 *start_end = buffer->line_starts + buffer->line_max; i32 result = 1; - char ch = 0; - for (loop = buffer_stringify_loop(buffer, i, size); - buffer_stringify_good(&loop); - buffer_stringify_next(&loop)){ - end = loop.size + loop.absolute_pos; - data = loop.data - loop.absolute_pos; - for (; i < end; ++i){ - ch = data[i]; - if (ch == '\n'){ - if (start_ptr == start_end){ - goto buffer_measure_starts_widths_end; + if (buffer_stringify_loop(&stream, buffer, i, size)){ + b32 still_looping = 0; + do{ + for (; i < stream.end; ++i){ + char ch = stream.data[i]; + if (ch == '\n'){ + if (start_ptr == start_end){ + goto buffer_measure_starts_widths_end; + } + + *start_ptr++ = start; + start = i + 1; } - - *start_ptr++ = start; - start = i + 1; } - } + still_looping = buffer_stringify_next(&stream); + }while(still_looping); } assert_4tech(i == size); @@ -123,9 +131,7 @@ buffer_measure_starts(Buffer_Measure_Starts *state, Buffer_Type *buffer){ internal_4tech void buffer_measure_wrap_y(Buffer_Type *buffer, f32 *wraps, f32 font_height, f32 *adv, f32 max_width){ - Buffer_Stringify_Type loop = {0}; - char *data = 0; - i32 end = 0; + Buffer_Stream_Type stream = {0}; i32 i = 0; i32 size = buffer_size(buffer); @@ -135,30 +141,30 @@ buffer_measure_wrap_y(Buffer_Type *buffer, f32 *wraps, f32 font_height, f32 *adv f32 x = 0.f; - for (loop = buffer_stringify_loop(buffer, i, size); - buffer_stringify_good(&loop); - buffer_stringify_next(&loop)){ - end = loop.size + loop.absolute_pos; - data = loop.data - loop.absolute_pos; - for (; i < end; ++i){ - u8 ch = (u8)data[i]; - if (ch == '\n'){ - wraps[wrap_index++] = last_wrap; - current_wrap += font_height; - last_wrap = current_wrap; - x = 0.f; - } - else{ - f32 current_adv = adv[ch]; - if (x + current_adv > max_width){ + if (buffer_stringify_loop(&stream, buffer, i, size)){ + b32 still_looping = 0; + do{ + for (; i < stream.end; ++i){ + u8 ch = (u8)stream.data[i]; + if (ch == '\n'){ + wraps[wrap_index++] = last_wrap; current_wrap += font_height; - x = current_adv; + last_wrap = current_wrap; + x = 0.f; } else{ - x += current_adv; + f32 current_adv = adv[ch]; + if (x + current_adv > max_width){ + current_wrap += font_height; + x = current_adv; + } + else{ + x += current_adv; + } } } - } + still_looping = buffer_stringify_next(&stream); + }while(still_looping); } wraps[wrap_index++] = last_wrap; @@ -201,9 +207,7 @@ buffer_remeasure_starts(Buffer_Type *buffer, i32 line_start, i32 line_end, i32 l } // Iteration data (yikes! Need better loop system) - Buffer_Stringify_Type loop = {0}; - i32 end = 0; - char *data = 0; + Buffer_Stream_Type stream = {0}; i32 size = buffer_size(buffer); i32 char_i = starts[line_start]; i32 line_i = line_start; @@ -211,26 +215,26 @@ buffer_remeasure_starts(Buffer_Type *buffer, i32 line_start, i32 line_end, i32 l // Line start measurement i32 start = char_i; - for (loop = buffer_stringify_loop(buffer, char_i, size); - buffer_stringify_good(&loop); - buffer_stringify_next(&loop)){ - end = loop.size + loop.absolute_pos; - data = loop.data - loop.absolute_pos; - for (; char_i < end; ++char_i){ - u8 ch = (u8)data[char_i]; - - if (ch == '\n'){ - starts[line_i] = start; - ++line_i; - start = char_i + 1; + if (buffer_stringify_loop(&stream, buffer, char_i, size)){ + b32 still_looping = 0; + do{ + for (; char_i < stream.end; ++char_i){ + u8 ch = (u8)stream.data[char_i]; - // TODO(allen): I would like to know that I am not guessing here, - // so let's try to turn the && into an Assert. - if (line_i >= new_line_end && (line_i >= new_line_count || start == starts[line_i])){ - goto buffer_remeasure_starts_end; + if (ch == '\n'){ + starts[line_i] = start; + ++line_i; + start = char_i + 1; + + // TODO(allen): I would like to know that I am not guessing here, + // so let's try to turn the && into an Assert. + if (line_i >= new_line_end && (line_i >= new_line_count || start == starts[line_i])){ + goto buffer_remeasure_starts_end; + } } } - } + still_looping = buffer_stringify_next(&stream); + }while(still_looping); } // TODO(allen): I suspect this can just go away. @@ -266,9 +270,7 @@ buffer_remeasure_wrap_y(Buffer_Type *buffer, i32 line_start, i32 line_end, i32 l } // Iteration data (yikes! Need better loop system) - Buffer_Stringify_Type loop = {0}; - i32 end = 0; - char *data = 0; + Buffer_Stream_Type stream = {0}; i32 size = buffer_size(buffer); i32 char_i = buffer->line_starts[line_start]; i32 line_i = line_start; @@ -278,37 +280,37 @@ buffer_remeasure_wrap_y(Buffer_Type *buffer, i32 line_start, i32 line_end, i32 l f32 current_wrap = last_wrap; f32 x = 0.f; - for (loop = buffer_stringify_loop(buffer, char_i, size); - buffer_stringify_good(&loop); - buffer_stringify_next(&loop)){ - end = loop.size + loop.absolute_pos; - data = loop.data - loop.absolute_pos; - for (; char_i < end; ++char_i){ - u8 ch = (u8)data[char_i]; - - if (ch == '\n'){ - wraps[line_i] = last_wrap; - ++line_i; - current_wrap += font_height; - last_wrap = current_wrap; - x = 0.f; + if (buffer_stringify_loop(&stream, buffer, char_i, size)){ + b32 still_looping = 0; + do{ + for (; char_i < stream.end; ++char_i){ + u8 ch = (u8)stream.data[char_i]; - // TODO(allen): I would like to know that I am not guessing here. - if (line_i >= new_line_end){ - goto buffer_remeasure_wraps_end; - } - } - else{ - f32 current_adv = adv[ch]; - if (x + current_adv > max_width){ + if (ch == '\n'){ + wraps[line_i] = last_wrap; + ++line_i; current_wrap += font_height; - x = current_adv; + last_wrap = current_wrap; + x = 0.f; + + // TODO(allen): I would like to know that I am not guessing here. + if (line_i >= new_line_end){ + goto buffer_remeasure_wraps_end; + } } else{ - x += current_adv; + f32 current_adv = adv[ch]; + if (x + current_adv > max_width){ + current_wrap += font_height; + x = current_adv; + } + else{ + x += current_adv; + } } } - } + still_looping = buffer_stringify_next(&stream); + }while(still_looping); } wraps[line_i++] = last_wrap; @@ -393,7 +395,7 @@ typedef struct Seek_State{ internal_4tech i32 cursor_seek_step(Seek_State *state, Buffer_Seek seek, i32 xy_seek, f32 max_width, - f32 font_height, f32 *adv, i32 size, uint8_t ch){ + f32 font_height, f32 *adv, i32 size, u8 ch){ Full_Cursor cursor = state->cursor; Full_Cursor prev_cursor = cursor; i32 result = 1; @@ -494,11 +496,7 @@ cursor_seek_step(Seek_State *state, Buffer_Seek seek, i32 xy_seek, f32 max_width internal_4tech Full_Cursor buffer_cursor_seek(Buffer_Type *buffer, Buffer_Seek seek, f32 max_width, f32 font_height, f32 *adv, Full_Cursor cursor){ - Buffer_Stringify_Type loop; - char *data; - i32 size, end; - i32 i; - i32 result; + i32 result = 0; Seek_State state; i32 xy_seek; @@ -524,22 +522,28 @@ buffer_cursor_seek(Buffer_Type *buffer, Buffer_Seek seek, f32 max_width, } if (adv){ - size = buffer_size(buffer); - xy_seek = (seek.type == buffer_seek_wrapped_xy || seek.type == buffer_seek_unwrapped_xy); + Buffer_Stream_Type stream = {0}; + i32 size = buffer_size(buffer); + i32 i = cursor.pos; + xy_seek = (seek.type == buffer_seek_wrapped_xy || seek.type == buffer_seek_unwrapped_xy); result = 1; - i = cursor.pos; - for (loop = buffer_stringify_loop(buffer, i, size); - buffer_stringify_good(&loop); - buffer_stringify_next(&loop)){ - end = loop.size + loop.absolute_pos; - data = loop.data - loop.absolute_pos; - for (; i < end; ++i){ - result = cursor_seek_step(&state, seek, xy_seek, max_width, - font_height, adv, size, data[i]); - if (!result) goto buffer_cursor_seek_end; - } + + if (buffer_stringify_loop(&stream, buffer, i, size)){ + b32 still_looping = 0; + do{ + for (; i < stream.end; ++i){ + u8 ch = (u8)stream.data[i]; + result = cursor_seek_step(&state, seek, xy_seek, max_width, + font_height, adv, size, ch); + if (!result){ + goto buffer_cursor_seek_end; + } + } + still_looping = buffer_stringify_next(&stream); + }while(still_looping); } + if (result){ result = cursor_seek_step(&state, seek, xy_seek, max_width, font_height, adv, size, 0); @@ -547,7 +551,7 @@ buffer_cursor_seek(Buffer_Type *buffer, Buffer_Seek seek, f32 max_width, } } - buffer_cursor_seek_end: + buffer_cursor_seek_end:; return(state.cursor); } @@ -797,10 +801,8 @@ struct Buffer_Render_Params{ }; struct Buffer_Render_State{ - Buffer_Stringify_Type loop; - char *data; - i32 end; - i32 size; + Buffer_Stream_Type stream; + b32 still_looping; i32 i; f32 ch_width; @@ -872,114 +874,112 @@ buffer_render_data(Buffer_Render_State *S_ptr, Buffer_Render_Params params, f32 S.write.x_max = params.port_x + params.clip_w; if (params.adv){ - for (S.loop = buffer_stringify_loop(params.buffer, params.start_cursor.pos, size); - buffer_stringify_good(&S.loop) && S.write.item < item_end; - buffer_stringify_next(&S.loop)){ - - S.end = S.loop.size + S.loop.absolute_pos; - S.data = S.loop.data - S.loop.absolute_pos; - - for (S.i = S.loop.absolute_pos; S.i < S.end; ++S.i){ - S.ch = (uint8_t)S.data[S.i]; - S.ch_width = measure_character(params.adv, S.ch); - - if (S.ch_width + S.write.x > params.width + shift_x && S.ch != '\n' && params.wrapped){ - if (params.virtual_white){ - S_stop.status = RenderStatus_NeedLineShift; - S_stop.line_index = S.line; - S_stop.pos = S.i+1; - DrYield(2, S_stop); + S.i = params.start_cursor.pos; + if (buffer_stringify_loop(&S.stream, params.buffer, S.i, size)){ + do{ + for (; S.i < S.stream.end; ++S.i){ + S.ch = (u8)S.stream.data[S.i]; + S.ch_width = measure_character(params.adv, S.ch); + + if (S.ch_width + S.write.x > params.width + shift_x && S.ch != '\n' && params.wrapped){ + if (params.virtual_white){ + S_stop.status = RenderStatus_NeedLineShift; + S_stop.line_index = S.line; + S_stop.pos = S.i+1; + DrYield(2, S_stop); + } + + S.write.x = shift_x + line_shift; + S.write.y += params.font_height; } - S.write.x = shift_x + line_shift; - S.write.y += params.font_height; - } - - if (S.write.y > params.height + shift_y){ - goto buffer_get_render_data_end; - } - - if (S.ch != ' ' && S.ch != '\t'){ - S.skipping_whitespace = 0; - } - - if (!S.skipping_whitespace){ - switch (S.ch){ - case '\n': - if (S.write.item < item_end){ - S.write = write_render_item(S.write, S.i, ' ', 0); - - if (params.virtual_white){ - S_stop.status = RenderStatus_NeedLineShift; - S_stop.line_index = S.line+1; - S_stop.pos = S.i+1; - DrYield(3, S_stop); - - S.skipping_whitespace = 1; - } - - ++S.line; - - S.write.x = shift_x + line_shift; - S.write.y += params.font_height; - } - break; - - case '\r': - if (S.write.item < item_end){ - S.write = write_render_item(S.write, S.i, '\\', BRFlag_Special_Character); - + if (S.write.y > params.height + shift_y){ + goto buffer_get_render_data_end; + } + + if (S.ch != ' ' && S.ch != '\t'){ + S.skipping_whitespace = 0; + } + + if (!S.skipping_whitespace){ + switch (S.ch){ + case '\n': if (S.write.item < item_end){ - S.write = write_render_item(S.write, S.i, 'r', BRFlag_Special_Character); + S.write = write_render_item(S.write, S.i, ' ', 0); + + if (params.virtual_white){ + S_stop.status = RenderStatus_NeedLineShift; + S_stop.line_index = S.line+1; + S_stop.pos = S.i+1; + DrYield(3, S_stop); + + S.skipping_whitespace = 1; + } + + ++S.line; + + S.write.x = shift_x + line_shift; + S.write.y += params.font_height; } - } - break; - - case '\t': - if (S.write.item < item_end){ - f32 new_x = S.write.x + S.ch_width; - S.write = write_render_item(S.write, S.i, ' ', 0); - S.write.x = new_x; - } - break; - - default: - if (S.write.item < item_end){ - if (S.ch >= ' ' && S.ch <= '~'){ - S.write = write_render_item(S.write, S.i, S.ch, 0); - } - else{ + break; + + case '\r': + if (S.write.item < item_end){ S.write = write_render_item(S.write, S.i, '\\', BRFlag_Special_Character); - char ch = S.ch; - char C = '0' + (ch / 0x10); - if ((ch / 0x10) > 0x9){ - C = ('A' - 0xA) + (ch / 0x10); - } - if (S.write.item < item_end){ - S.write = write_render_item(S.write, S.i, C, BRFlag_Special_Character); - } - - ch = (ch % 0x10); - C = '0' + ch; - if (ch > 0x9){ - C = ('A' - 0xA) + ch; - } - - if (S.write.item < item_end){ - S.write = write_render_item(S.write, S.i, C, BRFlag_Special_Character); + S.write = write_render_item(S.write, S.i, 'r', BRFlag_Special_Character); } } + break; + + case '\t': + if (S.write.item < item_end){ + f32 new_x = S.write.x + S.ch_width; + S.write = write_render_item(S.write, S.i, ' ', 0); + S.write.x = new_x; + } + break; + + default: + if (S.write.item < item_end){ + if (S.ch >= ' ' && S.ch <= '~'){ + S.write = write_render_item(S.write, S.i, S.ch, 0); + } + else{ + S.write = write_render_item(S.write, S.i, '\\', BRFlag_Special_Character); + + char ch = S.ch; + char C = '0' + (ch / 0x10); + if ((ch / 0x10) > 0x9){ + C = ('A' - 0xA) + (ch / 0x10); + } + + if (S.write.item < item_end){ + S.write = write_render_item(S.write, S.i, C, BRFlag_Special_Character); + } + + ch = (ch % 0x10); + C = '0' + ch; + if (ch > 0x9){ + C = ('A' - 0xA) + ch; + } + + if (S.write.item < item_end){ + S.write = write_render_item(S.write, S.i, C, BRFlag_Special_Character); + } + } + } + break; } - break; + } + + if (S.write.y > params.height + shift_y){ + goto buffer_get_render_data_end; } } - - if (S.write.y > params.height + shift_y){ - goto buffer_get_render_data_end; - } - } + S.still_looping = buffer_stringify_next(&S.stream); + }while(S.still_looping); } buffer_get_render_data_end:; diff --git a/buffer/4coder_gap_buffer.cpp b/buffer/4coder_gap_buffer.cpp index 9a153d9d..da39d3a1 100644 --- a/buffer/4coder_gap_buffer.cpp +++ b/buffer/4coder_gap_buffer.cpp @@ -101,12 +101,9 @@ buffer_end_init(Gap_Buffer_Init *init, void *scratch, i32 scratch_size){ typedef struct Gap_Buffer_Stream{ Gap_Buffer *buffer; char *data; - char *base; - i32 absolute_pos; - i32 pos; i32 end; - i32 size; i32 separated; + i32 absolute_end; } Gap_Buffer_Stream; internal_4tech b32 @@ -115,38 +112,34 @@ buffer_stringify_loop(Gap_Buffer_Stream *stream, Gap_Buffer *buffer, i32 start, if (0 <= start && start < end && end <= buffer->size1 + buffer->size2){ stream->buffer = buffer; - stream->base = buffer->data; - stream->absolute_pos = start; - - if (end <= buffer->size1){ - stream->end = end; - } - else{ - stream->end = end + buffer->gap_size; - } + stream->absolute_end = end; if (start < buffer->size1){ - if (end <= buffer->size1){ - stream->separated = 0; - } - else{ + if (buffer->size1 < end){ stream->separated = 1; } - stream->pos = start; + else{ + stream->separated = 0; + } + stream->data = buffer->data; } else{ stream->separated = 0; - stream->pos = start + buffer->gap_size; + stream->data = buffer->data + buffer->gap_size; } if (stream->separated){ - stream->size = buffer->size1 - start; + stream->end = buffer->size1; } else{ - stream->size = end - start; + stream->end = end; } - stream->data = buffer->data + stream->pos; + if (stream->end > stream->absolute_end){ + stream->end = stream->absolute_end; + } + + result = 1; } return(result); @@ -154,20 +147,15 @@ buffer_stringify_loop(Gap_Buffer_Stream *stream, Gap_Buffer *buffer, i32 start, internal_4tech b32 buffer_stringify_next(Gap_Buffer_Stream *stream){ - i32 size1 = 0, temp_end = 0; + b32 result = 0; + Gap_Buffer *buffer = stream->buffer; if (stream->separated){ + stream->data = buffer->data + buffer->gap_size; + stream->end = stream->absolute_end; stream->separated = 0; - size1 = stream->buffer->size1; - stream->pos = stream->buffer->gap_size + size1; - stream->absolute_pos = size1; - temp_end = stream->end; + result = 1; } - else{ - stream->buffer = 0; - temp_end = stream->pos; - } - stream->size = temp_end - stream->pos; - stream->data = stream->base + stream->pos; + return(result); } internal_4tech i32 @@ -209,7 +197,7 @@ buffer_replace_range(Gap_Buffer *buffer, i32 start, i32 end, char *str, i32 len, *request_amount = round_up_4tech(2*(*shift_amount + size), 4 << 10); result = 1; } - + return(result); }