Async Support Experiment: circumvent then redesign registration API
yaahc opened this issue · comments
TODO: explain the reasoning behind this direction
// execute an async function
// define one
// make the first param a mutable reference
// box<&dyn Any> that gets downcast
// engine will likely need to wrap it into an enum so it can handle other kinds of functions
// invoke it from a script equivalent
// store it, then retrieve and call it
use futures::future::{BoxFuture, FutureExt};
use std::any::Any;
fn main() {
let mut engine = Engine { fns: vec![] };
let f = Function::AsyncFn { f: wrapped_fn };
engine.fns.push(f);
let s = String::new();
let mut s: Box<dyn Any + Send + Sync> = Box::new(s);
{
let s = &mut s;
match engine.fns.get(0).unwrap() {
Function::AsyncFn { f } => futures::executor::block_on(f(s)),
}
}
let s = *s.downcast::<String>().unwrap();
dbg!(s);
}
async fn modify_this(this: &mut String) {
this.push_str("I got evaluated in the async context!")
}
fn wrapped_fn(mut this: &mut Box<dyn Any + Send + Sync>) -> BoxFuture<'_, ()> {
async move {
let this = this.downcast_mut().unwrap();
modify_this(this).await
}
.boxed()
}
struct Engine {
fns: Vec<Function>,
}
type WrappedFn1 = fn(&mut Box<dyn Any + Send + Sync>) -> BoxFuture<'_, ()>;
enum Function {
AsyncFn { f: WrappedFn1 },
}