new memory interface
This commit is contained in:
parent
e88b9ea324
commit
a89b46fda7
|
@ -128,8 +128,18 @@ FCPP_LINK bool append_partial(String *dest, String src);
|
||||||
FCPP_LINK bool append(String *dest, char c);
|
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, String src) { return append_partial(dest, src); }
|
||||||
inline bool append(String *dest, char *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)
|
inline bool terminate_with_null(String *str){
|
||||||
{ if (str->size < str->memory_size) str->str[str->size] = 0; else str->str[str->size-1] = 0; }
|
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(char *a, char *b);
|
||||||
FCPP_LINK int compare(String a, char *b);
|
FCPP_LINK int compare(String a, char *b);
|
||||||
|
|
145
4ed.cpp
145
4ed.cpp
|
@ -23,6 +23,16 @@ struct App_State_Resizing{
|
||||||
i32 min, max;
|
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{
|
struct App_Vars{
|
||||||
Mem_Options mem;
|
Mem_Options mem;
|
||||||
Command_Map map_top;
|
Command_Map map_top;
|
||||||
|
@ -52,6 +62,8 @@ struct App_Vars{
|
||||||
String hot_dir_base;
|
String hot_dir_base;
|
||||||
Hot_Directory hot_directory;
|
Hot_Directory hot_directory;
|
||||||
|
|
||||||
|
CLI_List cli_processes;
|
||||||
|
|
||||||
char query_[256];
|
char query_[256];
|
||||||
char dest_[256];
|
char dest_[256];
|
||||||
|
|
||||||
|
@ -966,7 +978,7 @@ case_change_range(Mem_Options *mem, File_View *view, Editing_File *file,
|
||||||
if (file->still_lexing)
|
if (file->still_lexing)
|
||||||
system_cancel_job(BACKGROUND_THREADS, file->lex_job);
|
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;
|
u8 *data = (u8*)file->buffer.data;
|
||||||
for (i32 i = range.start; i < range.end; ++i){
|
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){
|
COMPOSE_DECL(compose_write_auto_tab_line){
|
||||||
command_write_character(command, binding);
|
command_write_character(command, binding);
|
||||||
|
update_command_data(command->vars, command);
|
||||||
command_auto_tab_line_at_cursor(command, binding);
|
command_auto_tab_line_at_cursor(command, binding);
|
||||||
|
update_command_data(command->vars, command);
|
||||||
}
|
}
|
||||||
|
|
||||||
globalvar Command_Function command_table[cmdid_count];
|
globalvar Command_Function command_table[cmdid_count];
|
||||||
|
@ -1533,6 +1607,8 @@ extern "C"{
|
||||||
binding.function = function;
|
binding.function = function;
|
||||||
if (function) function(cmd, binding);
|
if (function) function(cmd, binding);
|
||||||
|
|
||||||
|
update_command_data(cmd->vars, cmd);
|
||||||
|
#if 0
|
||||||
App_Vars *vars = cmd->vars;
|
App_Vars *vars = cmd->vars;
|
||||||
Command_Data command_data;
|
Command_Data command_data;
|
||||||
command_data.vars = vars;
|
command_data.vars = vars;
|
||||||
|
@ -1550,6 +1626,7 @@ extern "C"{
|
||||||
command_data.part = cmd->part;
|
command_data.part = cmd->part;
|
||||||
|
|
||||||
*cmd = command_data;
|
*cmd = command_data;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
PUSH_PARAMETER_SIG(external_push_parameter){
|
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, 'i', MDFR_CTRL, command_interactive_switch_buffer);
|
||||||
map_add(commands, 'c', MDFR_ALT, command_open_color_tweaker);
|
map_add(commands, 'c', MDFR_ALT, command_open_color_tweaker);
|
||||||
map_add(commands, 'x', MDFR_ALT, command_open_menu);
|
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
|
internal void
|
||||||
setup_command_table(){
|
setup_command_table(){
|
||||||
#define SET(n) command_table[cmdid_##n] = command_##n
|
#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);
|
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;
|
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
|
// NOTE(allen): reorganizing panels on screen
|
||||||
i32 prev_width = vars->layout.full_width;
|
i32 prev_width = vars->layout.full_width;
|
||||||
i32 prev_height = vars->layout.full_height;
|
i32 prev_height = vars->layout.full_height;
|
||||||
|
|
26
4ed.h
26
4ed.h
|
@ -112,6 +112,27 @@ general_memory_open(General_Memory *general, void *memory, i32 size){
|
||||||
insert_bubble(&general->sentinel, first);
|
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
|
#define BUBBLE_MIN_SIZE 1024
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
|
@ -129,9 +150,6 @@ general_memory_attempt_split(Bubble *bubble, i32 wanted_size){
|
||||||
internal void*
|
internal void*
|
||||||
general_memory_allocate(General_Memory *general, i32 size, u32 type = 0){
|
general_memory_allocate(General_Memory *general, i32 size, u32 type = 0){
|
||||||
void *result = 0;
|
void *result = 0;
|
||||||
if (size < Kbytes(1)){
|
|
||||||
int x = 1; AllowLocal(x);
|
|
||||||
}
|
|
||||||
for (Bubble *bubble = general->sentinel.next;
|
for (Bubble *bubble = general->sentinel.next;
|
||||||
bubble != &general->sentinel;
|
bubble != &general->sentinel;
|
||||||
bubble = bubble->next){
|
bubble = bubble->next){
|
||||||
|
@ -150,6 +168,8 @@ general_memory_allocate(General_Memory *general, i32 size, u32 type = 0){
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
general_memory_do_merge(Bubble *left, Bubble *right){
|
general_memory_do_merge(Bubble *left, Bubble *right){
|
||||||
|
Assert(left->next == right);
|
||||||
|
Assert(right->prev == left);
|
||||||
left->size += sizeof(Bubble) + right->size;
|
left->size += sizeof(Bubble) + right->size;
|
||||||
remove_bubble(right);
|
remove_bubble(right);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1187,8 +1187,8 @@ file_grow_starts_as_needed(General_Memory *general, Editing_File *file, i32 addi
|
||||||
i32 max = file->buffer.line_max;
|
i32 max = file->buffer.line_max;
|
||||||
i32 count = file->buffer.line_count;
|
i32 count = file->buffer.line_count;
|
||||||
i32 target_lines = count + additional_lines;
|
i32 target_lines = count + additional_lines;
|
||||||
if (target_lines > max){
|
if (target_lines > max || max == 0){
|
||||||
max <<= 1;
|
max = LargeRoundUp(target_lines + max, Kbytes(1));
|
||||||
i32 *new_lines = (i32*)
|
i32 *new_lines = (i32*)
|
||||||
general_memory_reallocate(general, file->buffer.line_starts,
|
general_memory_reallocate(general, file->buffer.line_starts,
|
||||||
sizeof(i32)*count, sizeof(i32)*max, BUBBLE_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){
|
file_grow_widths_as_needed(General_Memory *general, Editing_File *file){
|
||||||
#if BUFFER_EXPERIMENT_SCALPEL <= 2
|
#if BUFFER_EXPERIMENT_SCALPEL <= 2
|
||||||
i32 line_count = file->buffer.line_count;
|
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));
|
i32 new_max = LargeRoundUp(line_count, Kbytes(1));
|
||||||
|
if (new_max < Kbytes(1)) new_max = Kbytes(1);
|
||||||
if (file->buffer.line_widths){
|
if (file->buffer.line_widths){
|
||||||
file->buffer.line_widths = (real32*)
|
file->buffer.line_widths = (f32*)
|
||||||
general_memory_reallocate_nocopy(general, file->buffer.line_widths, sizeof(real32)*new_max, BUBBLE_WIDTHS);
|
general_memory_reallocate(general, file->buffer.line_widths,
|
||||||
|
sizeof(f32)*file->buffer.widths_count, sizeof(f32)*new_max, BUBBLE_WIDTHS);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
file->buffer.line_widths = (real32*)
|
file->buffer.line_widths = (f32*)
|
||||||
general_memory_allocate(general, sizeof(real32)*new_max, BUBBLE_WIDTHS);
|
general_memory_allocate(general, sizeof(f32)*new_max, BUBBLE_WIDTHS);
|
||||||
}
|
}
|
||||||
file->buffer.widths_max = new_max;
|
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_create_from_string(General_Memory *general, Editing_File *file, u8 *filename, Font *font, String val){
|
||||||
*file = {};
|
*file = {};
|
||||||
#if BUFFER_EXPERIMENT_SCALPEL <= 2
|
#if BUFFER_EXPERIMENT_SCALPEL <= 2
|
||||||
|
|
||||||
Buffer_Init_Type init = buffer_begin_init(&file->buffer, val.str, val.size);
|
Buffer_Init_Type init = buffer_begin_init(&file->buffer, val.str, val.size);
|
||||||
for (; buffer_init_need_more(&init); ){
|
for (; buffer_init_need_more(&init); ){
|
||||||
i32 page_size = buffer_init_page_size(&init);
|
i32 page_size = buffer_init_page_size(&init);
|
||||||
page_size = LargeRoundUp(page_size, Kbytes(4));
|
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);
|
void *data = general_memory_allocate(general, page_size, BUBBLE_BUFFER);
|
||||||
buffer_init_provide_page(&init, data, page_size);
|
buffer_init_provide_page(&init, data, page_size);
|
||||||
}
|
}
|
||||||
|
@ -1695,21 +1697,7 @@ file_relex_parallel(Mem_Options *mem, Editing_File *file,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
internal bool32
|
internal bool32
|
||||||
file_grow_as_needed(General_Memory *general, Editing_File *file, i32 additional_size){
|
file_grow_as_needed_(General_Memory *general, Editing_File *file, i32 new_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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
|
@ -2267,7 +2255,7 @@ enum History_Mode{
|
||||||
};
|
};
|
||||||
|
|
||||||
internal void
|
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){
|
History_Mode history_mode){
|
||||||
#if BUFFER_EXPERIMENT_SCALPEL <= 1
|
#if BUFFER_EXPERIMENT_SCALPEL <= 1
|
||||||
General_Memory *general = &mem->general;
|
General_Memory *general = &mem->general;
|
||||||
|
@ -2460,13 +2448,13 @@ file_pre_edit_maintenance(Editing_File *file){
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
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){
|
Editing_Layout *layout, Edit_Spec spec, History_Mode history_mode){
|
||||||
Assert(file);
|
Assert(file);
|
||||||
ProfileMomentFunction();
|
ProfileMomentFunction();
|
||||||
|
|
||||||
// NOTE(allen): fixing stuff beforewards????
|
// 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);
|
file_pre_edit_maintenance(file);
|
||||||
|
|
||||||
#if BUFFER_EXPERIMENT_SCALPEL <= 1
|
#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 str_len = spec.step.edit.len;
|
||||||
|
|
||||||
i32 shift_amount = 0;
|
i32 shift_amount = 0;
|
||||||
while (buffer_replace_range(&file->buffer, start, end, str, str_len, &shift_amount))
|
i32 request_amount = 0;
|
||||||
file_grow_as_needed(general, file, shift_amount);
|
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
|
#if BUFFER_EXPERIMENT_SCALPEL <= 0
|
||||||
// NOTE(allen): fixing stuff afterwards
|
// 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);
|
File_View *current_view = view_to_file_view(current_panel->view);
|
||||||
if (current_view && current_view->file == file){
|
if (current_view && current_view->file == file){
|
||||||
view_measure_wraps(general, current_view);
|
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->cursor.pos);
|
write_cursor_with_index(cursors, &cursor_count, current_view->mark);
|
||||||
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){
|
for (i32 i = 0; i < panel_count; ++i, ++current_panel){
|
||||||
File_View *current_view = view_to_file_view(current_panel->view);
|
File_View *current_view = view_to_file_view(current_panel->view);
|
||||||
if (current_view && current_view->file == file){
|
if (current_view && current_view->file == file){
|
||||||
if (current_view != view){
|
view_cursor_move(current_view, cursors[cursor_count++].pos);
|
||||||
view_cursor_move(current_view, cursors[cursor_count++].pos);
|
current_view->mark = cursors[cursor_count++].pos;
|
||||||
current_view->mark = cursors[cursor_count++].pos;
|
current_view->preferred_x = view_get_cursor_x(current_view);
|
||||||
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????
|
// NOTE(allen): fixing stuff beforewards????
|
||||||
Assert(spec.str == 0);
|
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);
|
file_pre_edit_maintenance(file);
|
||||||
|
|
||||||
// NOTE(allen): actual text replacement
|
// NOTE(allen): actual text replacement
|
||||||
|
@ -2570,10 +2561,17 @@ 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(spec.step.first_child < file->undo.children.edit_count);
|
||||||
Assert(batch_size >= 0);
|
Assert(batch_size >= 0);
|
||||||
|
|
||||||
i32 shift_amount = buffer_batch_edit_max_shift(batch, batch_size);
|
Buffer_Batch_State state = {};
|
||||||
file_grow_as_needed(general, file, shift_amount);
|
i32 request_amount;
|
||||||
|
while (buffer_batch_edit_step(&state, &file->buffer,
|
||||||
buffer_batch_edit(&file->buffer, batch, (char*)str_base, batch_size);
|
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
|
// NOTE(allen): token fixing
|
||||||
if (file->tokens_complete){
|
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;
|
Buffer_Edit *end_edit = batch + batch_size;
|
||||||
|
|
||||||
i32 shift_amount = 0;
|
i32 shift_amount = 0;
|
||||||
|
i32 local_shift = 0;
|
||||||
|
|
||||||
for (; token < end_token && edit < end_edit; ++edit){
|
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){
|
for (; token->start < edit->start && token < end_token; ++token){
|
||||||
token->start += shift_amount;
|
token->start += shift_amount;
|
||||||
}
|
}
|
||||||
shift_amount += (edit->len - (edit->end - edit->start));
|
shift_amount += local_shift;
|
||||||
}
|
}
|
||||||
for (; token < end_token; ++token){
|
for (; token < end_token; ++token){
|
||||||
token->start += shift_amount;
|
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.pre_pos = view->cursor.pos;
|
||||||
spec.step.post_pos = next_cursor;
|
spec.step.post_pos = next_cursor;
|
||||||
spec.str = str;
|
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
|
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.step.edit.str_start = 0;
|
||||||
spec.str = stack->strings + step.edit.str_start;
|
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);
|
if (expected_type == ED_UNDO) view_cursor_move(view, step.pre_pos);
|
||||||
else view_cursor_move(view, step.post_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.step.edit.str_start = 0;
|
||||||
spec.str = file->undo.history.strings + step.edit.str_start;
|
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){
|
switch (spec.step.type){
|
||||||
case ED_NORMAL:
|
case ED_NORMAL:
|
||||||
|
@ -2906,7 +2910,7 @@ clipboard_copy(General_Memory *general, Working_Set *working, Range range, Editi
|
||||||
}
|
}
|
||||||
|
|
||||||
internal Edit_Spec
|
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 *edits, char *str_base, i32 str_size,
|
||||||
Buffer_Edit *inverse_array, char *inv_str, i32 inv_max,
|
Buffer_Edit *inverse_array, char *inv_str, i32 inv_max,
|
||||||
i32 edit_count){
|
i32 edit_count){
|
||||||
|
@ -2933,6 +2937,8 @@ view_compute_whitespace_edit(Mem_Options *mem, Editing_File *file,
|
||||||
spec.step.special_type = 1;
|
spec.step.special_type = 1;
|
||||||
spec.step.child_count = edit_count;
|
spec.step.child_count = edit_count;
|
||||||
spec.step.inverse_child_count = edit_count;
|
spec.step.inverse_child_count = edit_count;
|
||||||
|
spec.step.pre_pos = cursor_pos;
|
||||||
|
spec.step.post_pos = cursor_pos;
|
||||||
#else
|
#else
|
||||||
Edit_Spec spec = {};
|
Edit_Spec spec = {};
|
||||||
#endif
|
#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;
|
char *inv_str = (char*)part->base + part->pos;
|
||||||
Edit_Spec spec =
|
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);
|
inverse_array, inv_str, part->max - part->pos, edit_count);
|
||||||
|
|
||||||
view_do_white_batch_edit(mem, view, file, layout, spec, hist_normal);
|
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;
|
char *inv_str = (char*)part->base + part->pos;
|
||||||
Edit_Spec spec =
|
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);
|
inverse_array, inv_str, part->max - part->pos, edit_count);
|
||||||
|
|
||||||
view_do_white_batch_edit(mem, view, file, layout, spec, hist_normal);
|
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;
|
result = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (cursor_y > target_y + max_y) target_y += delta_y;
|
if (cursor_y > target_y + max_y){
|
||||||
while (cursor_y < target_y + taken_top_space) target_y -= delta_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 > max_target_y) target_y = max_target_y;
|
||||||
if (target_y < -extra_top) target_y = -extra_top;
|
if (target_y < -extra_top) target_y = -extra_top;
|
||||||
|
|
|
@ -31,7 +31,7 @@ struct Debug_Event{
|
||||||
|
|
||||||
struct Debug_Event_Array{
|
struct Debug_Event_Array{
|
||||||
volatile u32 count;
|
volatile u32 count;
|
||||||
Debug_Event e[512];
|
Debug_Event e[4096];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Profile_Frame{
|
struct Profile_Frame{
|
||||||
|
|
21
4ed_system.h
21
4ed_system.h
|
@ -7,6 +7,8 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
struct Plat_Handle{ u64 d[2]; };
|
||||||
|
|
||||||
// TODO(allen): This should either be a String or it should be improved
|
// 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.
|
// to handle 64-bit sized files. Staying in this state, however, is unacceptable.
|
||||||
struct File_Data{
|
struct File_Data{
|
||||||
|
@ -76,6 +78,25 @@ system_post_clipboard(String str);
|
||||||
internal i64
|
internal i64
|
||||||
system_time();
|
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_Context;
|
||||||
|
|
||||||
struct Thread_Memory{
|
struct Thread_Memory{
|
||||||
|
|
|
@ -597,6 +597,7 @@ buffer_remeasure_widths(Buffer_Type *buffer, void *advance_data, int stride,
|
||||||
int *starts;
|
int *starts;
|
||||||
float *widths;
|
float *widths;
|
||||||
int line_count;
|
int line_count;
|
||||||
|
int widths_count;
|
||||||
char *data;
|
char *data;
|
||||||
int size, end;
|
int size, end;
|
||||||
int i, j;
|
int i, j;
|
||||||
|
@ -606,17 +607,17 @@ buffer_remeasure_widths(Buffer_Type *buffer, void *advance_data, int stride,
|
||||||
starts = buffer->line_starts;
|
starts = buffer->line_starts;
|
||||||
widths = buffer->line_widths;
|
widths = buffer->line_widths;
|
||||||
line_count = buffer->line_count;
|
line_count = buffer->line_count;
|
||||||
|
widths_count = buffer->widths_count;
|
||||||
|
|
||||||
assert_4tech(0 <= line_start);
|
assert_4tech(0 <= line_start);
|
||||||
assert_4tech(line_start <= line_end);
|
assert_4tech(line_start <= line_end);
|
||||||
assert_4tech(line_end < line_count);
|
|
||||||
assert_4tech(line_count <= buffer->widths_max);
|
assert_4tech(line_count <= buffer->widths_max);
|
||||||
|
|
||||||
++line_end;
|
|
||||||
if (line_shift != 0){
|
if (line_shift != 0){
|
||||||
memmove_4tech(widths + line_end + line_shift, widths + line_end,
|
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;
|
line_end += line_shift;
|
||||||
i = line_start;
|
i = line_start;
|
||||||
|
@ -733,7 +734,6 @@ buffer_get_line_index_from_wrapped_y(float *wraps, float y, float font_height, i
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef NON_ABSTRACT_4TECH
|
#ifndef NON_ABSTRACT_4TECH
|
||||||
|
|
||||||
typedef struct{
|
typedef struct{
|
||||||
Full_Cursor cursor, prev_cursor;
|
Full_Cursor cursor, prev_cursor;
|
||||||
} Seek_State;
|
} Seek_State;
|
||||||
|
@ -1000,13 +1000,15 @@ buffer_invert_batch(Buffer_Invert_Batch *state, Buffer_Type *buffer, Buffer_Edit
|
||||||
internal_4tech void
|
internal_4tech void
|
||||||
buffer_batch_edit(Buffer_Type *buffer, Buffer_Edit *sorted_edits, char *strings, int edit_count){
|
buffer_batch_edit(Buffer_Type *buffer, Buffer_Edit *sorted_edits, char *strings, int edit_count){
|
||||||
Buffer_Batch_State state;
|
Buffer_Batch_State state;
|
||||||
|
int r;
|
||||||
|
|
||||||
debug_4tech(int result);
|
debug_4tech(int result);
|
||||||
|
|
||||||
state.i = 0;
|
state.i = 0;
|
||||||
state.shift_total = 0;
|
state.shift_total = 0;
|
||||||
|
|
||||||
debug_4tech(result =)
|
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);
|
assert_4tech(result == 0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1121,7 +1123,6 @@ buffer_get_render_data(Buffer_Type *buffer, float *wraps, Buffer_Render_Item *it
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer_get_render_data_end:
|
buffer_get_render_data_end:
|
||||||
|
|
||||||
if (y <= height + shift_y || item == items){
|
if (y <= height + shift_y || item == items){
|
||||||
ch = 0;
|
ch = 0;
|
||||||
ch_width = measure_character(advance_data, stride, ' ');
|
ch_width = measure_character(advance_data, stride, ' ');
|
||||||
|
|
|
@ -20,6 +20,7 @@ typedef struct{
|
||||||
float *line_widths;
|
float *line_widths;
|
||||||
int *line_starts;
|
int *line_starts;
|
||||||
int line_count;
|
int line_count;
|
||||||
|
int widths_count;
|
||||||
int line_max;
|
int line_max;
|
||||||
int widths_max;
|
int widths_max;
|
||||||
} Gap_Buffer;
|
} Gap_Buffer;
|
||||||
|
@ -110,7 +111,7 @@ buffer_end_init(Gap_Buffer_Init *init){
|
||||||
}
|
}
|
||||||
|
|
||||||
internal_4tech void*
|
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;
|
void *result;
|
||||||
int new_gap_size;
|
int new_gap_size;
|
||||||
|
|
||||||
|
@ -119,9 +120,9 @@ buffer_relocate(Gap_Buffer *buffer, char *new_data, int new_max){
|
||||||
result = buffer->data;
|
result = buffer->data;
|
||||||
new_gap_size = new_max - buffer_size(buffer);
|
new_gap_size = new_max - buffer_size(buffer);
|
||||||
memcpy_4tech(new_data, buffer->data, buffer->size1);
|
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->gap_size = new_gap_size;
|
||||||
buffer->max = new_max;
|
buffer->max = new_max;
|
||||||
|
|
||||||
|
@ -263,7 +264,7 @@ buffer_backify_next(Gap_Buffer_Backify_Loop *loop){
|
||||||
}
|
}
|
||||||
|
|
||||||
internal_4tech int
|
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;
|
char *data;
|
||||||
int result;
|
int result;
|
||||||
int size;
|
int size;
|
||||||
|
@ -301,7 +302,8 @@ buffer_replace_range(Gap_Buffer *buffer, int start, int end, char *str, int len,
|
||||||
result = 0;
|
result = 0;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
result = *shift_amount + size;
|
*request_amount = round_up_4tech(2*(*shift_amount + size), 4 << 10);
|
||||||
|
result = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return(result);
|
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
|
// NOTE(allen): This could should be optimized for Gap_Buffer
|
||||||
internal_4tech int
|
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;
|
Buffer_Edit *edit;
|
||||||
int i, result;
|
int i, result;
|
||||||
int shift_total, shift_amount;
|
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;
|
edit = sorted_edits + i;
|
||||||
for (; i < edit_count; ++i, ++edit){
|
for (; i < edit_count; ++i, ++edit){
|
||||||
result = buffer_replace_range(buffer, edit->start + shift_total, edit->end + shift_total,
|
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;
|
if (result) break;
|
||||||
shift_total += shift_amount;
|
shift_total += shift_amount;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ typedef struct{
|
||||||
int *line_starts;
|
int *line_starts;
|
||||||
float *line_widths;
|
float *line_widths;
|
||||||
int line_count;
|
int line_count;
|
||||||
|
int widths_count;
|
||||||
int line_max;
|
int line_max;
|
||||||
int widths_max;
|
int widths_max;
|
||||||
} Buffer;
|
} Buffer;
|
||||||
|
@ -92,14 +93,14 @@ buffer_end_init(Buffer_Init *init){
|
||||||
}
|
}
|
||||||
|
|
||||||
internal_4tech void*
|
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;
|
void *result;
|
||||||
|
|
||||||
assert_4tech(new_max >= buffer->size);
|
assert_4tech(new_max >= buffer->size);
|
||||||
|
|
||||||
result = buffer->data;
|
result = buffer->data;
|
||||||
memcpy_4tech(new_data, buffer->data, buffer->size);
|
memcpy_4tech(new_data, buffer->data, buffer->size);
|
||||||
buffer->data = new_data;
|
buffer->data = (char*)new_data;
|
||||||
buffer->max = new_max;
|
buffer->max = new_max;
|
||||||
|
|
||||||
return(result);
|
return(result);
|
||||||
|
@ -174,7 +175,7 @@ buffer_backify_next(Buffer_Backify_Loop *loop){
|
||||||
}
|
}
|
||||||
|
|
||||||
internal_4tech int
|
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;
|
char *data;
|
||||||
int result;
|
int result;
|
||||||
int size;
|
int size;
|
||||||
|
@ -189,20 +190,20 @@ buffer_replace_range(Buffer *buffer, int start, int end, char *str, int len, int
|
||||||
data = (char*)buffer->data;
|
data = (char*)buffer->data;
|
||||||
memmove_4tech(data + end + *shift_amount, data + end, buffer->size - end);
|
memmove_4tech(data + end + *shift_amount, data + end, buffer->size - end);
|
||||||
buffer->size += *shift_amount;
|
buffer->size += *shift_amount;
|
||||||
data[buffer->size] = 0;
|
|
||||||
if (len != 0) memcpy_4tech(data + start, str, len);
|
if (len != 0) memcpy_4tech(data + start, str, len);
|
||||||
|
|
||||||
result = 0;
|
result = 0;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
result = *shift_amount + size;
|
*request_amount = round_up_4tech(2*(*shift_amount + size), 4 << 10);
|
||||||
|
result = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal_4tech int
|
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;
|
Buffer_Edit *edit;
|
||||||
int i, result;
|
int i, result;
|
||||||
int shift_total, shift_amount;
|
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;
|
edit = sorted_edits + i;
|
||||||
for (; i < edit_count; ++i, ++edit){
|
for (; i < edit_count; ++i, ++edit){
|
||||||
result = buffer_replace_range(buffer, edit->start + shift_total, edit->end + shift_total,
|
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;
|
if (result) break;
|
||||||
shift_total += shift_amount;
|
shift_total += shift_amount;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@ typedef struct{
|
||||||
float *line_widths;
|
float *line_widths;
|
||||||
int *line_starts;
|
int *line_starts;
|
||||||
int line_count;
|
int line_count;
|
||||||
|
int widths_count;
|
||||||
int line_max;
|
int line_max;
|
||||||
int widths_max;
|
int widths_max;
|
||||||
} Multi_Gap_Buffer;
|
} Multi_Gap_Buffer;
|
||||||
|
@ -171,20 +172,26 @@ buffer_find_chunk(Multi_Gap_Buffer *buffer, int pos){
|
||||||
Fixed_Width_Gap_Buffer *gaps;
|
Fixed_Width_Gap_Buffer *gaps;
|
||||||
int start, end, m, this_pos;
|
int start, end, m, this_pos;
|
||||||
|
|
||||||
gaps = buffer->gaps;
|
if (pos == buffer_size(buffer)){
|
||||||
start = 0;
|
m = buffer->chunk_count;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
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);
|
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
|
// BOTTOM
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,19 @@
|
||||||
#define cat_4tech(a,b) cat_4tech_(a,b)
|
#define cat_4tech(a,b) cat_4tech_(a,b)
|
||||||
#endif
|
#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
|
inline_4tech float
|
||||||
measure_character(void *advance_data, int stride, char character){
|
measure_character(void *advance_data, int stride, char character){
|
||||||
char *advances;
|
char *advances;
|
||||||
|
|
144
win32_4ed.cpp
144
win32_4ed.cpp
|
@ -58,7 +58,7 @@
|
||||||
#define FPS 30
|
#define FPS 30
|
||||||
#define FRAME_TIME (1000000 / FPS)
|
#define FRAME_TIME (1000000 / FPS)
|
||||||
|
|
||||||
#define BUFFER_EXPERIMENT_SCALPEL 2
|
#define BUFFER_EXPERIMENT_SCALPEL 0
|
||||||
|
|
||||||
#include "4ed_meta.h"
|
#include "4ed_meta.h"
|
||||||
|
|
||||||
|
@ -545,11 +545,18 @@ Win32Callback(HWND hwnd, UINT uMsg,
|
||||||
case WM_KEYDOWN:
|
case WM_KEYDOWN:
|
||||||
case WM_KEYUP:
|
case WM_KEYUP:
|
||||||
{
|
{
|
||||||
bool8 previous_state, current_state;
|
switch (wParam){
|
||||||
previous_state = ((lParam & Bit_30)?(1):(0));
|
case VK_CONTROL:case VK_LCONTROL:case VK_RCONTROL:
|
||||||
current_state = ((lParam & Bit_31)?(0):(1));
|
case VK_MENU:case VK_LMENU:case VK_RMENU:
|
||||||
Win32KeyboardHandle(current_state, previous_state, wParam);
|
case VK_SHIFT:case VK_LSHIFT:case VK_RSHIFT: break;
|
||||||
result = DefWindowProc(hwnd, uMsg, wParam, lParam);
|
|
||||||
|
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;
|
}break;
|
||||||
|
|
||||||
case WM_MOUSEMOVE:
|
case WM_MOUSEMOVE:
|
||||||
|
@ -880,6 +887,131 @@ INTERNAL_get_thread_states(Thread_Group_ID id, bool8 *running, i32 *pending){
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
int
|
||||||
WinMain(HINSTANCE hInstance,
|
WinMain(HINSTANCE hInstance,
|
||||||
HINSTANCE hPrevInstance,
|
HINSTANCE hPrevInstance,
|
||||||
|
|
Loading…
Reference in New Issue