Sleeps for the given period of time in `ms`.
(ms: i32, ret: T)
| 26 | |
| 27 | /// Sleeps for the given period of time in `ms`. |
| 28 | pub(crate) fn do_sleep<T: 'static>(ms: i32, ret: T) -> Pin<Box<dyn Future<Output = T>>> { |
| 29 | assert!(ms >= 0, "Must have been validated by the caller"); |
| 30 | |
| 31 | let (timeout_tx, timeout_rx) = async_channel::unbounded(); |
| 32 | let callback = { |
| 33 | Closure::wrap(Box::new(move || timeout_tx.try_send(true).expect("Send must succeed")) |
| 34 | as Box<dyn FnMut()>) |
| 35 | }; |
| 36 | |
| 37 | let window = match web_sys::window() { |
| 38 | Some(window) => window, |
| 39 | None => log_and_panic!("Failed to get window"), |
| 40 | }; |
| 41 | if let Err(e) = window.set_timeout_with_callback_and_timeout_and_arguments( |
| 42 | callback.as_ref().unchecked_ref(), |
| 43 | ms, |
| 44 | &js_sys::Array::new(), |
| 45 | ) { |
| 46 | log_and_panic!("Failed to set timeout on window: {:?}", e); |
| 47 | } |
| 48 | |
| 49 | Box::pin(async move { |
| 50 | let _callback = callback; // Must grab ownership so that the closure remains alive until it is used. |
| 51 | if let Err(e) = timeout_rx.recv().await { |
| 52 | log_and_panic!("Failed to wait for timeout: {}", e); |
| 53 | } |
| 54 | ret |
| 55 | }) |
| 56 | } |
| 57 | |
| 58 | /// Returns the current monotonic time in milliseconds. |
| 59 | pub(crate) fn current_time_millis() -> f64 { |