a3.4.4 with more bug fixes

master
Allen Webster 2016-02-28 22:35:19 -05:00
parent 8256016707
commit 40f097b896
7 changed files with 129 additions and 78 deletions

View File

@ -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){

View File

@ -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 "<somedir>/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");

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

78
4ed.cpp
View File

@ -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);
}

View File

@ -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;
}