rust-buildgen requestAnimationFrameLoop 无法在闭包内使用结构方法

标签 rust wasm-bindgen

我正在尝试创建一个 requestAnimationFrame 循环,它将为每一帧调用 game.render()。我正在学习本教程 - https://rustwasm.github.io/wasm-bindgen/examples/request-animation-frame.html


struct Game {
    state: GameState,
    ctx: web_sys::CanvasRenderingContext2d
}

impl Game {
    fn render(self: Game) {
        self.ctx.begin_path();
        self.ctx.arc(self.state.x, 50.0, 40.0, 0.0, 2.0 * std::f64::consts::PI);
        self.ctx.stroke();
    }
}

#[wasm_bindgen(start)]
pub fn run() -> Result<(), JsValue> {

    let game = init();

    let f = Rc::new(RefCell::new(None));
    let g = f.clone();


    *g.borrow_mut() = Some(Closure::wrap(Box::new(move || {
        game.render();
        request_animation_frame(f.borrow().as_ref().unwrap());
    }) as Box<dyn FnMut()>));

    request_animation_frame(g.borrow().as_ref().unwrap());
    Ok(())
}


fn init() -> Game {
    let doc = document();
    let canvas = doc.create_element("canvas").unwrap();
    canvas.set_attribute("width", "800px").unwrap();
    canvas.set_attribute("height", "800px").unwrap();
    canvas.set_id("fp-canvas");
    body().append_child(&canvas).expect("Could not attach canvas");

    Game {
        ctx: context(),
        state: GameState {
            x: 3.0
        }
    }
}

但它给出了以下错误-


error[E0277]: expected a `std::ops::FnMut<()>` closure, found `[closure@src/lib.rs:89:51: 92:6 game:Game, f:std::rc::Rc<std::cell::RefCell<std::option::Option<wasm_bindgen::closure::Closure<dyn std::ops::FnMut()>>>>]`
  --> src/lib.rs:89:42
   |
89 |       *g.borrow_mut() = Some(Closure::wrap(Box::new(move || {
   |  __________________________________________^
90 | |         game.render();
91 | |         request_animation_frame(f.borrow().as_ref().unwrap());
92 | |     }) as Box<dyn FnMut()>));
   | |______^ expected an `FnMut<()>` closure, found `[closure@src/lib.rs:89:51: 92:6 game:Game, f:std::rc::Rc<std::cell::RefCell<std::option::Option<wasm_bindgen::closure::Closure<dyn std::ops::FnMut()>>>>]`
   |
   = help: the trait `std::ops::FnMut<()>` is not implemented for `[closure@src/lib.rs:89:51: 92:6 game:Game, f:std::rc::Rc<std::cell::RefCell<std::option::Option<wasm_bindgen::closure::Closure<dyn std::ops::FnMut()>>>>]`
   = note: wrap the `[closure@src/lib.rs:89:51: 92:6 game:Game, f:std::rc::Rc<std::cell::RefCell<std::option::Option<wasm_bindgen::closure::Closure<dyn std::ops::FnMut()>>>>]` in a closure with no arguments: `|| { /* code */ }
   = note: required for the cast to the object type `dyn std::ops::FnMut()`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
error: could not compile `fighting-pixel`.

To learn more, run the command again with --verbose.

如果我注释掉 game.render() 它会编译。但我想保留一个状态,该状态将被更新以创建动画。我做错了什么?为什么 Closure 不允许调用结构体方法?

预先感谢您的帮助。

最佳答案

我发现了问题。游戏结构就像 -

impl Game {
    fn render(self: &Game) {
        self.ctx.begin_path();
        self.ctx.arc(self.state.x, 50.0, 40.0, 0.0, 2.0 * std::f64::consts::PI);
        self.ctx.stroke();
    }
}

忘记为 self 添加 & 符号。感谢来自 Discord channel #wg-wasm 的 Pauan#6666 指出了这一点。

关于rust-buildgen requestAnimationFrameLoop 无法在闭包内使用结构方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58578044/

相关文章:

javascript - 无效或意外的 token 'import' - jest/babel/webpack

node.js - 如何在 Rust 的 wasm_bindgen 函数中发出 HTTP 请求?

rust - 生成返回字符串的函数时,为什么 wasm-opt 在 wasm-pack 构建中失败?

rust - 如何将宏属性应用于单独模块中定义的函数?

rust - 如何优化从具有已知偏移量和大小的文件中读取 UTF-8 字符串?

rust - 将 Diesel 方法移动到其他目录

rust - 在 ggez 库中网格坐标和绘制坐标如何相互关联?

generics - 如何在Rust中创建对通用特征对象的引用的Vec? [复制]

rust - `return` 语句不应该返回 `!`(从不输入)吗?

rust - 将在 JS 中实例化的 Rust 结构存储在 wasm 端的 Rust 向量中