use std::{mem, pin};
use dope_core::driver::{
retained,
route::{self, kind},
schedule,
};
use crate::executor;
#[must_use]
pub struct Activate<'driver, 'turn, 'root, 'd: 'root> {
drive: executor::raw::Drive<'driver, 'turn, 'root, 'd>,
target: route::Erased<'d, kind::Any>,
}
impl<'driver, 'turn, 'root, 'd: 'root> Activate<'driver, 'turn, 'root, 'd> {
pub(crate) const fn new(
target: route::Erased<'d, kind::Any>,
turn: schedule::Turn<'turn, 'd>,
driver: retained::Context<'driver, 'root, 'd>,
) -> Self {
Self {
drive: executor::raw::Drive { turn, driver },
target,
}
}
pub const fn target(&self) -> route::Erased<'d, kind::Any> {
self.target
}
pub fn reborrow(&mut self) -> Activate<'_, '_, 'root, 'd> {
Activate {
drive: self.drive.reborrow(),
target: self.target,
}
}
pub(crate) fn wake<R>(self, app: pin::Pin<&mut R>)
where
R: executor::raw::App<'d>,
{
if !R::WAKE_ROUTES.has_route(self.target.route()) {
return;
}
unsafe { R::activate(app, self) };
}
pub fn into_driver(
self,
) -> (
route::Erased<'d, kind::Any>,
retained::Context<'driver, 'root, 'd>,
) {
(self.target, self.drive.driver)
}
pub fn map<R>(
self,
map: impl FnOnce(
route::Erased<'d, kind::Any>,
schedule::Turn<'turn, 'd>,
retained::Context<'driver, 'root, 'd>,
) -> R,
) -> R {
let executor::raw::Drive { turn, driver } = self.drive;
map(self.target, turn, driver)
}
}
const _: () = {
assert!(
mem::size_of::<Activate<'static, 'static, 'static, 'static>>()
== mem::size_of::<executor::raw::Drive<'static, 'static, 'static, 'static>>()
+ mem::size_of::<route::Erased<'static, kind::Any>>()
);
assert!(
mem::align_of::<Activate<'static, 'static, 'static, 'static>>() == mem::align_of::<usize>()
);
};