1#![allow(non_upper_case_globals)]
2#![allow(non_camel_case_types)]
3#![allow(non_snake_case)]
4
5use crate::PlatformDispatcher;
6use async_task::Runnable;
7use objc::{
8 class, msg_send,
9 runtime::{BOOL, YES},
10 sel, sel_impl,
11};
12use std::ffi::c_void;
13
14include!(concat!(env!("OUT_DIR"), "/dispatch_sys.rs"));
15
16pub fn dispatch_get_main_queue() -> dispatch_queue_t {
17 unsafe { &_dispatch_main_q as *const _ as dispatch_queue_t }
18}
19
20pub struct MacDispatcher;
21
22impl PlatformDispatcher for MacDispatcher {
23 fn is_main_thread(&self) -> bool {
24 let is_main_thread: BOOL = unsafe { msg_send![class!(NSThread), isMainThread] };
25 is_main_thread == YES
26 }
27
28 fn dispatch(&self, runnable: Runnable) {
29 unsafe {
30 dispatch_async_f(
31 dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT.try_into().unwrap(), 0),
32 runnable.into_raw() as *mut c_void,
33 Some(trampoline),
34 );
35 }
36 }
37
38 fn dispatch_on_main_thread(&self, runnable: Runnable) {
39 unsafe {
40 dispatch_async_f(
41 dispatch_get_main_queue(),
42 runnable.into_raw() as *mut c_void,
43 Some(trampoline),
44 );
45 }
46 }
47}
48
49extern "C" fn trampoline(runnable: *mut c_void) {
50 let task = unsafe { Runnable::from_raw(runnable as *mut ()) };
51 task.run();
52}
53
54// #include <dispatch/dispatch.h>
55
56// int main(void) {
57
58// dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
59// // Do some lengthy background work here...
60// printf("Background Work\n");
61
62// dispatch_async(dispatch_get_main_queue(), ^{
63// // Once done, update your UI on the main queue here.
64// printf("UI Updated\n");
65
66// });
67// });
68
69// sleep(3); // prevent the program from terminating immediately
70
71// return 0;
72// }
73// ```