ui/winui/toolkit.cpp

branch
newapi
changeset 235
9c79f00fbf36
parent 234
9036b346cd66
equal deleted inserted replaced
234:9036b346cd66 235:9c79f00fbf36
41 41
42 #include "MainWindow.xaml.h" 42 #include "MainWindow.xaml.h"
43 43
44 #include "App.xaml.h" 44 #include "App.xaml.h"
45 45
46 #include <thread>
47
48 using namespace winrt; 46 using namespace winrt;
49 using namespace Microsoft::UI::Xaml; 47 using namespace Microsoft::UI::Xaml;
50 using namespace Microsoft::UI::Xaml::Controls; 48 using namespace Microsoft::UI::Xaml::Controls;
51 using namespace Microsoft::UI::Xaml::XamlTypeInfo; 49 using namespace Microsoft::UI::Xaml::XamlTypeInfo;
52 using namespace Microsoft::UI::Xaml::Markup; 50 using namespace Microsoft::UI::Xaml::Markup;
249 event.eventdata = NULL; 247 event.eventdata = NULL;
250 job->finish_callback(&event, job->finish_data); 248 job->finish_callback(&event, job->finish_data);
251 } 249 }
252 250
253 static void ui_job_thread(UiJob* job) { 251 static void ui_job_thread(UiJob* job) {
254 if (!job->job_func(job->job_data)) { 252 if (!job->job_func(job->job_data) && job->finish_callback) {
255 bool isQueued = uiDispatcherQueue.TryEnqueue([job]() 253 bool isQueued = uiDispatcherQueue.TryEnqueue([job]()
256 { 254 {
257 UiEvent event; 255 UiEvent event;
258 event.obj = job->obj; 256 event.obj = job->obj;
259 event.window = job->obj->window; 257 event.window = job->obj->window;
293 if (!isQueued) { 291 if (!isQueued) {
294 // TODO: error or try again? 292 // TODO: error or try again?
295 exit(-1); 293 exit(-1);
296 } 294 }
297 } 295 }
296
297 static UiJob kill_job; // &kill_job indicates to stop the thread
298
299 static void ui_threadpool_run(UiThreadpool* pool) {
300 for (;;) {
301 UiJob* job = pool->GetJob();
302 if (job == &kill_job) {
303 return;
304 }
305 else if (job) {
306 ui_job_thread(job);
307 }
308 }
309 }
310
311 UiThreadpool::UiThreadpool(int nthreads) {
312 for (int i = 0; i < nthreads; i++) {
313 std::thread thread(ui_threadpool_run, this);
314 thread.detach();
315 }
316 }
317
318 void UiThreadpool::EnqueueJob(UiJob* job)
319 {
320 std::unique_lock<std::mutex> lock(mutex);
321 queue.push(job);
322 lock.unlock();
323 condition.notify_one();
324 }
325
326 UiJob* UiThreadpool::GetJob() {
327 std::unique_lock<std::mutex> lock(mutex);
328
329 UiJob* job = nullptr;
330 while (!job) {
331 if (queue.empty()) {
332 condition.wait(lock);
333 continue;
334 }
335 else
336 {
337 job = queue.front();
338 queue.pop();
339 }
340 }
341
342 return job;
343 }
344
345 UIEXPORT UiThreadpool* ui_threadpool_create(int nthreads) {
346 return new UiThreadpool(nthreads);
347 }
348
349 UIEXPORT void ui_threadpool_destroy(UiThreadpool* pool) {
350 // TODO
351 }
352
353 UIEXPORT void ui_threadpool_job(UiThreadpool* pool, UiObject* obj, ui_threadfunc tf, void* td, ui_callback f, void* fd) {
354 UiJob* job = new UiJob;
355 job->obj = obj;
356 job->job_func = tf;
357 job->job_data = td;
358 job->finish_callback = f;
359 job->finish_data = fd;
360 pool->EnqueueJob(job);
361 }
362

mercurial