Open janpaul123 opened 2 years ago
From the Rust side, it would look like this:
operation1() -> Box<T> {
let data : Box<T> = ...
return vec![data.into_param()];
}
operation2(input: Vec<ZapParam>) {
let data = params[0] // how do we cast this into a Box<T> ?
}
From the JS side it'd look like:
const [data] = callRustSync('operation1', [])
callRustSync('operation2', [data])
Yeah exactly. To add some more details, we can call the type of data
a ZapPointer
perhaps, and we could even add a zaplib.isZapPointer
in addition to our zaplib.isZapBuffer
. (There are different ways to structure this so this is just one idea)
Re how do we cast this into a Box<T>
, I would imagine doing let data = params[0].into_val::<T>()
to get a T
.
And for the immutable case something similar, but for Arc<T>
.
We could even have convenience methods for getting &T
or &mut T
but that's not as necessary.
Workaround is something like this:
impl MyStruct {
fn into_param(self) -> ZapParam {
(Box::into_raw(Box::new(self)) as usize).to_string().into_param()
}
fn from_param(param: ZapParam) -> Self {
*unsafe { Box::from_raw(param.as_str().parse::<usize>().unwrap() as *mut Self ) }
}
}
Which has some overhead in the conversions from/to strings, plus it leaks memory if you drop the pointer on the JS side.
We should be able to send a
Box<T>
(mutable) or anArc<T>
(immutable) to JS. On the JS side you can't do anything with it, except send it back to Rust, or send it between Web Workers.This is useful when doing complicated things in Rust, while the "locus of control" is still in Javascript.
The particular use case for Flux involves having a matrix that we don't need to read of modify directly on the JS side, so we want flexibility on how to represent it in Rust (e.g. swap out one matrix library for another).