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