From a67d7ca9e69799728801e30eff6af1adc7d2e53b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Ankarstr=C3=B6m?= Date: Wed, 27 Jul 2022 22:31:29 +0200 Subject: Refactor thread/timer. --- c/main.cpp | 87 ++++++++++++++++++++++++++++++++++-------------------------- c/resource.h | 5 ++-- 2 files changed, 51 insertions(+), 41 deletions(-) (limited to 'c') diff --git a/c/main.cpp b/c/main.cpp index aab6535..29a4d46 100644 --- a/c/main.cpp +++ b/c/main.cpp @@ -12,10 +12,6 @@ #include "main.h" #include "pl.h" -/* Application state. */ -atom_t g_aThread; -int g_bThread; - /* Looked-up constants. */ int g_bThemes; int g_iDPI = 96; @@ -45,6 +41,7 @@ static LRESULT CALLBACK CBTProc(int, WPARAM, LPARAM); static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); void WndProcMainMenu(const HWND, unsigned short); void WndProcContextMenu(const HWND, unsigned short); +static void WaitFor(const char*, const char*); static INT_PTR CALLBACK AboutDlgProc(HWND, UINT, WPARAM, LPARAM); static void UpdateTheme(); @@ -270,31 +267,6 @@ LRESULT CALLBACK WndProc(const HWND hWnd, const UINT uMsg, const WPARAM wParam, return g_pElv->HandleNotify(lParam); } break; - case WM_TIMER: - switch (wParam) { - case IDR_TIMER: - { - static int i = 0; - - /* Animate ellipsis in status bar while doing - * work in other thread. */ - if (Pl("episode_data","thread_running",g_aThread)) { - i = (i+1)%4; - SendMessage(g_hWndStatus, SB_SETTEXT, MAKEWPARAM(1,0), - (LPARAM)(i==0? L".": - i==1? L"..": - i==2? L"...": - L"")); - } else { - i = 0; - g_bThread = 0; - prefer(KillTimer(hWnd, IDR_TIMER)); - g_pElv->Update(); - } - break; - } - } - break; case WM_COMMAND: { const unsigned short wCommand = LOWORD(wParam); @@ -372,16 +344,10 @@ void WndProcMainMenu(const HWND hWnd, unsigned short wCommand) g_pElv->Update(); break; case IDM_FILE_FETCH_DATA: - if (g_bThread) break; - Pl("episode_data","thread_create","update_episode_data",&g_aThread); - goto t; + WaitFor("episode_data","update_episode_data"); + break; case IDM_FILE_FETCH_SCREENWRITERS: - if (g_bThread) break; - Pl("episode_data","thread_create","update_screenwriters",&g_aThread); - t: KillTimer(hWnd, IDR_TIMER); - if (!prefer(SetTimer(hWnd, IDR_TIMER, 500, (TIMERPROC)NULL))) break; - SendMessage(g_hWndStatus, SB_SETTEXT, MAKEWPARAM(1,0), (LPARAM)L"."); - g_bThread = 1; + WaitFor("episode_data","update_screenwriters"); break; case IDM_FILE_ABOUT: DialogBox( @@ -498,6 +464,51 @@ void WndProcContextMenu(const HWND, unsigned short wCommand) } } +/* Call Prolog predicate in other thread, if available. */ +void WaitFor(const char* szMod, const char* szPred) +{ + static atom_t aThread; + static int bActive; + static int iTimer; + static std::wstring wsPred; + + if (bActive) { + std::wstringstream wss; + wss << L"Another task (" << wsPred.c_str() << ") is active. " + << "Do you want to cancel the existing task and start a new one?"; + if (EBMessageBox(wss.str().c_str(), L"Error", MB_YESNO|MB_ICONWARNING) != IDYES) + return; + KillTimer(NULL, iTimer); + bActive = 0; + g_pElv->Update(); + } + + /* The timer procedure animates an ellipsis in the status bar + * while the thread is running. */ + + static auto proc = [](HWND, UINT, UINT_PTR, DWORD) -> void { + static int i = 0; + + if (Pl("episode_data","thread_running",aThread)) { + i = (i+1)%4; + SendMessage(g_hWndStatus, SB_SETTEXT, MAKEWPARAM(1,0), + (LPARAM)(i==0? L".": i==1? L"..": i==2? L"...": L"")); + } else { + KillTimer(NULL, iTimer); + i = 0; + bActive = 0; + g_pElv->Update(); + } + }; + + Plx(szMod,"thread_create",szPred,&aThread); + SendMessage(g_hWndStatus, SB_SETTEXT, MAKEWPARAM(1,0), (LPARAM)L"."); + if (prefer(iTimer = SetTimer(NULL, -1, 500, proc))) { + wsPred = WsFromSz(szPred); + bActive = 1; + } +} + /* Handle messages to Help > About dialog. */ INT_PTR CALLBACK AboutDlgProc(const HWND hWnd, const UINT uMsg, const WPARAM wParam, const LPARAM) { diff --git a/c/resource.h b/c/resource.h index 8cf2230..3bf23b0 100644 --- a/c/resource.h +++ b/c/resource.h @@ -17,9 +17,8 @@ /* Resources, timers, menus. */ #define IDR_STATUS 0x0100 -#define IDR_TIMER 0x0101 -#define IDR_MENU 0x0102 -#define IDR_POPUPMENU 0x0103 +#define IDR_MENU 0x0101 +#define IDR_POPUPMENU 0x0102 /* Dialogs, controls, child windows. */ #define IDD_ABOUT 0x0200 -- cgit v1.2.3