use crate::application::submit_to_main_thread;
use crate::executor::already_on_main_thread_submit;
use some_executor::observer::{ExecutorNotified, FinishedObservation, Observer, ObserverNotified};
use some_executor::task::Task;
use some_executor::{
BoxedSendObserverFuture, BoxedStaticObserver, BoxedStaticObserverFuture, DynExecutor,
DynStaticExecutor, LocalExecutorExt, ObjSafeStaticTask, ObjSafeTask, SomeExecutor,
SomeExecutorExt, SomeLocalExecutor, SomeStaticExecutor,
};
use std::any::Any;
use std::convert::Infallible;
use std::future::Future;
use std::pin::Pin;
#[derive(Debug, Clone)]
pub struct MainThreadExecutor {}
impl SomeLocalExecutor<'static> for MainThreadExecutor {
type ExecutorNotifier = Infallible;
fn spawn_local<F: Future + 'static, Notifier: ObserverNotified<F::Output>>(
&mut self,
task: Task<F, Notifier>,
) -> impl Observer<Value = F::Output>
where
Self: Sized,
<F as Future>::Output: Unpin,
<F as Future>::Output: 'static,
{
let (s, o) = task.spawn_local(self);
let task_label = s.label().to_string();
already_on_main_thread_submit(task_label, async {
s.into_future().await;
});
o
}
fn spawn_local_async<F: Future + 'static, Notifier: ObserverNotified<F::Output>>(
&mut self,
task: Task<F, Notifier>,
) -> impl Future<Output = impl Observer<Value = F::Output>>
where
Self: Sized,
<F as Future>::Output: Unpin,
<F as Future>::Output: 'static,
{
let (s, o) = task.spawn_local(self);
let task_label = s.label().to_string();
#[allow(clippy::async_yields_async)]
async move {
already_on_main_thread_submit(task_label, async {
s.into_future().await;
});
o
}
}
fn spawn_local_objsafe(
&mut self,
task: Task<
Pin<Box<dyn Future<Output = Box<dyn Any>>>>,
Box<dyn ObserverNotified<dyn Any + 'static>>,
>,
) -> Box<
dyn Observer<
Output = FinishedObservation<Box<dyn Any + 'static>>,
Value = Box<dyn Any + 'static>,
> + 'static,
> {
let (s, o) = task.spawn_local_objsafe(self);
let task_label = s.label().to_string();
already_on_main_thread_submit(task_label, async {
s.into_future().await;
});
Box::new(o)
}
fn spawn_local_objsafe_async<'s>(
&'s mut self,
task: Task<
Pin<Box<dyn Future<Output = Box<dyn Any>>>>,
Box<dyn ObserverNotified<dyn Any + 'static>>,
>,
) -> Box<
dyn std::future::Future<
Output = Box<
dyn Observer<
Output = FinishedObservation<Box<dyn Any + 'static>>,
Value = Box<dyn Any + 'static>,
> + 'static,
>,
> + 's,
> {
#[allow(clippy::async_yields_async)]
Box::new(async {
let (s, o) = task.spawn_local_objsafe(self);
let task_label = s.label().to_string();
already_on_main_thread_submit(task_label, async {
s.into_future().await;
});
Box::new(o)
as Box<
dyn Observer<Output = FinishedObservation<Box<dyn Any>>, Value = Box<dyn Any>>,
>
})
}
fn executor_notifier(&mut self) -> Option<Self::ExecutorNotifier> {
None
}
}
impl LocalExecutorExt<'static> for MainThreadExecutor {}
impl SomeExecutor for MainThreadExecutor {
type ExecutorNotifier = Infallible;
fn spawn<F: Future + Send + 'static, Notifier: ObserverNotified<F::Output> + Send>(
&mut self,
task: Task<F, Notifier>,
) -> impl Observer<Value = F::Output>
where
Self: Sized,
F::Output: Send + Unpin,
{
let (s, o) = task.spawn(self);
let task_label = s.label().to_string();
submit_to_main_thread(task_label.clone(), || {
already_on_main_thread_submit(task_label, async {
s.into_future().await;
});
});
o
}
async fn spawn_async<F: Future + Send + 'static, Notifier: ObserverNotified<F::Output> + Send>(
&mut self,
task: Task<F, Notifier>,
) -> impl Observer<Value = F::Output>
where
Self: Sized,
F::Output: Send + Unpin,
{
let (s, o) = task.spawn(self);
let task_label = s.label().to_string();
submit_to_main_thread(task_label.clone(), || {
already_on_main_thread_submit(task_label, async {
s.into_future().await;
});
});
o
}
fn spawn_objsafe(
&mut self,
task: some_executor::ObjSafeTask,
) -> some_executor::BoxedSendObserver {
let (s, o) = task.spawn_objsafe(self);
let task_label = s.label().to_string();
submit_to_main_thread(task_label.clone(), || {
already_on_main_thread_submit(task_label, async {
s.into_future().await;
});
});
Box::new(o)
}
fn spawn_objsafe_async<'s>(&'s mut self, task: ObjSafeTask) -> BoxedSendObserverFuture<'s> {
#[allow(clippy::async_yields_async)]
Box::new(async {
let (s, o) = task.spawn_objsafe(self);
let task_label = s.label().to_string();
submit_to_main_thread(task_label.clone(), || {
already_on_main_thread_submit(task_label, async {
s.into_future().await;
});
});
Box::new(o)
as Box<
dyn Observer<
Value = Box<dyn Any + Send>,
Output = FinishedObservation<Box<dyn Any + Send>>,
> + Send,
>
})
}
fn clone_box(&self) -> Box<DynExecutor> {
Box::new(MainThreadExecutor {})
}
fn executor_notifier(&mut self) -> Option<Self::ExecutorNotifier> {
None
}
}
impl SomeExecutorExt for MainThreadExecutor {}
impl SomeStaticExecutor for MainThreadExecutor {
type ExecutorNotifier = Box<dyn ExecutorNotified>;
fn spawn_static<F: Future + 'static, Notifier: ObserverNotified<F::Output>>(
&mut self,
task: Task<F, Notifier>,
) -> impl Observer<Value = F::Output>
where
Self: Sized,
<F as Future>::Output: Unpin,
<F as Future>::Output: 'static,
{
let (s, o) = task.spawn_static(self);
let task_label = s.label().to_string();
already_on_main_thread_submit(task_label, async {
s.into_future().await;
});
o
}
fn spawn_static_async<F: Future + 'static, Notifier: ObserverNotified<F::Output>>(
&mut self,
task: Task<F, Notifier>,
) -> impl Future<Output = impl Observer<Value = F::Output>>
where
Self: Sized,
<F as Future>::Output: Unpin,
<F as Future>::Output: 'static,
{
let (s, o) = task.spawn_static(self);
let task_label = s.label().to_string();
#[allow(clippy::async_yields_async)]
async move {
already_on_main_thread_submit(task_label, async {
s.into_future().await;
});
o
}
}
fn spawn_static_objsafe(&mut self, task: ObjSafeStaticTask) -> BoxedStaticObserver {
let (s, o) = task.spawn_static_objsafe(self);
let task_label = s.label().to_string();
already_on_main_thread_submit(task_label, async {
s.into_future().await;
});
Box::new(o)
}
fn spawn_static_objsafe_async<'s>(
&'s mut self,
task: ObjSafeStaticTask,
) -> BoxedStaticObserverFuture<'s> {
#[allow(clippy::async_yields_async)]
Box::new(async {
let (s, o) = task.spawn_static_objsafe(self);
let task_label = s.label().to_string();
already_on_main_thread_submit(task_label, async {
s.into_future().await;
});
Box::new(o) as BoxedStaticObserver
})
}
fn clone_box(&self) -> Box<DynStaticExecutor> {
Box::new(MainThreadExecutor {})
}
fn executor_notifier(&mut self) -> Option<Self::ExecutorNotifier> {
None
}
}