我的生锈程序正在为2d html画布上下文管理内存,我正在尝试命中~60 for。我可以很容易地计算出每一帧之间的增量,结果大约是5毫秒。
我不清楚如何将我的锈菌组件程序用于其余11毫秒的睡眠。一种选择是让JavaScript在每个requestAnimationFrame上调用Rust,并使用它作为驱动程序,但我很好奇,如果可能的话,我想把它保存在Rust中。
在编译到wasm目标时,我实际上是在寻找与JavaScript的setTimeout(renderNext, 11)等效的Rust。
发布于 2019-09-03 07:25:34
在编译到wasm目标时,我实际上是在寻找与JavaScript的
setTimeout(renderNext, 11)等效的Rust。
有几个锈蚀板条箱绑定到JavaScript web,最显著的是web-sys。看看 overloads。
不过,这实际上并不等同于锈蚀,因为它非常直接地调用JS函数。但是,您将无法绕过这个问题:睡眠或获取当前时间都是主机环境必须提供的功能。它们不能仅用原始语言实现。
一种选择是让JavaScript在每个
requestAnimationFrame上调用Rust,并使用它作为驱动程序,但我很好奇,如果可能的话,我想把它保存在Rust中。
是的,您应该使用requestAnimationFrame ( docs)。这比自己选择时间要好得多。特别是,当选项卡不活动时,此方法也会暂停调用代码,诸如此类。在桌面环境中,您也会这样做:要求主机环境(即操作系统,通常通过OpenGL左右)同步您的程序以进行屏幕刷新。
发布于 2020-08-30 05:05:38
在您的requestAnimationFrame回调中,调用setTimeout,然后再调用requestAnimationFrame。您可以看到这个here的JS版本。
基于 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 */ }这样的闭包就可以了),以及您想要的最大框架。
几乎可以肯定地说,在这方面还需要改进。我对锈病非常陌生,只是花了很长时间才弄明白如何使这件事奏效。希望这能让其他人在未来更快。
https://stackoverflow.com/questions/57765987
复制相似问题