rust-buildgen requestAnimationFrameLoop无法在闭包内部使用struct方法

问题描述 投票:0回答:1

我正在尝试创建一个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不允许调用struct方法?

感谢您的帮助。

rust wasm-bindgen
1个回答
0
投票

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

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频道#wg-wasm的Pauan#6666指出了这一点。

© www.soinside.com 2019 - 2024. All rights reserved.