ui/winui/toolkit.cpp

changeset 5
83263002816f
parent 3
f154867f54dc
child 76
641dcc79e0ef
equal deleted inserted replaced
4:31137432bea8 5:83263002816f
48 using namespace Microsoft::UI::Xaml::Controls; 48 using namespace Microsoft::UI::Xaml::Controls;
49 using namespace Microsoft::UI::Xaml::XamlTypeInfo; 49 using namespace Microsoft::UI::Xaml::XamlTypeInfo;
50 using namespace Microsoft::UI::Xaml::Markup; 50 using namespace Microsoft::UI::Xaml::Markup;
51 using namespace Windows::UI::Xaml::Interop; 51 using namespace Windows::UI::Xaml::Interop;
52 using namespace winrt::Windows::Foundation; 52 using namespace winrt::Windows::Foundation;
53 using namespace Windows::UI::Core;
53 54
54 static const char* application_name; 55 static const char* application_name;
55 56
56 static ui_callback startup_func; 57 static ui_callback startup_func;
57 static void* startup_data; 58 static void* startup_data;
67 static void* appclose_udata; 68 static void* appclose_udata;
68 69
69 70
70 static UiObject* active_window; 71 static UiObject* active_window;
71 72
73 static winrt::Microsoft::UI::Dispatching::DispatcherQueue uiDispatcherQueue = { nullptr };
74
72 void ui_app_run_startup() { 75 void ui_app_run_startup() {
76 uiDispatcherQueue = winrt::Microsoft::UI::Dispatching::DispatcherQueue::GetForCurrentThread();
77
73 if (startup_func) { 78 if (startup_func) {
74 startup_func(NULL, startup_data); 79 startup_func(NULL, startup_data);
75 } 80 }
76 } 81 }
77 82
231 236
232 void ui_close(UiObject* obj) { 237 void ui_close(UiObject* obj) {
233 238
234 } 239 }
235 240
241 static void ui_job_finished(UiJob *job) {
242 UiEvent event;
243 event.obj = job->obj;
244 event.window = job->obj->window;
245 event.document = job->obj->ctx->document;
246 event.intval = 0;
247 event.eventdata = NULL;
248 job->finish_callback(&event, job->finish_data);
249 }
250
251 static void ui_job_thread(UiJob* job) {
252 if (!job->job_func(job->job_data) && job->finish_callback) {
253 bool isQueued = uiDispatcherQueue.TryEnqueue([job]()
254 {
255 UiEvent event;
256 event.obj = job->obj;
257 event.window = job->obj->window;
258 event.document = job->obj->ctx->document;
259 event.intval = 0;
260 event.eventdata = NULL;
261 job->finish_callback(&event, job->finish_data);
262 delete job;
263 });
264 if (!isQueued) {
265 // TODO: error or try again?
266 exit(-1);
267 }
268 }
269 else {
270 delete job;
271 }
272 }
273
274 UIEXPORT void ui_job(UiObject* obj, ui_threadfunc tf, void* td, ui_callback f, void* fd) {
275 UiJob* job = new UiJob;
276 job->obj = obj;
277 job->job_func = tf;
278 job->job_data = td;
279 job->finish_callback = f;
280 job->finish_data = fd;
281
282 std::thread jobThread(ui_job_thread, job);
283 jobThread.detach();
284 }
285
286 UIEXPORT void ui_call_mainthread(ui_threadfunc tf, void* td) {
287 bool isQueued = uiDispatcherQueue.TryEnqueue([tf, td]()
288 {
289 (void)tf(td);
290 });
291 if (!isQueued) {
292 // TODO: error or try again?
293 exit(-1);
294 }
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