FromWasmAbi не реализовано для fn(SomeStruct), в то время как SomeStruct является #[wasm_bindgen]

У меня есть 3 структуры и два типа определены

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 {/* ... */}

Все 3 структуры wasm_bindgen а типы нельзя пометить как wasm_bindgen, Однако типы - это просто функции, принимающие структуры и возвращающие void

Когда я добавлю wasm_bindgen в Gameimpl Я получаю следующую ошибку

 --> src/game.rs:16:1
     |
  16 | #[wasm_bindgen]
     | ^^^^^^^^^^^^^^^ the trait `wasm_bindgen::convert::traits::FromWasmAbi` is not implemented for `fn(board::Board)`

Это потому new имеет следующую подпись

pub fn new(on_move: OnMoveEvent, on_game_over: OnGameOverEvent) -> Game

Мне казалось, что должно быть просто переводить типы, так как они принимают функции wasm_bindgen структурирует, но, похоже, дело не в этом

Это ошибка или я что-то упустил?

Полный код здесь.

1 ответ

Решение

Собираюсь ответить на мой собственный вопрос после небольшого исследования:

Поскольку я пытался передать некоторые функции из JS в Rust, нельзя гарантировать, что они имеют определенную подпись.

Вместо js-sys crate предоставляет способ получения замыканий JavaScript в экспортированных функциях Rust

Я изменил свой код на следующее:

#[wasm_bindgen]
pub struct Game {
  board: Board,
  on_cpu_move: js_sys::Function,
  on_game_over: js_sys::Function,
}

а также new подпись выглядит так:

  pub fn new(on_move: js_sys::Function, on_game_over: js_sys::Function) -> Game {

Затем мне нужно вызвать обратный вызов, что JS потребитель собирается предоставить, это делается так:

...
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);
}
...

Это зависит от JS потребитель должен убедиться, что они предоставляют правильные типы.

надеюсь, кто-нибудь найдет это полезным.

Другие вопросы по тегам