use alloc::{rc::Rc, vec::Vec};
use core::{cell::Cell, fmt, future::Future, marker::PhantomData};
use crate::Spawn;
#[derive(Clone, Default)]
pub struct LocalSpawner(
Rc<Cell<Vec<async_std::task::JoinHandle<()>>>>,
PhantomData<*mut ()>,
);
impl fmt::Debug for LocalSpawner {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("LocalSpawner")
.field(&"..")
.field(&self.1)
.finish()
}
}
impl LocalSpawner {
pub fn block_on(self, f: impl Future<Output = ()> + 'static) {
async_std::task::block_on(async move {
self.spawn_local(f);
loop {
let handles = self.0.take();
if handles.is_empty() {
break;
}
for join in handles {
join.await;
}
}
});
}
}
impl Spawn for LocalSpawner {
#[inline(always)]
fn spawn_local(&self, f: impl Future<Output = ()> + 'static) {
let mut joins = self.0.take();
joins.push(async_std::task::Builder::new().local(f).unwrap());
self.0.set(joins);
}
#[inline(always)]
fn spawn(&self, f: impl Future<Output = ()> + Send + 'static) {
let mut joins = self.0.take();
joins.push(async_std::task::Builder::new().spawn(f).unwrap());
self.0.set(joins);
}
}