use std::sync::Arc;
use std::sync::LazyLock;
use futures::future::BoxFuture;
use futures::future::abortable;
use wasm_bindgen_futures::spawn_local;
use crate::runtime::AbortHandle;
use crate::runtime::AbortHandleRef;
use crate::runtime::Executor;
use crate::runtime::Handle;
pub struct WasmRuntime;
impl WasmRuntime {
pub fn handle() -> Handle {
static RUNTIME: LazyLock<Arc<dyn Executor>> = LazyLock::new(|| Arc::new(WasmRuntime));
Handle::new(Arc::downgrade(&RUNTIME))
}
}
impl Executor for WasmRuntime {
fn spawn(&self, fut: BoxFuture<'static, ()>) -> AbortHandleRef {
let (fut, handle) = abortable(fut);
spawn_local(async move {
let _ = fut.await;
});
Box::new(FuturesAbortHandle(handle))
}
fn spawn_cpu(&self, task: Box<dyn FnOnce() + Send + 'static>) -> AbortHandleRef {
spawn_local(async move { task() });
Box::new(NoOpAbortHandle)
}
fn spawn_blocking_io(&self, task: Box<dyn FnOnce() + Send + 'static>) -> AbortHandleRef {
spawn_local(async move { task() });
Box::new(NoOpAbortHandle)
}
}
struct FuturesAbortHandle(futures::future::AbortHandle);
impl AbortHandle for FuturesAbortHandle {
fn abort(self: Box<Self>) {
self.0.abort();
}
}
struct NoOpAbortHandle;
impl AbortHandle for NoOpAbortHandle {
fn abort(self: Box<Self>) {
}
}