Sun, 28 Jan 2024 19:33:56 +0100
implement ui_job() and add ui_call_mainthread (WinUI3)
make/vs/testapp/main.c | file | annotate | diff | comparison | revisions | |
ui/ui/toolkit.h | file | annotate | diff | comparison | revisions | |
ui/winui/pch.h | file | annotate | diff | comparison | revisions | |
ui/winui/toolkit.cpp | file | annotate | diff | comparison | revisions | |
ui/winui/toolkit.h | file | annotate | diff | comparison | revisions |
--- a/make/vs/testapp/main.c Sun Jan 28 17:10:30 2024 +0100 +++ b/make/vs/testapp/main.c Sun Jan 28 19:33:56 2024 +0100 @@ -55,6 +55,21 @@ UiList* menuList; +void event_mt(UiEvent* event, void* data) { + char* mt_str = data; + + printf("%s\n", mt_str); +} + +int test_threadfunc(void *data) { + char* str = data; + + return 0; +} + +void action_thread_test(UiEvent* event, void* data) { + ui_job(event->obj, test_threadfunc, "testdata", event_mt, "testdata2"); +} void action1(UiEvent* event, void* data) { char* action = data; @@ -247,7 +262,7 @@ ui_scrolledwindow0(obj) { ui_grid(obj, .margin = 10, .columnspacing = 5, .rowspacing = 20) { - ui_button(obj, .label = "Button1", .onclick = action1, .onclickdata = "action1"); + ui_button(obj, .label = "Thread Test", .onclick = action_thread_test, .onclickdata = "action1"); ui_button(obj, .label = "Button2", .icon = "Back", .onclick = action1, .onclickdata = "action2"); ui_button(obj, .icon = "Forward", .onclick = action1, .onclickdata = "action3", .hexpand = true); ui_newline(obj);
--- a/ui/ui/toolkit.h Sun Jan 28 17:10:30 2024 +0100 +++ b/ui/ui/toolkit.h Sun Jan 28 19:33:56 2024 +0100 @@ -371,6 +371,7 @@ UIEXPORT void ui_close(UiObject *obj); UIEXPORT void ui_job(UiObject *obj, ui_threadfunc tf, void *td, ui_callback f, void *fd); +UIEXPORT void ui_call_mainthread(ui_threadfunc tf, void* td); UIEXPORT void* ui_document_new(size_t size); UIEXPORT void ui_document_destroy(void *doc);
--- a/ui/winui/pch.h Sun Jan 28 17:10:30 2024 +0100 +++ b/ui/winui/pch.h Sun Jan 28 19:33:56 2024 +0100 @@ -33,6 +33,7 @@ #include <winrt/Microsoft.UI.Input.h> #include <winrt/Windows.UI.Core.h> #include <winrt/Windows.ApplicationModel.h> +#include <winrt\Microsoft.UI.Dispatching.h> #include <winrt/Windows.Storage.Streams.h>
--- a/ui/winui/toolkit.cpp Sun Jan 28 17:10:30 2024 +0100 +++ b/ui/winui/toolkit.cpp Sun Jan 28 19:33:56 2024 +0100 @@ -43,6 +43,8 @@ #include "App.xaml.h" +#include <thread> + using namespace winrt; using namespace Microsoft::UI::Xaml; using namespace Microsoft::UI::Xaml::Controls; @@ -50,6 +52,7 @@ using namespace Microsoft::UI::Xaml::Markup; using namespace Windows::UI::Xaml::Interop; using namespace winrt::Windows::Foundation; +using namespace Windows::UI::Core; static const char* application_name; @@ -69,7 +72,11 @@ static UiObject* active_window; +static winrt::Microsoft::UI::Dispatching::DispatcherQueue uiDispatcherQueue = { nullptr }; + void ui_app_run_startup() { + uiDispatcherQueue = winrt::Microsoft::UI::Dispatching::DispatcherQueue::GetForCurrentThread(); + if (startup_func) { startup_func(NULL, startup_data); } @@ -233,3 +240,58 @@ } +static void ui_job_finished(UiJob *job) { + UiEvent event; + event.obj = job->obj; + event.window = job->obj->window; + event.document = job->obj->ctx->document; + event.intval = 0; + event.eventdata = NULL; + job->finish_callback(&event, job->finish_data); +} + +static void ui_job_thread(UiJob* job) { + if (!job->job_func(job->job_data)) { + bool isQueued = uiDispatcherQueue.TryEnqueue([job]() + { + UiEvent event; + event.obj = job->obj; + event.window = job->obj->window; + event.document = job->obj->ctx->document; + event.intval = 0; + event.eventdata = NULL; + job->finish_callback(&event, job->finish_data); + delete job; + }); + if (!isQueued) { + // TODO: error or try again? + exit(-1); + } + } + else { + delete job; + } +} + +UIEXPORT void ui_job(UiObject* obj, ui_threadfunc tf, void* td, ui_callback f, void* fd) { + UiJob* job = new UiJob; + job->obj = obj; + job->job_func = tf; + job->job_data = td; + job->finish_callback = f; + job->finish_data = fd; + + std::thread jobThread(ui_job_thread, job); + jobThread.detach(); +} + +UIEXPORT void ui_call_mainthread(ui_threadfunc tf, void* td) { + bool isQueued = uiDispatcherQueue.TryEnqueue([tf, td]() + { + (void)tf(td); + }); + if (!isQueued) { + // TODO: error or try again? + exit(-1); + } +}
--- a/ui/winui/toolkit.h Sun Jan 28 17:10:30 2024 +0100 +++ b/ui/winui/toolkit.h Sun Jan 28 19:33:56 2024 +0100 @@ -30,6 +30,14 @@ #include "../ui/toolkit.h" +typedef struct UiJob { + UiObject* obj; + ui_threadfunc job_func; + void* job_data; + ui_callback finish_callback; + void* finish_data; +} UiJob; + typedef void(*ui_eventfunc)(void*, void*); void ui_app_run_startup();