Разоблачение ванильных классов Rust с помощью wasm_bindgen - PullRequest
2 голосов
/ 20 июня 2019

Я изучаю, как нацеливаться на WASM с помощью Rust, через из этого урока . Я хочу иметь возможность отделить код моего домена от кода, который предоставляет его WASM. Таким образом, я мог бы повторно использовать код домена в приложении без WASM без суеты. Я не могу найти примеры, которые делают это, и я не знаю, что это поддерживается.

В данный момент я обертываю мою ванильную структуру Rust другой структурой, которая имеет обертки вокруг открытых методов класса домена. Я почти уверен, что это неправильный способ сделать это, но пока он работает.

Я хочу иметь возможность связать CellValue с WASM.

// Inside a vanilla Rust library

// We could bind CellValue with #[wasm_bindgen],
// but I want to keep all WASM stuff out of this library
enum CellValue {
    Live = 0,
    Dead = 1
}

// ...

struct World {
    // ...
    cells: Vec<CellValue> // need to bind a direct reference to the values in here
}

Вот так я выставляю World для WASM - я обертываю его в GOL и реализую методы в GOL, чтобы WASM мог взаимодействовать с World.

// Inside the wasm binding library

#[wasm_bindgen]
pub struct GOL {
    world: gol::World
}


#[wasm_bindgen]
impl GOL {
    pub fn make_new(rows: usize, cols: usize) -> Self
    {
        Self {
            world: GameOfLife::make_new(rows, cols)
        }
    }

    // and so on...
}

Для CellValue я не могу имитировать подход, который я использовал с GOL, потому что мне нужно иметь возможность ссылаться на данные внутри каждой ячейки, которая хранится в World.

Как я уже сказал, единственная причина, по которой я прыгаю через эти обручи, заключается в том, что я могу избежать перетаскивания кода моего домена с помощью #[wasm_bindgen]. Возможно ли вообще получить такую ​​привязку?

1 Ответ

0 голосов
/ 21 июня 2019

Обновление : я нашел работоспособное решение, посмотрев эту библиотеку. Это эмулятор ZX Spectrum, написанный таким образом, с wasm_bindgen секвестрированным в интерфейсе. Парадигма заключается в взаимодействии через небезопасный указатель, например:

#[wasm_bindgen]
pub fn get_cell_value(world: *mut World) -> *const CellValue // return a raw reference to the type defined in the domain
{
    // Return a reference to the first element in the array
}

Затем, на стороне JavaScript, сделайте что-то вроде этого:

import { memory } from "gol/gol_bg"; // Actual WASM generated by wasm_bindgen
import { make_world, get_cell_array } from "wasm-game-of-life";

// ...

const world = make_world(width, height);

const cellsPtr = get_cells_array(world); // Pointer to the first element of the Vec

const cells = new Uint8Array(memory.buffer, cellsPtr, width * height);
...