From 0fe64471026b23e58bae578f750d4d4071ea0f1e Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Fri, 26 Feb 2016 12:40:51 -0500 Subject: [PATCH] commands run in coroutines --- 4coder_buffer_types.h | 118 ++++++- 4coder_custom.cpp | 84 +++-- 4coder_custom.h | 138 ++++---- 4coder_helper.h | 22 +- 4coder_string.h | 2 + 4ed.cpp | 137 ++++---- 4ed.h | 17 - 4ed_app_target.cpp | 4 +- 4ed_command.cpp | 6 +- 4ed_debug_view.cpp | 772 +++++++++++++++++++++--------------------- 4ed_file_view.cpp | 52 +-- 4ed_gui.cpp | 8 +- 4ed_layout.cpp | 8 - 4ed_system.h | 9 +- win32_4ed.cpp | 72 ++-- 15 files changed, 747 insertions(+), 702 deletions(-) diff --git a/4coder_buffer_types.h b/4coder_buffer_types.h index 43ea2dfc..e7893258 100644 --- a/4coder_buffer_types.h +++ b/4coder_buffer_types.h @@ -12,14 +12,25 @@ #ifndef FRED_BUFFER_TYPES_H #define FRED_BUFFER_TYPES_H -typedef union Range{ - struct{ - int min, max; - }; - struct{ - int start, end; - }; -} Range; +typedef unsigned char Code; + +typedef enum{ + MDFR_SHIFT_INDEX, + MDFR_CONTROL_INDEX, + MDFR_ALT_INDEX, + MDFR_CAPS_INDEX, + // always last + MDFR_INDEX_COUNT +} Key_Control; + +typedef struct Key_Event_Data{ + Code keycode; + Code character; + Code character_no_caps_lock; + + char modifiers[MDFR_INDEX_COUNT]; +} Key_Event_Data; + typedef struct Full_Cursor{ int pos; @@ -91,6 +102,97 @@ seek_line_char(int line, int character){ return(result); } + +typedef union Range{ + struct{ + int min, max; + }; + struct{ + int start, end; + }; +} Range; + +inline Range +make_range(int p1, int p2){ + Range range; + if (p1 < p2){ + range.min = p1; + range.max = p2; + } + else{ + range.max = p2; + range.min = p1; + } + return(range); +} + + +enum Dynamic_Type{ + dynamic_type_int, + dynamic_type_string, + // never below this + dynamic_type_count +}; + +struct Dynamic{ + int type; + union{ + struct{ + int str_len; + char *str_value; + }; + int int_value; + }; +}; + +inline Dynamic +dynamic_int(int x){ + Dynamic result; + result.type = dynamic_type_int; + result.int_value = x; + return result; +} + +inline Dynamic +dynamic_string(const char *string, int len){ + Dynamic result; + result.type = dynamic_type_string; + result.str_len = len; + result.str_value = (char*)(string); + return result; +} + +inline int +dynamic_to_int(Dynamic *dynamic){ + int result = 0; + if (dynamic->type == dynamic_type_int){ + result = dynamic->int_value; + } + return result; +} + +inline char* +dynamic_to_string(Dynamic *dynamic, int *len){ + char *result = 0; + if (dynamic->type == dynamic_type_string){ + result = dynamic->str_value; + *len = dynamic->str_len; + } + return result; +} + +inline int +dynamic_to_bool(Dynamic *dynamic){ + int result = 0; + if (dynamic->type == dynamic_type_int){ + result = (dynamic->int_value != 0); + } + else{ + result = 1; + } + return result; +} + #endif // BOTTOM diff --git a/4coder_custom.cpp b/4coder_custom.cpp index c01363a8..e92def68 100644 --- a/4coder_custom.cpp +++ b/4coder_custom.cpp @@ -85,14 +85,14 @@ CUSTOM_COMMAND_SIG(write_increment){ char text[] = "++"; int size = sizeof(text) - 1; Buffer_Summary buffer = app->get_active_buffer(app); - app->buffer_replace_range(app, &buffer, buffer.file_cursor_pos, buffer.file_cursor_pos, text, size); + app->buffer_replace_range(app, &buffer, buffer.buffer_cursor_pos, buffer.buffer_cursor_pos, text, size); } CUSTOM_COMMAND_SIG(write_decrement){ char text[] = "--"; int size = sizeof(text) - 1; Buffer_Summary buffer = app->get_active_buffer(app); - app->buffer_replace_range(app, &buffer, buffer.file_cursor_pos, buffer.file_cursor_pos, text, size); + app->buffer_replace_range(app, &buffer, buffer.buffer_cursor_pos, buffer.buffer_cursor_pos, text, size); } CUSTOM_COMMAND_SIG(open_long_braces){ @@ -103,12 +103,11 @@ CUSTOM_COMMAND_SIG(open_long_braces){ int pos; view = app->get_active_file_view(app); - buffer = app->get_buffer(app, view.file_id); + buffer = app->get_buffer(app, view.buffer_id); pos = view.cursor.pos; app->buffer_replace_range(app, &buffer, pos, pos, text, size); app->view_set_cursor(app, &view, seek_pos(pos + 2), 1); - app->view_set_mark(app, &view, seek_pos(pos + 4)); push_parameter(app, par_range_start, pos); push_parameter(app, par_range_end, pos + size); @@ -116,7 +115,27 @@ CUSTOM_COMMAND_SIG(open_long_braces){ exec_command(app, cmdid_auto_tab_range); } -CUSTOM_COMMAND_SIG(ifdef_off){ +CUSTOM_COMMAND_SIG(open_long_braces_semicolon){ + File_View_Summary view; + Buffer_Summary buffer; + char text[] = "{\n\n};"; + int size = sizeof(text) - 1; + int pos; + + view = app->get_active_file_view(app); + buffer = app->get_buffer(app, view.buffer_id); + + pos = view.cursor.pos; + app->buffer_replace_range(app, &buffer, pos, pos, text, size); + app->view_set_cursor(app, &view, seek_pos(pos + 2), 1); + + push_parameter(app, par_range_start, pos); + push_parameter(app, par_range_end, pos + size); + push_parameter(app, par_clear_blank_lines, 0); + exec_command(app, cmdid_auto_tab_range); +} + +CUSTOM_COMMAND_SIG(if0_off){ File_View_Summary view; Buffer_Summary buffer; @@ -164,7 +183,7 @@ CUSTOM_COMMAND_SIG(backspace_word){ app->refresh_file_view(app, &view); pos1 = view.cursor.pos; - buffer = app->get_buffer(app, view.file_id); + buffer = app->get_buffer(app, view.buffer_id); app->buffer_replace_range(app, &buffer, pos1, pos2, 0, 0); } @@ -182,7 +201,7 @@ CUSTOM_COMMAND_SIG(switch_to_compilation){ view = app->get_active_file_view(app); buffer = app->get_buffer_by_name(app, make_string(name, name_size)); - app->view_set_file(app, &view, buffer.file_id); + app->view_set_buffer(app, &view, buffer.buffer_id); } CUSTOM_COMMAND_SIG(move_up_10){ @@ -231,7 +250,7 @@ CUSTOM_COMMAND_SIG(switch_to_file_in_quotes){ view = app->get_active_file_view(app); if (view.exists){ - buffer = app->get_buffer(app, view.file_id); + buffer = app->get_buffer(app, view.buffer_id); if (buffer.ready){ pos = view.cursor.pos; app->buffer_seek_delimiter(app, &buffer, pos, '"', 1, &end); @@ -249,22 +268,37 @@ CUSTOM_COMMAND_SIG(switch_to_file_in_quotes){ copy(&file_name, make_string(buffer.file_name, buffer.file_name_len)); truncate_to_path_of_directory(&file_name); append(&file_name, make_string(short_file_name, size)); - - buffer = app->get_buffer_by_name(app, file_name); + exec_command(app, cmdid_change_active_panel); - view = app->get_active_file_view(app); - if (buffer.exists){ - app->view_set_file(app, &view, buffer.file_id); - } - else{ - push_parameter(app, par_name, expand_str(file_name)); - exec_command(app, cmdid_interactive_open); - } + push_parameter(app, par_name, expand_str(file_name)); + exec_command(app, cmdid_interactive_open); } } } } +CUSTOM_COMMAND_SIG(goto_line){ + User_Input in; + Query bar; + int line_number = 0; + + in = {}; + bar = app->create_query(app, make_lit_string("Line Number: "), QueryBar); + while (1){ + in = app->get_user_input(app, AbortOnEsc | AbortOnClick); + if (in.abort) break; + if (in.key.character >= '0' && in.key.character <= '9' || in.key.character == 0){ + app->update_query(app, &bar, in.key); + if (bar.complete) break; + } + } + app->close_query(app, &bar); + if (in.abort) return; + line_number = str_to_int(bar.string); + + active_view_to_line(app, line_number); +} + CUSTOM_COMMAND_SIG(open_in_other){ exec_command(app, cmdid_change_active_panel); exec_command(app, cmdid_interactive_open); @@ -432,7 +466,8 @@ extern "C" GET_BINDING_DATA(get_bindings){ bind(context, '=', MDFR_CTRL, write_increment); bind(context, '-', MDFR_CTRL, write_decrement); bind(context, '[', MDFR_CTRL, open_long_braces); - bind(context, 'i', MDFR_ALT, ifdef_off); + bind(context, '{', MDFR_CTRL, open_long_braces); + bind(context, 'i', MDFR_ALT, if0_off); bind(context, '1', MDFR_ALT, switch_to_file_in_quotes); end_map(context); @@ -440,10 +475,10 @@ extern "C" GET_BINDING_DATA(get_bindings){ begin_map(context, mapid_file); - // NOTE(allen|a3.1): Binding this essentially binds all key combos that + // NOTE(allen|a3.4.4): Binding this essentially binds all key combos that // would normally insert a character into a buffer. - // Or apply this rule (which always works): if the code for the key - // is not in the codes struct, it is a vanilla key. + // Or apply this rule: if the code for the key is not an enum value + // such as key_left or key_back then it is a vanilla key. // It is possible to override this binding for individual keys. bind_vanilla_keys(context, cmdid_write_character); @@ -477,9 +512,6 @@ extern "C" GET_BINDING_DATA(get_bindings){ bind(context, 'Z', MDFR_CTRL, cmdid_timeline_scrub); bind(context, 'z', MDFR_CTRL, cmdid_undo); bind(context, 'y', MDFR_CTRL, cmdid_redo); - bind(context, key_left, MDFR_ALT, cmdid_increase_rewind_speed); - bind(context, key_right, MDFR_ALT, cmdid_increase_fastforward_speed); - bind(context, key_down, MDFR_ALT, cmdid_stop_rewind_fastforward); bind(context, 'h', MDFR_CTRL, cmdid_history_backward); bind(context, 'H', MDFR_CTRL, cmdid_history_forward); bind(context, 'd', MDFR_CTRL, cmdid_delete_range); @@ -495,7 +527,7 @@ extern "C" GET_BINDING_DATA(get_bindings){ bind(context, 'f', MDFR_CTRL, cmdid_search); bind(context, 'r', MDFR_CTRL, cmdid_reverse_search); - bind(context, 'g', MDFR_CTRL, cmdid_goto_line); + bind(context, 'g', MDFR_CTRL, goto_line); bind(context, 'K', MDFR_CTRL, cmdid_kill_buffer); bind(context, 'O', MDFR_CTRL, cmdid_reopen); diff --git a/4coder_custom.h b/4coder_custom.h index 2566c63d..749dd997 100644 --- a/4coder_custom.h +++ b/4coder_custom.h @@ -7,8 +7,6 @@ #define MDFR_ALT 2 #define MDFR_SHIFT 4 -typedef unsigned char Code; - enum Command_ID{ cmdid_null, cmdid_write_character, @@ -27,7 +25,7 @@ enum Command_ID{ cmdid_search, cmdid_reverse_search, cmdid_word_complete, - cmdid_goto_line, + //cmdid_goto_line, cmdid_set_mark, cmdid_copy, cmdid_cut, @@ -37,9 +35,6 @@ enum Command_ID{ cmdid_timeline_scrub, cmdid_undo, cmdid_redo, - cmdid_increase_rewind_speed, - cmdid_increase_fastforward_speed, - cmdid_stop_rewind_fastforward, cmdid_history_backward, cmdid_history_forward, cmdid_interactive_new, @@ -108,79 +103,13 @@ enum Hook_ID{ hook_type_count }; -enum Dynamic_Type{ - dynamic_type_int, - dynamic_type_string, - // never below this - dynamic_type_count -}; - -struct Dynamic{ - int type; - union{ - struct{ - int str_len; - char *str_value; - }; - int int_value; - }; -}; - -inline Dynamic -dynamic_int(int x){ - Dynamic result; - result.type = dynamic_type_int; - result.int_value = x; - return result; -} - -inline Dynamic -dynamic_string(const char *string, int len){ - Dynamic result; - result.type = dynamic_type_string; - result.str_len = len; - result.str_value = (char*)(string); - return result; -} - -inline int -dynamic_to_int(Dynamic *dynamic){ - int result = 0; - if (dynamic->type == dynamic_type_int){ - result = dynamic->int_value; - } - return result; -} - -inline char* -dynamic_to_string(Dynamic *dynamic, int *len){ - char *result = 0; - if (dynamic->type == dynamic_type_string){ - result = dynamic->str_value; - *len = dynamic->str_len; - } - return result; -} - -inline int -dynamic_to_bool(Dynamic *dynamic){ - int result = 0; - if (dynamic->type == dynamic_type_int){ - result = (dynamic->int_value != 0); - } - else{ - result = 1; - } - return result; -} - // NOTE(allen): None of the members of *_Summary structs nor any of the // data pointed to by the members should be modified, I would have made // them all const... but that causes a lot problems for C++ reasons. struct Buffer_Summary{ int exists; int ready; - int file_id; + int buffer_id; int size; @@ -189,7 +118,7 @@ struct Buffer_Summary{ char *file_name; char *buffer_name; - int file_cursor_pos; + int buffer_cursor_pos; int is_lexed; int map_id; }; @@ -197,7 +126,7 @@ struct Buffer_Summary{ struct File_View_Summary{ int exists; int view_id; - int file_id; + int buffer_id; Full_Cursor cursor; Full_Cursor mark; @@ -206,6 +135,19 @@ struct File_View_Summary{ int unwrapped_lines; }; +struct User_Input{ + Key_Event_Data key; + int abort; +}; + +struct Query{ + int query_id; + int complete; + int type; + String prompt; + String string; +}; + #ifndef FRED_STRING_STRUCT #define FRED_STRING_STRUCT struct String{ @@ -249,7 +191,7 @@ struct Application_Links; #define BUFFER_SEEK_DELIMITER_SIG(name) int name(Application_Links *context, Buffer_Summary *buffer, int start, char delim, int seek_forward, int *out) #define BUFFER_READ_RANGE_SIG(name) int name(Application_Links *context, Buffer_Summary *buffer, int start, int end, char *out) #define BUFFER_REPLACE_RANGE_SIG(name) int name(Application_Links *context, Buffer_Summary *buffer, int start, int end, char *str, int len) -// TODO(allen): buffer save +#define BUFFER_SAVE_SIG(name) int name(Application_Links *context, Buffer_Summary *buffer, char *filename, int len) // File view manipulation #define GET_VIEW_MAX_INDEX_SIG(name) int name(Application_Links *context) @@ -259,7 +201,23 @@ struct Application_Links; #define REFRESH_FILE_VIEW_SIG(name) int name(Application_Links *context, File_View_Summary *view) #define VIEW_SET_CURSOR_SIG(name) int name(Application_Links *context, File_View_Summary *view, Buffer_Seek seek, int set_preferred_x) #define VIEW_SET_MARK_SIG(name) int name(Application_Links *context, File_View_Summary *view, Buffer_Seek seek) -#define VIEW_SET_FILE_SIG(name) int name(Application_Links *context, File_View_Summary *view, int file_id) +#define VIEW_SET_BUFFER_SIG(name) int name(Application_Links *context, File_View_Summary *view, int buffer_id) + +// Directly get user input +#define AbortOnEsc 0x1 +#define AbortOnClick 0x2 +#define GET_USER_INPUT_SIG(name) User_Input name(Application_Links *context, unsigned int flags) + +// Queries +#define QueryForFile 0x1 +#define QueryForBuffer 0x2 + +#define QueryBar 0x0 +#define QueryScreen 0x010000 + +#define CREATE_QUERY_SIG(name) Query name(Application_Links *context, String prompt, unsigned int flags) +#define UPDATE_QUERY_SIG(name) void name(Application_Links *context, Query *query, Key_Event_Data key) +#define CLOSE_QUERY_SIG(name) void name(Application_Links *context, Query *query) extern "C"{ // Command exectuion @@ -283,6 +241,7 @@ extern "C"{ typedef BUFFER_SEEK_DELIMITER_SIG(Buffer_Seek_Delimiter_Function); typedef BUFFER_READ_RANGE_SIG(Buffer_Read_Range_Function); typedef BUFFER_REPLACE_RANGE_SIG(Buffer_Replace_Range_Function); + typedef BUFFER_SAVE_SIG(Buffer_Save_Function); // View manipulation typedef GET_VIEW_MAX_INDEX_SIG(Get_View_Max_Index_Function); @@ -292,10 +251,21 @@ extern "C"{ typedef REFRESH_FILE_VIEW_SIG(Refresh_File_View_Function); typedef VIEW_SET_CURSOR_SIG(View_Set_Cursor_Function); typedef VIEW_SET_MARK_SIG(View_Set_Mark_Function); - typedef VIEW_SET_FILE_SIG(View_Set_File_Function); + typedef VIEW_SET_BUFFER_SIG(View_Set_Buffer_Function); + + // Directly get user input + typedef GET_USER_INPUT_SIG(Get_User_Input_Function); + + // Queries + typedef CREATE_QUERY_SIG(Create_Query_Function); + typedef UPDATE_QUERY_SIG(Update_Query_Function); + typedef CLOSE_QUERY_SIG(Close_Query_Function); } struct Application_Links{ + // Application data ptr + void *data; + // Command exectuion Exec_Command_Function *exec_command_keep_stack; Push_Parameter_Function *push_parameter; @@ -317,6 +287,7 @@ struct Application_Links{ Buffer_Seek_Delimiter_Function *buffer_seek_delimiter; Buffer_Read_Range_Function *buffer_read_range; Buffer_Replace_Range_Function *buffer_replace_range; + Buffer_Save_Function *buffer_save; // View manipulation Get_View_Max_Index_Function *get_view_max_index; @@ -326,10 +297,15 @@ struct Application_Links{ Refresh_File_View_Function *refresh_file_view; View_Set_Cursor_Function *view_set_cursor; View_Set_Mark_Function *view_set_mark; - View_Set_File_Function *view_set_file; + View_Set_Buffer_Function *view_set_buffer; - // Application data ptr - void *data; + // Directly get user input + Get_User_Input_Function* get_user_input; + + // Queries + Create_Query_Function* create_query; + Update_Query_Function* update_query; + Close_Query_Function* close_query; }; struct Custom_API{ diff --git a/4coder_helper.h b/4coder_helper.h index 100d97cd..6a677978 100644 --- a/4coder_helper.h +++ b/4coder_helper.h @@ -213,19 +213,10 @@ push_directory(Application_Links *app){ return(result); } -#define expand_string(d) ((d).str), ((d).size) - inline Range get_range(File_View_Summary *view){ Range range; - if (view->cursor.pos < view->mark.pos){ - range.min = view->cursor.pos; - range.max = view->mark.pos; - } - else{ - range.max = view->cursor.pos; - range.min = view->mark.pos; - } + range = make_range(view->cursor.pos, view->mark.pos); return(range); } @@ -241,3 +232,14 @@ exec_command(Application_Links *app, Custom_Command_Function *func){ app->clear_parameters(app); } +inline void +active_view_to_line(Application_Links *app, int line_number){ + File_View_Summary view; + 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. + app->view_set_cursor(app, &view, seek_line_char(line_number, 0), 1); +} + diff --git a/4coder_string.h b/4coder_string.h index 28db3936..f2724562 100644 --- a/4coder_string.h +++ b/4coder_string.h @@ -22,6 +22,8 @@ NOTES ON USE: // TODO(allen): // - comments // - memcpy / memmove replacements (different file for optimization options?) +// - examples and docs +// - finish a full set of tools for file name handling // #include "4coder_config.h" diff --git a/4ed.cpp b/4ed.cpp index 69f09bab..f9735a59 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -81,6 +81,7 @@ struct App_Vars{ i32 *map_id_table; i32 user_map_count; Command_Binding prev_command; + Coroutine *command_coroutine; Sys_App_Binding *sys_app_bindings; i32 sys_app_count, sys_app_max; @@ -381,50 +382,43 @@ COMMAND_DECL(seek_white_or_token_left){ } COMMAND_DECL(seek_alphanumeric_right){ -#if BUFFER_EXPERIMENT_SCALPEL <= 3 ProfileMomentFunction(); REQ_FILE_VIEW(view); REQ_FILE(file, view); i32 pos = buffer_seek_alphanumeric_right(&file->state.buffer, view->cursor.pos); view_cursor_move(view, pos); -#endif } COMMAND_DECL(seek_alphanumeric_left){ -#if BUFFER_EXPERIMENT_SCALPEL <= 3 ProfileMomentFunction(); REQ_FILE_VIEW(view); REQ_FILE(file, view); i32 pos = buffer_seek_alphanumeric_left(&file->state.buffer, view->cursor.pos); view_cursor_move(view, pos); -#endif } COMMAND_DECL(seek_alphanumeric_or_camel_right){ -#if BUFFER_EXPERIMENT_SCALPEL <= 3 ProfileMomentFunction(); REQ_FILE_VIEW(view); REQ_FILE(file, view); i32 pos = buffer_seek_alphanumeric_or_camel_right(&file->state.buffer, view->cursor.pos); view_cursor_move(view, pos); -#endif } COMMAND_DECL(seek_alphanumeric_or_camel_left){ -#if BUFFER_EXPERIMENT_SCALPEL <= 3 ProfileMomentFunction(); REQ_FILE_VIEW(view); REQ_FILE(file, view); i32 pos = buffer_seek_alphanumeric_or_camel_left(&file->state.buffer, view->cursor.pos); view_cursor_move(view, pos); -#endif } COMMAND_DECL(search){ +#if 0 ProfileMomentFunction(); REQ_FILE_VIEW(view); REQ_FILE(fixed, view); @@ -434,9 +428,11 @@ COMMAND_DECL(search){ view->isearch.str = vars->mini_str; view->isearch.reverse = 0; view->isearch.pos = view->cursor.pos - 1; +#endif } COMMAND_DECL(reverse_search){ +#if 0 ProfileMomentFunction(); REQ_FILE_VIEW(view); REQ_FILE(fixed, view); @@ -446,6 +442,7 @@ COMMAND_DECL(reverse_search){ view->isearch.str = vars->mini_str; view->isearch.reverse = 1; view->isearch.pos = view->cursor.pos + 1; +#endif } COMMAND_DECL(word_complete){ @@ -515,7 +512,6 @@ COMMAND_DECL(word_complete){ } } } - // TODO(allen): figure out how labels are scoped. double_break:; size = word_end - word_start; @@ -604,18 +600,6 @@ COMMAND_DECL(word_complete){ } } -COMMAND_DECL(goto_line){ - ProfileMomentFunction(); - REQ_FILE_VIEW(view); - REQ_FILE(fixed, view); - USE_VARS(vars); - - view_set_widget(view, FWIDG_GOTO_LINE); - view->isearch.str = vars->mini_str; - view->isearch.reverse = 1; - view->isearch.pos = view->cursor.pos; -} - COMMAND_DECL(set_mark){ ProfileMomentFunction(); REQ_FILE_VIEW(view); @@ -652,7 +636,7 @@ COMMAND_DECL(copy){ } } - Range range = get_range(view->cursor.pos, view->mark); + Range range = make_range(view->cursor.pos, view->mark); if (start_set) range.start = r_start; if (end_set) range.end = r_end; if (range.start < range.end){ @@ -689,7 +673,7 @@ COMMAND_DECL(cut){ } } - Range range = get_range(view->cursor.pos, view->mark); + Range range = make_range(view->cursor.pos, view->mark); if (start_set) range.start = r_start; if (end_set) range.end = r_end; if (range.start < range.end){ @@ -754,7 +738,7 @@ COMMAND_DECL(paste_next){ if (working_set->clipboard_size > 0 && view->mode.rewrite){ view->next_mode.rewrite = 1; - Range range = get_range(view->mark, view->cursor.pos); + Range range = make_range(view->mark, view->cursor.pos); String *src = working_set_clipboard_roll_down(working_set); i32 next_cursor_pos = range.start+src->size; view_replace_range(system, @@ -789,7 +773,7 @@ COMMAND_DECL(delete_range){ USE_LAYOUT(layout); USE_MEM(mem); - Range range = get_range(view->cursor.pos, view->mark); + Range range = make_range(view->cursor.pos, view->mark); if (range.start < range.end){ i32 next_cursor_pos = range.start; view_replace_range(system, mem, view, layout, range.start, range.end, @@ -829,42 +813,6 @@ COMMAND_DECL(redo){ view_redo(system, mem, layout, view); } -COMMAND_DECL(increase_rewind_speed){ - ProfileMomentFunction(); - REQ_FILE_VIEW(view); - REQ_FILE_HISTORY(file, view); - - i32 rewind_speed = ROUND32(view->rewind_speed * 4.f); - if (rewind_speed > 1) rewind_speed >>= 1; - else if (rewind_speed == 1) rewind_speed = 0; - else if (rewind_speed == 0) rewind_speed = -1; - else rewind_speed *= 2; - - view->rewind_speed = rewind_speed * 0.25f; -} - -COMMAND_DECL(increase_fastforward_speed){ - ProfileMomentFunction(); - REQ_FILE_VIEW(view); - REQ_FILE_HISTORY(file, view); - - i32 neg_rewind_speed = -ROUND32(view->rewind_speed * 4.f); - if (neg_rewind_speed > 1) neg_rewind_speed >>= 1; - else if (neg_rewind_speed == 1) neg_rewind_speed = 0; - else if (neg_rewind_speed == 0) neg_rewind_speed = -1; - else neg_rewind_speed *= 2; - - view->rewind_speed = -neg_rewind_speed * 0.25f; -} - -COMMAND_DECL(stop_rewind_fastforward){ - ProfileMomentFunction(); - REQ_FILE_VIEW(view); - REQ_FILE_HISTORY(file, view); - - view->rewind_speed = 0; -} - COMMAND_DECL(history_backward){ ProfileMomentFunction(); REQ_FILE_VIEW(view); @@ -1233,7 +1181,7 @@ case_change_range(System_Functions *system, Mem_Options *mem, File_View *view, Editing_File *file, u8 a, u8 z, u8 char_delta){ #if BUFFER_EXPERIMENT_SCALPEL <= 0 - Range range = get_range(view->cursor.pos, view->mark); + Range range = make_range(view->cursor.pos, view->mark); if (range.start < range.end){ Edit_Step step = {}; step.type = ED_NORMAL; @@ -1337,7 +1285,7 @@ COMMAND_DECL(auto_tab_range){ } if (file->state.token_stack.tokens && file->state.tokens_complete){ - Range range = get_range(view->cursor.pos, view->mark); + Range range = make_range(view->cursor.pos, view->mark); if (start_set) range.start = r_start; if (end_set) range.end = r_end; view_auto_tab_tokens(system, mem, view, layout, range.start, range.end, clear_blank_lines); @@ -2040,9 +1988,9 @@ fill_buffer_summary(Buffer_Summary *buffer, Editing_File *file, Working_Set *wor buffer->exists = 1; buffer->ready = file_is_ready(file); buffer->is_lexed = file->settings.tokens_exist; - buffer->file_id = (int)(file - working_set->files); + buffer->buffer_id = (int)(file - working_set->files); buffer->size = file->state.buffer.size; - buffer->file_cursor_pos = file->state.cursor_pos; + buffer->buffer_cursor_pos = file->state.cursor_pos; buffer->file_name_len = file->name.source_path.size; buffer->buffer_name_len = file->name.live_name.size; @@ -2057,7 +2005,7 @@ fill_view_summary(File_View_Summary *view, File_View *file_view, Live_Views *liv view->exists = 1; view->view_id = (int)((char*)file_view - (char*)live_set->views) / live_set->stride; if (file_view->file){ - view->file_id = (int)(file_view->file - working_set->files); + view->buffer_id = (int)(file_view->file - working_set->files); view->mark = view_compute_cursor_from_pos(file_view, file_view->mark); view->cursor = file_view->cursor; view->preferred_x = file_view->preferred_x; @@ -2181,7 +2129,7 @@ extern "C"{ REFRESH_BUFFER_SIG(external_refresh_buffer){ int result; - *buffer = external_get_buffer(context, buffer->file_id); + *buffer = external_get_buffer(context, buffer->buffer_id); result = buffer->exists; return(result); } @@ -2195,7 +2143,7 @@ extern "C"{ if (buffer->exists){ working_set = cmd->working_set; - file = working_set->files + buffer->file_id; + file = working_set->files + buffer->buffer_id; if (!file->state.is_dummy && file_is_ready(file)){ size = buffer_size(&file->state.buffer); if (start < size){ @@ -2225,7 +2173,7 @@ extern "C"{ if (buffer->exists){ working_set = cmd->working_set; - file = working_set->files + buffer->file_id; + file = working_set->files + buffer->buffer_id; if (!file->state.is_dummy && file_is_ready(file)){ size = buffer_size(&file->state.buffer); if (0 <= start && start <= end && end <= size){ @@ -2254,7 +2202,7 @@ extern "C"{ if (buffer->exists){ working_set = cmd->working_set; - file = working_set->files + buffer->file_id; + file = working_set->files + buffer->buffer_id; if (!file->state.is_dummy && file_is_ready(file)){ size = buffer_size(&file->state.buffer); if (0 <= start && start <= end && end <= size){ @@ -2377,7 +2325,7 @@ extern "C"{ return(result); } - VIEW_SET_FILE_SIG(external_view_set_file){ + VIEW_SET_BUFFER_SIG(external_view_set_buffer){ Command_Data *cmd = (Command_Data*)context->data; Live_Views *live_set; View *vptr; @@ -2393,8 +2341,8 @@ extern "C"{ if (file_view){ working_set = cmd->working_set; max = working_set->file_index_count; - if (file_id >= 0 && file_id < max){ - file = working_set->files + file_id; + if (buffer_id >= 0 && buffer_id < max){ + file = working_set->files + buffer_id; if (!file->state.is_dummy){ view_set_file(cmd->system, file_view, file, cmd->vars->font_set, cmd->style, cmd->vars->hooks[hook_open_file], cmd, &app_links); @@ -2409,7 +2357,18 @@ extern "C"{ } } -inline void +struct Command_In{ + Command_Data *cmd; + Command_Binding bind; +}; + +internal void +command_caller(Coroutine *coroutine){ + Command_In *cmd = (Command_In*)coroutine->in; + cmd->bind.function(cmd->cmd->system, cmd->cmd, cmd->bind); +} + +internal void app_links_init(System_Functions *system){ app_links.exec_command_keep_stack = external_exec_command_keep_stack; app_links.push_parameter = external_push_parameter; @@ -2429,6 +2388,7 @@ app_links_init(System_Functions *system){ app_links.buffer_seek_delimiter = external_buffer_seek_delimiter; app_links.buffer_read_range = external_buffer_read_range; app_links.buffer_replace_range = external_buffer_replace_range; + app_links.buffer_save = 0;//external_buffer_save; app_links.get_view_max_index = external_get_view_max_index; app_links.get_file_view = external_get_file_view; @@ -2437,7 +2397,13 @@ app_links_init(System_Functions *system){ app_links.refresh_file_view = external_refresh_file_view; app_links.view_set_cursor = external_view_set_cursor; app_links.view_set_mark = external_view_set_mark; - app_links.view_set_file = external_view_set_file; + app_links.view_set_buffer = external_view_set_buffer; + + app_links.get_user_input = 0;//external_get_user_input; + + app_links.create_query = 0;//external_create_query; + app_links.update_query = 0;//external_update_query; + app_links.close_query = 0;//external_close_query; } #if FRED_INTERNAL @@ -2502,7 +2468,6 @@ setup_command_table(){ SET(search); SET(reverse_search); SET(word_complete); - SET(goto_line); SET(set_mark); SET(copy); SET(cut); @@ -2512,9 +2477,6 @@ setup_command_table(){ SET(timeline_scrub); SET(undo); SET(redo); - SET(increase_rewind_speed); - SET(increase_fastforward_speed); - SET(stop_rewind_fastforward); SET(history_backward); SET(history_forward); SET(interactive_new); @@ -3705,6 +3667,22 @@ App_Step_Sig(app_step){ switch (vars->state){ case APP_STATE_EDIT: { + if (cmd_bind.function){ + Command_In cmd_in; + cmd_in.cmd = cmd; + cmd_in.bind = cmd_bind; + vars->command_coroutine = system->launch_coroutine(command_caller, &cmd_in, 0); + app_result.redraw = 1; + } + +#if 0 + if (cmd_bind.function){ + cmd_bind.function(system, cmd, cmd_bind); + app_result.redraw = 1; + } +#endif + +#if 0 Handle_Command_Function *handle_command = 0; if (view) handle_command = view->handle_command; if (handle_command){ @@ -3718,6 +3696,7 @@ App_Step_Sig(app_step){ } } vars->prev_command = cmd_bind; +#endif }break; case APP_STATE_RESIZING: diff --git a/4ed.h b/4ed.h index 4d96a602..9da3fff1 100644 --- a/4ed.h +++ b/4ed.h @@ -22,23 +22,6 @@ struct Application_Memory{ #define KEY_INPUT_BUFFER_SIZE 4 #define KEY_INPUT_BUFFER_DSIZE (KEY_INPUT_BUFFER_SIZE << 1) -enum Key_Control{ - CONTROL_KEY_SHIFT, - CONTROL_KEY_CONTROL, - CONTROL_KEY_ALT, - CONTROL_KEY_CAPS, - // always last - CONTROL_KEY_COUNT -}; - -struct Key_Event_Data{ - u8 keycode; - u8 character; - u8 character_no_caps_lock; - - b8 modifiers[CONTROL_KEY_COUNT]; -}; - struct Key_Input_Data{ Key_Event_Data press[KEY_INPUT_BUFFER_SIZE]; Key_Event_Data hold[KEY_INPUT_BUFFER_SIZE]; diff --git a/4ed_app_target.cpp b/4ed_app_target.cpp index ffbb0810..4997fc94 100644 --- a/4ed_app_target.cpp +++ b/4ed_app_target.cpp @@ -8,8 +8,8 @@ */ // TOP - -#define VERSION_NUMBER "alpha 3.4.3" + +#define VERSION_NUMBER "alpha 3.4.4" #ifdef FRED_SUPER #define VERSION_TYPE " super!" diff --git a/4ed_command.cpp b/4ed_command.cpp index c53084da..1be1e71b 100644 --- a/4ed_command.cpp +++ b/4ed_command.cpp @@ -129,9 +129,9 @@ internal Command_Binding map_extract(Command_Map *map, Key_Event_Data key){ Command_Binding bind = {}; - b32 ctrl = key.modifiers[CONTROL_KEY_CONTROL]; - b32 alt = key.modifiers[CONTROL_KEY_ALT]; - b32 shift = key.modifiers[CONTROL_KEY_SHIFT]; + b32 ctrl = key.modifiers[MDFR_CONTROL_INDEX]; + b32 alt = key.modifiers[MDFR_ALT_INDEX]; + b32 shift = key.modifiers[MDFR_SHIFT_INDEX]; u16 code; u8 command = MDFR_NONE; diff --git a/4ed_debug_view.cpp b/4ed_debug_view.cpp index 558a9c27..1ae49a8e 100644 --- a/4ed_debug_view.cpp +++ b/4ed_debug_view.cpp @@ -1,386 +1,386 @@ -/* - * Mr. 4th Dimention - Allen Webster - * - * 13.09.2015 - * - * Internal debug view for 4coder - * - */ - -// TOP -#if FRED_INTERNAL - -enum Debug_Mode{ - DBG_MEMORY, - DBG_OS_EVENTS -}; - -struct Dbg_Past_Key{ - Key_Event_Data key; - i32 frame_index; - bool8 modifiers[3]; -}; - -struct Debug_View{ - View view_base; - i16 font_id; - Debug_Mode mode; - Dbg_Past_Key past_keys[32]; - i32 past_key_count, past_key_pos; - i16 prev_mouse_wheel; -}; - -inline Debug_View* -view_to_debug_view(View *view){ - Assert(!view || view->type == VIEW_TYPE_DEBUG); - return (Debug_View*)view; -} - -internal i32 -draw_general_memory(Debug_View *view, i32_Rect rect, Render_Target *target, i32 y){ - i16 font_id = view->font_id; - i32 y_advance = get_font_info(&target->font_set, font_id)->height; - Bubble *sentinel = &view->view_base.mem->general.sentinel; - - for (Bubble *bubble = sentinel->next; - bubble != sentinel; - bubble = bubble->next){ - bool32 used = (bubble->flags & MEM_BUBBLE_USED) != 0; - u32 color; - if (used) color = 0xFFFFFFFF; - else color = 0xFF00FFFF; - - char str[256]; - String s = make_fixed_width_string(str); - if (used){ - switch (bubble->type){ - case BUBBLE_BUFFER: append(&s, "buffer "); break; - case BUBBLE_STARTS: append(&s, "starts "); break; - case BUBBLE_WIDTHS: append(&s, "widths "); break; - case BUBBLE_WRAPS: append(&s, "wraps "); break; - case BUBBLE_TOKENS: append(&s, "tokens "); break; - case BUBBLE_UNDO_STRING: append(&s, "undo string "); break; - case BUBBLE_UNDO: append(&s, "undo "); break; - default: append(&s, "unknown "); break; - } - } - else{ - append(&s, "unused "); - } - append_int_to_str(bubble->size, &s); - terminate_with_null(&s); - - draw_string(target, font_id, str, rect.x0, y, color); - y += y_advance; - - Bubble *next = bubble->next; - if (next != sentinel){ - u8 *end_ptr = (u8*)(bubble + 1) + bubble->size; - u8 *next_ptr = (u8*)(next); - if (end_ptr != next_ptr){ - color = 0xFFFF0000; - s = make_fixed_width_string(str); - append(&s, "discontinuity"); - terminate_with_null(&s); - - draw_string(target, font_id, str, rect.x0, y, color); - y += y_advance; - } - } - } - - return y; -} - -internal i32 -draw_system_memory(System_Functions *system, Debug_View *view, i32_Rect rect, - Render_Target *target, i32 y){ - i16 font_id = view->font_id; - i32 y_advance = get_font_info(&target->font_set, font_id)->height; - Bubble *sentinel = system->internal_sentinel(); - - for (Bubble *bubble = sentinel->next; - bubble != sentinel; - bubble = bubble->next){ - Sys_Bubble *sysb = (Sys_Bubble*)bubble; - u32 color = 0xFFFFFFFF; - - char str[256]; - String s = make_fixed_width_string(str); - - append(&s, sysb->file_name); - append(&s, " "); - append_int_to_str(sysb->line_number, &s); - append(&s, " "); - append_int_to_str(bubble->size, &s); - terminate_with_null(&s); - - draw_string(target, font_id, str, rect.x0, y, color); - - y += y_advance; - } - - return y; -} - -internal void -draw_background_threads(System_Functions *system, - Debug_View *view, i32_Rect rect, Render_Target *target){ - i32 pending; - bool8 running[4]; - system->internal_get_thread_states(BACKGROUND_THREADS, running, &pending); - - i32 box_size = 30; - - i32_Rect trect; - trect.x0 = rect.x1 - box_size; - trect.y0 = rect.y0; - trect.x1 = rect.x1; - trect.y1 = rect.y0 + box_size; - - u32 light = 0xFF606060; - for (i32 i = 0; i < 4; ++i){ - u32 color; - if (running[i]) color = 0xFF9090FF; - else color = 0xFF101010; - draw_rectangle(target, trect, color); - draw_rectangle_outline(target, trect, light); - trect.x0 -= box_size; - trect.x1 -= box_size; - } - - char str[256]; - String s = make_fixed_width_string(str); - append_int_to_str(pending, &s); - terminate_with_null(&s); - draw_string(target, view->font_id, str, trect.x1, trect.y1, light); -} - -struct Dbg_Modifier{ - char *name; - u8 modifier; -}; -internal void -draw_modifiers(Debug_View *view, Render_Target *target, - bool8 *modifiers, u32 on_color, u32 off_color, i32 *x, i32 y){ - persist Dbg_Modifier dm[] = { - {"CTRL", CONTROL_KEY_CONTROL}, - {"ALT", CONTROL_KEY_ALT}, - {"SHIFT", CONTROL_KEY_SHIFT} - }; - for (i32 i = 0; i < CONTROL_KEY_COUNT; ++i){ - Dbg_Modifier m = dm[i]; - u32 color; - - if (modifiers[m.modifier]) color = on_color; - else color = off_color; - - *x = draw_string(target, view->font_id, m.name, *x, y, color); - *x += 5; - } -} - -internal i32 -draw_key_event(Debug_View *view, Render_Target *target, - Dbg_Past_Key *key, i32 x, i32 y, u32 on_color, u32 off_color){ - draw_modifiers(view, target, key->modifiers, - on_color, off_color, &x, y); - - i16 font_id = view->font_id; - Render_Font *font = get_font_info(&target->font_set, font_id)->font; - - if (font && font->glyphs[key->key.character].exists){ - char c[2]; - c[0] = (char)key->key.character; - c[1] = 0; - x = draw_string(target, font_id, c, x, y, on_color); - } - else{ - char c[10] = {}; - String str = make_fixed_width_string(c); - append(&str, "\\"); - append_int_to_str(key->key.keycode, &str); - terminate_with_null(&str); - x = draw_string(target, font_id, c, x, y, on_color); - } - - return x; -} - -internal void -draw_os_events(Debug_View *view, i32_Rect rect, Render_Target *target, - Input_Summary *active_input){ - persist i32 max_past = ArrayCount(view->past_keys); - - i32 x, y, max_x, max_y; - x = rect.x0; - y = rect.y0; - - i16 font_id = view->font_id; - i32 line_height = get_font_info(&target->font_set, font_id)->height; - -#if 0 - draw_modifiers(view, target, active_input->keys.modifiers, - 0xFFFFFFFF, 0xFF444444, &x, y); -#endif - - max_x = x; - x = rect.x0; - y += line_height; - - for (i32 j = 0; j < view->past_key_count; ++j){ - Dbg_Past_Key *key = view->past_keys + j; - u32 on_color, off_color; - - switch ((view->past_key_pos - j - 1 + max_past*2) % max_past){ - case 0: on_color = 0xFFAAAAFF; off_color = 0xFF505088; break; - case 1: on_color = 0xFF9999CC; off_color = 0xFF404077; break; - case 2: on_color = 0xFF8888AA; off_color = 0xFF303066; break; - default: on_color = 0xFF888888; off_color = 0xFF303030; break; - } - - x = draw_key_event(view, target, key, x, y, on_color, off_color); - - if (max_x < x) max_x = x; - x = rect.x0; - y += line_height; - } - - i32_Rect mrect = rect; - mrect.x0 = max_x + 1; - - max_y = y; - x = mrect.x0; - y = mrect.y0; - - { - u32 color; - if (active_input->mouse.out_of_window){ - color = 0xFFFF0000; - draw_string(target, font_id, "OUT", x, y, color); - } - else{ - color = 0xFF008800; - draw_string(target, font_id, "IN", x, y, color); - } - y += line_height; - - char c[16]; - String s = make_fixed_width_string(c); - append_int_to_str(active_input->mouse.mx, &s); - append(&s, ", "); - append_int_to_str(active_input->mouse.my, &s); - terminate_with_null(&s); - draw_string(target, font_id, c, x, y, color); - y += line_height; - - u32 btn_color; - if (active_input->mouse.l) btn_color = color; - else btn_color = 0xFF444444; - x = draw_string(target, font_id, "L ", x, y, btn_color); - - if (active_input->mouse.r) btn_color = color; - else btn_color = 0xFF444444; - x = draw_string(target, font_id, "R", x, y, btn_color); - - x = mrect.x0; - y += line_height; - - s = make_fixed_width_string(c); - append_int_to_str(view->prev_mouse_wheel, &s); - terminate_with_null(&s); - - if (active_input->mouse.wheel_used) btn_color = color; - else btn_color = 0xFF444444; - draw_string(target, font_id, c, x, y, btn_color); - - y += line_height; - } -} - -internal i32 -draw_debug_view(System_Functions *system, - Debug_View *view, i32_Rect rect, Render_Target *target, - Input_Summary *active_input){ - i32 result = 0; - - draw_rectangle(target, rect, 0xFF000000); - - switch (view->mode){ - case DBG_MEMORY: - { - i32 y = rect.y0; - y = draw_general_memory(view, rect, target, y); - draw_rectangle(target, i32R(rect.x0, y, rect.x1, y+2), 0xFF222222); - y += 2; - y = draw_system_memory(system, view, rect, target, y); - }break; - case DBG_OS_EVENTS: - { - draw_os_events(view, rect, target, active_input); - }break; - } - return result; -} - -internal void -step_debug_view(Debug_View *view, i32_Rect rect, Render_Target *target, - Input_Summary *active_input){ - persist i32 max_past = ArrayCount(view->past_keys); - -#if 0 - b8 *modifiers = active_input->keys.modifiers; - for (i32 i = 0; i < active_input->keys.count; ++i){ - Dbg_Past_Key *past_key = view->past_keys + view->past_key_pos; - ++view->past_key_pos; - view->past_key_pos = view->past_key_pos % max_past; - - past_key->key = active_input->keys.keys[i]; - past_key->modifiers[0] = modifiers[0]; - past_key->modifiers[1] = modifiers[1]; - past_key->modifiers[2] = modifiers[2]; - -#if 0 - i32 this_index = view->past_key_pos; - past_key->frame_index = INTERNAL_frame_index; - if (profile_frame.first_key == -1){ - profile_frame.first_key = this_index; - } -#endif - past_key->frame_index = -1; - - if (view->past_key_count < max_past) ++view->past_key_count; - } - - if (active_input->mouse.wheel_used) - view->prev_mouse_wheel = active_input->mouse.wheel_amount; -#endif -} - -internal -Do_View_Sig(do_debug_view){ - view->mouse_cursor_type = APP_MOUSE_CURSOR_ARROW; - Debug_View *debug_view = (Debug_View*)view; - i32 result = 0; - - switch (message){ - case VMSG_RESIZE: break; - case VMSG_STYLE_CHANGE: break; - case VMSG_STEP: step_debug_view(debug_view, rect, target, active_input); result = 1; break; - case VMSG_DRAW: draw_debug_view(system, debug_view, rect, target, active_input); break; - case VMSG_FREE: break; - } - - return result; -} - -internal Debug_View* -debug_view_init(View *view){ - Debug_View *result = (Debug_View*)view; - view->type = VIEW_TYPE_DEBUG; - view->do_view = do_debug_view; - return result; -} - -#endif -// BOTTOM +/* + * Mr. 4th Dimention - Allen Webster + * + * 13.09.2015 + * + * Internal debug view for 4coder + * + */ + +// TOP +#if FRED_INTERNAL + +enum Debug_Mode{ + DBG_MEMORY, + DBG_OS_EVENTS +}; + +struct Dbg_Past_Key{ + Key_Event_Data key; + i32 frame_index; + bool8 modifiers[3]; +}; + +struct Debug_View{ + View view_base; + i16 font_id; + Debug_Mode mode; + Dbg_Past_Key past_keys[32]; + i32 past_key_count, past_key_pos; + i16 prev_mouse_wheel; +}; + +inline Debug_View* +view_to_debug_view(View *view){ + Assert(!view || view->type == VIEW_TYPE_DEBUG); + return (Debug_View*)view; +} + +internal i32 +draw_general_memory(Debug_View *view, i32_Rect rect, Render_Target *target, i32 y){ + i16 font_id = view->font_id; + i32 y_advance = get_font_info(&target->font_set, font_id)->height; + Bubble *sentinel = &view->view_base.mem->general.sentinel; + + for (Bubble *bubble = sentinel->next; + bubble != sentinel; + bubble = bubble->next){ + bool32 used = (bubble->flags & MEM_BUBBLE_USED) != 0; + u32 color; + if (used) color = 0xFFFFFFFF; + else color = 0xFF00FFFF; + + char str[256]; + String s = make_fixed_width_string(str); + if (used){ + switch (bubble->type){ + case BUBBLE_BUFFER: append(&s, "buffer "); break; + case BUBBLE_STARTS: append(&s, "starts "); break; + case BUBBLE_WIDTHS: append(&s, "widths "); break; + case BUBBLE_WRAPS: append(&s, "wraps "); break; + case BUBBLE_TOKENS: append(&s, "tokens "); break; + case BUBBLE_UNDO_STRING: append(&s, "undo string "); break; + case BUBBLE_UNDO: append(&s, "undo "); break; + default: append(&s, "unknown "); break; + } + } + else{ + append(&s, "unused "); + } + append_int_to_str(bubble->size, &s); + terminate_with_null(&s); + + draw_string(target, font_id, str, rect.x0, y, color); + y += y_advance; + + Bubble *next = bubble->next; + if (next != sentinel){ + u8 *end_ptr = (u8*)(bubble + 1) + bubble->size; + u8 *next_ptr = (u8*)(next); + if (end_ptr != next_ptr){ + color = 0xFFFF0000; + s = make_fixed_width_string(str); + append(&s, "discontinuity"); + terminate_with_null(&s); + + draw_string(target, font_id, str, rect.x0, y, color); + y += y_advance; + } + } + } + + return y; +} + +internal i32 +draw_system_memory(System_Functions *system, Debug_View *view, i32_Rect rect, + Render_Target *target, i32 y){ + i16 font_id = view->font_id; + i32 y_advance = get_font_info(&target->font_set, font_id)->height; + Bubble *sentinel = system->internal_sentinel(); + + for (Bubble *bubble = sentinel->next; + bubble != sentinel; + bubble = bubble->next){ + Sys_Bubble *sysb = (Sys_Bubble*)bubble; + u32 color = 0xFFFFFFFF; + + char str[256]; + String s = make_fixed_width_string(str); + + append(&s, sysb->file_name); + append(&s, " "); + append_int_to_str(sysb->line_number, &s); + append(&s, " "); + append_int_to_str(bubble->size, &s); + terminate_with_null(&s); + + draw_string(target, font_id, str, rect.x0, y, color); + + y += y_advance; + } + + return y; +} + +internal void +draw_background_threads(System_Functions *system, + Debug_View *view, i32_Rect rect, Render_Target *target){ + i32 pending; + bool8 running[4]; + system->internal_get_thread_states(BACKGROUND_THREADS, running, &pending); + + i32 box_size = 30; + + i32_Rect trect; + trect.x0 = rect.x1 - box_size; + trect.y0 = rect.y0; + trect.x1 = rect.x1; + trect.y1 = rect.y0 + box_size; + + u32 light = 0xFF606060; + for (i32 i = 0; i < 4; ++i){ + u32 color; + if (running[i]) color = 0xFF9090FF; + else color = 0xFF101010; + draw_rectangle(target, trect, color); + draw_rectangle_outline(target, trect, light); + trect.x0 -= box_size; + trect.x1 -= box_size; + } + + char str[256]; + String s = make_fixed_width_string(str); + append_int_to_str(pending, &s); + terminate_with_null(&s); + draw_string(target, view->font_id, str, trect.x1, trect.y1, light); +} + +struct Dbg_Modifier{ + char *name; + u8 modifier; +}; +internal void +draw_modifiers(Debug_View *view, Render_Target *target, + bool8 *modifiers, u32 on_color, u32 off_color, i32 *x, i32 y){ + persist Dbg_Modifier dm[] = { + {"CTRL", MDFR_CONTROL_INDEX}, + {"ALT", MDFR_ALT_INDEX}, + {"SHIFT", MDFR_SHIFT_INDEX} + }; + for (i32 i = 0; i < MDFR_INDEX_COUNT; ++i){ + Dbg_Modifier m = dm[i]; + u32 color; + + if (modifiers[m.modifier]) color = on_color; + else color = off_color; + + *x = draw_string(target, view->font_id, m.name, *x, y, color); + *x += 5; + } +} + +internal i32 +draw_key_event(Debug_View *view, Render_Target *target, + Dbg_Past_Key *key, i32 x, i32 y, u32 on_color, u32 off_color){ + draw_modifiers(view, target, key->modifiers, + on_color, off_color, &x, y); + + i16 font_id = view->font_id; + Render_Font *font = get_font_info(&target->font_set, font_id)->font; + + if (font && font->glyphs[key->key.character].exists){ + char c[2]; + c[0] = (char)key->key.character; + c[1] = 0; + x = draw_string(target, font_id, c, x, y, on_color); + } + else{ + char c[10] = {}; + String str = make_fixed_width_string(c); + append(&str, "\\"); + append_int_to_str(key->key.keycode, &str); + terminate_with_null(&str); + x = draw_string(target, font_id, c, x, y, on_color); + } + + return x; +} + +internal void +draw_os_events(Debug_View *view, i32_Rect rect, Render_Target *target, + Input_Summary *active_input){ + persist i32 max_past = ArrayCount(view->past_keys); + + i32 x, y, max_x, max_y; + x = rect.x0; + y = rect.y0; + + i16 font_id = view->font_id; + i32 line_height = get_font_info(&target->font_set, font_id)->height; + +#if 0 + draw_modifiers(view, target, active_input->keys.modifiers, + 0xFFFFFFFF, 0xFF444444, &x, y); +#endif + + max_x = x; + x = rect.x0; + y += line_height; + + for (i32 j = 0; j < view->past_key_count; ++j){ + Dbg_Past_Key *key = view->past_keys + j; + u32 on_color, off_color; + + switch ((view->past_key_pos - j - 1 + max_past*2) % max_past){ + case 0: on_color = 0xFFAAAAFF; off_color = 0xFF505088; break; + case 1: on_color = 0xFF9999CC; off_color = 0xFF404077; break; + case 2: on_color = 0xFF8888AA; off_color = 0xFF303066; break; + default: on_color = 0xFF888888; off_color = 0xFF303030; break; + } + + x = draw_key_event(view, target, key, x, y, on_color, off_color); + + if (max_x < x) max_x = x; + x = rect.x0; + y += line_height; + } + + i32_Rect mrect = rect; + mrect.x0 = max_x + 1; + + max_y = y; + x = mrect.x0; + y = mrect.y0; + + { + u32 color; + if (active_input->mouse.out_of_window){ + color = 0xFFFF0000; + draw_string(target, font_id, "OUT", x, y, color); + } + else{ + color = 0xFF008800; + draw_string(target, font_id, "IN", x, y, color); + } + y += line_height; + + char c[16]; + String s = make_fixed_width_string(c); + append_int_to_str(active_input->mouse.mx, &s); + append(&s, ", "); + append_int_to_str(active_input->mouse.my, &s); + terminate_with_null(&s); + draw_string(target, font_id, c, x, y, color); + y += line_height; + + u32 btn_color; + if (active_input->mouse.l) btn_color = color; + else btn_color = 0xFF444444; + x = draw_string(target, font_id, "L ", x, y, btn_color); + + if (active_input->mouse.r) btn_color = color; + else btn_color = 0xFF444444; + x = draw_string(target, font_id, "R", x, y, btn_color); + + x = mrect.x0; + y += line_height; + + s = make_fixed_width_string(c); + append_int_to_str(view->prev_mouse_wheel, &s); + terminate_with_null(&s); + + if (active_input->mouse.wheel_used) btn_color = color; + else btn_color = 0xFF444444; + draw_string(target, font_id, c, x, y, btn_color); + + y += line_height; + } +} + +internal i32 +draw_debug_view(System_Functions *system, + Debug_View *view, i32_Rect rect, Render_Target *target, + Input_Summary *active_input){ + i32 result = 0; + + draw_rectangle(target, rect, 0xFF000000); + + switch (view->mode){ + case DBG_MEMORY: + { + i32 y = rect.y0; + y = draw_general_memory(view, rect, target, y); + draw_rectangle(target, i32R(rect.x0, y, rect.x1, y+2), 0xFF222222); + y += 2; + y = draw_system_memory(system, view, rect, target, y); + }break; + case DBG_OS_EVENTS: + { + draw_os_events(view, rect, target, active_input); + }break; + } + return result; +} + +internal void +step_debug_view(Debug_View *view, i32_Rect rect, Render_Target *target, + Input_Summary *active_input){ + persist i32 max_past = ArrayCount(view->past_keys); + +#if 0 + b8 *modifiers = active_input->keys.modifiers; + for (i32 i = 0; i < active_input->keys.count; ++i){ + Dbg_Past_Key *past_key = view->past_keys + view->past_key_pos; + ++view->past_key_pos; + view->past_key_pos = view->past_key_pos % max_past; + + past_key->key = active_input->keys.keys[i]; + past_key->modifiers[0] = modifiers[0]; + past_key->modifiers[1] = modifiers[1]; + past_key->modifiers[2] = modifiers[2]; + +#if 0 + i32 this_index = view->past_key_pos; + past_key->frame_index = INTERNAL_frame_index; + if (profile_frame.first_key == -1){ + profile_frame.first_key = this_index; + } +#endif + past_key->frame_index = -1; + + if (view->past_key_count < max_past) ++view->past_key_count; + } + + if (active_input->mouse.wheel_used) + view->prev_mouse_wheel = active_input->mouse.wheel_amount; +#endif +} + +internal +Do_View_Sig(do_debug_view){ + view->mouse_cursor_type = APP_MOUSE_CURSOR_ARROW; + Debug_View *debug_view = (Debug_View*)view; + i32 result = 0; + + switch (message){ + case VMSG_RESIZE: break; + case VMSG_STYLE_CHANGE: break; + case VMSG_STEP: step_debug_view(debug_view, rect, target, active_input); result = 1; break; + case VMSG_DRAW: draw_debug_view(system, debug_view, rect, target, active_input); break; + case VMSG_FREE: break; + } + + return result; +} + +internal Debug_View* +debug_view_init(View *view){ + Debug_View *result = (Debug_View*)view; + view->type = VIEW_TYPE_DEBUG; + view->do_view = do_debug_view; + return result; +} + +#endif +// BOTTOM diff --git a/4ed_file_view.cpp b/4ed_file_view.cpp index 2e500bf4..884a9cb5 100644 --- a/4ed_file_view.cpp +++ b/4ed_file_view.cpp @@ -57,8 +57,8 @@ delayed_action(Delay *delay, Action_Type type, enum File_View_Widget_Type{ FWIDG_NONE, - FWIDG_SEARCH, - FWIDG_GOTO_LINE, + //FWIDG_SEARCH, + //FWIDG_GOTO_LINE, FWIDG_TIMELINES, // never below this FWIDG_TYPE_COUNT @@ -121,7 +121,6 @@ struct File_View{ File_View_Mode mode, next_mode; File_View_Widget widget; - f32 rewind_amount, rewind_speed; i32 rewind_max, scrub_max; b32 unwrapped_lines; b32 show_whitespace; @@ -158,20 +157,6 @@ get_file(Working_Set *working_set, i32 file_id){ return(result); } -internal Range -get_range(i32 a, i32 b){ - Range result = {}; - if (a < b){ - result.start = a; - result.end = b; - } - else{ - result.start = b; - result.end = a; - } - return result; -} - inline bool32 starts_new_line(u8 character){ return (character == '\n'); @@ -1489,8 +1474,8 @@ view_widget_height(File_View *view, i32 font_height){ i32 result = 0; switch (view->widget.type){ case FWIDG_NONE: break; - case FWIDG_SEARCH: result = font_height + 2; break; - case FWIDG_GOTO_LINE: result = font_height + 2; break; + //case FWIDG_SEARCH: result = font_height + 2; break; + //case FWIDG_GOTO_LINE: result = font_height + 2; break; case FWIDG_TIMELINES: result = view->widget.height; break; } return result; @@ -2908,9 +2893,6 @@ step_file_view(System_Functions *system, View *view_, i32_Rect rect, Widget_ID wid = make_id(&state, 2); i32 new_count; if (do_undo_slider(wid, &state, &layout, total_count, undo_count, 0, &new_count)){ - view->rewind_speed = 0; - view->rewind_amount = 0; - for (i32 i = 0; i < scrub_max && new_count < undo_count; ++i){ view_undo(system, view_->mem, view->layout, view); --undo_count; @@ -2961,26 +2943,6 @@ step_file_view(System_Functions *system, View *view_, i32_Rect rect, } }break; } - - i32 rewind_max = view->rewind_max; - view->rewind_amount += view->rewind_speed; - for (i32 i = 0; view->rewind_amount <= -1.f; ++i, view->rewind_amount += 1.f){ - if (i < rewind_max) view_undo(system, view_->mem, view->layout, view); - } - - for (i32 i = 0; view->rewind_amount >= 1.f; ++i, view->rewind_amount -= 1.f){ - if (i < rewind_max) view_redo(system, view_->mem, view->layout, view); - } - - if (view->rewind_speed < 0.f && undo_count == 0){ - view->rewind_speed = 0.f; - view->rewind_amount = 0.f; - } - - if (view->rewind_speed > 0.f && redo_count == 0){ - view->rewind_speed = 0.f; - view->rewind_amount = 0.f; - } } return result; @@ -3304,6 +3266,7 @@ draw_file_loaded(File_View *view, i32_Rect rect, b32 is_active, Render_Target *t } }break; +#if 0 case FWIDG_SEARCH: { Widget_ID wid = make_id(&state, 1); @@ -3323,6 +3286,8 @@ draw_file_loaded(File_View *view, i32_Rect rect, b32 is_active, Render_Target *t persist String gotoline_str = make_lit_string("Goto Line: "); do_text_field(wid, &state, &layout, gotoline_str, view->isearch.str); }break; +#endif + } ui_finish_frame(&view->widget.state, &state, &layout, widg_rect, 0, 0); @@ -3392,6 +3357,7 @@ command_search(System_Functions*,Command_Data*,Command_Binding); internal void command_reverse_search(System_Functions*,Command_Data*,Command_Binding); +#if 0 internal HANDLE_COMMAND_SIG(handle_command_file_view){ File_View *file_view = (File_View*)(view); @@ -3519,6 +3485,7 @@ HANDLE_COMMAND_SIG(handle_command_file_view){ }break; } } +#endif inline void free_file_view(View *view){ @@ -3557,7 +3524,6 @@ internal File_View* file_view_init(View *view, Editing_Layout *layout){ view->type = VIEW_TYPE_FILE; view->do_view = do_file_view; - view->handle_command = handle_command_file_view; File_View *result = (File_View*)view; result->layout = layout; diff --git a/4ed_gui.cpp b/4ed_gui.cpp index 9ed08e17..a6a8212e 100644 --- a/4ed_gui.cpp +++ b/4ed_gui.cpp @@ -180,8 +180,8 @@ app_single_line_input_core(System_Functions *system, Working_Set *working_set, else if (key.character == '\n' || key.character == '\t'){ result.made_a_change = 1; - if (key.modifiers[CONTROL_KEY_CONTROL] || - key.modifiers[CONTROL_KEY_ALT]){ + if (key.modifiers[MDFR_CONTROL_INDEX] || + key.modifiers[MDFR_ALT_INDEX]){ result.hit_ctrl_newline = 1; } else{ @@ -227,8 +227,8 @@ app_single_line_input_core(System_Functions *system, Working_Set *working_set, else if (key.character){ result.hit_a_character = 1; - if (!key.modifiers[CONTROL_KEY_CONTROL] && - !key.modifiers[CONTROL_KEY_ALT]){ + if (!key.modifiers[MDFR_CONTROL_INDEX] && + !key.modifiers[MDFR_ALT_INDEX]){ if (mode.string->size+1 < mode.string->memory_size){ u8 new_character = (u8)key.character; mode.string->str[mode.string->size] = new_character; diff --git a/4ed_layout.cpp b/4ed_layout.cpp index 3e947178..3d4c59a8 100644 --- a/4ed_layout.cpp +++ b/4ed_layout.cpp @@ -42,13 +42,6 @@ struct View; typedef Do_View_Sig(Do_View_Function); -#define HANDLE_COMMAND_SIG(name) \ - void (name)(System_Functions *system, View *view, \ - Command_Data *command, Command_Binding binding, \ - Key_Event_Data key) - -typedef HANDLE_COMMAND_SIG(Handle_Command_Function); - // TODO(allen): this shouldn't exist enum View_Type{ VIEW_TYPE_NONE, @@ -70,7 +63,6 @@ struct View{ Panel *panel; Command_Map *map; Do_View_Function *do_view; - Handle_Command_Function *handle_command; Mem_Options *mem; i32 type; i32 block_size; diff --git a/4ed_system.h b/4ed_system.h index 012a5ed9..87505dcc 100644 --- a/4ed_system.h +++ b/4ed_system.h @@ -72,21 +72,17 @@ struct Coroutine{ void *yield_handle; void *in; void *out; - i32 done; }; #define Sys_Launch_Coroutine_Sig(name) Coroutine *name(Coroutine_Function *func, void *in, void *out) typedef Sys_Launch_Coroutine_Sig(System_Launch_Coroutine); -#define Sys_Resume_Coroutine_Sig(name) void name(Coroutine *coroutine, void *in, void *out) +#define Sys_Resume_Coroutine_Sig(name) Coroutine *name(Coroutine *coroutine, void *in, void *out) typedef Sys_Resume_Coroutine_Sig(System_Resume_Coroutine); -#define Sys_Yield_Coroutine_Sig(name) void *name(Coroutine *coroutine) +#define Sys_Yield_Coroutine_Sig(name) void name(Coroutine *coroutine) typedef Sys_Yield_Coroutine_Sig(System_Yield_Coroutine); -#define Sys_Release_Coroutine_Sig(name) void name(Coroutine *coroutine) -typedef Sys_Release_Coroutine_Sig(System_Relase_Coroutine); - // thread struct Thread_Context; @@ -201,7 +197,6 @@ struct System_Functions{ System_Launch_Coroutine *launch_coroutine; System_Resume_Coroutine *resume_coroutine; System_Yield_Coroutine *yield_coroutine; - System_Relase_Coroutine *release_coroutine; // cli: 4 System_CLI_Call *cli_call; diff --git a/win32_4ed.cpp b/win32_4ed.cpp index 057ce0f3..3da8873d 100644 --- a/win32_4ed.cpp +++ b/win32_4ed.cpp @@ -91,7 +91,7 @@ struct Win32_Input_Chunk_Persistent{ b8 keep_playing; Control_Keys controls; - b8 control_keys[CONTROL_KEY_COUNT]; + b8 control_keys[MDFR_INDEX_COUNT]; }; struct Win32_Input_Chunk{ @@ -102,6 +102,7 @@ struct Win32_Input_Chunk{ struct Win32_Coroutine{ Coroutine coroutine; Win32_Coroutine *next; + int done; }; struct Win32_Vars{ @@ -747,35 +748,39 @@ INTERNAL_get_thread_states(Thread_Group_ID id, bool8 *running, i32 *pending){ } #endif -internal Coroutine* +internal Win32_Coroutine* Win32AllocCoroutine(){ Win32_Coroutine *result = win32vars.coroutine_free; Assert(result != 0); win32vars.coroutine_free = result->next; - return(&result->coroutine); + return(result); } internal void -Win32FreeCoroutine(Coroutine *coroutine){ - Win32_Coroutine *data = (Win32_Coroutine*)coroutine; +Win32FreeCoroutine(Win32_Coroutine *data){ data->next = win32vars.coroutine_free; win32vars.coroutine_free = data; } internal void Win32CoroutineMain(void *arg_){ - Coroutine *coroutine = (Coroutine*)arg_; - coroutine->func(coroutine); - coroutine->done = 1; - SwitchToFiber(coroutine->yield_handle); + Win32_Coroutine *c = (Win32_Coroutine*)arg_; + c->coroutine.func(&c->coroutine); + c->done = 1; + Win32FreeCoroutine(c); + SwitchToFiber(c->coroutine.yield_handle); } internal Sys_Launch_Coroutine_Sig(system_launch_coroutine){ + Win32_Coroutine *c; Coroutine *coroutine; void *fiber; - coroutine = Win32AllocCoroutine(); + c = Win32AllocCoroutine(); + c->done = 0; + + coroutine = &c->coroutine; fiber = CreateFiber(0, Win32CoroutineMain, coroutine); @@ -784,17 +789,22 @@ Sys_Launch_Coroutine_Sig(system_launch_coroutine){ coroutine->yield_handle = GetCurrentFiber(); coroutine->in = in; coroutine->out = out; - coroutine->done = 0; SwitchToFiber(fiber); + if (c->done){ + Win32FreeCoroutine(c); + coroutine = 0; + } + return(coroutine); } Sys_Resume_Coroutine_Sig(system_resume_coroutine){ + Win32_Coroutine *c = (Win32_Coroutine*)coroutine; void *fiber; - Assert(coroutine->done == 0); + Assert(c->done == 0); coroutine->yield_handle = GetCurrentFiber(); coroutine->in = in; @@ -803,18 +813,17 @@ Sys_Resume_Coroutine_Sig(system_resume_coroutine){ fiber = Win32Ptr(coroutine->plat_handle); SwitchToFiber(fiber); + + if (c->done){ + Win32FreeCoroutine(c); + coroutine = 0; + } + + return(coroutine); } Sys_Yield_Coroutine_Sig(system_yield_coroutine){ - void *result; SwitchToFiber(coroutine->yield_handle); - result = coroutine->in; - return(result); -} - -Sys_Release_Coroutine_Sig(system_release_coroutine){ - Assert(coroutine->done); - Win32FreeCoroutine(coroutine); } internal @@ -1037,7 +1046,6 @@ Win32LoadSystemCode(){ win32vars.system->launch_coroutine = system_launch_coroutine; win32vars.system->resume_coroutine = system_resume_coroutine; win32vars.system->yield_coroutine = system_yield_coroutine; - win32vars.system->release_coroutine = system_release_coroutine; win32vars.system->cli_call = system_cli_call; win32vars.system->cli_begin_update = system_cli_begin_update; @@ -1133,7 +1141,7 @@ Win32Callback(HWND hwnd, UINT uMsg, switch (wParam){ case VK_SHIFT: { - control_keys[CONTROL_KEY_SHIFT] = down; + control_keys[MDFR_SHIFT_INDEX] = down; }break; case VK_CONTROL: @@ -1160,8 +1168,8 @@ Win32Callback(HWND hwnd, UINT uMsg, } } - control_keys[CONTROL_KEY_CONTROL] = ctrl; - control_keys[CONTROL_KEY_ALT] = alt; + control_keys[MDFR_CONTROL_INDEX] = ctrl; + control_keys[MDFR_ALT_INDEX] = alt; } system_release_lock(INPUT_LOCK); }break; @@ -1200,8 +1208,8 @@ Win32Callback(HWND hwnd, UINT uMsg, int result; GetKeyboardState(state); - if (control_keys[CONTROL_KEY_CONTROL] && - !control_keys[CONTROL_KEY_ALT]) + if (control_keys[MDFR_CONTROL_INDEX] && + !control_keys[MDFR_ALT_INDEX]) state[VK_CONTROL] = 0; x = 0; result = ToAscii(vk, scan, state, &x, 0); @@ -1305,7 +1313,7 @@ Win32Callback(HWND hwnd, UINT uMsg, win32vars.input_chunk.pers.mouse_r = 0; b8 *control_keys = win32vars.input_chunk.pers.control_keys; - for (int i = 0; i < CONTROL_KEY_COUNT; ++i) control_keys[i] = 0; + for (int i = 0; i < MDFR_INDEX_COUNT; ++i) control_keys[i] = 0; win32vars.input_chunk.pers.controls = {}; system_release_lock(INPUT_LOCK); @@ -1401,6 +1409,8 @@ Win32Callback(HWND hwnd, UINT uMsg, DWORD UpdateLoop(LPVOID param){ + ConvertThreadToFiber(0); + for (;win32vars.input_chunk.pers.keep_playing;){ i64 timer_start = system_time(); @@ -1409,7 +1419,7 @@ UpdateLoop(LPVOID param){ win32vars.input_chunk.trans = {}; system_release_lock(INPUT_LOCK); - input_chunk.pers.control_keys[CONTROL_KEY_CAPS] = GetKeyState(VK_CAPITAL) & 0x1; + input_chunk.pers.control_keys[MDFR_CAPS_INDEX] = GetKeyState(VK_CAPITAL) & 0x1; POINT mouse_point; if (GetCursorPos(&mouse_point) && ScreenToClient(win32vars.window_handle, &mouse_point)){ @@ -1601,6 +1611,12 @@ main(int argc, char **argv){ win32vars.system = system; Win32LoadSystemCode(); + ConvertThreadToFiber(0); + win32vars.coroutine_free = win32vars.coroutine_data; + for (i32 i = 0; i+1 < ArrayCount(win32vars.coroutine_data); ++i){ + win32vars.coroutine_data[i].next = win32vars.coroutine_data + i + 1; + } + LPVOID base; #if FRED_INTERNAL base = (LPVOID)Tbytes(1);