commands run in coroutines
This commit is contained in:
parent
19e7c96c55
commit
0fe6447102
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
138
4coder_custom.h
138
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{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
137
4ed.cpp
137
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:
|
||||
|
|
17
4ed.h
17
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];
|
||||
|
|
|
@ -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!"
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue