starting undo refactoring

This commit is contained in:
Allen Webster 2015-10-19 16:30:25 -04:00
parent c100efd1af
commit 1f1d02ec73
5 changed files with 225 additions and 511 deletions

View File

@ -1074,7 +1074,7 @@ COMMAND_DECL(to_uppercase){
spec.end = range.end;
spec.str_len = range.end - range.start;
spec.next_cursor_pos = view->cursor.pos;
view_pre_replace_range(mem, file, spec);
view_update_history_before_edit(mem, file, spec);
if (file->still_lexing){
system_cancel_job(BACKGROUND_THREADS, file->lex_job);
@ -1107,7 +1107,7 @@ COMMAND_DECL(to_lowercase){
spec.end = range.end;
spec.str_len = range.end - range.start;
spec.next_cursor_pos = view->cursor.pos;
view_pre_replace_range(mem, file, spec);
view_update_history_before_edit(mem, file, spec);
if (file->still_lexing){
system_cancel_job(BACKGROUND_THREADS, file->lex_job);

View File

@ -51,7 +51,20 @@ struct Edit_Step{
i32 next_block, prev_block;
};
struct Edit_Stack{
u8 *strings;
i32 size, max;
Edit_Step *edits;
i32 edit_count, edit_max;
};
struct Undo_Data{
Edit_Stack undo;
Edit_Stack redo;
Edit_Stack history;
#if 0
u8 *strings;
i32 str_size, str_redo, str_max;
@ -63,6 +76,8 @@ struct Undo_Data{
i32 history_block_count, history_head_block;
Edit_Step *history;
#endif
i32 edit_history, edit_history_max;
i32 edit_history_cursor;
i32 current_block_normal;
@ -76,7 +91,7 @@ struct Editing_File{
Font *font;
i32 cursor_pos;
bool32 is_dummy;
b32 is_dummy;
char source_path_[256];
char live_name_[256];
@ -86,9 +101,9 @@ struct Editing_File{
String extension;
Cpp_Token_Stack token_stack;
bool32 tokens_complete;
bool32 tokens_exist;
bool32 still_lexing;
b32 tokens_complete;
b32 tokens_exist;
b32 still_lexing;
u32 lex_job;
i32 base_map_id;
@ -1218,6 +1233,18 @@ file_measure_starts(General_Memory *general, Editing_File *file){
file->buffer.line_count = state.count;
}
internal void
file_remeasure_starts(General_Memory *general, Editing_File *file,
i32 line_start, i32 line_end, i32 line_shift,
i32 character_shift){
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);
}
struct Opaque_Font_Advance{
void *data;
int offset;
@ -1234,9 +1261,7 @@ get_opaque_font_advance(Font *font){
}
internal void
file_measure_widths(General_Memory *general, Editing_File *file, Font *font){
ProfileMomentFunction();
file_grow_widths_as_needed(General_Memory *general, Editing_File *file){
i32 line_count = file->buffer.line_count;
if (line_count > file->buffer.widths_max){
i32 new_max = LargeRoundUp(line_count, Kbytes(1));
@ -1250,21 +1275,26 @@ file_measure_widths(General_Memory *general, Editing_File *file, Font *font){
}
file->buffer.widths_max = new_max;
}
}
internal void
file_measure_widths(General_Memory *general, Editing_File *file, Font *font){
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.offset, opad.stride);
}
internal void
file_remeasure_starts(General_Memory *general, Editing_File *file,
i32 line_start, i32 line_end, i32 line_shift,
i32 character_shift){
file_remeasure_widths(General_Memory *general, Editing_File *file, Font *font,
i32 line_start, i32 line_end, i32 line_shift){
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);
file_grow_widths_as_needed(general, file);
Opaque_Font_Advance opad = get_opaque_font_advance(font);
buffer_remeasure_widths(&file->buffer, opad.data, opad.offset, opad.stride,
line_start, line_end, line_shift);
}
inline i32
@ -1536,7 +1566,7 @@ file_kill_tokens(General_Memory *general, Editing_File *file){
internal void
file_first_lex_parallel(General_Memory *general, Editing_File *file){
#if 0
#if 1
Assert(file->token_stack.tokens == 0);
file->tokens_complete = 0;
@ -1549,8 +1579,9 @@ file_first_lex_parallel(General_Memory *general, Editing_File *file){
job.data[1] = general;
job.memory_request = Kbytes(64);
file->lex_job = system_post_job(BACKGROUND_THREADS, job);
#endif
#else
file_kill_tokens(general, file);
#endif
}
internal void
@ -1909,9 +1940,7 @@ file_replace_range(Mem_Options *mem, Editing_File *file,
i32 line_shift = new_line_count - replaced_line_count;
file_remeasure_starts(general, file, line_start, line_end, line_shift, shift_amount);
// TODO(allen): Can we "remeasure" widths now!?
file_measure_widths(general, file, file->font);
file_remeasure_widths(general, file, file->font, line_start, line_end, line_shift);
Shift_Information shift;
shift.start = start;
@ -2416,7 +2445,7 @@ struct Edit_Spec{
};
internal void
view_pre_replace_range(Mem_Options *mem, Editing_File *file, Edit_Spec spec){
view_update_history_before_edit(Mem_Options *mem, Editing_File *file, Edit_Spec spec){
General_Memory *general = &mem->general;
bool32 can_merge = 0, do_merge = 0;
@ -2570,8 +2599,15 @@ view_pre_replace_range(Mem_Options *mem, Editing_File *file, Edit_Spec spec){
}
internal void
view_post_replace_range(Mem_Options *mem, File_View *view, Editing_File *file,
Editing_Layout *layout, Shift_Information shift){
view_replace_range(Mem_Options *mem, File_View *view, Editing_File *file,
Editing_Layout *layout, Edit_Spec spec){
Assert(file);
view_update_history_before_edit(mem, file, spec);
Shift_Information shift =
file_replace_range(mem, file, spec.start, spec.end, (char*)spec.str, spec.str_len);
General_Memory *general = &mem->general;
i32 panel_count = layout->panel_count;
@ -2616,16 +2652,6 @@ view_post_replace_range(Mem_Options *mem, File_View *view, Editing_File *file,
end_temp_memory(temp);
}
internal void
view_replace_range(Mem_Options *mem, File_View *view, Editing_File *file,
Editing_Layout *layout, Edit_Spec spec){
Assert(file);
view_pre_replace_range(mem, file, spec);
Shift_Information shift =
file_replace_range(mem, file, spec.start, spec.end, (char*)spec.str, spec.str_len);
view_post_replace_range(mem, view, file, layout, shift);
}
inline void
view_replace_range(Mem_Options *mem, File_View *view, Editing_Layout *layout,
i32 start, i32 end, u8 *str, i32 len, i32 next_cursor_pos){
@ -2827,7 +2853,7 @@ view_clean_whitespace(Mem_Options *mem, File_View *view, Editing_Layout *layout)
i32 line_count = file->buffer.line_count;
i32 edit_max = line_count * 2;
Buffer_Edit *edits = push_array(part, Buffer_Edit, edit_max);
i32 edit_i = 0;
i32 edit_count = 0;
for (i32 line_i = 0; line_i < line_count; ++line_i){
i32 start = file->buffer.line_starts[line_i];
@ -2846,19 +2872,20 @@ view_clean_whitespace(Mem_Options *mem, File_View *view, Editing_Layout *layout)
new_edit.len = preferred_indentation;
new_edit.start = start;
new_edit.end = hard_start;
edits[edit_i++] = new_edit;
edits[edit_count++] = new_edit;
}
Assert(edit_i <= edit_max);
Assert(edit_count <= edit_max);
}
Assert(buffer_batch_debug_sort_check(edits, edit_i));
Assert(buffer_batch_debug_sort_check(edits, edit_count));
General_Memory *general = &mem->general;
i32 shift_amount = buffer_batch_edit_max_shift(edits, edit_i);
i32 shift_amount = buffer_batch_edit_max_shift(edits, edit_count);
file_grow_as_needed(general, file, shift_amount);
buffer_batch_edit(&file->buffer, edits, edit_i);
buffer_batch_edit(&file->buffer, edits, edit_count);
// NOTE(allen): meta data
Buffer_Measure_Starts state = {};
if (buffer_measure_starts(&state, &file->buffer)) Assert(0);
@ -2868,6 +2895,7 @@ view_clean_whitespace(Mem_Options *mem, File_View *view, Editing_Layout *layout)
i32 cursor_max = layout->panel_max_count * 2;
Cursor_With_Index *cursors = push_array(part, Cursor_With_Index, cursor_max);
// NOTE(allen): cursor fixing
i32 panel_count = layout->panel_count;
i32 cursor_count = 0;
Panel *current_panel = layout->panels;
@ -2882,7 +2910,7 @@ view_clean_whitespace(Mem_Options *mem, File_View *view, Editing_Layout *layout)
if (cursor_count > 0){
buffer_sort_cursors(cursors, cursor_count);
buffer_batch_edit_update_cursors(cursors, cursor_count, edits, edit_i);
buffer_batch_edit_update_cursors(cursors, cursor_count, edits, edit_count);
buffer_unsort_cursors(cursors, cursor_count);
}
@ -2897,412 +2925,31 @@ view_clean_whitespace(Mem_Options *mem, File_View *view, Editing_Layout *layout)
}
}
// NOTE(allen): token fixing
if (file->tokens_complete){
Cpp_Token_Stack tokens = file->token_stack;
Cpp_Token *token = tokens.tokens;
Cpp_Token *end_token = tokens.tokens + tokens.count;
Buffer_Edit *edit = edits;
Buffer_Edit *end_edit = edits + edit_count;
i32 shift_amount = 0;
for (; token < end_token && edit < end_edit; ++edit){
for (; token->start < edit->start && token < end_token; ++token){
token->start += shift_amount;
}
shift_amount += (edit->len - (edit->end - edit->start));
}
for (; token < end_token; ++token){
token->start += shift_amount;
}
}
end_temp_memory(temp);
}
#if 0
// NOTE(allen): Assumes that whitespace_buffer has at least
// indent.tabs*4 + indent.spaces bytes available.
internal Shift_Information
buffer_set_indent_whitespace(Mem_Options *mem, Editing_File *file,
Indent_Definition indent,
u8 *whitespace_buffer,
i32 line_start){
i32 i = 0;
while (i < indent.tabs){
for (i32 j = 0; j < 4; ++j) whitespace_buffer[i++] = ' ';
}
while (i < indent.tabs + indent.spaces){
whitespace_buffer[i++] = ' ';
}
Range leading_white;
leading_white.smaller = line_start;
Line_Hard_Start hard_start;
hard_start = buffer_find_hard_start(file, line_start);
leading_white.larger = hard_start.first_character;
Shift_Information shift = {};
if (leading_white.smaller < leading_white.larger){
shift = buffer_replace_range(mem, file,
leading_white.smaller, leading_white.larger,
whitespace_buffer, i);
}
return shift;
}
inline Indent_Definition
indent_by_width(i32 width, i32 tab_width){
Indent_Definition indent;
indent.tabs = 0;
indent.spaces = width;
return indent;
}
struct Nest_Level{
i32 brace_level, paren_level, bracket_level;
};
struct Nest_Level_Hint{
Nest_Level start_level;
i32 start_pos;
};
internal Nest_Level
buffer_compute_nest_level_raw(Editing_File *file, i32 pos, Nest_Level_Hint hint = {}){
Nest_Level result = hint.start_level;
for (i32 i = hint.start_pos; i < pos; ++i){
if (file->data[i] == '/' &&
i+1 < file->size && file->data[i+1] == '*'){
Seek_Result seek = seek_block_comment_end((char*)file->data, file->size, pos);
pos = seek.pos;
}
else if (file->data[i] == '/' &&
i+1 < file->size && file->data[i+1] == '/'){
Seek_Result seek = seek_unescaped_eol((char*)file->data, file->size, pos);
pos = seek.pos;
}
else if (file->data[i] == '"'){
Seek_Result seek = seek_unescaped_delim((char*)file->data, file->size, pos, '"');
pos = seek.pos;
}
else if (file->data[i] == '\''){
Seek_Result seek = seek_unescaped_delim((char*)file->data, file->size, pos, '\'');
pos = seek.pos;
}
switch (file->data[i]){
case '{':
++result.brace_level;
break;
case '}':
if (result.brace_level > 0){
--result.brace_level;
}
break;
case '(':
++result.paren_level;
break;
case ')':
if (result.paren_level > 0){
--result.paren_level;
}
break;
case '[':
++result.bracket_level;
break;
case ']':
if (result.bracket_level > 0){
--result.bracket_level;
}
break;
}
}
return result;
}
internal Nest_Level
buffer_compute_nest_level_tokens(Editing_File *file, i32 pos, Nest_Level_Hint hint = {}){
Nest_Level result = hint.start_level;
Cpp_Token_Stack token_stack = file->token_stack;
i32 start_token;
{
Cpp_Get_Token_Result get_result = cpp_get_token(&file->token_stack, hint.start_pos);
start_token = get_result.token_index;
if (get_result.in_whitespace){
++start_token;
}
}
for (i32 i = start_token; i < token_stack.count && token_stack.tokens[i].start < pos; ++i){
if (token_stack.tokens[i].flags & CPP_TFLAG_PP_BODY){
continue;
}
switch (token_stack.tokens[i].type){
case CPP_TOKEN_BRACE_OPEN:
++result.brace_level;
break;
case CPP_TOKEN_BRACE_CLOSE:
if (result.brace_level > 0){
--result.brace_level;
}
break;
case CPP_TOKEN_PARENTHESE_OPEN:
++result.paren_level;
break;
case CPP_TOKEN_PARENTHESE_CLOSE:
if (result.paren_level > 0){
--result.paren_level;
}
break;
case CPP_TOKEN_BRACKET_OPEN:
++result.bracket_level;
break;
case CPP_TOKEN_BRACKET_CLOSE:
if (result.bracket_level > 0){
--result.bracket_level;
}
break;
}
}
return result;
}
#endif
#if 0
internal void
view_auto_tab(Mem_Options *mem, File_View *view, i32 start, i32 end){
Editing_File *file = view->file;
u8 *data = (u8*)file->data;
start = view_find_beginning_of_line(view, start);
end = view_find_end_of_line(view, end);
i32 cursor = view->cursor.pos;
i32 mark = view->mark;
Nest_Level_Hint hint = {};
while (start < end){
Line_Hard_Start hard_start;
hard_start = buffer_find_hard_start(file, start);
i32 x_pos = 0;
i32 read_until = hard_start.first_character;
u8 first_character = file->data[read_until];
if (first_character == '}' ||
first_character == ')' ||
first_character == ']'){
++read_until;
}
Nest_Level nesting;
bool32 is_label = 0;
bool32 is_continuation = 0;
bool32 is_preprocessor = 0;
bool32 is_string_continuation = 0;
AllowLocal(is_string_continuation);
// TODO(allen): Better system for finding out what extra data types a file has?
if (file->tokens_complete){
nesting = buffer_compute_nest_level_tokens(file, read_until, hint);
i32 colon_expect_level = 1;
Cpp_Get_Token_Result token_get =
cpp_get_token(&file->token_stack, hard_start.first_character);
i32 token_i;
{
if (token_get.in_whitespace){
token_i = -1;
}
else{
token_i = token_get.token_index;
}
}
while (colon_expect_level != 0){
Cpp_Token_Type type = CPP_TOKEN_JUNK;
if (token_i >= 0 && token_i < file->token_stack.count){
type = file->token_stack.tokens[token_i].type;
}
if (is_keyword(type)){
Cpp_Token *token = file->token_stack.tokens + token_i;
String lexeme = make_string((char*)file->data + token->start, token->size);
if (colon_expect_level == 1){
if (match("case", lexeme)){
colon_expect_level = 2;
}
else if (match("public", lexeme)){
colon_expect_level = 3;
}
else if (match("private", lexeme)){
colon_expect_level = 3;
}
else if (match("protected", lexeme)){
colon_expect_level = 3;
}
}
else{
colon_expect_level = 0;
}
}
else{
switch (type){
case CPP_TOKEN_IDENTIFIER:
{
colon_expect_level = 3;
}break;
case CPP_TOKEN_COLON:
{
if (colon_expect_level == 3){
is_label = 1;
colon_expect_level = 0;
}
}break;
default:
{
colon_expect_level = 0;
}break;
}
}
++token_i;
}
if (!token_get.in_whitespace){
Cpp_Token *token = file->token_stack.tokens + token_get.token_index;
if (token->type == CPP_TOKEN_STRING_CONSTANT ||
token->type == CPP_TOKEN_CHARACTER_CONSTANT){
is_string_continuation = 1;
}
}
if (!is_string_continuation){
token_i = token_get.token_index;
bool32 in_whitespace = token_get.in_whitespace;
if (token_i >= 0){
Cpp_Token *token = file->token_stack.tokens + token_i;
bool32 never_continuation = 0;
if (!in_whitespace){
switch (token->type){
case CPP_TOKEN_BRACE_CLOSE:
case CPP_TOKEN_BRACE_OPEN:
case CPP_TOKEN_PARENTHESE_OPEN:
case CPP_TOKEN_PARENTHESE_CLOSE:
case CPP_TOKEN_COMMENT:
never_continuation = 1;
break;
}
if (token->flags & CPP_TFLAG_PP_DIRECTIVE ||
token->flags & CPP_TFLAG_PP_BODY){
never_continuation = 1;
}
}
else{
++token_i;
}
if (!never_continuation){
--token_i;
token = file->token_stack.tokens + token_i;
bool32 keep_looping = 1;
is_continuation = 1;
while (token_i >= 0 && keep_looping){
--token_i;
keep_looping = 0;
if (token->flags & CPP_TFLAG_PP_DIRECTIVE ||
token->flags & CPP_TFLAG_PP_BODY){
keep_looping = 1;
}
else{
switch (token->type){
case CPP_TOKEN_BRACE_CLOSE:
case CPP_TOKEN_BRACE_OPEN:
case CPP_TOKEN_PARENTHESE_OPEN:
case CPP_TOKEN_SEMICOLON:
case CPP_TOKEN_COLON:
case CPP_TOKEN_COMMA:
is_continuation = 0;
break;
case CPP_TOKEN_COMMENT:
case CPP_TOKEN_JUNK:
keep_looping = 1;
break;
}
}
}
if (token_i == -1){
is_continuation = 0;
}
}
}
}
token_i = token_get.token_index;
if (token_i >= 0){
Cpp_Token *token = file->token_stack.tokens + token_i;
if (!token_get.in_whitespace){
if (token->flags & CPP_TFLAG_PP_DIRECTIVE ||
token->flags & CPP_TFLAG_PP_BODY){
is_preprocessor = 1;
}
}
}
}
else{
nesting = buffer_compute_nest_level_raw(file, read_until, hint);
}
hint.start_level = nesting;
hint.start_pos = read_until;
if (is_preprocessor || is_string_continuation){
x_pos = 0;
}
else{
x_pos = 4*(nesting.brace_level + nesting.bracket_level + nesting.paren_level);
if (is_continuation){
x_pos += 4;
}
if (is_label){
x_pos -= 4;
}
if (x_pos < 0){
x_pos = 0;
}
}
// TODO(allen): Need big transient memory for this operation.
// NOTE(allen): This is temporary. IRL it should probably come
// from transient memory space.
u8 whitespace[200];
Indent_Definition indent;
// TODO(allen): Revist all this.
indent = indent_by_width(x_pos, 4);
TentativeAssert(indent.tabs + indent.spaces < 200);
Shift_Information shift;
shift = buffer_set_indent_whitespace(mem, file, indent, whitespace, start);
if (hint.start_pos >= shift.start){
hint.start_pos += shift.amount;
}
if (cursor >= shift.start && cursor <= shift.end){
Line_Hard_Start hard_start;
hard_start = buffer_find_hard_start(file, shift.start);
cursor = hard_start.first_character;
}
else if (cursor > shift.end){
cursor += shift.amount;
}
if (mark >= shift.start && mark <= shift.end){
Line_Hard_Start hard_start;
hard_start = buffer_find_hard_start(file, shift.start);
mark = hard_start.first_character;
}
else if (mark > shift.end){
mark += shift.amount;
}
start = view_find_beginning_of_next_line(view, start);
end += shift.amount;
}
view_cursor_move(view, cursor);
view->mark = pos_adjust_to_self(mark, data, file->size);
}
#endif
internal u32*
style_get_color(Style *style, Cpp_Token token){
u32 *result;

View File

@ -25,9 +25,13 @@ typedef int16_t i16;
typedef i32 bool32;
typedef i8 bool8;
typedef i32 b32;
typedef i8 b8;
typedef float real32;
typedef double real64;
typedef float f32;
typedef double f64;
#define internal static
#define globalvar static

View File

@ -166,6 +166,7 @@ measure_character(void *advance_data, int offset, int stride, int *new_line, cha
return(width);
}
#if 0
internal_4tech void
buffer_measure_widths(Buffer *buffer, void *advance_data, int offset, int stride){
float *widths;
@ -206,6 +207,7 @@ buffer_measure_widths(Buffer *buffer, void *advance_data, int offset, int stride
widths[i] = width;
}
}
#endif
internal_4tech void
buffer_remeasure_starts(Buffer *buffer, int line_start, int line_end, int line_shift, int text_shift){
@ -219,6 +221,11 @@ buffer_remeasure_starts(Buffer *buffer, int line_start, int line_end, int line_s
lines = buffer->line_starts;
line_count = buffer->line_count;
Assert(0 <= line_start);
Assert(line_start <= line_end);
Assert(line_end < line_count);
Assert(line_count + line_shift <= buffer->line_max);
if (line_shift != 0){
memmove_4tech(lines + line_end + line_shift + 1, lines + line_end + 1,
sizeof(int)*(line_count - line_end - 1));
@ -252,9 +259,70 @@ buffer_remeasure_starts(Buffer *buffer, int line_start, int line_end, int line_s
}
}
Assert(line_count >= 1);
buffer->line_count = line_count;
}
internal_4tech void
buffer_remeasure_widths(Buffer *buffer, void *advance_data, int offset, int stride,
int line_start, int line_end, int line_shift){
int *starts;
float *widths;
int line_count;
char *data;
int size;
int i, j, new_line;
float width;
char ch, next;
starts = buffer->line_starts;
widths = buffer->line_widths;
line_count = buffer->line_count;
Assert(0 <= line_start);
Assert(line_start <= line_end);
Assert(line_end < line_count);
Assert(line_count <= buffer->widths_max);
if (line_shift != 0){
memmove_4tech(widths + line_end + line_shift + 1, widths + line_end + 1,
sizeof(float)*(line_count - line_end - 1));
line_count += line_shift;
}
data = buffer->data;
size = buffer->size;
Assert(size < buffer->max);
data[size] = 0;
i = line_start;
j = starts[i];
for (; i <= line_end; ++i){
Assert(j == starts[i]);
new_line = 0;
width = 0;
ch = data[j];
next = data[++j];
while (new_line == 0){
width += measure_character(advance_data, offset, stride, &new_line, ch);
ch = next;
next = data[++j];
}
--j;
widths[i] = width;
}
}
inline_4tech void
buffer_measure_widths(Buffer *buffer, void *advance_data, int offset, int stride){
Assert(buffer->line_count >= 1);
buffer_remeasure_widths(buffer, advance_data, offset, stride, 0, buffer->line_count-1, 0);
}
internal_4tech int
buffer_get_line_index(Buffer *buffer, int pos, int l_bound, int u_bound){
int *lines;
@ -316,25 +384,23 @@ write_cursor_with_index(Cursor_With_Index *positions, int *count, int pos){
++*count;
}
internal_4tech int
buffer_quick_partition_cursors(Cursor_With_Index *positions, int start, int pivot){
int i;
int pivot_pos;
pivot_pos = positions[pivot].pos;
for (i = start; i < pivot; ++i){
if (positions[i].pos < pivot_pos){
Swap(positions[start], positions[i]);
++start;
}
}
Swap(positions[start], positions[pivot]);
return start;
}
#define CursorSwap__(a,b) { Cursor_With_Index t = a; a = b; b = t; }
internal_4tech void
buffer_quick_sort_cursors(Cursor_With_Index *positions, int start, int pivot){
int mid;
mid = buffer_quick_partition_cursors(positions, start, pivot);
int i, mid;
int pivot_pos;
mid = start;
pivot_pos = positions[pivot].pos;
for (i = mid; i < pivot; ++i){
if (positions[i].pos < pivot_pos){
CursorSwap__(positions[mid], positions[i]);
++mid;
}
}
CursorSwap__(positions[mid], positions[pivot]);
if (start < mid - 1) buffer_quick_sort_cursors(positions, start, mid - 1);
if (mid + 1 < pivot) buffer_quick_sort_cursors(positions, mid + 1, pivot);
}
@ -345,29 +411,27 @@ buffer_sort_cursors(Cursor_With_Index *positions, int count){
buffer_quick_sort_cursors(positions, 0, count-1);
}
internal_4tech int
buffer_quick_unpartition_cursors(Cursor_With_Index *positions, int start, int pivot){
int i;
int pivot_index;
pivot_index = positions[pivot].index;
for (i = start; i < pivot; ++i){
if (positions[i].index < pivot_index){
Swap(positions[start], positions[i]);
++start;
}
}
Swap(positions[start], positions[pivot]);
return start;
}
internal_4tech void
buffer_quick_unsort_cursors(Cursor_With_Index *positions, int start, int pivot){
int mid;
mid = buffer_quick_unpartition_cursors(positions, start, pivot);
int i, mid;
int pivot_index;
mid = start;
pivot_index = positions[pivot].index;
for (i = mid; i < pivot; ++i){
if (positions[i].index < pivot_index){
CursorSwap__(positions[mid], positions[i]);
++mid;
}
}
CursorSwap__(positions[mid], positions[pivot]);
if (start < mid - 1) buffer_quick_unsort_cursors(positions, start, mid - 1);
if (mid + 1 < pivot) buffer_quick_unsort_cursors(positions, mid + 1, pivot);
}
#undef CursorSwap__
inline_4tech void
buffer_unsort_cursors(Cursor_With_Index *positions, int count){
Assert(count > 0);
@ -376,16 +440,14 @@ buffer_unsort_cursors(Cursor_With_Index *positions, int count){
internal_4tech void
buffer_update_cursors(Cursor_With_Index *sorted_positions, int count, int start, int end, int len){
Cursor_With_Index *position, *end_position;
Cursor_With_Index *position;
int shift_amount;
shift_amount = (len - (end - start));
position = sorted_positions;
end_position = sorted_positions + count;
for (; position < end_position && position->pos < start; ++position);
for (; position < end_position && position->pos < end; ++position) position->pos = start;
for (; position < end_position; ++position) position->pos += shift_amount;
position = sorted_positions + count - 1;
for (; position >= sorted_positions && position->pos >= end; --position) position->pos += shift_amount;
for (; position >= sorted_positions && position->pos >= start; --position) position->pos = start;
}
typedef enum{
@ -450,11 +512,11 @@ typedef struct{
internal_4tech Full_Cursor
buffer_cursor_seek(Buffer *buffer, Buffer_Seek seek,
float max_width, float font_height, void *width_data, int offset, int stride, Full_Cursor cursor){
float max_width, float font_height, void *advance_data, int offset, int stride, Full_Cursor cursor){
Full_Cursor prev_cursor;
char *data, *data_;
char *data, *advances;
int size;
int do_newline, do_slashr;
int do_newline;
char ch, next;
float ch_width;
@ -467,8 +529,11 @@ buffer_cursor_seek(Buffer *buffer, Buffer_Seek seek,
Assert(size < buffer->max);
data[size] = 0;
data_ = (char*)width_data + offset;
advances = (char*)advance_data + offset;
x = 0;
y = 0;
px = 0;
xy_seek = (seek.type == buffer_seek_wrapped_xy || seek.type == buffer_seek_unwrapped_xy);
for (;;){
@ -478,21 +543,21 @@ buffer_cursor_seek(Buffer *buffer, Buffer_Seek seek,
next = data[cursor.pos+1];
switch (ch){
case '\r': do_newline = 0; do_slashr = 1; break;
case '\n': do_newline = 1; do_slashr = 0; break;
case '\n': do_newline = 1; break;
case '\r':
do_newline = 0;
++cursor.character;
ch_width = *(float*)(advances + stride * '\\') + *(float*)(advances + stride * 'r');
break;
default:
do_newline = 0; do_slashr = 0;
do_newline = 0;
++cursor.character;
ch_width = *(float*)(data_ + stride * ch);
ch_width = *(float*)(advances + stride * ch);
break;
}
if (do_slashr){
++cursor.character;
ch_width = *(float*)(data_ + stride * '\\') + *(float*)(data_ + stride * 'r');
}
if (cursor.wrapped_x + ch_width >= max_width){
cursor.wrapped_y += font_height;
cursor.wrapped_x = 0;
@ -519,9 +584,6 @@ buffer_cursor_seek(Buffer *buffer, Buffer_Seek seek,
}
get_out = 0;
x = 0;
y = 0;
px = 0;
switch (seek.type){
case buffer_seek_pos:
@ -555,15 +617,14 @@ buffer_cursor_seek(Buffer *buffer, Buffer_Seek seek,
break;
}
if (seek.round_down){
if (y > seek.y - font_height && x > seek.x){
cursor = prev_cursor;
if (y > seek.y - font_height && x >= seek.x){
if (!seek.round_down){
if ((seek.x - px) < (x - seek.x)) cursor = prev_cursor;
break;
}
}
else{
if (y > seek.y - font_height && x >= seek.x){
if ((seek.x - px) < (x - seek.x)) cursor = prev_cursor;
if (x > seek.x){
cursor = prev_cursor;
break;
}
}
@ -592,7 +653,7 @@ buffer_batch_debug_sort_check(Buffer_Edit *sorted_edits, int edit_count){
if (start_point > edit->start){
result = 0; break;
}
start_point = Max(edit->end, edit->start + 1);
start_point = (edit->end < edit->start + 1)?edit->start + 1:edit->end;
}
return(result);
@ -649,12 +710,13 @@ buffer_batch_edit_step(Buffer_Batch_State *state, Buffer *buffer, Buffer_Edit *s
internal_4tech void
buffer_batch_edit(Buffer *buffer, Buffer_Edit *sorted_edits, int edit_count){
Buffer_Batch_State state;
int result;
debug_4tech(int result);
state.i = 0;
state.shift_total = 0;
result = buffer_batch_edit_step(&state, buffer, sorted_edits, edit_count);
debug_4tech(result =)
buffer_batch_edit_step(&state, buffer, sorted_edits, edit_count);
Assert(result == 0);
}

View File

@ -947,13 +947,14 @@ WinMain(HINSTANCE hInstance,
u32 creation_flag = 0;
for (i32 i = 0; i < win32vars.groups[BACKGROUND_THREADS].count; ++i){
Thread_Context *thread = win32vars.groups[BACKGROUND_THREADS].threads + i;
thread->handle = CreateThread(0, 0, ThreadProc, thread, creation_flag, (LPDWORD)&thread->windows_id);
thread->id = i + 1;
thread->queue = &win32vars.queues[BACKGROUND_THREADS];
Thread_Memory *memory = win32vars.thread_memory + i;
*memory = {};
memory->id = thread->id;
thread->queue = &win32vars.queues[BACKGROUND_THREADS];
thread->handle = CreateThread(0, 0, ThreadProc, thread, creation_flag, (LPDWORD)&thread->windows_id);
}
Assert(win32vars.locks);