Reputation: 7866
I have a 3 structs and two types defined
type OnMoveEvent = fn(Board) -> ();
type OnGameOverEvent = fn(Player) -> ();
#[wasm_bindgen]
pub struct Game {
on_move: OnMoveEvent,
on_game_over: OnGameOverEvent,
board: Board,
}
#[wasm_bindgen]
pub struct Board {/* ... */}
#[wasm_bindgen]
pub struct Player {/* ... */}
All 3 structs are wasm_bindgen
and types can not be marked as wasm_bindgen
. However types are just functions accepting structs and returning void
When I add wasm_bindgen
to Game
impl
I get the following error
--> src/game.rs:16:1
|
16 | #[wasm_bindgen]
| ^^^^^^^^^^^^^^^ the trait `wasm_bindgen::convert::traits::FromWasmAbi` is not implemented for `fn(board::Board)`
That is because new
has the following signature
pub fn new(on_move: OnMoveEvent, on_game_over: OnGameOverEvent) -> Game
It seemed to me that it should be simple to translate types as they are functions accepting wasm_bindgen
structs, but it appears as it's not the case
Is this a bug or am I missing something?
The full code is here.
Upvotes: 4
Views: 2132
Reputation: 7866
Going to answer my own question after a bit of research:
Because I was trying to pass some functions from JS to Rust, those can not be guaranteed to have certain signature.
Instead js-sys
crate provides a way to Receiving JavaScript Closures in Exported Rust Functions
I changed my code to following:
#[wasm_bindgen]
pub struct Game {
board: Board,
on_cpu_move: js_sys::Function,
on_game_over: js_sys::Function,
}
and new
signature looks like this:
pub fn new(on_move: js_sys::Function, on_game_over: js_sys::Function) -> Game {
Then I need to call a callback that a JS
consumer is going to provide, this is done like so:
...
let state = self.board.state();
let this = JsValue::NULL;
if state.game_over {
let _ = self.on_game_over.call0(&this);
} else {
let board = JsValue::from(self.board);
let _ = self.on_cpu_move.call1(&this, &board);
}
...
It is up to JS
consumer to make sure they provide right types.
hope somebody finds it useful.
Upvotes: 3