new memory interface

This commit is contained in:
Allen Webster 2015-11-01 20:04:37 -05:00
parent e88b9ea324
commit a89b46fda7
12 changed files with 525 additions and 119 deletions

View File

@ -128,8 +128,18 @@ FCPP_LINK bool append_partial(String *dest, String src);
FCPP_LINK bool append(String *dest, char c);
inline bool append(String *dest, String src) { return append_partial(dest, src); }
inline bool append(String *dest, char *src) { return append_partial(dest, src); }
inline void terminate_with_null(String *str)
{ if (str->size < str->memory_size) str->str[str->size] = 0; else str->str[str->size-1] = 0; }
inline bool terminate_with_null(String *str){
bool result;
if (str->size < str->memory_size){
str->str[str->size] = 0;
result = 1;
}
else{
str->str[str->size-1] = 0;
result = 0;
}
return result;
}
FCPP_LINK int compare(char *a, char *b);
FCPP_LINK int compare(String a, char *b);

149
4ed.cpp
View File

@ -23,6 +23,16 @@ struct App_State_Resizing{
i32 min, max;
};
struct CLI_Process{
CLI_Handles cli;
Editing_File *out_file;
};
struct CLI_List{
CLI_Process *procs;
i32 count, max;
};
struct App_Vars{
Mem_Options mem;
Command_Map map_top;
@ -51,6 +61,8 @@ struct App_Vars{
char hot_dir_base_[256];
String hot_dir_base;
Hot_Directory hot_directory;
CLI_List cli_processes;
char query_[256];
char dest_[256];
@ -480,7 +492,7 @@ COMMAND_DECL(paste){
String *src = working_set_clipboard_head(working_set);
i32 pos_left = view->cursor.pos;
i32 next_cursor_pos = pos_left+src->size;
view_replace_range(mem, view, layout, pos_left, pos_left, (u8*)src->str, src->size, next_cursor_pos);
@ -966,7 +978,7 @@ case_change_range(Mem_Options *mem, File_View *view, Editing_File *file,
if (file->still_lexing)
system_cancel_job(BACKGROUND_THREADS, file->lex_job);
view_update_history_before_edit(mem, file, step, 0, hist_normal);
file_update_history_before_edit(mem, file, step, 0, hist_normal);
u8 *data = (u8*)file->buffer.data;
for (i32 i = range.start; i < range.end; ++i){
@ -1518,9 +1530,71 @@ COMMAND_DECL(set_settings){
}
}
COMMAND_DECL(build){
ProfileMomentFunction();
USE_VARS(vars);
USE_MEM(mem);
USE_WORKING_SET(working_set);
USE_STYLE(style);
USE_LIVE_SET(live_set);
USE_PANEL(panel);
if (vars->cli_processes.count < vars->cli_processes.max){
Get_File_Result file = working_set_get_available_file(working_set);
if (file.file){
file_create_empty(&mem->general, file.file, (u8*)"*cli process*", style->font);
table_add(&working_set->table, file.file->source_path, file.index);
View *new_view = live_set_alloc_view(live_set, mem);
view_replace_major(new_view, panel, live_set);
File_View *file_view = file_view_init(new_view, &vars->delay, &vars->layout);
view_set_file(file_view, file.file, style,
vars->hooks[hook_open_file], command, app_links);
file.file->tokens_exist = 0;
new_view->map = app_get_map(vars, file.file->base_map_id);
i32 i = vars->cli_processes.count++;
CLI_Process *proc = vars->cli_processes.procs + i;
if (!system_cli_call("..\\misc", "build_all_test", &proc->cli)){
--vars->cli_processes.count;
}
proc->out_file = file.file;
}
else{
// TODO(allen): feedback message - no available file
}
}
else{
// TODO(allen): feedback message - no available process slot
}
}
internal void
update_command_data(App_Vars *vars, Command_Data *cmd){
Command_Data command_data;
command_data.vars = vars;
command_data.mem = &vars->mem;
command_data.working_set = &vars->working_set;
command_data.layout = &vars->layout;
command_data.panel = command_data.layout->panels + command_data.layout->active_panel;
command_data.view = command_data.panel->view;
command_data.live_set = &vars->live_set;
command_data.style = &vars->style;
command_data.delay = &vars->delay;
command_data.screen_width = cmd->screen_width;
command_data.screen_height = cmd->screen_height;
command_data.key = cmd->key;
command_data.part = cmd->part;
*cmd = command_data;
}
COMPOSE_DECL(compose_write_auto_tab_line){
command_write_character(command, binding);
update_command_data(command->vars, command);
command_auto_tab_line_at_cursor(command, binding);
update_command_data(command->vars, command);
}
globalvar Command_Function command_table[cmdid_count];
@ -1532,7 +1606,9 @@ extern "C"{
Command_Binding binding;
binding.function = function;
if (function) function(cmd, binding);
update_command_data(cmd->vars, cmd);
#if 0
App_Vars *vars = cmd->vars;
Command_Data command_data;
command_data.vars = vars;
@ -1550,6 +1626,7 @@ extern "C"{
command_data.part = cmd->part;
*cmd = command_data;
#endif
}
PUSH_PARAMETER_SIG(external_push_parameter){
@ -1724,24 +1801,9 @@ setup_top_commands(Command_Map *commands, Partition *part, Key_Codes *codes, Com
map_add(commands, 'i', MDFR_CTRL, command_interactive_switch_buffer);
map_add(commands, 'c', MDFR_ALT, command_open_color_tweaker);
map_add(commands, 'x', MDFR_ALT, command_open_menu);
map_add(commands, 'm', MDFR_ALT, command_build);
}
#if 0 // TODO(allen): Here's an idea
internal void
setup_command_table(){
BEGIN_META_CODE{
int count;
char **command_names = get_all_commands(&count);
for (int i = 0; i < count; ++i){
char *name_ = command_names[i];
String name = make_string_slowly(name_);
outcode("command_table[cmdid_", out_str(name), "] = command_", out_str(name), "\n");
}
}END_META_CODE
}
#endif
internal void
setup_command_table(){
#define SET(n) command_table[cmdid_##n] = command_##n
@ -2475,6 +2537,13 @@ app_init(Thread_Context *thread, Application_Memory *memory,
vars->mini_str = make_string((char*)vars->mini_buffer, 0, 512);
// NOTE(allen): child proc list setup
i32 max_children = 16;
partition_align(partition, 8);
vars->cli_processes.procs = push_array(partition, CLI_Process, max_children);
vars->cli_processes.max = max_children;
vars->cli_processes.count = 0;
return 1;
}
@ -2522,6 +2591,48 @@ app_step(Thread_Context *thread, Key_Codes *codes,
}
}
// NOTE(allen): update child processes
{
Temp_Memory temp = begin_temp_memory(&vars->mem.part);
u32 max = Kbytes(32);
char *dest = push_array(&vars->mem.part, char, max);
u32 amount;
i32 count = vars->cli_processes.count;
for (i32 i = 0; i < count; ++i){
CLI_Process *proc = vars->cli_processes.procs + i;
Editing_File *out_file = proc->out_file;
i32 new_cursor = out_file->cursor_pos;
for (system_cli_begin_update(&proc->cli);
system_cli_update_step(&proc->cli, dest, max, &amount);){
if (out_file){
amount = eol_in_place_convert_in(dest, amount);
Edit_Spec spec = {};
spec.step.type = ED_NORMAL;
spec.step.edit.start = buffer_size(&out_file->buffer);
spec.step.edit.end = spec.step.edit.start;
spec.step.edit.len = amount;
spec.step.pre_pos = new_cursor;
spec.step.post_pos = spec.step.edit.start + amount;
spec.str = (u8*)dest;
file_do_single_edit(&vars->mem, out_file,
&vars->layout, spec, hist_normal);
app_result.redraw = 1;
new_cursor = spec.step.post_pos;
}
}
if (system_cli_end_update(&proc->cli)){
*proc = vars->cli_processes.procs[--count];
--i;
}
}
vars->cli_processes.count = count;
end_temp_memory(temp);
}
// NOTE(allen): reorganizing panels on screen
i32 prev_width = vars->layout.full_width;
i32 prev_height = vars->layout.full_height;

26
4ed.h
View File

@ -112,6 +112,27 @@ general_memory_open(General_Memory *general, void *memory, i32 size){
insert_bubble(&general->sentinel, first);
}
internal void
general_memory_check(General_Memory *general){
Bubble *sentinel = &general->sentinel;
for (Bubble *bubble = sentinel->next;
bubble != sentinel;
bubble = bubble->next){
Assert(bubble);
Bubble *next = bubble->next;
Assert(bubble == next->prev);
if (next != sentinel){
Assert(bubble->next > bubble);
Assert(bubble > bubble->prev);
char *end_ptr = (char*)(bubble + 1) + bubble->size;
char *next_ptr = (char*)next;
Assert(end_ptr == next_ptr);
}
}
}
#define BUBBLE_MIN_SIZE 1024
internal void
@ -129,9 +150,6 @@ general_memory_attempt_split(Bubble *bubble, i32 wanted_size){
internal void*
general_memory_allocate(General_Memory *general, i32 size, u32 type = 0){
void *result = 0;
if (size < Kbytes(1)){
int x = 1; AllowLocal(x);
}
for (Bubble *bubble = general->sentinel.next;
bubble != &general->sentinel;
bubble = bubble->next){
@ -150,6 +168,8 @@ general_memory_allocate(General_Memory *general, i32 size, u32 type = 0){
inline void
general_memory_do_merge(Bubble *left, Bubble *right){
Assert(left->next == right);
Assert(right->prev == left);
left->size += sizeof(Bubble) + right->size;
remove_bubble(right);
}

View File

@ -1187,8 +1187,8 @@ file_grow_starts_as_needed(General_Memory *general, Editing_File *file, i32 addi
i32 max = file->buffer.line_max;
i32 count = file->buffer.line_count;
i32 target_lines = count + additional_lines;
if (target_lines > max){
max <<= 1;
if (target_lines > max || max == 0){
max = LargeRoundUp(target_lines + max, Kbytes(1));
i32 *new_lines = (i32*)
general_memory_reallocate(general, file->buffer.line_starts,
sizeof(i32)*count, sizeof(i32)*max, BUBBLE_STARTS);
@ -1267,15 +1267,17 @@ internal void
file_grow_widths_as_needed(General_Memory *general, Editing_File *file){
#if BUFFER_EXPERIMENT_SCALPEL <= 2
i32 line_count = file->buffer.line_count;
if (line_count > file->buffer.widths_max){
if (line_count > file->buffer.widths_max || file->buffer.widths_max == 0){
i32 new_max = LargeRoundUp(line_count, Kbytes(1));
if (new_max < Kbytes(1)) new_max = Kbytes(1);
if (file->buffer.line_widths){
file->buffer.line_widths = (real32*)
general_memory_reallocate_nocopy(general, file->buffer.line_widths, sizeof(real32)*new_max, BUBBLE_WIDTHS);
file->buffer.line_widths = (f32*)
general_memory_reallocate(general, file->buffer.line_widths,
sizeof(f32)*file->buffer.widths_count, sizeof(f32)*new_max, BUBBLE_WIDTHS);
}
else{
file->buffer.line_widths = (real32*)
general_memory_allocate(general, sizeof(real32)*new_max, BUBBLE_WIDTHS);
file->buffer.line_widths = (f32*)
general_memory_allocate(general, sizeof(f32)*new_max, BUBBLE_WIDTHS);
}
file->buffer.widths_max = new_max;
}
@ -1379,11 +1381,11 @@ internal void
file_create_from_string(General_Memory *general, Editing_File *file, u8 *filename, Font *font, String val){
*file = {};
#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));
if (page_size < Kbytes(4)) page_size = Kbytes(4);
void *data = general_memory_allocate(general, page_size, BUBBLE_BUFFER);
buffer_init_provide_page(&init, data, page_size);
}
@ -1396,7 +1398,7 @@ file_create_from_string(General_Memory *general, Editing_File *file, u8 *filenam
file_set_name(file, filename);
file->base_map_id = mapid_file;
file_measure_starts(general, file);
file_measure_widths(general, file, font);
file->font = font;
@ -1695,21 +1697,7 @@ file_relex_parallel(Mem_Options *mem, Editing_File *file,
#endif
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){
i32 request_size = LargeRoundUp(target_size*2, Kbytes(256));
char *new_data = (char*)
general_memory_allocate(general, request_size, BUBBLE_BUFFER);
TentativeAssert(new_data);
void *old_data = buffer_relocate(&file->buffer, new_data, request_size);
general_memory_free(general, old_data);
}
#endif
return result;
file_grow_as_needed_(General_Memory *general, Editing_File *file, i32 new_size){
}
internal void
@ -2267,7 +2255,7 @@ enum History_Mode{
};
internal void
view_update_history_before_edit(Mem_Options *mem, Editing_File *file, Edit_Step step, u8 *str,
file_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;
@ -2460,13 +2448,13 @@ file_pre_edit_maintenance(Editing_File *file){
}
internal void
view_do_single_edit(Mem_Options *mem, File_View *view, Editing_File *file,
file_do_single_edit(Mem_Options *mem, Editing_File *file,
Editing_Layout *layout, Edit_Spec spec, History_Mode history_mode){
Assert(file);
ProfileMomentFunction();
// NOTE(allen): fixing stuff beforewards????
view_update_history_before_edit(mem, file, spec.step, spec.str, history_mode);
file_update_history_before_edit(mem, file, spec.step, spec.str, history_mode);
file_pre_edit_maintenance(file);
#if BUFFER_EXPERIMENT_SCALPEL <= 1
@ -2479,8 +2467,15 @@ view_do_single_edit(Mem_Options *mem, File_View *view, Editing_File *file,
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);
i32 request_amount = 0;
while (buffer_replace_range(&file->buffer, start, end, str, str_len, &shift_amount, &request_amount)){
void *new_data = 0;
if (request_amount > 0){
new_data = general_memory_allocate(general, request_amount, BUBBLE_BUFFER);
}
void *old_data = buffer_edit_provide_memory(&file->buffer, new_data, request_amount);
if (old_data) general_memory_free(general, old_data);
}
#if BUFFER_EXPERIMENT_SCALPEL <= 0
// NOTE(allen): fixing stuff afterwards
@ -2516,10 +2511,8 @@ view_do_single_edit(Mem_Options *mem, File_View *view, Editing_File *file,
File_View *current_view = view_to_file_view(current_panel->view);
if (current_view && current_view->file == file){
view_measure_wraps(general, current_view);
if (current_view != view){
write_cursor_with_index(cursors, &cursor_count, current_view->cursor.pos);
write_cursor_with_index(cursors, &cursor_count, current_view->mark);
}
write_cursor_with_index(cursors, &cursor_count, current_view->cursor.pos);
write_cursor_with_index(cursors, &cursor_count, current_view->mark);
}
}
@ -2535,11 +2528,9 @@ view_do_single_edit(Mem_Options *mem, File_View *view, Editing_File *file,
for (i32 i = 0; i < panel_count; ++i, ++current_panel){
File_View *current_view = view_to_file_view(current_panel->view);
if (current_view && current_view->file == file){
if (current_view != view){
view_cursor_move(current_view, cursors[cursor_count++].pos);
current_view->mark = cursors[cursor_count++].pos;
current_view->preferred_x = view_get_cursor_x(current_view);
}
view_cursor_move(current_view, cursors[cursor_count++].pos);
current_view->mark = cursors[cursor_count++].pos;
current_view->preferred_x = view_get_cursor_x(current_view);
}
}
@ -2556,7 +2547,7 @@ view_do_white_batch_edit(Mem_Options *mem, File_View *view, Editing_File *file,
// NOTE(allen): fixing stuff beforewards????
Assert(spec.str == 0);
view_update_history_before_edit(mem, file, spec.step, 0, history_mode);
file_update_history_before_edit(mem, file, spec.step, 0, history_mode);
file_pre_edit_maintenance(file);
// NOTE(allen): actual text replacement
@ -2569,11 +2560,18 @@ view_do_white_batch_edit(Mem_Options *mem, File_View *view, Editing_File *file,
Assert(spec.step.first_child < file->undo.children.edit_count);
Assert(batch_size >= 0);
i32 shift_amount = buffer_batch_edit_max_shift(batch, batch_size);
file_grow_as_needed(general, file, shift_amount);
buffer_batch_edit(&file->buffer, batch, (char*)str_base, batch_size);
Buffer_Batch_State state = {};
i32 request_amount;
while (buffer_batch_edit_step(&state, &file->buffer,
batch, (char*)str_base, batch_size, &request_amount)){
void *new_data = 0;
if (request_amount > 0){
new_data = general_memory_allocate(general, request_amount, BUBBLE_BUFFER);
}
void *old_data = buffer_edit_provide_memory(&file->buffer, new_data, request_amount);
if (old_data) general_memory_free(general, old_data);
}
// NOTE(allen): token fixing
if (file->tokens_complete){
@ -2585,12 +2583,18 @@ view_do_white_batch_edit(Mem_Options *mem, File_View *view, Editing_File *file,
Buffer_Edit *end_edit = batch + batch_size;
i32 shift_amount = 0;
i32 local_shift = 0;
for (; token < end_token && edit < end_edit; ++edit){
local_shift = (edit->len - (edit->end - edit->start));
for (; token->start < edit->start && edit->start < token->start + token->size &&
token < end_token; ++token){
token->size += local_shift;
}
for (; token->start < edit->start && token < end_token; ++token){
token->start += shift_amount;
}
shift_amount += (edit->len - (edit->end - edit->start));
shift_amount += local_shift;
}
for (; token < end_token; ++token){
token->start += shift_amount;
@ -2656,7 +2660,7 @@ view_replace_range(Mem_Options *mem, File_View *view, Editing_Layout *layout,
spec.step.pre_pos = view->cursor.pos;
spec.step.post_pos = next_cursor;
spec.str = str;
view_do_single_edit(mem, view, view->file, layout, spec, hist_normal);
file_do_single_edit(mem, view->file, layout, spec, hist_normal);
}
internal void
@ -2683,7 +2687,7 @@ view_undo_redo(Mem_Options *mem, Editing_Layout *layout, File_View *view, Editin
spec.step.edit.str_start = 0;
spec.str = stack->strings + step.edit.str_start;
view_do_single_edit(mem, view, file, layout, spec, hist_normal);
file_do_single_edit(mem, file, layout, spec, hist_normal);
if (expected_type == ED_UNDO) view_cursor_move(view, step.pre_pos);
else view_cursor_move(view, step.post_pos);
@ -2742,7 +2746,7 @@ view_history_step(Mem_Options *mem, Editing_Layout *layout, File_View *view, His
spec.step.edit.str_start = 0;
spec.str = file->undo.history.strings + step.edit.str_start;
view_do_single_edit(mem, view, file, layout, spec, history_mode);
file_do_single_edit(mem, file, layout, spec, history_mode);
switch (spec.step.type){
case ED_NORMAL:
@ -2906,7 +2910,7 @@ clipboard_copy(General_Memory *general, Working_Set *working, Range range, Editi
}
internal Edit_Spec
view_compute_whitespace_edit(Mem_Options *mem, Editing_File *file,
file_compute_whitespace_edit(Mem_Options *mem, Editing_File *file, i32 cursor_pos,
Buffer_Edit *edits, char *str_base, i32 str_size,
Buffer_Edit *inverse_array, char *inv_str, i32 inv_max,
i32 edit_count){
@ -2933,6 +2937,8 @@ 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;
spec.step.pre_pos = cursor_pos;
spec.step.post_pos = cursor_pos;
#else
Edit_Spec spec = {};
#endif
@ -2989,7 +2995,7 @@ view_clean_whitespace(Mem_Options *mem, File_View *view, Editing_Layout *layout)
char *inv_str = (char*)part->base + part->pos;
Edit_Spec spec =
view_compute_whitespace_edit(mem, file, edits, str_base, str_size,
file_compute_whitespace_edit(mem, file, view->cursor.pos, edits, str_base, str_size,
inverse_array, inv_str, part->max - part->pos, edit_count);
view_do_white_batch_edit(mem, view, file, layout, spec, hist_normal);
@ -3178,7 +3184,7 @@ view_auto_tab_tokens(Mem_Options *mem, File_View *view, Editing_Layout *layout,
char *inv_str = (char*)part->base + part->pos;
Edit_Spec spec =
view_compute_whitespace_edit(mem, file, edits, str_base, str_size,
file_compute_whitespace_edit(mem, file, view->cursor.pos, edits, str_base, str_size,
inverse_array, inv_str, part->max - part->pos, edit_count);
view_do_white_batch_edit(mem, view, file, layout, spec, hist_normal);
@ -3537,8 +3543,12 @@ step_file_view(Thread_Context *thread, View *view_, i32_Rect rect,
result = 1;
}
while (cursor_y > target_y + max_y) target_y += delta_y;
while (cursor_y < target_y + taken_top_space) target_y -= delta_y;
if (cursor_y > target_y + max_y){
target_y = cursor_y - max_y + delta_y;
}
if (cursor_y < target_y + taken_top_space){
target_y = cursor_y - delta_y - taken_top_space;
}
if (target_y > max_target_y) target_y = max_target_y;
if (target_y < -extra_top) target_y = -extra_top;

View File

@ -31,7 +31,7 @@ struct Debug_Event{
struct Debug_Event_Array{
volatile u32 count;
Debug_Event e[512];
Debug_Event e[4096];
};
struct Profile_Frame{

View File

@ -7,6 +7,8 @@
*
*/
struct Plat_Handle{ u64 d[2]; };
// TODO(allen): This should either be a String or it should be improved
// to handle 64-bit sized files. Staying in this state, however, is unacceptable.
struct File_Data{
@ -76,6 +78,25 @@ system_post_clipboard(String str);
internal i64
system_time();
struct CLI_Handles{
Plat_Handle proc;
Plat_Handle out_read;
Plat_Handle out_write;
u32 scratch_space[4];
};
internal b32
system_cli_call(char *path, char *script_name, CLI_Handles *cli_out);
internal void
system_cli_begin_update(CLI_Handles *cli);
internal b32
system_cli_update_step(CLI_Handles *cli, char *dest, u32 max, u32 *amount);
internal b32
system_cli_end_update(CLI_Handles *cli);
struct Thread_Context;
struct Thread_Memory{

View File

@ -597,6 +597,7 @@ buffer_remeasure_widths(Buffer_Type *buffer, void *advance_data, int stride,
int *starts;
float *widths;
int line_count;
int widths_count;
char *data;
int size, end;
int i, j;
@ -606,17 +607,17 @@ buffer_remeasure_widths(Buffer_Type *buffer, void *advance_data, int stride,
starts = buffer->line_starts;
widths = buffer->line_widths;
line_count = buffer->line_count;
widths_count = buffer->widths_count;
assert_4tech(0 <= line_start);
assert_4tech(line_start <= line_end);
assert_4tech(line_end < line_count);
assert_4tech(line_count <= buffer->widths_max);
++line_end;
if (line_shift != 0){
memmove_4tech(widths + line_end + line_shift, widths + line_end,
sizeof(float)*(line_count - line_end));
sizeof(float)*(widths_count - line_end));
}
buffer->widths_count = line_count;
line_end += line_shift;
i = line_start;
@ -733,7 +734,6 @@ 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;
} Seek_State;
@ -1000,13 +1000,15 @@ buffer_invert_batch(Buffer_Invert_Batch *state, Buffer_Type *buffer, Buffer_Edit
internal_4tech void
buffer_batch_edit(Buffer_Type *buffer, Buffer_Edit *sorted_edits, char *strings, int edit_count){
Buffer_Batch_State state;
int r;
debug_4tech(int result);
state.i = 0;
state.shift_total = 0;
debug_4tech(result =)
buffer_batch_edit_step(&state, buffer, sorted_edits, strings, edit_count);
buffer_batch_edit_step(&state, buffer, sorted_edits, strings, edit_count, &r);
assert_4tech(result == 0);
}
#endif
@ -1121,7 +1123,6 @@ buffer_get_render_data(Buffer_Type *buffer, float *wraps, Buffer_Render_Item *it
}
buffer_get_render_data_end:
if (y <= height + shift_y || item == items){
ch = 0;
ch_width = measure_character(advance_data, stride, ' ');

View File

@ -20,6 +20,7 @@ typedef struct{
float *line_widths;
int *line_starts;
int line_count;
int widths_count;
int line_max;
int widths_max;
} Gap_Buffer;
@ -110,7 +111,7 @@ buffer_end_init(Gap_Buffer_Init *init){
}
internal_4tech void*
buffer_relocate(Gap_Buffer *buffer, char *new_data, int new_max){
buffer_edit_provide_memory(Gap_Buffer *buffer, void *new_data, int new_max){
void *result;
int new_gap_size;
@ -119,9 +120,9 @@ buffer_relocate(Gap_Buffer *buffer, char *new_data, int new_max){
result = buffer->data;
new_gap_size = new_max - buffer_size(buffer);
memcpy_4tech(new_data, buffer->data, buffer->size1);
memcpy_4tech(new_data + buffer->size1 + new_gap_size, buffer->data + buffer->size1 + buffer->gap_size, buffer->size2);
memcpy_4tech((char*)new_data + buffer->size1 + new_gap_size, buffer->data + buffer->size1 + buffer->gap_size, buffer->size2);
buffer->data = new_data;
buffer->data = (char*)new_data;
buffer->gap_size = new_gap_size;
buffer->max = new_max;
@ -263,7 +264,7 @@ buffer_backify_next(Gap_Buffer_Backify_Loop *loop){
}
internal_4tech int
buffer_replace_range(Gap_Buffer *buffer, int start, int end, char *str, int len, int *shift_amount){
buffer_replace_range(Gap_Buffer *buffer, int start, int end, char *str, int len, int *shift_amount, int *request_amount){
char *data;
int result;
int size;
@ -301,7 +302,8 @@ buffer_replace_range(Gap_Buffer *buffer, int start, int end, char *str, int len,
result = 0;
}
else{
result = *shift_amount + size;
*request_amount = round_up_4tech(2*(*shift_amount + size), 4 << 10);
result = 1;
}
return(result);
@ -309,7 +311,7 @@ buffer_replace_range(Gap_Buffer *buffer, int start, int end, char *str, int len,
// NOTE(allen): This could should be optimized for Gap_Buffer
internal_4tech int
buffer_batch_edit_step(Buffer_Batch_State *state, Gap_Buffer *buffer, Buffer_Edit *sorted_edits, char *strings, int edit_count){
buffer_batch_edit_step(Buffer_Batch_State *state, Gap_Buffer *buffer, Buffer_Edit *sorted_edits, char *strings, int edit_count, int *request_amount){
Buffer_Edit *edit;
int i, result;
int shift_total, shift_amount;
@ -321,7 +323,7 @@ buffer_batch_edit_step(Buffer_Batch_State *state, Gap_Buffer *buffer, Buffer_Edi
edit = sorted_edits + i;
for (; i < edit_count; ++i, ++edit){
result = buffer_replace_range(buffer, edit->start + shift_total, edit->end + shift_total,
strings + edit->str_start, edit->len, &shift_amount);
strings + edit->str_start, edit->len, &shift_amount, request_amount);
if (result) break;
shift_total += shift_amount;
}

View File

@ -20,6 +20,7 @@ typedef struct{
int *line_starts;
float *line_widths;
int line_count;
int widths_count;
int line_max;
int widths_max;
} Buffer;
@ -92,14 +93,14 @@ buffer_end_init(Buffer_Init *init){
}
internal_4tech void*
buffer_relocate(Buffer *buffer, char *new_data, int new_max){
buffer_edit_provide_memory(Buffer *buffer, void *new_data, int new_max){
void *result;
assert_4tech(new_max >= buffer->size);
result = buffer->data;
memcpy_4tech(new_data, buffer->data, buffer->size);
buffer->data = new_data;
buffer->data = (char*)new_data;
buffer->max = new_max;
return(result);
@ -174,7 +175,7 @@ buffer_backify_next(Buffer_Backify_Loop *loop){
}
internal_4tech int
buffer_replace_range(Buffer *buffer, int start, int end, char *str, int len, int *shift_amount){
buffer_replace_range(Buffer *buffer, int start, int end, char *str, int len, int *shift_amount, int *request_amount){
char *data;
int result;
int size;
@ -189,20 +190,20 @@ buffer_replace_range(Buffer *buffer, int start, int end, char *str, int len, int
data = (char*)buffer->data;
memmove_4tech(data + end + *shift_amount, data + end, buffer->size - end);
buffer->size += *shift_amount;
data[buffer->size] = 0;
if (len != 0) memcpy_4tech(data + start, str, len);
result = 0;
}
else{
result = *shift_amount + size;
*request_amount = round_up_4tech(2*(*shift_amount + size), 4 << 10);
result = 1;
}
return(result);
}
internal_4tech int
buffer_batch_edit_step(Buffer_Batch_State *state, Buffer *buffer, Buffer_Edit *sorted_edits, char *strings, int edit_count){
buffer_batch_edit_step(Buffer_Batch_State *state, Buffer *buffer, Buffer_Edit *sorted_edits, char *strings, int edit_count, int *request_amount){
Buffer_Edit *edit;
int i, result;
int shift_total, shift_amount;
@ -214,7 +215,7 @@ buffer_batch_edit_step(Buffer_Batch_State *state, Buffer *buffer, Buffer_Edit *s
edit = sorted_edits + i;
for (; i < edit_count; ++i, ++edit){
result = buffer_replace_range(buffer, edit->start + shift_total, edit->end + shift_total,
strings + edit->str_start, edit->len, &shift_amount);
strings + edit->str_start, edit->len, &shift_amount, request_amount);
if (result) break;
shift_total += shift_amount;
}

View File

@ -34,6 +34,7 @@ typedef struct{
float *line_widths;
int *line_starts;
int line_count;
int widths_count;
int line_max;
int widths_max;
} Multi_Gap_Buffer;
@ -170,21 +171,27 @@ internal_4tech int
buffer_find_chunk(Multi_Gap_Buffer *buffer, int pos){
Fixed_Width_Gap_Buffer *gaps;
int start, end, m, this_pos;
gaps = buffer->gaps;
start = 0;
end = buffer->chunk_count;
for(;;){
m = (start + end) / 2;
this_pos = gaps[m].start_pos;
if (this_pos < pos) start = m;
else if (this_pos > pos) end = m;
else break;
if (start+1 == end){
m = start; break;
}
assert_4tech(start < end);
if (pos == buffer_size(buffer)){
m = buffer->chunk_count;
}
else{
gaps = buffer->gaps;
start = 0;
end = buffer->chunk_count;
for(;;){
m = (start + end) / 2;
this_pos = gaps[m].start_pos;
if (this_pos < pos) start = m;
else if (this_pos > pos) end = m;
else break;
if (start+1 == end){
m = start; break;
}
assert_4tech(start < end);
}
}
return(m);
}
@ -360,6 +367,84 @@ buffer_backify_next(Multi_Gap_Buffer_Backify_Loop *loop){
}
}
internal_4tech int
buffer_replace_range(Multi_Gap_Buffer *buffer, int start, int end, char *str, int len, int *shift_amount_out, int *request_amount){
Fixed_Width_Gap_Buffer *gaps, *gap;
int gap_start, gap_end;
int result;
int size;
int local_end;
int shift_amount;
size = buffer_size(buffer);
assert_4tech(0 <= start);
assert_4tech(start <= end);
assert_4tech(end <= size);
*shift_amount_out = (len - (end - start));
gaps = buffer->gaps;
gap_start = buffer_find_chunk(buffer, start);
gap_end = buffer_find_chunk(buffer, end);
gap = gaps + gap_start;
if (gap_start < gap_end){
memmove_4tech(gap + 1, gaps + gap_end, sizeof(*gaps)*(buffer->chunk_count - gap_end));
buffer->chunk_count -= (gap_end - gap_start + 1);
++gap;
local_end = end - gap->start_pos;
if (gap->size1 >= local_end){
gap->size2 -= (local_end - gap->size1);
gap->size1 = 0;
}
else{
memmove_4tech(gap->data, gap->data + local_end, gap->size1 - local_end);
gap->size1 -= local_end;
}
--gap;
}
if (end > gap->size1 + gap->size2) end = gap->size1 + gap->size2;
shift_amount = (len - (end - start));
if (shift_amount + gap->size1 + gap->size2 <= fixed_width_buffer_size){
start -= gap->start_pos;
end -= gap->start_pos;
data = gap->data;
if (end < gap->size1){
move_size = gap->size1 - end;
memmove_4tech(data + gap->size1 + gap->gap_size - move_size, data + end, move_size);
gap->size1 -= move_size;
gap->size2 += move_size;
}
if (start > gap->size1){
move_size = start - gap->size1;
memmove_4tech(data + gap->size1, data + gap->size1 + gap->gap_size, move_size);
gap->size1 += move_size;
gap->size2 -= move_size;
}
memcpy_4tech(data + start, str, len);
gap->size2 = size - end;
gap->size1 = start + len;
gap->gap_size -= shift_amount;
assert_4tech(gap->size1 + gap->size2 == size + shift_amount);
assert_4tech(gap->size1 + gap->gap_size + gap->size2 == gap->max);
result = 0;
}
else{
div_ceil_4tech(shift_amount, fixed_width_buffer_half_size);
result = 1;
}
return(result);
}
// BOTTOM

View File

@ -53,6 +53,19 @@
#define cat_4tech(a,b) cat_4tech_(a,b)
#endif
#ifndef round_up_4tech
internal_4tech int
lroundup_(int x, int granularity){
int original_x;
original_x = x;
x /= granularity;
x *= granularity;
if (x < original_x) x += granularity;
return x;
}
#define round_up_4tech(x,g) lroundup_(x,g)
#endif
inline_4tech float
measure_character(void *advance_data, int stride, char character){
char *advances;

View File

@ -58,7 +58,7 @@
#define FPS 30
#define FRAME_TIME (1000000 / FPS)
#define BUFFER_EXPERIMENT_SCALPEL 2
#define BUFFER_EXPERIMENT_SCALPEL 0
#include "4ed_meta.h"
@ -545,11 +545,18 @@ Win32Callback(HWND hwnd, UINT uMsg,
case WM_KEYDOWN:
case WM_KEYUP:
{
bool8 previous_state, current_state;
previous_state = ((lParam & Bit_30)?(1):(0));
current_state = ((lParam & Bit_31)?(0):(1));
Win32KeyboardHandle(current_state, previous_state, wParam);
result = DefWindowProc(hwnd, uMsg, wParam, lParam);
switch (wParam){
case VK_CONTROL:case VK_LCONTROL:case VK_RCONTROL:
case VK_MENU:case VK_LMENU:case VK_RMENU:
case VK_SHIFT:case VK_LSHIFT:case VK_RSHIFT: break;
default:
bool8 previous_state, current_state;
previous_state = ((lParam & Bit_30)?(1):(0));
current_state = ((lParam & Bit_31)?(0):(1));
Win32KeyboardHandle(current_state, previous_state, wParam);
result = DefWindowProc(hwnd, uMsg, wParam, lParam);
}
}break;
case WM_MOUSEMOVE:
@ -880,6 +887,131 @@ INTERNAL_get_thread_states(Thread_Group_ID id, bool8 *running, i32 *pending){
}
#endif
internal b32
system_cli_call(char *path, char *script_name, CLI_Handles *cli_out){
char cmd[] = "c:\\windows\\system32\\cmd.exe";
char *env_variables = 0;
char command_line[2048];
b32 success = 1;
String s = make_fixed_width_string(command_line);
copy(&s, make_lit_string("/C "));
append_partial(&s, script_name);
append_partial(&s, make_lit_string(".bat "));
success = terminate_with_null(&s);
if (success){
success = 0;
SECURITY_ATTRIBUTES sec_attributes;
HANDLE out_read;
HANDLE out_write;
sec_attributes = {};
sec_attributes.nLength = sizeof(SECURITY_ATTRIBUTES);
sec_attributes.bInheritHandle = TRUE;
if (CreatePipe(&out_read, &out_write, &sec_attributes, 0)){
if (SetHandleInformation(out_read, HANDLE_FLAG_INHERIT, 0)){
STARTUPINFO startup = {};
startup.cb = sizeof(STARTUPINFO);
startup.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
startup.hStdError = out_write;
startup.hStdOutput = out_write;
startup.wShowWindow = SW_HIDE;
PROCESS_INFORMATION info = {};
Assert(sizeof(Plat_Handle) >= sizeof(HANDLE));
if (CreateProcess(cmd, command_line,
0, 0, TRUE, 0,
env_variables, path,
&startup, &info)){
success = 1;
CloseHandle(info.hThread);
*(HANDLE*)&cli_out->proc = info.hProcess;
*(HANDLE*)&cli_out->out_read = out_read;
*(HANDLE*)&cli_out->out_write = out_write;
}
else{
CloseHandle(out_read);
CloseHandle(out_write);
*(HANDLE*)&cli_out->proc = INVALID_HANDLE_VALUE;
*(HANDLE*)&cli_out->out_read = INVALID_HANDLE_VALUE;
*(HANDLE*)&cli_out->out_write = INVALID_HANDLE_VALUE;
}
}
else{
// TODO(allen): failed SetHandleInformation
}
}
else{
// TODO(allen): failed CreatePipe
}
}
return success;
}
struct CLI_Loop_Control{
u32 remaining_amount;
};
internal void
system_cli_begin_update(CLI_Handles *cli){
Assert(sizeof(cli->scratch_space) >= sizeof(CLI_Loop_Control));
CLI_Loop_Control *loop = (CLI_Loop_Control*)cli->scratch_space;
loop->remaining_amount = 0;
}
internal b32
system_cli_update_step(CLI_Handles *cli, char *dest, u32 max, u32 *amount){
HANDLE handle = *(HANDLE*)&cli->out_read;
CLI_Loop_Control *loop = (CLI_Loop_Control*)cli->scratch_space;
b32 has_more = 0;
DWORD remaining = loop->remaining_amount;
u32 pos = 0;
DWORD read_amount = 0;
for (;;){
if (remaining == 0){
if (!PeekNamedPipe(handle, 0, 0, 0, &remaining, 0)) break;
if (remaining == 0) break;
}
if (remaining + pos < max){
has_more = 1;
ReadFile(handle, dest + pos, remaining, &read_amount, 0);
TentativeAssert(remaining == read_amount);
pos += remaining;
remaining = 0;
}
else{
has_more = 1;
ReadFile(handle, dest + pos, max - pos, &read_amount, 0);
TentativeAssert(max - pos == read_amount);
loop->remaining_amount = remaining - (max - pos);
pos = max;
break;
}
}
*amount = pos;
return has_more;
}
internal b32
system_cli_end_update(CLI_Handles *cli){
b32 close_me = 0;
if (WaitForSingleObject(*(HANDLE*)&cli->proc, 0) == WAIT_OBJECT_0){
close_me = 1;
CloseHandle(*(HANDLE*)&cli->proc);
CloseHandle(*(HANDLE*)&cli->out_read);
CloseHandle(*(HANDLE*)&cli->out_write);
}
return close_me;
}
int
WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,