rope edits

master
Allen Webster 2015-11-04 17:14:24 -05:00
parent cab1801465
commit 7b3c7094f8
9 changed files with 712 additions and 161 deletions

16
4ed.cpp
View File

@ -229,7 +229,7 @@ COMMAND_DECL(write_character){
}
COMMAND_DECL(seek_whitespace_right){
#if BUFFER_EXPERIMENT_SCALPEL <= 2
#if BUFFER_EXPERIMENT_SCALPEL <= 3
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
@ -240,7 +240,7 @@ COMMAND_DECL(seek_whitespace_right){
}
COMMAND_DECL(seek_whitespace_left){
#if BUFFER_EXPERIMENT_SCALPEL <= 2
#if BUFFER_EXPERIMENT_SCALPEL <= 3
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
@ -251,7 +251,7 @@ COMMAND_DECL(seek_whitespace_left){
}
COMMAND_DECL(seek_whitespace_up){
#if BUFFER_EXPERIMENT_SCALPEL <= 2
#if BUFFER_EXPERIMENT_SCALPEL <= 3
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
@ -262,7 +262,7 @@ COMMAND_DECL(seek_whitespace_up){
}
COMMAND_DECL(seek_whitespace_down){
#if BUFFER_EXPERIMENT_SCALPEL <= 2
#if BUFFER_EXPERIMENT_SCALPEL <= 3
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
@ -356,7 +356,7 @@ COMMAND_DECL(seek_white_or_token_left){
}
COMMAND_DECL(seek_alphanumeric_right){
#if BUFFER_EXPERIMENT_SCALPEL <= 2
#if BUFFER_EXPERIMENT_SCALPEL <= 3
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
@ -367,7 +367,7 @@ COMMAND_DECL(seek_alphanumeric_right){
}
COMMAND_DECL(seek_alphanumeric_left){
#if BUFFER_EXPERIMENT_SCALPEL <= 2
#if BUFFER_EXPERIMENT_SCALPEL <= 3
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
@ -378,7 +378,7 @@ COMMAND_DECL(seek_alphanumeric_left){
}
COMMAND_DECL(seek_alphanumeric_or_camel_right){
#if BUFFER_EXPERIMENT_SCALPEL <= 2
#if BUFFER_EXPERIMENT_SCALPEL <= 3
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);
@ -390,7 +390,7 @@ COMMAND_DECL(seek_alphanumeric_or_camel_right){
}
COMMAND_DECL(seek_alphanumeric_or_camel_left){
#if BUFFER_EXPERIMENT_SCALPEL <= 2
#if BUFFER_EXPERIMENT_SCALPEL <= 3
ProfileMomentFunction();
REQ_FILE_VIEW(view);
REQ_FILE(file, view);

View File

@ -1148,7 +1148,7 @@ file_synchronize_times(Editing_File *file, u8 *filename){
internal b32
file_save(Partition *part, Editing_File *file, char *filename){
b32 result = 0;
#if BUFFER_EXPERIMENT_SCALPEL <= 2
#if BUFFER_EXPERIMENT_SCALPEL <= 3
Temp_Memory temp = begin_temp_memory(part);
i32 max = partition_remaining(part);
if (file->dos_write_mode){
@ -1199,7 +1199,7 @@ enum File_Bubble_Type{
internal i32
file_grow_starts_as_needed(General_Memory *general, Buffer_Type *buffer, i32 additional_lines){
bool32 result = GROW_NOT_NEEDED;
#if BUFFER_EXPERIMENT_SCALPEL <= 2
#if BUFFER_EXPERIMENT_SCALPEL <= 3
i32 max = buffer->line_max;
i32 count = buffer->line_count;
i32 target_lines = count + additional_lines;
@ -1223,7 +1223,7 @@ file_grow_starts_as_needed(General_Memory *general, Buffer_Type *buffer, i32 add
internal void
file_measure_starts(General_Memory *general, Buffer_Type *buffer){
#if BUFFER_EXPERIMENT_SCALPEL <= 2
#if BUFFER_EXPERIMENT_SCALPEL <= 3
ProfileMomentFunction();
if (!buffer->line_starts){
i32 max = buffer->line_max = Kbytes(1);
@ -1256,7 +1256,7 @@ internal void
file_remeasure_starts(General_Memory *general, Buffer_Type *buffer,
i32 line_start, i32 line_end, i32 line_shift,
i32 character_shift){
#if BUFFER_EXPERIMENT_SCALPEL <= 2
#if BUFFER_EXPERIMENT_SCALPEL <= 3
ProfileMomentFunction();
Assert(buffer->line_starts);
file_grow_starts_as_needed(general, buffer, line_shift);
@ -1279,7 +1279,7 @@ get_opaque_font_advance(Font *font){
internal void
file_grow_widths_as_needed(General_Memory *general, Buffer_Type *buffer){
#if BUFFER_EXPERIMENT_SCALPEL <= 2
#if BUFFER_EXPERIMENT_SCALPEL <= 3
i32 line_count = buffer->line_count;
if (line_count > buffer->widths_max || buffer->widths_max == 0){
i32 new_max = LargeRoundUp(line_count, Kbytes(1));
@ -1300,7 +1300,7 @@ file_grow_widths_as_needed(General_Memory *general, Buffer_Type *buffer){
internal void
file_measure_widths(General_Memory *general, Buffer_Type *buffer, Font *font){
#if BUFFER_EXPERIMENT_SCALPEL <= 2
#if BUFFER_EXPERIMENT_SCALPEL <= 3
ProfileMomentFunction();
file_grow_widths_as_needed(general, buffer);
Opaque_Font_Advance opad = get_opaque_font_advance(font);
@ -1311,7 +1311,7 @@ file_measure_widths(General_Memory *general, Buffer_Type *buffer, Font *font){
internal void
file_remeasure_widths(General_Memory *general, Buffer_Type *buffer, Font *font,
i32 line_start, i32 line_end, i32 line_shift){
#if BUFFER_EXPERIMENT_SCALPEL <= 2
#if BUFFER_EXPERIMENT_SCALPEL <= 3
ProfileMomentFunction();
file_grow_widths_as_needed(general, buffer);
Opaque_Font_Advance opad = get_opaque_font_advance(font);
@ -1329,7 +1329,7 @@ view_wrapped_line_span(real32 line_width, real32 max_width){
internal i32
view_compute_lowest_line(File_View *view){
i32 lowest_line = 0;
#if BUFFER_EXPERIMENT_SCALPEL <= 2
#if BUFFER_EXPERIMENT_SCALPEL <= 3
i32 last_line = view->line_count - 1;
if (last_line > 0){
if (view->unwrapped_lines){
@ -1355,7 +1355,7 @@ view_compute_lowest_line(File_View *view){
internal void
view_measure_wraps(General_Memory *general, File_View *view){
#if BUFFER_EXPERIMENT_SCALPEL <= 2
#if BUFFER_EXPERIMENT_SCALPEL <= 3
ProfileMomentFunction();
Buffer_Type *buffer;
@ -2019,7 +2019,7 @@ file_post_history(General_Memory *general, Editing_File *file,
inline Full_Cursor
view_compute_cursor_from_pos(File_View *view, i32 pos){
#if BUFFER_EXPERIMENT_SCALPEL <= 2
#if BUFFER_EXPERIMENT_SCALPEL <= 3
Editing_File *file = view->file;
Style *style = view->style;
Font *font = style->font;
@ -2037,7 +2037,7 @@ view_compute_cursor_from_pos(File_View *view, i32 pos){
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 <= 2
#if BUFFER_EXPERIMENT_SCALPEL <= 3
Editing_File *file = view->file;
Style *style = view->style;
Font *font = style->font;
@ -2055,7 +2055,7 @@ view_compute_cursor_from_unwrapped_xy(File_View *view, real32 seek_x, real32 see
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 <= 2
#if BUFFER_EXPERIMENT_SCALPEL <= 3
Editing_File *file = view->file;
Style *style = view->style;
Font *font = style->font;
@ -2491,17 +2491,21 @@ file_do_single_edit(Mem_Options *mem, Editing_File *file,
file_pre_edit_maintenance(file);
// NOTE(allen): actual text replacement
#if BUFFER_EXPERIMENT_SCALPEL <= 2
#if BUFFER_EXPERIMENT_SCALPEL <= 3
i32 shift_amount = 0;
General_Memory *general = &mem->general;
Partition *part = &mem->part;
char *str = (char*)spec.str;
i32 start = spec.step.edit.start;
i32 end = spec.step.edit.end;
i32 str_len = spec.step.edit.len;
i32 scratch_size = partition_remaining(part);
Assert(scratch_size > 0);
i32 request_amount = 0;
while (buffer_replace_range(&file->buffer, start, end, str, str_len, &shift_amount, &request_amount)){
while (buffer_replace_range(&file->buffer, start, end, str, str_len, &shift_amount,
part->base + part->pos, scratch_size, &request_amount)){
void *new_data = 0;
if (request_amount > 0){
new_data = general_memory_allocate(general, request_amount, BUBBLE_BUFFER);
@ -2539,7 +2543,7 @@ file_do_single_edit(Mem_Options *mem, Editing_File *file,
file_relex_parallel(mem, file, start, end, shift_amount);
#endif
#if BUFFER_EXPERIMENT_SCALPEL <= 2
#if BUFFER_EXPERIMENT_SCALPEL <= 3
Temp_Memory cursor_temp = begin_temp_memory(&mem->part);
i32 cursor_max = layout->panel_max_count * 2;
Cursor_With_Index *cursors = push_array(&mem->part, Cursor_With_Index, cursor_max);
@ -2946,7 +2950,7 @@ 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 <= 2
#if BUFFER_EXPERIMENT_SCALPEL <= 3
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);
@ -3820,7 +3824,7 @@ draw_file_view(Thread_Context *thread, View *view_, i32_Rect rect, bool32 is_act
bar.rect.y1 = bar.rect.y0 + font->height + 2;
rect.y0 += font->height + 2;
#if BUFFER_EXPERIMENT_SCALPEL <= 2
#if BUFFER_EXPERIMENT_SCALPEL <= 3
i32 max_x = rect.x1 - rect.x0;
i32 max_y = rect.y1 - rect.y0 + font->height;
@ -3895,17 +3899,6 @@ draw_file_view(Thread_Context *thread, View *view_, i32_Rect rect, bool32 is_act
i32 prev_ind = -1;
u32 highlight_color = 0;
u32 chunk_highlights[] = {
0x22FF0000,
0x22FFFF00,
0x2200FF00,
0x2200FFFF,
0x220000FF,
0x22FF00FF
};
i32 current_chunk = item->chunk_i;
u32 chunk_highlight = chunk_highlights[current_chunk % ArrayCount(chunk_highlights)];
for (i32 i = 0; i < count; ++i, ++item){
i32 ind = item->index;
if (tokens_use && ind != prev_ind){
@ -3930,11 +3923,6 @@ draw_file_view(Thread_Context *thread, View *view_, i32_Rect rect, bool32 is_act
}
u32 char_color = main_color;
if (item->chunk_i > current_chunk){
current_chunk = item->chunk_i;
chunk_highlight = chunk_highlights[current_chunk % ArrayCount(chunk_highlights)];
}
if (cursor_begin <= ind && ind < cursor_end && (ind != prev_ind || cursor_begin < ind)){
if (is_active) draw_rectangle(target, f32R(item->x0, item->y0, item->x1, item->y1), cursor_color);
else draw_rectangle_outline(target, f32R(item->x0, item->y0, item->x1, item->y1), cursor_color);
@ -3943,9 +3931,6 @@ draw_file_view(Thread_Context *thread, View *view_, i32_Rect rect, bool32 is_act
else if (highlight_color){
draw_rectangle(target, f32R(item->x0, item->y0, item->x1, item->y1), highlight_color);
}
else if (chunk_highlight){
draw_rectangle(target, f32R(item->x0, item->y0, item->x1, item->y1), chunk_highlight);
}
u32 fade_color = 0xFFFF00FF;
f32 fade_amount = 0.f;
@ -4126,7 +4111,7 @@ HANDLE_COMMAND_SIG(handle_command_file_view){
case FWIDG_SEARCH:
{
#if BUFFER_EXPERIMENT_SCALPEL <= 2
#if BUFFER_EXPERIMENT_SCALPEL <= 3
String *string = &file_view->isearch.str;
Single_Line_Input_Step result =
app_single_line_input_step(codes, key, string);

View File

@ -17,7 +17,7 @@
#define Buffer_Stringify_Type cat_4tech(Buffer_Type, _Stringify_Loop)
#define Buffer_Backify_Type cat_4tech(Buffer_Type, _Backify_Loop)
#if BUFFER_EXPERIMENT_SCALPEL <= 2
#if BUFFER_EXPERIMENT_SCALPEL <= 3
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);
@ -72,7 +72,7 @@ buffer_count_newlines(Buffer_Type *buffer, int start, int end){
}
#endif
#if BUFFER_EXPERIMENT_SCALPEL <= 2
#if BUFFER_EXPERIMENT_SCALPEL <= 3
internal_4tech int
buffer_seek_whitespace_down(Buffer_Type *buffer, int pos){
Buffer_Stringify_Type loop;
@ -479,8 +479,8 @@ buffer_rfind_string_end:
}
#endif
#if BUFFER_EXPERIMENT_SCALPEL <= 2
typedef struct{
#if BUFFER_EXPERIMENT_SCALPEL <= 3
typedef struct Buffer_Measure_Starts{
int i;
int count;
int start;
@ -742,8 +742,9 @@ buffer_get_line_index_from_wrapped_y(float *wraps, float y, float font_height, i
#endif
#ifndef NON_ABSTRACT_4TECH
typedef struct{
Full_Cursor cursor, prev_cursor;
typedef struct Seek_State{
Full_Cursor cursor;
Full_Cursor prev_cursor;
} Seek_State;
internal_4tech int
@ -854,7 +855,7 @@ cursor_seek_step_end:
#endif
#if BUFFER_EXPERIMENT_SCALPEL <= 2
#if BUFFER_EXPERIMENT_SCALPEL <= 3
internal_4tech Full_Cursor
buffer_cursor_seek(Buffer_Type *buffer, Buffer_Seek seek, float max_width, float font_height,
void *advance_data, int stride, Full_Cursor cursor){
@ -940,7 +941,7 @@ buffer_cursor_from_wrapped_xy(Buffer_Type *buffer, float x, float y, int round_d
}
#endif
#if BUFFER_EXPERIMENT_SCALPEL <= 2
#if BUFFER_EXPERIMENT_SCALPEL <= 3
internal_4tech void
buffer_invert_edit_shift(Buffer_Type *buffer, Buffer_Edit edit, Buffer_Edit *inverse, char *strings,
int *str_pos, int max, int shift_amount){
@ -965,7 +966,7 @@ buffer_invert_edit(Buffer_Type *buffer, Buffer_Edit edit, Buffer_Edit *inverse,
buffer_invert_edit_shift(buffer, edit, inverse, strings, str_pos, max, 0);
}
typedef struct{
typedef struct Buffer_Invert_Batch{
int i;
int shift_amount;
int len;
@ -1004,7 +1005,7 @@ buffer_invert_batch(Buffer_Invert_Batch *state, Buffer_Type *buffer, Buffer_Edit
}
#endif
#if BUFFER_EXPERIMENT_SCALPEL <= 1
#if BUFFER_EXPERIMENT_SCALPEL <= 2
internal_4tech void
buffer_batch_edit(Buffer_Type *buffer, Buffer_Edit *sorted_edits, char *strings, int edit_count){
Buffer_Batch_State state;
@ -1021,7 +1022,7 @@ buffer_batch_edit(Buffer_Type *buffer, Buffer_Edit *sorted_edits, char *strings,
}
#endif
#if BUFFER_EXPERIMENT_SCALPEL <= 2
#if BUFFER_EXPERIMENT_SCALPEL <= 3
internal_4tech void
buffer_get_render_data(Buffer_Type *buffer, float *wraps, Buffer_Render_Item *items, int max, int *count,
float port_x, float port_y, float scroll_x, float scroll_y, int wrapped,
@ -1077,9 +1078,6 @@ buffer_get_render_data(Buffer_Type *buffer, float *wraps, Buffer_Render_Item *it
switch (ch){
case '\n':
write_render_item_inline(item, i, ' ', x, y, advance_data, stride, font_height);
#if BUFFER_EXPERIMENT_SCALPEL == 2
item->chunk_i = loop.chunk_i*2 + ((loop.pos >= buffer->gaps[loop.chunk_i].size1)?1:0);
#endif
++item_i;
++item;
@ -1089,17 +1087,11 @@ buffer_get_render_data(Buffer_Type *buffer, float *wraps, Buffer_Render_Item *it
case 0:
ch_width = write_render_item_inline(item, i, '\\', x, y, advance_data, stride, font_height);
#if BUFFER_EXPERIMENT_SCALPEL == 2
item->chunk_i = loop.chunk_i*2 + ((loop.pos >= buffer->gaps[loop.chunk_i].size1)?1:0);
#endif
++item_i;
++item;
x += ch_width;
ch_width = write_render_item_inline(item, i, '0', x, y, advance_data, stride, font_height);
#if BUFFER_EXPERIMENT_SCALPEL == 2
item->chunk_i = loop.chunk_i*2 + ((loop.pos >= buffer->gaps[loop.chunk_i].size1)?1:0);
#endif
++item_i;
++item;
x += ch_width;
@ -1107,17 +1099,11 @@ buffer_get_render_data(Buffer_Type *buffer, float *wraps, Buffer_Render_Item *it
case '\r':
ch_width = write_render_item_inline(item, i, '\\', x, y, advance_data, stride, font_height);
#if BUFFER_EXPERIMENT_SCALPEL == 2
item->chunk_i = loop.chunk_i*2 + ((loop.pos >= buffer->gaps[loop.chunk_i].size1)?1:0);
#endif
++item_i;
++item;
x += ch_width;
ch_width = write_render_item_inline(item, i, 'r', x, y, advance_data, stride, font_height);
#if BUFFER_EXPERIMENT_SCALPEL == 2
item->chunk_i = loop.chunk_i*2 + ((loop.pos >= buffer->gaps[loop.chunk_i].size1)?1:0);
#endif
++item_i;
++item;
x += ch_width;
@ -1125,16 +1111,10 @@ buffer_get_render_data(Buffer_Type *buffer, float *wraps, Buffer_Render_Item *it
case '\t':
ch_width_sub = write_render_item_inline(item, i, '\\', x, y, advance_data, stride, font_height);
#if BUFFER_EXPERIMENT_SCALPEL == 2
item->chunk_i = loop.chunk_i*2 + ((loop.pos >= buffer->gaps[loop.chunk_i].size1)?1:0);
#endif
++item_i;
++item;
write_render_item_inline(item, i, 't', x + ch_width_sub, y, advance_data, stride, font_height);
#if BUFFER_EXPERIMENT_SCALPEL == 2
item->chunk_i = loop.chunk_i*2 + ((loop.pos >= buffer->gaps[loop.chunk_i].size1)?1:0);
#endif
++item_i;
++item;
x += ch_width;
@ -1142,9 +1122,6 @@ buffer_get_render_data(Buffer_Type *buffer, float *wraps, Buffer_Render_Item *it
default:
write_render_item(item, i, ch, x, y, ch_width, font_height);
#if BUFFER_EXPERIMENT_SCALPEL == 2
item->chunk_i = loop.chunk_i*2 + ((loop.pos >= buffer->gaps[loop.chunk_i].size1)?1:0);
#endif
++item_i;
++item;
x += ch_width;
@ -1160,9 +1137,6 @@ buffer_get_render_data_end:
ch = 0;
ch_width = measure_character(advance_data, stride, ' ');
write_render_item(item, size, ch, x, y, ch_width, font_height);
#if BUFFER_EXPERIMENT_SCALPEL == 2
item->chunk_i = -1;
#endif
++item_i;
++item;
x += ch_width;

View File

@ -13,7 +13,7 @@
// TOP
typedef struct{
typedef struct Gap_Buffer{
char *data;
int size1, gap_size, size2, max;
@ -39,7 +39,7 @@ buffer_size(Gap_Buffer *buffer){
return(size);
}
typedef struct{
typedef struct Gap_Buffer_Init{
Gap_Buffer *buffer;
char *data;
int size;
@ -110,7 +110,7 @@ buffer_end_init(Gap_Buffer_Init *init, void *scratch, int scratch_size){
return(result);
}
typedef struct{
typedef struct Gap_Buffer_Stringify_Loop{
Gap_Buffer *buffer;
char *data, *base;
int absolute_pos;
@ -172,7 +172,7 @@ buffer_stringify_next(Gap_Buffer_Stringify_Loop *loop){
loop->data = loop->base + loop->pos;
}
typedef struct{
typedef struct Gap_Buffer_Backify_Loop{
Gap_Buffer *buffer;
char *data, *base;
int pos, end;

View File

@ -13,7 +13,7 @@
// TOP
typedef struct{
typedef struct Buffer{
char *data;
int size, max;
@ -37,7 +37,7 @@ buffer_size(Buffer *buffer){
return buffer->size;
}
typedef struct{
typedef struct Buffer_Init{
Buffer *buffer;
char *data;
int size;
@ -92,7 +92,7 @@ buffer_end_init(Buffer_Init *init, void *scratch, int scratch_size){
return(result);
}
typedef struct{
typedef struct Buffer_Stringify_Loop{
Buffer *buffer;
char *data, *end;
int absolute_pos;
@ -125,7 +125,7 @@ buffer_stringify_next(Buffer_Stringify_Loop *loop){
loop->buffer = 0;
}
typedef struct{
typedef struct Buffer_Backify_Loop{
Buffer *buffer;
char *data, *end;
int absolute_pos;

View File

@ -16,7 +16,7 @@
// TOP
typedef struct{
typedef struct Fixed_Width_Gap_Buffer{
char *data;
int size1, gap_size, size2;
int start_pos;
@ -25,7 +25,7 @@ typedef struct{
#define fixed_width_buffer_size Kbytes(8)
#define fixed_width_buffer_half_size Kbytes(4)
typedef struct{
typedef struct Multi_Gap_Buffer{
Fixed_Width_Gap_Buffer *gaps;
int chunk_count;
int chunk_alloced;
@ -57,7 +57,7 @@ buffer_size(Multi_Gap_Buffer *buffer){
return(size);
}
typedef struct{
typedef struct Multi_Gap_Buffer_Init{
Multi_Gap_Buffer *buffer;
char *data;
int size;
@ -202,7 +202,7 @@ buffer_find_chunk(Multi_Gap_Buffer *buffer, int pos){
return(m);
}
typedef struct{
typedef struct Multi_Gap_Buffer_Stringify_Loop{
Multi_Gap_Buffer *buffer;
Fixed_Width_Gap_Buffer *gaps;
char *data;
@ -290,7 +290,7 @@ buffer_stringify_next(Multi_Gap_Buffer_Stringify_Loop *loop){
}
}
typedef struct{
typedef struct Multi_Gap_Buffer_Backify_Loop{
Multi_Gap_Buffer *buffer;
Fixed_Width_Gap_Buffer *gaps;
char *data;

View File

@ -15,7 +15,7 @@
typedef struct Rope_Node{
int left, right, parent;
int left_total, total;
int left_weight, weight;
int str_start;
} Rope_Node;
@ -26,6 +26,10 @@ typedef struct Rope_String{
#define rope_string_full_size 256
#define rope_string_width (rope_string_full_size-sizeof(Rope_String))
typedef struct Rope_Buffer_Edit_State{
int left, right, throw_away, middle;
} Rope_Buffer_Edit_State;
typedef struct Rope_Buffer{
void *data;
int free_rope_string;
@ -41,6 +45,10 @@ typedef struct Rope_Buffer{
int widths_count;
int line_max;
int widths_max;
int grow_string_memory;
int edit_stage;
Rope_Buffer_Edit_State edit_state;
} Rope_Buffer;
inline_4tech int
@ -53,7 +61,7 @@ buffer_good(Rope_Buffer *buffer){
inline_4tech int
buffer_size(Rope_Buffer *buffer){
int size;
size = buffer->nodes->left_total;
size = buffer->nodes->left_weight;
return(size);
}
@ -195,26 +203,106 @@ buffer_construct_stage(int parent, int right, int weight){
}
internal_4tech int
buffer_end_init(Rope_Buffer_Init *init, void *scratch, int scratch_size){
buffer_build_tree(Rope_Buffer *buffer, char *str, int len, int root,
void *scratch, int scratch_size, int *request_amount){
Rope_Construct_Stage *stack, *stage;
Rope_Node *node, *nodes;
char *dest;
int stack_max, top;
int result;
int node_index;
int is_right_side;
int read_pos;
nodes = buffer->nodes;
stack = (Rope_Construct_Stage*)scratch;
stack_max = scratch_size / sizeof(Rope_Construct_Stage);
top = 0;
result = 1;
read_pos = 0;
stack[top++] = buffer_construct_stage(root, 0, len);
for (;top > 0;){
stage = stack + (--top);
if (buffer_alloc_rope_node(buffer, &node_index)){
node = nodes + node_index;
node->parent = stage->parent_index;
node->weight = stage->weight;
node->left = 0;
node->right = 0;
is_right_side = stage->is_right_side;
if (stage->weight > rope_string_width){
node->str_start = 0;
node->left_weight = stage->weight / 2;
assert_4tech(top < stack_max);
stack[top++] = buffer_construct_stage(node_index, 1, node->weight - node->left_weight);
assert_4tech(top < stack_max);
stack[top++] = buffer_construct_stage(node_index, 0, node->left_weight);
}
else{
node->left_weight = 0;
if (buffer_alloc_rope_string(buffer, &node->str_start)){
dest = (char*)buffer->data + node->str_start;
assert_4tech(read_pos < len);
memcpy_4tech(dest, str + read_pos, node->weight);
read_pos += node->weight;
}
else{
result = 0;
if (request_amount){
buffer->grow_string_memory = 1;
*request_amount = buffer->string_count*rope_string_full_size*2;
}
break;
}
}
node = nodes + node->parent;
if (is_right_side) node->right = node_index;
else node->left = node_index;
}
else{
result = 0;
if (request_amount){
buffer->grow_string_memory = 0;
*request_amount = buffer->node_count*sizeof(Rope_Node)*2;
}
break;
}
}
if (!result && request_amount){
top = 0;
stack[top++] = buffer_construct_stage(nodes[root].left, 0, 0);
for (;top > 0;){
stage = stack + (--top);
node_index = stage->parent_index;
node = nodes + node_index;
if (node->left) stack[top++] = buffer_construct_stage(node->left, 0, 0);
if (node->right) stack[top++] = buffer_construct_stage(node->right, 0, 0);
if (node->str_start) buffer_free_rope_string(buffer, node->str_start);
buffer_free_rope_node(buffer, node_index);
}
}
return(result);
}
internal_4tech int
buffer_end_init(Rope_Buffer_Init *init, void *scratch, int scratch_size){
Rope_Buffer *buffer;
Rope_String *rope_string;
Rope_Node *node;
char *src, *dest;
int node_index;
int i, top, stack_max, is_right_side;
int read_pos, read_end;
int i;
int result;
int count;
src = init->data;
read_pos = 0;
read_end = init->size;
result = 0;
buffer = init->buffer;
if (buffer->nodes && buffer->data){
// NOTE(allen): initialize free lists
buffer->string_count = init->rope_string_count;
buffer->free_rope_string = 0;
@ -231,66 +319,550 @@ buffer_end_init(Rope_Buffer_Init *init, void *scratch, int scratch_size){
node = buffer->nodes + 1;
count = init->node_count;
for (i = 1; i < count; ++i, ++node){
for (i = 1; i < count-1; ++i, ++node){
node->parent = i+1;
}
node->parent = 0;
result = 1;
// NOTE(allen): initialize tree
node = buffer->nodes;
node->parent = 0;
node->total = init->size;
node->left_total = init->size;
node->weight = init->size;
node->left_weight = init->size;
result = buffer_build_tree(buffer, init->data, init->size, 0, scratch, scratch_size, 0);
}
return(result);
}
internal_4tech int
buffer_find_node(Rope_Buffer *buffer, int pos, int *node_start){
Rope_Node *nodes, *node;
*node_start = 0;
nodes = buffer->nodes;
node = nodes + nodes->left;
for (;node->str_start == 0;){
if (pos < node->left_weight){
node = nodes + node->left;
}
else{
*node_start += node->left_weight;
pos -= node->left_weight;
node = nodes + node->right;
}
}
return (int)(node - nodes);
}
typedef struct Rope_Buffer_Stringify_Loop{
Rope_Buffer *buffer;
char *data;
int absolute_pos;
int size;
int pos, end_pos;
int node, node_end;
} Rope_Buffer_Stringify_Loop;
internal_4tech Rope_Buffer_Stringify_Loop
buffer_stringify_loop(Rope_Buffer *buffer, int start, int end){
Rope_Buffer_Stringify_Loop result;
Rope_Node *node;
int size, node_start_pos, temp_end;
size = buffer_size(buffer);
if (0 <= start && start < end && end <= size){
result.buffer = buffer;
result.absolute_pos = start;
stack = (Rope_Construct_Stage*)scratch;
stack_max = scratch_size / sizeof(Rope_Construct_Stage);
top = 0;
result.node = buffer_find_node(buffer, start, &node_start_pos);
result.pos = start - node_start_pos;
stack[top++] = buffer_construct_stage(0, 0, init->size);
for (;top > 0;){
stage = stack + (--top);
if (buffer_alloc_rope_node(buffer, &node_index)){
node = buffer->nodes + node_index;
node->parent = stage->parent_index;
node->total = stage->weight;
is_right_side = stage->is_right_side;
if (stage->weight > rope_string_width){
node->left_total = stage->weight / 2;
assert_4tech(top < stack_max);
stack[top++] = buffer_construct_stage(node_index, 1, node->total - node->left_total);
assert_4tech(top < stack_max);
stack[top++] = buffer_construct_stage(node_index, 0, node->left_total);
}
else{
node->left_total = 0;
node->left = 0;
node->right = 0;
if (buffer_alloc_rope_string(buffer, &node->str_start)){
dest = (char*)buffer->data + node->str_start;
assert_4tech(read_pos < read_end);
memcpy_4tech(dest, src + read_pos, node->total);
read_pos += node->total;
}
else{
result = 0;
break;
}
}
node = buffer->nodes + node->parent;
if (is_right_side) node->right = node_index;
else node->left = node_index;
}
else{
result = 0;
result.node_end = buffer_find_node(buffer, end, &node_start_pos);
result.end_pos = end - node_start_pos;
node = buffer->nodes + result.node;
temp_end = node->weight;
if (result.node == result.node_end) temp_end = result.end_pos;
result.data = (char*)buffer->data + node->str_start + result.pos;
result.size = temp_end - result.pos;
}
else result.buffer = 0;
return(result);
}
inline_4tech int
buffer_stringify_good(Rope_Buffer_Stringify_Loop *loop){
int result;
result = (loop->buffer != 0);
return(result);
}
internal_4tech void
buffer_stringify_next(Rope_Buffer_Stringify_Loop *loop){
Rope_Node *node, *child, *nodes;
int temp_end;
if (loop->node == loop->node_end && loop->pos + loop->size == loop->end_pos){
loop->buffer = 0;
}
else{
nodes = loop->buffer->nodes;
node = nodes + loop->node;
for (;;){
assert_4tech(node->parent != 0);
child = node;
node = nodes + node->parent;
if (nodes + node->left == child){
break;
}
else{
assert_4tech(nodes + node->right == child);
}
}
node = nodes + node->right;
for (;node->left;){
node = nodes + node->left;
}
loop->pos = 0;
loop->node = (int)(node - nodes);
loop->absolute_pos += loop->size;
temp_end = node->weight;
if (loop->node == loop->node_end) temp_end = loop->end_pos;
loop->size = temp_end;
loop->data = (char*)loop->buffer->data + node->str_start;
}
}
typedef struct Rope_Buffer_Backify_Loop{
Rope_Buffer *buffer;
char *data;
int absolute_pos;
int size;
int pos, end_pos;
int node, node_end;
} Rope_Buffer_Backify_Loop;
internal_4tech Rope_Buffer_Backify_Loop
buffer_backify_loop(Rope_Buffer *buffer, int start, int end){
Rope_Buffer_Backify_Loop result;
int size, node_start_pos, temp_end;
size = buffer_size(buffer);
++start;
if (0 <= end && end < start && start <= size){
result.buffer = buffer;
result.node_end = buffer_find_node(buffer, end, &node_start_pos);
result.end_pos = end - node_start_pos;
result.node = buffer_find_node(buffer, start, &node_start_pos);
temp_end = start - node_start_pos;
if (result.node_end == result.node){
result.pos = result.end_pos;
result.absolute_pos = end;
}
else{
result.pos = 0;
result.absolute_pos = node_start_pos;
}
result.size = temp_end - result.pos;
result.data = (char*)buffer->data + buffer->nodes[result.node].str_start + result.pos;
}
else result.buffer = 0;
return(result);
}
inline_4tech int
buffer_backify_good(Rope_Buffer_Backify_Loop *loop){
int result;
result = (loop->buffer != 0);
return(result);
}
internal_4tech void
buffer_backify_next(Rope_Buffer_Backify_Loop *loop){
Rope_Node *node, *child, *nodes;
int temp_start;
if (loop->node == loop->node_end && loop->pos == loop->end_pos){
loop->buffer = 0;
}
else{
nodes = loop->buffer->nodes;
node = nodes + loop->node;
for (;;){
assert_4tech(node->parent != 0);
child = node;
node = nodes + node->parent;
if (nodes + node->right == child){
break;
}
else{
assert_4tech(nodes + node->left == child);
}
}
node = nodes + node->left;
for (;node->right;){
node = nodes + node->right;
}
loop->pos = 0;
loop->node = (int)(node - nodes);
loop->absolute_pos -= node->weight;
temp_start = 0;
if (loop->node == loop->node_end) temp_start = loop->end_pos;
loop->size = node->weight - temp_start;
loop->data = (char*)loop->buffer->data + node->str_start;
}
}
internal_4tech int
buffer_concat(Rope_Buffer *buffer, int node_a, int node_b, int *root, int *request_amount){
Rope_Node *r, *a, *b, *nodes;
int result;
result = 0;
if (buffer_alloc_rope_node(buffer, root)){
nodes = buffer->nodes;
r = nodes + *root;
a = nodes + node_a;
b = nodes + node_b;
r->left = node_a;
r->right = node_b;
r->weight = a->weight + b->weight;
r->left_weight = a->weight;
r->str_start = 0;
r->parent = 0;
a->parent = *root;
b->parent = *root;
}
else{
result = 1;
buffer->grow_string_memory = 0;
*request_amount = buffer->node_count*sizeof(Rope_Node)*2;
}
return(result);
}
internal_4tech int
buffer_string_split(Rope_Buffer *buffer, int *node_index, int pos, int *request_amount){
Rope_Node *node, *a, *b;
int node_a, node_b;
int new_string_start, string_start;
int result;
result = 0;
if (pos > 0){
if (buffer_alloc_rope_string(buffer, &new_string_start)){
if (buffer_alloc_rope_node(buffer, &node_a)){
if (buffer_alloc_rope_node(buffer, &node_b)){
node = buffer->nodes + *node_index;
string_start = node->str_start;
memcpy_4tech((char*)buffer->data + new_string_start, (char*)buffer->data + string_start + pos, node->weight - pos);
node->str_start = 0;
node->left_weight = pos;
node->left = node_a;
node->right = node_b;
a = buffer->nodes + node_a;
b = buffer->nodes + node_b;
a->parent = *node_index;
a->left = 0;
a->right = 0;
a->left_weight = 0;
a->weight = pos;
a->str_start = string_start;
b->parent = *node_index;;
b->left = 0;
b->right = 0;
b->left_weight = 0;
b->weight = node->weight - pos;
b->str_start = new_string_start;
*node_index = node_b;
}
else{
buffer_free_rope_string(buffer, new_string_start);
buffer_free_rope_node(buffer, node_a);
result = 1;
buffer->grow_string_memory = 0;
*request_amount = buffer->node_count*sizeof(Rope_Node)*2;
}
}
else{
buffer_free_rope_string(buffer, new_string_start);
result = 1;
buffer->grow_string_memory = 0;
*request_amount = buffer->node_count*sizeof(Rope_Node)*2;
}
}
else{
result = 1;
buffer->grow_string_memory = 1;
*request_amount = buffer->string_count*rope_string_full_size*2;
}
}
assert_4tech(!result || read_pos == read_end);
return(result);
}
internal_4tech void
buffer_reduce_node(Rope_Buffer *buffer, int node_index){
Rope_Node *parent, *child, *node, *nodes;
int child_index;
nodes = buffer->nodes;
node = nodes + node_index;
parent = nodes + node->parent;
child_index = node->left;
if (child_index == 0) child_index = node->right;
assert_4tech(child_index != 0);
child = nodes + child_index;
if (parent->left == node_index) parent->left = child_index;
else parent->right = child_index;
child->parent = node->parent;
for (;parent != nodes;){
parent->weight = nodes[parent->left].weight + nodes[parent->right].weight;
parent->left_weight = nodes[parent->left].weight;
parent = nodes + parent->parent;
}
parent->weight = parent->left_weight = nodes[parent->left].weight;
buffer_free_rope_node(buffer, node_index);
}
internal_4tech int
buffer_split(Rope_Buffer *buffer, int pos, int *node_a, int *node_b, int *request_amount){
Rope_Node *node, *nodes, *child;
int node_index, node_start_pos, split_root;
int result;
debug_4tech(int dbg_check);
result = 0;
node_index = buffer_find_node(buffer, pos, &node_start_pos);
if (node_start_pos < pos){
if (buffer_string_split(buffer, &node_index, pos - node_start_pos, request_amount)){
result = 1;
goto buffer_split_end;
}
}
split_root = 0;
nodes = buffer->nodes;
node = nodes + node_index;
for (;;){
child = node;
node = nodes + node->parent;
if (child == nodes + node->right){
break;
}
else{
assert_4tech(child == nodes + node->left);
}
}
for (;;){
if (split_root == 0){
split_root = node->right;
}
else{
debug_4tech(dbg_check =)
buffer_concat(buffer, split_root, node->right, &split_root, request_amount);
assert_4tech(!dbg_check);
}
node_index = (int)(node - nodes);
node->right = 0;
node = nodes + node->left;
buffer_reduce_node(buffer, node_index);
for (;;){
child = node;
node = nodes + child->parent;
if (nodes + node->left == child){
break;
}
else{
assert_4tech(nodes + node->right == child);
}
}
if (node == nodes) break;
}
*node_a = nodes->left;
*node_b = split_root;
buffer_split_end:
return(result);
}
internal_4tech int
buffer_build_tree_floating(Rope_Buffer *buffer, char *str, int len, int *out,
void *scratch, int scratch_size, int *request_amount){
int result;
int super_root;
result = 0;
if (buffer_alloc_rope_node(buffer, &super_root)){
if (buffer_build_tree(buffer, str, len, super_root, scratch, scratch_size, request_amount)){
*out = buffer->nodes[super_root].left;
buffer_free_rope_node(buffer, super_root);
}
else{
result = 1;
buffer_free_rope_node(buffer, super_root);
}
}
else{
result = 1;
buffer->grow_string_memory = 0;
*request_amount = buffer->node_count*sizeof(Rope_Node)*2;
}
return(result);
}
internal_4tech int
buffer_replace_range(Rope_Buffer *buffer, int start, int end, char *str, int len, int *shift_amount,
void *scratch, int scratch_size, int *request_amount){
Rope_Node *nodes;
Rope_Buffer_Edit_State state;
int result;
state = buffer->edit_state;
*shift_amount = (len - (end - start));
result = 0;
for (; buffer->edit_stage < 6; ++buffer->edit_stage){
switch (buffer->edit_stage){
case 0:
if (buffer_split(buffer, end, &state.throw_away, &state.right, request_amount)){
result = 1;
goto rope_buffer_replace_range_end;
} break;
case 1:
if (start == end){
state.left = state.throw_away;
}
else{
if (buffer_split(buffer, start, &state.left, &state.throw_away, request_amount)){
result = 1;
goto rope_buffer_replace_range_end;
}
}
if (len == 0){
buffer->edit_stage = 5 - 1;
}
break;
case 2:
if (buffer_build_tree_floating(buffer, str, len, &state.middle, scratch, scratch_size, request_amount)){
result = 1;
goto rope_buffer_replace_range_end;
} break;
case 3:
if (buffer_concat(buffer, state.left, state.middle, &state.throw_away, request_amount)){
result = 1;
goto rope_buffer_replace_range_end;
} break;
case 4:
if (buffer_concat(buffer, state.throw_away, state.right, &state.middle, request_amount)){
result = 1;
goto rope_buffer_replace_range_end;
}
buffer->edit_stage = 6;
break;
case 5:
if (buffer_concat(buffer, state.left, state.right, &state.middle, request_amount)){
result = 1;
goto rope_buffer_replace_range_end;
} break;
}
}
buffer->edit_stage = 0;
nodes = buffer->nodes;
nodes->left = state.middle;
nodes->weight = nodes->left_weight = nodes[state.middle].weight;
state = {};
rope_buffer_replace_range_end:
buffer->edit_state = state;
return(result);
}
internal_4tech void*
buffer_edit_provide_memory(Rope_Buffer *buffer, void *new_data, int size){
void *result;
Rope_String *rope_string;
Rope_Node *node;
int start, end, i;
if (buffer->grow_string_memory){
assert_4tech(size >= buffer->string_count * rope_string_full_size);
result = buffer->data;
memcpy_4tech(new_data, buffer->data, buffer->string_count * rope_string_full_size);
buffer->data = new_data;
start = buffer->string_count*rope_string_full_size;
end = size/rope_string_full_size;
buffer->string_count = end;
end = (end-1)*rope_string_full_size;
for (i = start; i < end; i += rope_string_full_size){
rope_string = (Rope_String*)((char*)new_data + i);
rope_string->next_free = i + rope_string_full_size;
}
rope_string = (Rope_String*)((char*)new_data + i);
rope_string->next_free = buffer->free_rope_string;
buffer->free_rope_string = start;
}
else{
assert_4tech(size >= buffer->node_count * sizeof(Rope_Node));
result = buffer->nodes;
memcpy_4tech(new_data, buffer->nodes, buffer->node_count * sizeof(Rope_Node));
buffer->nodes = (Rope_Node*)new_data;
start = buffer->node_count;
end = size/sizeof(Rope_Node);
buffer->node_count = end;
end -= 1;
node = buffer->nodes + start;
for (i = start; i < end; ++i, ++node){
node->parent = i+1;
}
node->parent = buffer->free_rope_node;
buffer->free_rope_node = start;
}
return(result);
}

View File

@ -86,12 +86,12 @@ measure_character(void *advance_data, int stride, char character){
return(width);
}
typedef struct{
typedef struct Buffer_Edit{
int str_start, len;
int start, end;
} Buffer_Edit;
typedef struct{
typedef struct Buffer_Batch_State{
int i;
int shift_total;
} Buffer_Batch_State;
@ -103,7 +103,7 @@ typedef enum{
buffer_seek_line_char
} Buffer_Seek_Type;
typedef struct{
typedef struct Buffer_Seek{
Buffer_Seek_Type type;
union{
struct { int pos; };
@ -149,20 +149,18 @@ seek_line_char(int line, int character){
return(result);
}
typedef struct{
typedef struct Full_Cursor{
int pos;
int line, character;
float unwrapped_x, unwrapped_y;
float wrapped_x, wrapped_y;
} Full_Cursor;
typedef struct{
typedef struct Buffer_Render_Item{
int index;
int glyphid;
float x0, y0;
float x1, y1;
int chunk_i;
} Buffer_Render_Item;
inline_4tech void
@ -198,7 +196,7 @@ make_cursor_hint(int line_index, int *starts, float *wrap_ys, float font_height)
return(hint);
}
typedef struct{
typedef struct Cursor_With_Index{
int pos, index;
} Cursor_With_Index;

22
temp.cpp Normal file
View File

@ -0,0 +1,22 @@
/*
* YOUR INFO HERE!
*/
// a b c d e f g
#define swap(a,b) {auto t=a; a=b; b=t;}
struct Thing{
int x, y, z;
};
struct Stuff{
Thing x;
int a, b, c;
};
void insert_sort(int *items, int size){
}