koute/stdweb

Rust-defined 'object' owned by JS

AThilenius opened this issue · 2 comments

In wasm-bindgen you can expose Rust 'objects':

#[wasm_bindgen]
pub struct MyObject {}

#[wasm_bindgen]
impl MyObject {
    #[wasm_bindgen(constructor)]
    pub fn new() -> MyObject {
        MyObject {}
    }

    pub fn instance_method(&self) {
        // ...
    }
}

Then in JS you can create an instance, invoke 'methods' and free the object:

const instance = new Rust.MyObject();
instance.instance_method();
instance.free();

stdweb is one of the coolest libraries I've used (the js! macro is astounding), but I'm coming up short on how this would be translated to stdweb? I think it's via ReferenceType and traits, but have only found examples of using JS created objects from Rust. Mixing wasm-bindgen and stdweb seems problematic because they appear to handle complex value and reference marshaling differently.

I'm happy to contribute back to the README at some point, if I can wrap my head around this.

koute commented

Unfortunately something like that isn't currently very well supported. In general I'd prefer to just better integrate with wasm-bindgen in the future (type conversions, etc.) so that you'd simply use wasm-bindgen here.

Nooo. Long term it seems like the right choice though. wasm-bindgen feels very 'JS drives the show' and stdweb the other way around, with this questing belonging to the former camp.

Do you have any (hacky) recommendations how how to pass a reference through a wasm-bindgen method and use it in stdweb? Either a built-in like CanvasElement or a custom class instance?

The dirty-hack that pops to mind is to attach pass-by-ref args to something global (like a lookup array on window) on the JS side, then use the js! macro to grab a reference to it and remove it from window on the Rust side. Any GC concerns to watch out for there? This also requires writing a shim in Rust for each object type.