gpt4 book ai didi

asynchronous - Rust编译wasm(webassembly)时,怎么休眠10毫秒?

转载 作者:行者123 更新时间:2023-11-29 08:15:14 26 4
gpt4 key购买 nike

我的 Rust 程序正在管理 2d html Canvas 上下文的内存,我正试图达到 ~60fps。我可以很容易地计算出每帧之间的增量,结果大约是 ~5 毫秒。

我不清楚如何让我的 Rust webassembly 程序在剩余的 11 毫秒内进入休眠状态。一种选择是让 JavaScript 在每个 requestAnimationFrame 上调用 Rust 并将其用作驱动程序,但我很想尽可能将其全部保留在 Rust 中。

在编译到 wasm 目标时,我正在有效地寻找与 JavaScript 的 setTimeout(renderNext, 11) 等效的 Rust。

最佳答案

在您的 requestAnimationFrame 回调中,调用 setTimeout,然后让它对 requestAnimationFrame 进行下一次调用。你可以看到这个here的JS版本.

基于 the example in the wasm-bindgen book ,这是我在 Rust 中的做法:

fn animate_limited(mut draw_frame: impl FnMut() + 'static, max_fps: i32) {
// Based on:
// https://rustwasm.github.io/docs/wasm-bindgen/examples/request-animation-frame.html#srclibrs

// https://doc.rust-lang.org/book/ch15-05-interior-mutability.html
let animate_cb = Rc::new(RefCell::new(None));
let animate_cb2 = animate_cb.clone();

let timeout_cb = Rc::new(RefCell::new(None));
let timeout_cb2 = timeout_cb.clone();

let w = window();
*timeout_cb2.borrow_mut() = Some(Closure::wrap(Box::new(move || {
request_animation_frame(&w, animate_cb.borrow().as_ref().unwrap());
}) as Box<dyn FnMut()>));

let w2 = window();
*animate_cb2.borrow_mut() = Some(Closure::wrap(Box::new(move || {
draw_frame();

set_timeout(&w2, timeout_cb.borrow().as_ref().unwrap(), 1000 / max_fps);
}) as Box<dyn FnMut()>));

request_animation_frame(&window(), animate_cb2.borrow().as_ref().unwrap());
}

fn window() -> web_sys::Window {
web_sys::window().expect("no global `window` exists")
}

fn request_animation_frame(window: &web_sys::Window, f: &Closure<dyn FnMut()>) -> i32 {
window
.request_animation_frame(f.as_ref().unchecked_ref())
.expect("should register `requestAnimationFrame` OK")
}

fn set_timeout(window: &web_sys::Window, f: &Closure<dyn FnMut()>, timeout_ms: i32) -> i32 {
window
.set_timeout_with_callback_and_timeout_and_arguments_0(
f.as_ref().unchecked_ref(),
timeout_ms,
)
.expect("should register `setTimeout` OK")
}

然后你只需传递 animate_limited 一个函数来完成你的绘图(像 move || {/* drawing logic here */} 这样的闭包就可以了),以及您想要的最大帧率。

几乎肯定会有改进。我是 Rust 的新手,只是花了太长时间来弄清楚如何让它工作。希望这会让其他人在未来更快。

关于asynchronous - Rust编译wasm(webassembly)时,怎么休眠10毫秒?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57765987/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com