diff options
Diffstat (limited to 'c')
-rw-r--r-- | c/data.cpp | 16 | ||||
-rw-r--r-- | c/data.h | 5 | ||||
-rw-r--r-- | c/main.cpp | 52 | ||||
-rw-r--r-- | c/test.cpp | 11 | ||||
-rw-r--r-- | c/win.h | 1 |
5 files changed, 47 insertions, 38 deletions
@@ -1,3 +1,4 @@ +#include <algorithm> #include <windows.h> #include <wininet.h> #include <libxml/HTMLparser.h> @@ -93,12 +94,12 @@ bool WcharsFromXmlchars(wchar_t (&dst)[N], XmlCharPtr utf8) return MultiByteToWideChar(CP_UTF8, 0, src, cchNarrow, dst, cchWide); } -void FetchData(FileView<ElvDataA>& fvElv, FileView<DlvDataA>& fvDlv) +void FetchData(bool* bDone) { LIBXML_TEST_VERSION; - //InternetFile inf{L"https://www.detectiveconanworld.com/wiki/Anime"}; - InternetFile inf{L"file://C:/Users/John/Desktop/dcw.html"}; + InternetFile inf{L"https://www.detectiveconanworld.com/wiki/Anime"}; + //InternetFile inf{L"file://C:/Users/John/Desktop/dcw.html"}; char buf[1024]; HtmlParserCtxtPtr ctxt = htmlCreatePushParserCtxt(nullptr, nullptr, @@ -124,12 +125,15 @@ void FetchData(FileView<ElvDataA>& fvElv, FileView<DlvDataA>& fvDlv) printf("%d nodes\n", cNodes); for (int i = 0; i < cNodes; i++) { + extern FileView<ElvDataA> g_fvElv; + extern FileView<DlvDataA> g_fvDlv; + const xmlNodePtr node = nodes->nodeTab[i]; if (xmlChildElementCount(node) != 8) throw std::runtime_error("unexpected remote data format"); - ElvDataA& e = fvElv.At(i); - DlvDataA& d = fvDlv.At(i); + ElvDataA& e = g_fvElv.At(i); + DlvDataA& d = g_fvDlv.At(i); /* Get cells. */ const xmlNodePtr nodeEp = xmlFirstElementChild(node); @@ -151,4 +155,6 @@ void FetchData(FileView<ElvDataA>& fvElv, FileView<DlvDataA>& fvDlv) if (nodeLink) WcharsFromXmlchars(d.wiki, xmlGetProp(nodeLink, (const xmlChar*)"href")); } + + *bDone = true; } @@ -161,7 +161,10 @@ struct FileView T* view; size_t c; }; - + +/* Fetch data from the web. */ +void FetchData(bool* bDone); + inline int FromWeb(const int iEp, ElvDataA& e, DlvDataA& d) noexcept { WcharPtr title, wiki, date, source, hint; @@ -1,5 +1,6 @@ #include <exception> #include <stdexcept> +#include <thread> #include <windows.h> #include <commctrl.h> #include <SWI-Prolog.h> @@ -71,8 +72,8 @@ static void InitializeMainWindow(HWND); static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); /* Process main menu commands. */ static void HandleMainMenu(HWND, WORD); -/* Call Prolog predicate in other thread, if available. */ -static void WaitFor(const char*, const char*); +/* Wait for thread. */ +void WaitFor(void (*f)(bool*)); /* Handle messages to Help > About dialog. */ static INT_PTR CALLBACK AboutDlgProc(HWND, UINT, WPARAM, LPARAM); /* Try to style application according to current Windows theme. */ @@ -400,11 +401,13 @@ void HandleMainMenu(const HWND hWnd, const WORD command) break; case IDM_FILE_FETCH_DATA: - WaitFor("episode_data","update_episode_data"); + { + WaitFor(FetchData); break; + } case IDM_FILE_FETCH_SCREENWRITERS: - WaitFor("episode_data","update_screenwriters"); + //WaitFor("episode_data","update_screenwriters"); break; case IDM_FILE_ABOUT: @@ -451,26 +454,24 @@ void HandleMainMenu(const HWND hWnd, const WORD command) } } -void WaitFor(const char* mod, const char* pred) +void WaitFor(void (*f)(bool*)) { /* WaitFor uses a thread on the Prolog side to execute a * predicate asynchronously. */ - static WcharPtr predActive; + static bool bActive = false; + static bool bDone = false; static UINT_PTR iTimer; - static atom_t aThread; - if (predActive) { - wchar_t msg[256] = {0}; - Swprintf(msg, - L"Another task (%s) is active. " + if (bActive) { + if (EBMessageBox(L"Another task is active. " L"Do you want to cancel the existing task and start a new one?", - static_cast<wchar_t*>(predActive)); - if (EBMessageBox(msg, L"Error", MB_YESNO|MB_ICONWARNING) != IDYES) + L"Error", MB_YESNO|MB_ICONWARNING) == IDYES) { + KillTimer(nullptr, iTimer); + bActive = false; + g_elv->Update(); + } else return; - KillTimer(nullptr, iTimer); - predActive = nullptr; - g_elv->Update(); } /* The timer procedure animates an ellipsis in the status bar @@ -481,22 +482,23 @@ void WaitFor(const char* mod, const char* pred) static int i = 0; static const wchar_t* text[] = {L".", L"..", L"...", L""}; - if (Pl("episode_data","thread_running",aThread)) { - i = (i+1)%(sizeof(text)/sizeof(*text)); - SendMessage(g_hWndStatus, SB_SETTEXT, MAKEWPARAM(1,0), - reinterpret_cast<LPARAM>(text[i])); - } else { + if (bDone) { KillTimer(nullptr, iTimer); i = 0; - predActive = nullptr; + bActive = 0; g_elv->Update(); + } else { + i = (i+1)%(sizeof(text)/sizeof(*text)); + SendMessage(g_hWndStatus, SB_SETTEXT, MAKEWPARAM(1,0), + reinterpret_cast<LPARAM>(text[i])); } }; - Plx(mod,"thread_create",pred,&aThread); + bDone = false; + bActive = true; + std::thread{f, &bDone}.detach(); SendMessage(g_hWndStatus, SB_SETTEXT, MAKEWPARAM(1,0), reinterpret_cast<LPARAM>(L".")); - if (Prefer(iTimer = SetTimer(nullptr, -1, 500, proc))) - predActive = WcharPtr::FromNarrow(pred); + Prefer(iTimer = SetTimer(nullptr, -1, 500, proc)); } INT_PTR CALLBACK AboutDlgProc(const HWND hWnd, const UINT uMsg, const WPARAM wParam, const LPARAM) @@ -1,3 +1,4 @@ +#include <thread> #include <windows.h> #include "data.h" @@ -224,12 +225,8 @@ TESTS TEST(Fetch) { - extern FileView<ElvDataA> g_fvElv; - extern FileView<DlvDataA> g_fvDlv; - void FetchData(FileView<ElvDataA>& fvElv, FileView<DlvDataA>& fvDlv); - //FileView<ElvDataA> fvElv{L"testelv.dat", 1080}; - //FileView<DlvDataA> fvDlv{L"testdlv.dat", 1080}; - FetchData(g_fvElv, g_fvDlv); + bool bDone = false; + std::thread{FetchData, &bDone}.detach(); } }; @@ -245,7 +242,7 @@ int RunTests() //MigrateCfg{} //MigrateDlvDataFromPrologToDisk{}, //DownloadDataViaProlog{}, - Fetch{}, + //Fetch{}, }; printf("Results (%llu tests):\n", sizeof(tests)/sizeof(*tests)); @@ -2,6 +2,7 @@ #define WIN_H #include <optional> +#include <string_view> #include <windows.h> /* Run given procedure at creation of next window. */ |