Yields execution until the browser is ready to render the next frame.
()
| 67 | |
| 68 | /// Yields execution until the browser is ready to render the next frame. |
| 69 | fn do_request_animation_frame() -> Pin<Box<dyn Future<Output = ()>>> { |
| 70 | let (frame_tx, frame_rx) = async_channel::unbounded(); |
| 71 | let callback = Closure::wrap(Box::new(move |_timestamp: f64| { |
| 72 | frame_tx.try_send(()).expect("Send must succeed") |
| 73 | }) as Box<dyn FnMut(f64)>); |
| 74 | |
| 75 | let window = match web_sys::window() { |
| 76 | Some(window) => window, |
| 77 | None => log_and_panic!("Failed to get window"), |
| 78 | }; |
| 79 | if let Err(e) = window.request_animation_frame(callback.as_ref().unchecked_ref()) { |
| 80 | log_and_panic!("Failed to request animation frame on window: {:?}", e); |
| 81 | } |
| 82 | |
| 83 | Box::pin(async move { |
| 84 | let _callback = callback; // Must grab ownership so that the closure remains alive until it is used. |
| 85 | if let Err(e) = frame_rx.recv().await { |
| 86 | log_and_panic!("Failed to wait for animation frame: {}", e); |
| 87 | } |
| 88 | }) |
| 89 | } |
| 90 | |
| 91 | /// Yields execution until the browser processes one message-channel event. |
| 92 | fn do_message_channel_yield() -> Pin<Box<dyn Future<Output = ()>>> { |