From 14e35d7eecc6318ea84e71868f7e13fbbaf5ac0a Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Tue, 3 May 2016 15:33:22 -0400 Subject: [PATCH] animation and event completion event handling --- 4ed.cpp | 4 +++- 4ed.h | 1 + 4ed_file_view.cpp | 21 +++++++++------------ win32_4ed.cpp | 34 ++++++++++++++++++++-------------- 4 files changed, 33 insertions(+), 27 deletions(-) diff --git a/4ed.cpp b/4ed.cpp index d83a916b..24bb21d1 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -3978,7 +3978,9 @@ App_Step_Sig(app_step){ if (panel == mouse_panel && !mouse->out_of_window){ input.mouse = mouse_state; } - do_input_file_view(system, exchange, view, panel->inner, active, &input); + if (do_input_file_view(system, exchange, view, panel->inner, active, &input)){ + app_result.animating = 1; + } } } diff --git a/4ed.h b/4ed.h index 69bafe51..b3ee3f88 100644 --- a/4ed.h +++ b/4ed.h @@ -100,6 +100,7 @@ struct Application_Step_Result{ b32 lctrl_lalt_is_altgr; b32 trying_to_kill; b32 perform_kill; + b32 animating; }; #define App_Step_Sig(name) void \ diff --git a/4ed_file_view.cpp b/4ed_file_view.cpp index e017339e..af24a2f2 100644 --- a/4ed_file_view.cpp +++ b/4ed_file_view.cpp @@ -3457,9 +3457,9 @@ view_reinit_scrolling(View *view){ #define CursorMaxY(m,h) (CursorMaxY_(m,h) > 0)?(CursorMaxY_(m,h)):(0) #define CursorMinY(m,h) (CursorMinY_(m,h) > 0)?(CursorMinY_(m,h)):(0) -internal i32 +internal b32 file_step(View *view, i32_Rect region, Input_Summary *user_input, b32 is_active){ - i32 result = 0; + i32 is_animating = 0; Editing_File *file = view->file; if (file && !file->state.is_loading){ // TODO(allen): rewrite with real scrolling system now. @@ -3504,7 +3504,7 @@ file_step(View *view, i32_Rect region, Input_Summary *user_input, b32 is_active) if (file->state.paste_effect.tick_down > 0){ --file->state.paste_effect.tick_down; - result = 1; + is_animating = 1; } if (user_input->mouse.press_l && is_active){ @@ -3518,12 +3518,11 @@ file_step(View *view, i32_Rect region, Input_Summary *user_input, b32 is_active) view->mode = {}; } } - result = 1; } if (!is_active) view_set_widget(view, FWIDG_NONE); } - return(result); + return(is_animating); } internal void @@ -4270,11 +4269,11 @@ app_single_number_input_step(System_Functions *system, Key_Event_Data key, Strin return result; } -internal i32 +internal b32 do_input_file_view(System_Functions *system, Exchange *exchange, View *view, i32_Rect rect, b32 is_active, Input_Summary *user_input){ - i32 result = 0; + b32 is_animating = 0; b32 is_file_scroll = 0; GUI_Session gui_session; @@ -4304,7 +4303,7 @@ do_input_file_view(System_Functions *system, Exchange *exchange, view_reinit_scrolling(view); } if (file_step(view, gui_session.rect, user_input, is_active)){ - result = 1; + is_animating = 1; } is_file_scroll = 1; }break; @@ -4325,7 +4324,6 @@ do_input_file_view(System_Functions *system, Exchange *exchange, key = get_single_key(keys, i); step = app_single_line_input_step(system, key, string); if ((step.hit_newline || step.hit_ctrl_newline) && !step.no_file_match){ - result = 1; view->gui_target.active = e->id; } } @@ -4348,7 +4346,6 @@ do_input_file_view(System_Functions *system, Exchange *exchange, key = get_single_key(keys, i); step = app_single_file_input_step(system, working_set, key, &hdir->string, hdir, 1, 1, 0); if ((step.hit_newline || step.hit_ctrl_newline) && !step.no_file_match){ - result = 1; view->gui_target.active = e->id; } } @@ -4540,7 +4537,7 @@ do_input_file_view(System_Functions *system, Exchange *exchange, scroll_vars.target_x, scroll_vars.target_y, &scroll_vars.scroll_x, &scroll_vars.scroll_y, (view->id) + 1, is_new_target)){ - result = 1; + is_animating = 1; } scroll_vars.prev_target_x = scroll_vars.target_x; @@ -4569,7 +4566,7 @@ do_input_file_view(System_Functions *system, Exchange *exchange, } } - return(result); + return(is_animating); } internal i32 diff --git a/win32_4ed.cpp b/win32_4ed.cpp index 6957ef7d..a3774a86 100644 --- a/win32_4ed.cpp +++ b/win32_4ed.cpp @@ -48,11 +48,12 @@ #define frame_useconds (1000000 / FPS) // TODO(allen): Do we still need all of these? I've abandoned the -// main thread / update loop thread thing for a while at least. +// main thread / update loop thread thing (at least for a while). #define WM_4coder_LOAD_FONT (WM_USER + 1) #define WM_4coder_PAINT (WM_USER + 2) #define WM_4coder_SET_CURSOR (WM_USER + 3) #define WM_4coder_ANIMATE (WM_USER + 4) +#define WM_4coder_EVENT_COMPLETE (WM_USER + 5) struct Thread_Context{ u32 job_id; @@ -649,35 +650,35 @@ Win32GenHandle(HANDLE h){ } internal DWORD WINAPI -ThreadProc(LPVOID lpParameter){ +JobThreadProc(LPVOID lpParameter){ Thread_Context *thread = (Thread_Context*)lpParameter; Work_Queue *queue = thread->queue; - + for (;;){ u32 read_index = queue->read_position; u32 write_index = queue->write_position; - + if (read_index != write_index){ u32 next_read_index = (read_index + 1) % JOB_ID_WRAP; u32 safe_read_index = InterlockedCompareExchange(&queue->read_position, - next_read_index, read_index); - + next_read_index, read_index); + if (safe_read_index == read_index){ Full_Job_Data *full_job = queue->jobs + (safe_read_index % QUEUE_WRAP); // NOTE(allen): This is interlocked so that it plays nice // with the cancel job routine, which may try to cancel this job // at the same time that we try to run it - + i32 safe_running_thread = InterlockedCompareExchange(&full_job->running_thread, - thread->id, THREAD_NOT_ASSIGNED); - + thread->id, THREAD_NOT_ASSIGNED); + if (safe_running_thread == THREAD_NOT_ASSIGNED){ thread->job_id = full_job->id; thread->running = 1; Thread_Memory *thread_memory = 0; - + // TODO(allen): remove memory_request if (full_job->job.memory_request != 0){ thread_memory = win32vars.thread_memory + thread->id - 1; @@ -691,7 +692,8 @@ ThreadProc(LPVOID lpParameter){ } } full_job->job.callback(win32vars.system, thread, thread_memory, - &exchange_vars.thread, full_job->job.data); + &exchange_vars.thread, full_job->job.data); + PostMessage(win32vars.window_handle, WM_4coder_EVENT_COMPLETE, 0, 0); full_job->running_thread = 0; thread->running = 0; } @@ -755,7 +757,7 @@ Sys_Cancel_Job_Sig(system_cancel_job){ thread = group->threads + thread_id - 1; TerminateThread(thread->handle, 0); u32 creation_flag = 0; - thread->handle = CreateThread(0, 0, ThreadProc, thread, creation_flag, (LPDWORD)&thread->windows_id); + thread->handle = CreateThread(0, 0, JobThreadProc, thread, creation_flag, (LPDWORD)&thread->windows_id); system_release_lock(CANCEL_LOCK0 + thread_id - 1); thread->running = 0; } @@ -1597,6 +1599,7 @@ UpdateStep(){ else{ file->flags |= FEx_Save_Failed; } + PostMessage(0, WM_4coder_EVENT_COMPLETE, 0, 0); } if (file->flags & FEx_Request){ @@ -1612,6 +1615,7 @@ UpdateStep(){ file->data = sysfile.data; file->size = sysfile.size; } + PostMessage(0, WM_4coder_EVENT_COMPLETE, 0, 0); } } @@ -1648,7 +1652,9 @@ UpdateStep(){ system_acquire_lock(FRAME_LOCK); timer_start = system_time(); - PostMessage(NULL, WM_4coder_ANIMATE, 0, 0); + if (result.animating){ + PostMessage(0, WM_4coder_ANIMATE, 0, 0); + } } DWORD @@ -1841,7 +1847,7 @@ int main(int argc, char **argv){ memory->id = thread->id; thread->queue = &exchange_vars.thread.queues[BACKGROUND_THREADS]; - thread->handle = CreateThread(0, 0, ThreadProc, thread, creation_flag, (LPDWORD)&thread->windows_id); + thread->handle = CreateThread(0, 0, JobThreadProc, thread, creation_flag, (LPDWORD)&thread->windows_id); } Assert(win32vars.locks);