lots of cleanup to the command coroutine events

master
Allen Webster 2017-07-17 20:00:07 -04:00
parent 61f3187767
commit 24857007bc
2 changed files with 116 additions and 96 deletions

202
4ed.cpp
View File

@ -1698,7 +1698,7 @@ App_Step_Sig(app_step){
} }
} }
// NOTE(allen): Keyboard input to command coroutine. // NOTE(allen): Keyboard and Mouse input to command coroutine.
if (models->command_coroutine != 0){ if (models->command_coroutine != 0){
Coroutine *command_coroutine = models->command_coroutine; Coroutine *command_coroutine = models->command_coroutine;
u32 get_flags = models->command_coroutine_flags[0]; u32 get_flags = models->command_coroutine_flags[0];
@ -1706,106 +1706,126 @@ App_Step_Sig(app_step){
get_flags |= abort_flags; get_flags |= abort_flags;
Command_Data *command = cmd;
USE_VIEW(view);
Partition *part = &models->mem.part;
Temp_Memory temp = begin_temp_memory(part);
// HACK(allen): This can be simplified a lot more.
enum{
Event_Keyboard,
Event_Mouse,
};
struct Coroutine_Event{
u32 type;
u32 key_i;
};
Coroutine_Event *events = push_array(part, Coroutine_Event, 32);
u32 event_count = 0;
Key_Input_Data key_data = get_key_data(&vars->available_input);
if ((get_flags & EventOnAnyKey) || (get_flags & EventOnEsc)){ if ((get_flags & EventOnAnyKey) || (get_flags & EventOnEsc)){
Key_Input_Data key_data = get_key_data(&vars->available_input);
for (i32 key_i = 0; key_i < key_data.count; ++key_i){ for (i32 key_i = 0; key_i < key_data.count; ++key_i){
Key_Event_Data key = get_single_key(&key_data, key_i); Coroutine_Event *new_event = &events[event_count++];
Command_Data *command = cmd; new_event->type = Event_Keyboard;
USE_VIEW(view); new_event->key_i = key_i;
b32 pass_in = 0;
cmd->key = key;
Command_Map *map = 0;
if (view) map = view->map;
if (map == 0) map = &models->map_top;
Command_Binding cmd_bind = map_extract_recursive(map, key);
User_Input user_in = {0};
user_in.type = UserInputKey;
user_in.key = key;
user_in.command.command = cmd_bind.custom;
if ((EventOnEsc & abort_flags) && key.keycode == key_esc){
user_in.abort = true;
}
else if (EventOnAnyKey & abort_flags){
user_in.abort = true;
}
if (EventOnAnyKey & get_flags){
pass_in = true;
consume_input(&vars->available_input, Input_AnyKey, "command coroutine");
}
if (key.keycode == key_esc){
if (EventOnEsc & get_flags){
pass_in = true;
}
consume_input(&vars->available_input, Input_Esc, "command coroutine");
}
if (pass_in){
models->command_coroutine = app_resume_coroutine(system, &models->app_links, Co_Command, command_coroutine, &user_in, models->command_coroutine_flags);
app_result.animating = true;
// TOOD(allen): Deduplicate
// TODO(allen): Should I somehow allow a view to clean up however it wants after a
// command finishes, or after transfering to another view mid command?
if (view != 0 && models->command_coroutine == 0){
init_query_set(&view->query_set);
}
if (models->command_coroutine == 0) break;
}
} }
} }
// NOTE(allen): Mouse input to command coroutine
if (models->command_coroutine != 0 && (get_flags & EventOnMouse)){ if (models->command_coroutine != 0 && (get_flags & EventOnMouse)){
Command_Data *command = cmd; Coroutine_Event *new_event = &events[event_count++];
USE_VIEW(view); new_event->type = Event_Mouse;
b32 pass_in = 0; }
Coroutine_Event *event = events;
for (u32 event_i = 0; event_i < event_count; ++event_i, ++event){
b32 pass_in = false;
User_Input user_in = {0}; User_Input user_in = {0};
user_in.type = UserInputMouse;
user_in.mouse = input->mouse;
if (abort_flags & EventOnMouseMove){ switch (event->type){
user_in.abort = true; case Event_Keyboard:
} {
if (get_flags & EventOnMouseMove){ Key_Event_Data key = get_single_key(&key_data, event->key_i);
pass_in = true; cmd->key = key;
consume_input(&vars->available_input, Input_MouseMove, "command coroutine");
}
if (input->mouse.press_l || input->mouse.release_l || input->mouse.l){ Command_Map *map = 0;
if (abort_flags & EventOnLeftButton){ if (view){
user_in.abort = true; map = view->map;
} }
if (get_flags & EventOnLeftButton){ if (map == 0){
pass_in = true; map = &models->map_top;
consume_input(&vars->available_input, Input_MouseLeftButton, "command coroutine"); }
} Command_Binding cmd_bind = map_extract_recursive(map, key);
}
if (input->mouse.press_r || input->mouse.release_r || input->mouse.r){ user_in.type = UserInputKey;
if (abort_flags & EventOnRightButton){ user_in.key = key;
user_in.abort = true; user_in.command.command = cmd_bind.custom;
}
if (get_flags & EventOnRightButton){
pass_in = true;
consume_input(&vars->available_input, Input_MouseRightButton, "command coroutine");
}
}
if (input->mouse.wheel != 0){ if ((abort_flags & EventOnEsc) && key.keycode == key_esc){
if (abort_flags & EventOnWheel){ user_in.abort = true;
user_in.abort = true; }
} else if (abort_flags & EventOnAnyKey){
if (get_flags & EventOnWheel){ user_in.abort = true;
pass_in = true; }
consume_input(&vars->available_input, Input_MouseWheel, "command coroutine");
} if (get_flags & EventOnAnyKey){
pass_in = true;
consume_input(&vars->available_input, Input_AnyKey, "command coroutine");
}
if (key.keycode == key_esc){
if (get_flags & EventOnEsc){
pass_in = true;
}
consume_input(&vars->available_input, Input_Esc, "command coroutine");
}
}break;
case Event_Mouse:
{
user_in.type = UserInputMouse;
user_in.mouse = input->mouse;
if (abort_flags & EventOnMouseMove){
user_in.abort = true;
}
if (get_flags & EventOnMouseMove){
pass_in = true;
consume_input(&vars->available_input, Input_MouseMove, "command coroutine");
}
if (input->mouse.press_l || input->mouse.release_l || input->mouse.l){
if (abort_flags & EventOnLeftButton){
user_in.abort = true;
}
if (get_flags & EventOnLeftButton){
pass_in = true;
consume_input(&vars->available_input, Input_MouseLeftButton, "command coroutine");
}
}
if (input->mouse.press_r || input->mouse.release_r || input->mouse.r){
if (abort_flags & EventOnRightButton){
user_in.abort = true;
}
if (get_flags & EventOnRightButton){
pass_in = true;
consume_input(&vars->available_input, Input_MouseRightButton, "command coroutine");
}
}
if (input->mouse.wheel != 0){
if (abort_flags & EventOnWheel){
user_in.abort = true;
}
if (get_flags & EventOnWheel){
pass_in = true;
consume_input(&vars->available_input, Input_MouseWheel, "command coroutine");
}
}
}break;
} }
if (pass_in){ if (pass_in){
@ -1813,14 +1833,16 @@ App_Step_Sig(app_step){
app_result.animating = true; app_result.animating = true;
// TOOD(allen): Deduplicate
// TODO(allen): Should I somehow allow a view to clean up however it wants after a // TODO(allen): Should I somehow allow a view to clean up however it wants after a
// command finishes, or after transfering to another view mid command? // command finishes, or after transfering to another view mid command?
if (view != 0 && models->command_coroutine == 0){ if (view != 0 && models->command_coroutine == 0){
init_query_set(&view->query_set); init_query_set(&view->query_set);
} }
if (models->command_coroutine == 0) break;
} }
} }
end_temp_memory(temp);
} }
// NOTE(allen): pass raw input to the panels // NOTE(allen): pass raw input to the panels

View File

@ -214,7 +214,6 @@ DOC_SEE(Command_ID)
return(result); return(result);
} }
// TODO(allen): This is a bit of a mess and needs to be fixed.
API_EXPORT bool32 API_EXPORT bool32
Exec_System_Command(Application_Links *app, View_Summary *view, Buffer_Identifier buffer_id, char *path, int32_t path_len, char *command, int32_t command_len, Command_Line_Interface_Flag flags) Exec_System_Command(Application_Links *app, View_Summary *view, Buffer_Identifier buffer_id, char *path, int32_t path_len, char *command, int32_t command_len, Command_Line_Interface_Flag flags)
/* /*
@ -2096,7 +2095,6 @@ DOC_SEE(User_Input)
result.type = UserInputKey; result.type = UserInputKey;
result.abort = 0; result.abort = 0;
result.key = cmd->key; result.key = cmd->key;
// TODO(allen): It would be nice to fill this.
result.command.cmdid = 0; result.command.cmdid = 0;
return(result); return(result);