use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Poll};
use std::time::Duration;
use crate::executor;
pub struct SleepFuture {
registered: bool,
duration_ms: u64,
deadline_ms: u64,
}
impl SleepFuture {
#[allow(clippy::cast_possible_truncation)]
pub(crate) fn new(duration: Duration) -> Self {
Self {
registered: false,
duration_ms: duration.as_millis() as u64,
deadline_ms: 0,
}
}
}
impl Future for SleepFuture {
type Output = ();
fn poll(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<()> {
if self.registered {
let now = executor::current_time_ms();
if now == 0 || now >= self.deadline_ms {
return Poll::Ready(());
}
return Poll::Pending;
}
self.registered = true;
let task_id = executor::with_current_polling_task(|id| {
id.expect("timer::sleep must be called from within an auralis task")
});
let now = executor::current_time_ms();
self.deadline_ms = now.saturating_add(self.duration_ms);
if self.duration_ms == 0 || (now > 0 && self.deadline_ms <= now) {
return Poll::Ready(());
}
executor::Executor::schedule_timer(
&executor::current_executor_instance(),
self.deadline_ms,
task_id,
);
Poll::Pending
}
}
pub async fn sleep(duration: Duration) {
SleepFuture::new(duration).await;
}