libsurfer/
async_util.rs

1/// Code related to asynchronous features.
2///
3/// As wasm32 and most other platforms behave differently, there are these wrappers.
4use futures_core::Future;
5use log::info;
6use serde::Deserialize;
7
8#[derive(Debug, Deserialize, PartialEq, Eq)]
9pub enum AsyncJob {
10    SaveState,
11}
12
13// Wasm doesn't seem to support std::thread, so this spawns a thread where we can
14// but runs the work sequentially where we can not.
15pub fn perform_work<F>(f: F)
16where
17    F: FnOnce() + Send + 'static,
18{
19    #[cfg(target_arch = "wasm32")]
20    {
21        wasm_bindgen_futures::spawn_local(async {
22            info!("Starting async task");
23            f();
24        });
25        info!("Returning from perform work")
26    }
27
28    #[cfg(not(target_arch = "wasm32"))]
29    {
30        tokio::spawn(async {
31            info!("Starting async task");
32            f();
33        });
34        info!("Returning from perform work");
35    }
36}
37
38// NOTE: wasm32 does not require a Send bound.
39#[cfg(target_arch = "wasm32")]
40pub fn perform_async_work<F>(f: F)
41where
42    F: Future<Output = ()> + 'static,
43{
44    wasm_bindgen_futures::spawn_local(f);
45}
46
47// NOTE: not wasm32 requires a Send bound too.
48#[cfg(not(target_arch = "wasm32"))]
49pub fn perform_async_work<F>(f: F)
50where
51    F: Future<Output = ()> + Send + 'static,
52{
53    tokio::spawn(f);
54}
55
56#[cfg(target_arch = "wasm32")]
57pub async fn sleep_ms(delay: u64) {
58    use wasm_bindgen_futures::js_sys;
59
60    let mut cb = |resolve: js_sys::Function, _reject: js_sys::Function| {
61        web_sys::window()
62            .unwrap()
63            .set_timeout_with_callback_and_timeout_and_arguments_0(&resolve, delay as i32)
64            .unwrap();
65    };
66
67    let p = js_sys::Promise::new(&mut cb);
68
69    wasm_bindgen_futures::JsFuture::from(p).await.unwrap();
70}
71
72#[cfg(not(target_arch = "wasm32"))]
73pub async fn sleep_ms(delay_ms: u64) {
74    tokio::time::sleep(tokio::time::Duration::from_millis(delay_ms)).await;
75}
76
77#[macro_export]
78macro_rules! spawn {
79    ($task:expr) => {
80        #[cfg(not(target_arch = "wasm32"))]
81        tokio::spawn($task);
82        #[cfg(target_arch = "wasm32")]
83        wasm_bindgen_futures::spawn_local($task);
84    };
85}