use std::{pin, task};
use dope_core::driver::{
retained,
schedule::{app, ready},
};
pub struct Context<'poll, 'd: 'poll, R> {
root: pin::Pin<&'poll mut R>,
wake: ready::Target<'d>,
work: app::Work<'poll, 'd>,
driver: retained::Context<'poll, 'poll, 'd>,
}
#[derive(Clone, Copy)]
pub struct Budget<'poll, 'd> {
wake: ready::Target<'d>,
work: app::Work<'poll, 'd>,
}
impl<'poll, 'd: 'poll, R> Context<'poll, 'd, R> {
pub(crate) fn new(
root: pin::Pin<&'poll mut R>,
wake: ready::Target<'d>,
work: app::Work<'poll, 'd>,
driver: retained::Context<'poll, 'poll, 'd>,
) -> Self {
Self {
root,
wake,
work,
driver,
}
}
pub fn into_parts(
self,
) -> (
pin::Pin<&'poll mut R>,
ready::Target<'d>,
app::Work<'poll, 'd>,
retained::Context<'poll, 'poll, 'd>,
) {
(self.root, self.wake, self.work, self.driver)
}
pub fn into_poll(
self,
) -> (
pin::Pin<&'poll mut R>,
Budget<'poll, 'd>,
retained::Context<'poll, 'poll, 'd>,
) {
(self.root, Budget::new(self.wake, self.work), self.driver)
}
}
impl<'poll, 'd> Budget<'poll, 'd> {
pub(crate) const fn new(wake: ready::Target<'d>, work: app::Work<'poll, 'd>) -> Self {
Self { wake, work }
}
pub fn target(self) -> ready::Target<'d> {
self.wake
}
pub fn try_continue(self) -> Option<app::Permit<'poll, 'd>> {
let permit = self.work.permit();
if permit.is_none() {
self.wake.wake();
}
permit
}
}
pub trait Root<'d>: Sized {
type Output;
fn poll(context: Context<'_, 'd, Self>) -> task::Poll<Self::Output>;
}