From 69a83d0ca5454ca2825eb213a57f4bdbbf52856d Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Wed, 16 Mar 2016 12:50:26 -0400 Subject: [PATCH] check files before closing --- 4ed.cpp | 56 +++++++++++++++++++++++++++++++++++++++++++ 4ed.h | 5 ++-- 4ed_delay.cpp | 2 ++ 4ed_file_view.cpp | 61 ++++++++++++++++++++++++++++++++++++++++++++--- 4ed_metagen.cpp | 1 + win32_4ed.cpp | 46 ++++++++++++++++++++--------------- 6 files changed, 147 insertions(+), 24 deletions(-) diff --git a/4ed.cpp b/4ed.cpp index 97ad16ce..f3e90a02 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -3646,6 +3646,57 @@ App_Step_Sig(app_step){ } } ProfileEnd(prepare_commands); + + // NOTE(allen): process the command_coroutine if it is unfinished + ProfileStart(try_to_shutdown); + if (app_result.trying_to_kill){ + b32 there_is_unsaved = 0; + + File_Node *node, *sent; + sent = &models->working_set.used_sentinel; + for (dll_items(node, sent)){ + Editing_File *file = (Editing_File*)node; + if (buffer_needs_save(file)){ + there_is_unsaved = 1; + break; + } + } + + if (there_is_unsaved){ + Coroutine *command_coroutine = models->command_coroutine; + View *view = cmd->view; + i32 i = 0; + + while (command_coroutine){ + User_Input user_in = {0}; + user_in.abort = 1; + command_coroutine = system->resume_coroutine(command_coroutine, &user_in, models->command_coroutine_flags); + ++i; + if (i >= 128){ + // TODO(allen): post grave warning, resource cleanup system + command_coroutine = 0; + } + } + if (view != 0){ + init_query_set(&view->query_set); + } + + if (view == 0){ + Panel *panel = models->layout.used_sentinel.next; + view = panel->view; + } + + view_show_interactive(system, view, &models->map_ui, + IAct_Sure_To_Close, IInt_Sure_To_Close, make_lit_string("Are you sure?")); + + models->command_coroutine = command_coroutine; + app_result.redraw = 1; + } + else{ + app_result.perform_kill = 1; + } + } + ProfileEnd(try_to_shutdown); // NOTE(allen): process the command_coroutine if it is unfinished ProfileStart(command_coroutine); @@ -4343,6 +4394,11 @@ App_Step_Sig(app_step){ } } }break; + + case DACT_CLOSE: + { + app_result.perform_kill = 1; + }break; } if (string.str){ diff --git a/4ed.h b/4ed.h index c27572fe..524ee181 100644 --- a/4ed.h +++ b/4ed.h @@ -70,8 +70,7 @@ struct Plat_Settings{ String current_directory, \ Plat_Settings *plat_settings, \ char ***files, i32 **file_count, \ - Command_Line_Parameters clparams \ - ) + Command_Line_Parameters clparams) typedef App_Read_Command_Line_Sig(App_Read_Command_Line); @@ -100,6 +99,8 @@ struct Application_Step_Result{ Application_Mouse_Cursor mouse_cursor_type; b32 redraw; b32 lctrl_lalt_is_altgr; + b32 trying_to_kill; + b32 perform_kill; }; #define App_Step_Sig(name) void \ diff --git a/4ed_delay.cpp b/4ed_delay.cpp index c5b08717..b881e9dc 100644 --- a/4ed_delay.cpp +++ b/4ed_delay.cpp @@ -9,6 +9,7 @@ enum Action_Type{ DACT_TRY_KILL, DACT_KILL, DACT_TOUCH_FILE, + DACT_CLOSE, }; struct Delayed_Action{ @@ -129,3 +130,4 @@ delayed_action_repush(Delay *delay, Delayed_Action *act){ #define delayed_try_kill(delay, ...) delayed_action_(delay, DACT_TRY_KILL, __VA_ARGS__) #define delayed_kill(delay, ...) delayed_action_(delay, DACT_KILL, __VA_ARGS__) #define delayed_touch_file(delay, ...) delayed_action_(delay, DACT_TOUCH_FILE, __VA_ARGS__) +#define delayed_close(delay, ...) delayed_action_(delay, DACT_CLOSE, __VA_ARGS__) diff --git a/4ed_file_view.cpp b/4ed_file_view.cpp index bb258780..76cf22a5 100644 --- a/4ed_file_view.cpp +++ b/4ed_file_view.cpp @@ -15,13 +15,15 @@ enum Interactive_Action{ IAct_New, IAct_Switch, IAct_Kill, - IAct_Sure_To_Kill + IAct_Sure_To_Kill, + IAct_Sure_To_Close }; enum Interactive_Interaction{ IInt_Sys_File_List, IInt_Live_File_List, - IInt_Sure_To_Kill + IInt_Sure_To_Kill, + IInt_Sure_To_Close }; struct View_Mode{ @@ -2677,6 +2679,21 @@ interactive_view_complete(View *view){ delayed_try_kill(&models->delay1, view->dest); break; + case IAct_Sure_To_Close: + switch (view->user_action){ + case 0: + delayed_close(&models->delay1); + break; + + case 1: + break; + + case 2: + // TODO(allen): Save all. + break; + } + break; + case IAct_Sure_To_Kill: switch (view->user_action){ case 0: @@ -3236,11 +3253,49 @@ interactive_shit(System_Functions *system, View *view, UI_State *state, UI_Layou } }break; + case IInt_Sure_To_Close: + { + i32 action = -1; + char s_[256]; + String s; + s = make_fixed_width_string(s_); + append(&s, "There are unsaved changes in, close anyway?"); + do_label(state, layout, s, 1.f); + + i32 id = 0; + if (do_list_option(++id, state, layout, make_lit_string("(Y)es"))){ + action = 0; + } + + if (do_list_option(++id, state, layout, make_lit_string("(N)o"))){ + action = 1; + } + + if (action == -1 && input_stage){ + i32 key_count = keys->count; + for (i32 i = 0; i < key_count; ++i){ + Key_Event_Data key = keys->keys[i]; + switch (key.character){ + case 'y': case 'Y': action = 0; break; + case 'n': case 'N': action = 1; break; + } + if (action == -1 && key.keycode == key_esc) action = 1; + if (action != -1) break; + } + } + + if (action != -1){ + complete = 1; + view->user_action = action; + } + }break; + case IInt_Sure_To_Kill: { i32 action = -1; char s_[256]; - String s = make_fixed_width_string(s_); + String s; + s = make_fixed_width_string(s_); append(&s, view->dest); append(&s, " has unsaved changes, kill it?"); do_label(state, layout, s, 1.f); diff --git a/4ed_metagen.cpp b/4ed_metagen.cpp index 7128de5d..ab5dff16 100644 --- a/4ed_metagen.cpp +++ b/4ed_metagen.cpp @@ -155,6 +155,7 @@ char *daction_enum[] = { "TRY_KILL", "KILL", "TOUCH_FILE", + "CLOSE", }; char str_alloc_copy[] = diff --git a/win32_4ed.cpp b/win32_4ed.cpp index 891dbf1c..cb26fafd 100644 --- a/win32_4ed.cpp +++ b/win32_4ed.cpp @@ -83,7 +83,9 @@ struct Win32_Input_Chunk_Transient{ b8 out_of_window; i8 mouse_wheel; - b32 redraw; + b8 trying_to_kill; + + b8 redraw; }; struct Win32_Input_Chunk_Persistent{ @@ -1424,7 +1426,7 @@ Win32Callback(HWND hwnd, UINT uMsg, case WM_DESTROY: { system_acquire_lock(INPUT_LOCK); - win32vars.input_chunk.pers.keep_playing = 0; + win32vars.input_chunk.trans.trying_to_kill = 1; system_release_lock(INPUT_LOCK); }break; @@ -1512,44 +1514,50 @@ UpdateLoop(LPVOID param){ } } } - + u32 redraw = exchange_vars.thread.force_redraw; if (redraw) exchange_vars.thread.force_redraw = 0; redraw = redraw || input_chunk.trans.redraw; - + Key_Input_Data input_data; Mouse_State mouse; Application_Step_Result result; - + input_data = input_chunk.trans.key_data; mouse.out_of_window = input_chunk.trans.out_of_window; - + mouse.l = input_chunk.pers.mouse_l; mouse.press_l = input_chunk.trans.mouse_l_press; mouse.release_l = input_chunk.trans.mouse_l_release; - + mouse.r = input_chunk.pers.mouse_r; mouse.press_r = input_chunk.trans.mouse_r_press; mouse.release_r = input_chunk.trans.mouse_r_release; - + mouse.wheel = input_chunk.trans.mouse_wheel; - + mouse.x = input_chunk.pers.mouse_x; mouse.y = input_chunk.pers.mouse_y; - + result.mouse_cursor_type = APP_MOUSE_CURSOR_DEFAULT; result.redraw = redraw; result.lctrl_lalt_is_altgr = win32vars.lctrl_lalt_is_altgr; - + result.trying_to_kill = input_chunk.trans.trying_to_kill; + result.perform_kill = 0; + win32vars.app.step(win32vars.system, - &input_data, - &mouse, - &win32vars.target, - &memory_vars, - &exchange_vars, - win32vars.clipboard_contents, - 1, win32vars.first, redraw, - &result); + &input_data, + &mouse, + &win32vars.target, + &memory_vars, + &exchange_vars, + win32vars.clipboard_contents, + 1, win32vars.first, redraw, + &result); + + if (result.perform_kill){ + win32vars.input_chunk.pers.keep_playing = 0; + } ProfileStart(OS_frame_out);