diff --git a/4coder_buffer_types.h b/4coder_buffer_types.h index ace28eab..b61be5ca 100644 --- a/4coder_buffer_types.h +++ b/4coder_buffer_types.h @@ -12,6 +12,21 @@ #ifndef FRED_BUFFER_TYPES_H #define FRED_BUFFER_TYPES_H +#ifndef FRED_STRING_STRUCT +#define FRED_STRING_STRUCT +typedef struct String{ + char *str; + int size; + int memory_size; +} String; + +typedef struct Offset_String{ + int offset; + int size; +} Offset_String; +#endif + + typedef unsigned char Code; typedef enum{ @@ -135,14 +150,14 @@ make_range(int p1, int p2){ } -enum Dynamic_Type{ +typedef enum Dynamic_Type{ dynamic_type_int, dynamic_type_string, // never below this dynamic_type_count -}; +} Dynamic_Type; -struct Dynamic{ +typedef struct Dynamic{ int type; union{ struct{ @@ -151,7 +166,7 @@ struct Dynamic{ }; int int_value; }; -}; +} Dynamic; inline Dynamic dynamic_int(int x){ diff --git a/4coder_custom.cpp b/4coder_custom.cpp index b999bdda..361f3011 100644 --- a/4coder_custom.cpp +++ b/4coder_custom.cpp @@ -2,23 +2,21 @@ * Example use of customization API */ -#define FCPP_STRING_IMPLEMENTATION -#include "4coder_string.h" - // NOTE(allen): See exec_command and surrounding code in 4coder_helper.h // to decide whether you want macro translations, without them you will // have to manipulate the command and parameter stack through // "app->" which may be more or less clear depending on your use. -// -// I suggest you try disabling macro translation and getting your code working -// that way, because I'll be removing it entirely sometime soon -#define DisableMacroTranslations 0 #include "4coder_custom.h" + +#define FCPP_STRING_IMPLEMENTATION +#include "4coder_string.h" + +#define UseInterfacesThatArePhasingOut 0 #include "4coder_helper.h" #ifndef literal -#define literal(s) s, (sizeof(s)-1) +#define literal(s) (s), (sizeof(s)-1) #endif // NOTE(allen|a3.3): All of your custom ids should be enumerated @@ -514,8 +512,20 @@ CUSTOM_COMMAND_SIG(query_replace){ } CUSTOM_COMMAND_SIG(open_all_cpp_and_h){ - String dir = push_directory(app); + // NOTE(allen|a3.4.4): This method of getting the hot directory works + // because this custom.cpp gives no special meaning to app->memory + // and doesn't set up a persistent allocation system within app->memory. + // push_directory isn't a very good option since it's tied to the parameter + // stack, so I am phasing that idea out now. + String dir = make_string(app->memory, 0, app->memory_size); + dir.size = app->directory_get_hot(app, dir.str, dir.memory_size); + int dir_size = dir.size; + + + // NOTE(allen|a3.4.4): Here we get the list of files in this directory. + // Notice that we free_file_list at the end. File_List list = app->get_file_list(app, dir.str, dir.size); + for (int i = 0; i < list.count; ++i){ File_Info *info = list.infos + i; if (!info->folder){ @@ -524,12 +534,19 @@ CUSTOM_COMMAND_SIG(open_all_cpp_and_h){ match(extension, make_lit_string("hpp")) || match(extension, make_lit_string("c")) || match(extension, make_lit_string("h"))){ - push_parameter(app, par_name, info->filename.str, info->filename.size); + // NOTE(allen): There's no way in the 4coder API to use relative + // paths at the moment, so everything should be full paths. Which is + // managable. Here simply set the dir string size back to where it + // was originally, so that new appends overwrite old ones. + dir.size = dir_size; + append(&dir, info->filename); + push_parameter(app, par_name, dir.str, dir.size); push_parameter(app, par_do_in_background, 1); exec_command(app, cmdid_interactive_open); } } } + app->free_file_list(app, list); } @@ -539,9 +556,13 @@ CUSTOM_COMMAND_SIG(open_in_other){ } CUSTOM_COMMAND_SIG(open_my_files){ - // NOTE(allen|a3.1): The command cmdid_interactive_open can now open + // NOTE(allen|a3.1): EXAMPLE probably not useful in practice. + // + // The command cmdid_interactive_open can now open // a file specified on the parameter stack. If the file does not exist - // cmdid_interactive_open behaves as usual. + // cmdid_interactive_open behaves as usual. If par_do_in_background + // is set to true the command is prevented from changing the view under + // any circumstance. push_parameter(app, par_name, literal("w:/4ed/data/test/basic.cpp")); exec_command(app, cmdid_interactive_open); @@ -563,7 +584,9 @@ CUSTOM_COMMAND_SIG(open_my_files){ } CUSTOM_COMMAND_SIG(build_at_launch_location){ - // NOTE(allen|a3.3): An example of calling build by setting all + // NOTE(allen|a3.3): EXAMPLE probably not all that useful in practice. + // + // An example of calling build by setting all // parameters directly. This only works if build.bat can be called // from the directory the application is launched at. push_parameter(app, par_cli_overlap_with_conflict, 1); @@ -578,11 +601,11 @@ CUSTOM_COMMAND_SIG(build_search){ // directories looking for a file, in this case a batch file to execute. // // - // Step 1: push_directory returns a String containing the current "hot" directory - // (whatever directory you most recently visited in the 4coder file browsing interface) + // Step 1: Grab all of the user memory (or, you know, less if you've got better + // thing to do with some of it). Make a string and store the hot directory in it. // - // Step 2: app->directory_has_file queries the file system to see if "build.bat" exists - // If it does exist several parameters are pushed: + // Step 2: app->file_exists queries the file system to see if "/build.bat" exists. + // If it does exist several parameters are pushed and cmdid_command_line is executed: // - par_cli_overlap_with_conflict: whether to launch this process if an existing process // is already being used for output on the same buffer // @@ -599,15 +622,18 @@ CUSTOM_COMMAND_SIG(build_search){ // To set par_cli_command: app->push_parameter does not make a copy of the dir because // dir isn't going to change again. // - // Step 3: If the batch file did not exist try to move to the parent directory using + // Step 3: If the batch file did not exist change the dir string to the parent directory using // app->directory_cd. The cd function can also be used to navigate to subdirectories. // It returns true if it can actually move in the specified direction, and false otherwise. + // // This doesn't actually change the hot directory of 4coder, it's only effect is to - // modify the string you passed in to reflect the change in directory. + // modify the string you passed in to reflect the change in directory if that change was possible. int keep_going = 1; int old_size; - String dir = push_directory(app); + String dir = make_string(app->memory, 0, app->memory_size); + dir.size = app->directory_get_hot(app, dir.str, dir.memory_size); + while (keep_going){ old_size = dir.size; append(&dir, "build.bat"); diff --git a/4coder_custom.h b/4coder_custom.h index 27dc7d90..bc4c2ee4 100644 --- a/4coder_custom.h +++ b/4coder_custom.h @@ -265,8 +265,8 @@ extern "C"{ struct Application_Links{ // User data - void *data; - int size; + void *memory; + int memory_size; // Command exectuion Exec_Command_Function *exec_command_keep_stack; diff --git a/4coder_helper.h b/4coder_helper.h index 289f6745..87bf9f0e 100644 --- a/4coder_helper.h +++ b/4coder_helper.h @@ -204,6 +204,7 @@ push_parameter(Application_Links *app, const char *param, int param_len, const c app->push_parameter(app, dynamic_string(param_copy, param_len), dynamic_string(value_copy, value_len)); } +#if UseInterfacesThatArePhasingOut inline String push_directory(Application_Links *app){ String result; @@ -212,6 +213,7 @@ push_directory(Application_Links *app){ result.size = app->directory_get_hot(app, result.str, result.memory_size); return(result); } +#endif inline Range get_range(File_View_Summary *view){ @@ -238,8 +240,8 @@ active_view_to_line(Application_Links *app, int line_number){ view = app->get_active_file_view(app); // NOTE(allen|a3.4.4): We don't have to worry about whether this is a valid line number. - // When the position specified isn't possible for whatever reason it will set the cursor to - // a nearby valid position. + // When it's not possible to place a cursor at the position for whatever reason it will set the + // cursor to a nearby valid position. app->view_set_cursor(app, &view, seek_line_char(line_number, 0), 1); } @@ -291,9 +293,9 @@ query_user_general(Application_Links *app, Query_Bar *bar, int force_number){ } } - // NOTE(allen|a3.4.4): All we have to do to update what is shown on the query bar - // is to edit or local Query_Bar struct! This is handy because it means our Query_Bar - // can double as storing the state of the input AND as the source for the UI. + // NOTE(allen|a3.4.4): All we have to do to update the query bar is edit our + // local Query_Bar struct! This is handy because it means our Query_Bar + // is always correct for typical use without extra work updating the bar. if (in.type == UserInputKey){ if (in.key.keycode == '\n' || in.key.keycode == '\t'){ break; diff --git a/4coder_string.h b/4coder_string.h index 3fae8d3d..f736dbe7 100644 --- a/4coder_string.h +++ b/4coder_string.h @@ -63,15 +63,15 @@ inline bool char_is_alpha_numeric(char c) { return (c >= 'a' && c <= 'z' || c >= inline bool char_is_hex(char c) { return c >= '0' && c <= '9' || c >= 'A' && c <= 'F' || c >= 'a' && c <= 'f'; } inline bool char_is_basic(char c) { return c >= ' ' && c <= '~'; } -inline String make_string(char *s, int size, int mem_size); -inline String make_string(char *s, int size); +inline String make_string(void *s, int size, int mem_size); +inline String make_string(void *s, int size); #define make_lit_string(str) (make_string((char*)(str), sizeof(str)-1, sizeof(str))) #define make_fixed_width_string(str) (make_string((char*)(str), 0, sizeof(str))) #define expand_str(s) ((s).str), ((s).size) -inline String make_string_slowly(char *s); +inline String make_string_slowly(void *s); inline char* make_c_str(String s); inline String substr(String str, int start); @@ -183,28 +183,28 @@ FCPP_LINK char * file_extension_c(String str); FCPP_LINK bool remove_last_folder(String *str); FCPP_LINK void replace_char(String str, char replace, char with); -inline String make_string(char *str, int size, int mem_size){ +inline String make_string(void *str, int size, int mem_size){ String result; - result.str = str; + result.str = (char*)str; result.size = size; result.memory_size = mem_size; return result; } inline String -make_string(char *str, int size){ +make_string(void *str, int size){ String result; - result.str = str; + result.str = (char*)str; result.size = size; result.memory_size = size; return result; } inline String -make_string_slowly(char *str){ +make_string_slowly(void *str){ String result; - result.str = str; - result.size = str_size(str); + result.str = (char*)str; + result.size = str_size((char*)str); result.memory_size = result.size; return result; } diff --git a/4ed.cpp b/4ed.cpp index 95c40043..c86ff544 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -2508,8 +2508,8 @@ command_caller(Coroutine *coroutine){ internal void app_links_init(System_Functions *system, void *data, int size){ - app_links.data = data; - app_links.size = size; + app_links.memory = data; + app_links.memory_size = size; app_links.exec_command_keep_stack = external_exec_command_keep_stack; app_links.push_parameter = external_push_parameter; @@ -3257,7 +3257,7 @@ App_Init_Sig(app_init){ vars->font_set = &target->font_set; - font_set_init(vars->font_set, partition, 16, 4); + font_set_init(vars->font_set, partition, 16, 5); { struct Font_Setup{ @@ -3380,9 +3380,6 @@ App_Step_Sig(app_step){ app_result.redraw = 1; } - Panel *panels = vars->layout.panels; - Panel *active_panel = &panels[vars->layout.active_panel]; - // NOTE(allen): OS clipboard event handling if (clipboard.str){ String *dest = working_set_next_clipboard_string(&vars->mem.general, &vars->working_set, clipboard.size); @@ -3407,6 +3404,7 @@ App_Step_Sig(app_step){ } // NOTE(allen): update child processes + Panel *panels = vars->layout.panels; if (time_step){ Temp_Memory temp = begin_temp_memory(&vars->mem.part); u32 max = Kbytes(32); @@ -3461,7 +3459,7 @@ App_Step_Sig(app_step){ new_cursor = spec.step.post_pos; } - Panel *panel = vars->layout.panels; + Panel *panel = panels; i32 panel_count = vars->layout.panel_count; for (i32 i = 0; i < panel_count; ++i, ++panel){ View *view = panel->view; @@ -3601,11 +3599,12 @@ App_Step_Sig(app_step){ // NOTE(allen): prepare to start executing commands ProfileStart(command_coroutine); + Command_Data *cmd = &vars->command_data; cmd->mem = &vars->mem; - cmd->panel = active_panel; - cmd->view = active_panel->view; + cmd->panel = panels + vars->layout.active_panel; + cmd->view = cmd->panel->view; cmd->working_set = &vars->working_set; cmd->layout = &vars->layout; cmd->live_set = &vars->live_set; @@ -3659,7 +3658,7 @@ App_Step_Sig(app_step){ if ((get_flags & EventOnAnyKey) || (get_flags & EventOnEsc)){ for (i32 key_i = 0; key_i < key_data.count; ++key_i){ Key_Event_Data key = get_single_key(&key_data, key_i); - View *view = active_panel->view; + View *view = cmd->view; b32 pass_in = 0; cmd->key = key; @@ -3711,7 +3710,7 @@ App_Step_Sig(app_step){ } if (vars->command_coroutine != 0 && (get_flags & EventOnMouse)){ - View *view = active_panel->view; + View *view = cmd->view; b32 pass_in = 0; User_Input user_in; @@ -3774,11 +3773,13 @@ App_Step_Sig(app_step){ } } } + + update_command_data(vars, cmd); + ProfileEnd(command_coroutine); // NOTE(allen): pass raw input to the panels ProfileStart(step); - View *active_view = active_panel->view; Input_Summary dead_input = {}; dead_input.mouse.x = mouse->x; @@ -3825,26 +3826,24 @@ App_Step_Sig(app_step){ View *view_ = panel->view; if (view_){ Assert(view_->do_view); - b32 active = (panel == active_panel); + b32 active = (panel == cmd->panel); Input_Summary input = (active)?(active_input):(dead_input); if (panel == mouse_panel && !mouse->out_of_window){ input.mouse = mouse_state; } - if (view_->do_view(system, exchange, view_, panel->inner, active_view, + if (view_->do_view(system, exchange, view_, panel->inner, cmd->view, VMSG_STEP, 0, &input, &active_input)){ app_result.redraw = 1; } } } } + + update_command_data(vars, cmd); ProfileEnd(step); - + // NOTE(allen): command execution ProfileStart(command); - - cmd->panel = active_panel; - cmd->view = active_panel->view; - if (!consumed_input[0] || !consumed_input[1]){ b32 consumed_input2[2] = {0}; @@ -3857,7 +3856,7 @@ App_Step_Sig(app_step){ cmd->key = key; if (hit_esc || !consumed_input[0]){ - View *view = active_panel->view; + View *view = cmd->view; Command_Map *map = 0; if (view) map = view->map; @@ -3900,8 +3899,8 @@ App_Step_Sig(app_step){ consumed_input[0] |= consumed_input2[0]; consumed_input[1] |= consumed_input2[1]; } - - active_panel = panels + vars->layout.active_panel; + + update_command_data(vars, cmd); ProfileEnd(command); ProfileStart(resizing); @@ -4002,10 +4001,11 @@ App_Step_Sig(app_step){ } if (mouse_in_edit_area && mouse_panel != 0 && mouse->press_l){ - active_panel = mouse_panel; vars->layout.active_panel = mouse_panel_i; app_result.redraw = 1; } + + update_command_data(vars, cmd); ProfileEnd(resizing); // NOTE(allen): processing sys app bindings @@ -4153,14 +4153,18 @@ App_Step_Sig(app_step){ { App_Open_File_Result result; result = app_open_file_background(vars, exchange, working_set, string); - if (result.is_new && result.file == 0){ - delayed_action_repush(&vars->delay2, act); - } - else{ - Sys_App_Binding *binding = app_push_file_binding(vars, result.sys_id, result.file_index); - binding->success = 0; - binding->fail = 0; - binding->panel = panel; + if (result.is_new){ + if (result.file){ + if (result.sys_id){ + Sys_App_Binding *binding = app_push_file_binding(vars, result.sys_id, result.file_index); + binding->success = 0; + binding->fail = 0; + binding->panel = panel; + } + else{ + delayed_action_repush(&vars->delay2, act); + } + } } }break; @@ -4347,12 +4351,12 @@ App_Step_Sig(app_step){ View *view = panel->view; if (view){ view->do_view(system, exchange, - view, inner, active_view, + view, inner, cmd->view, VMSG_RESIZE, 0, &dead_input, &active_input); view = (view->is_minor)?view->major:0; if (view){ view->do_view(system, exchange, - view, inner, active_view, + view, inner, cmd->view, VMSG_RESIZE, 0, &dead_input, &active_input); } } @@ -4384,12 +4388,12 @@ App_Step_Sig(app_step){ View *view = panel->view; if (view){ view->do_view(system, exchange, - view, panel->inner, active_view, + view, panel->inner, cmd->view, VMSG_STYLE_CHANGE, 0, &dead_input, &active_input); view = (view->is_minor)?view->major:0; if (view){ view->do_view(system, exchange, - view, panel->inner, active_view, + view, panel->inner, cmd->view, VMSG_STYLE_CHANGE, 0, &dead_input, &active_input); } } @@ -4414,7 +4418,7 @@ App_Step_Sig(app_step){ View *view = panel->view; Style *style = &vars->style; - b32 active = (panel == active_panel); + b32 active = (panel == cmd->panel); u32 back_color = style->main.back_color; draw_rectangle(target, full, back_color); @@ -4422,7 +4426,7 @@ App_Step_Sig(app_step){ Assert(view->do_view); draw_push_clip(target, panel->inner); view->do_view(system, exchange, - view, panel->inner, active_view, + view, panel->inner, cmd->view, VMSG_DRAW, target, &dead_input, &active_input); draw_pop_clip(target); } diff --git a/win32_4ed.cpp b/win32_4ed.cpp index 21b023e4..d303e19c 100644 --- a/win32_4ed.cpp +++ b/win32_4ed.cpp @@ -451,6 +451,8 @@ Sys_Set_File_List_Sig(system_set_file_list){ } else{ Win32FreeMemory(file_list->block); + file_list->block = 0; + file_list->block_size = 0; } } @@ -812,6 +814,7 @@ Sys_Launch_Coroutine_Sig(system_launch_coroutine){ SwitchToFiber(fiber); if (c->done){ + DeleteFiber(fiber); Win32FreeCoroutine(c); coroutine = 0; } @@ -834,6 +837,7 @@ Sys_Resume_Coroutine_Sig(system_resume_coroutine){ SwitchToFiber(fiber); if (c->done){ + DeleteFiber(fiber); Win32FreeCoroutine(c); coroutine = 0; }