aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Ankarström <john@ankarstrom.se>2022-08-21 02:04:15 +0200
committerJohn Ankarström <john@ankarstrom.se>2022-08-21 02:04:15 +0200
commit07bde9f8575701bd0db60baf71aca2465361ff64 (patch)
tree4660c1311b9ea9a14b31fa61f67f878857d80ee9
parentb9573a485baf98e9fb749289b8b9c1f73f70d280 (diff)
downloadEpisodeBrowser-07bde9f8575701bd0db60baf71aca2465361ff64.tar.gz
Reimplement WaitFor.
-rw-r--r--c/data.cpp16
-rw-r--r--c/data.h5
-rw-r--r--c/main.cpp52
-rw-r--r--c/test.cpp11
-rw-r--r--c/win.h1
5 files changed, 47 insertions, 38 deletions
diff --git a/c/data.cpp b/c/data.cpp
index 0e747f1..4bded44 100644
--- a/c/data.cpp
+++ b/c/data.cpp
@@ -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;
}
diff --git a/c/data.h b/c/data.h
index da8d108..4e0d97a 100644
--- a/c/data.h
+++ b/c/data.h
@@ -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;
diff --git a/c/main.cpp b/c/main.cpp
index 97b71b9..d6e3027 100644
--- a/c/main.cpp
+++ b/c/main.cpp
@@ -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)
diff --git a/c/test.cpp b/c/test.cpp
index 5bd8958..d784367 100644
--- a/c/test.cpp
+++ b/c/test.cpp
@@ -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));
diff --git a/c/win.h b/c/win.h
index a77362f..93b1416 100644
--- a/c/win.h
+++ b/c/win.h
@@ -2,6 +2,7 @@
#define WIN_H
#include <optional>
+#include <string_view>
#include <windows.h>
/* Run given procedure at creation of next window. */