FromWasmAbi не реализовано для fn (SomeStruct), в то время как SomeStruct является # [wasm_bindgen] - PullRequest
0 голосов
/ 08 декабря 2018

У меня есть 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 к Game impl, я получаю следующую ошибку

 --> 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 Ответ

0 голосов
/ 08 декабря 2018

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

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

Вместо этого js-sys ящик обеспечивает способ Получение замыканий 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 убедиться, что он предоставляет правильные типы.

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

...