2020-12-26 23:44:53 +01:00
|
|
|
use core::future::Future;
|
2021-03-02 15:45:22 +01:00
|
|
|
use core::marker::PhantomData;
|
2020-12-26 23:44:53 +01:00
|
|
|
use core::pin::Pin;
|
|
|
|
use core::task::{Context, Poll};
|
|
|
|
use futures::Stream;
|
|
|
|
|
2021-02-02 05:14:52 +01:00
|
|
|
use super::raw;
|
2020-12-26 23:44:53 +01:00
|
|
|
use crate::time::{Duration, Instant};
|
|
|
|
|
2021-03-02 15:45:22 +01:00
|
|
|
pub struct Delay {
|
|
|
|
_data: PhantomData<bool>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Delay {
|
|
|
|
pub fn new() -> Self {
|
|
|
|
Delay {
|
|
|
|
_data: PhantomData {},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl crate::traits::delay::Delay for Delay {
|
|
|
|
type DelayFuture<'a> = impl Future<Output = ()> + 'a;
|
|
|
|
|
|
|
|
fn delay_ms<'a>(self: Pin<&'a mut Self>, millis: u64) -> Self::DelayFuture<'a> {
|
|
|
|
Timer::after(Duration::from_millis(millis))
|
|
|
|
}
|
|
|
|
fn delay_us<'a>(self: Pin<&'a mut Self>, micros: u64) -> Self::DelayFuture<'a> {
|
|
|
|
Timer::after(Duration::from_micros(micros))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-26 23:44:53 +01:00
|
|
|
pub struct Timer {
|
|
|
|
expires_at: Instant,
|
2020-12-30 00:56:32 +01:00
|
|
|
yielded_once: bool,
|
2020-12-26 23:44:53 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Timer {
|
|
|
|
pub fn at(expires_at: Instant) -> Self {
|
2020-12-30 00:56:32 +01:00
|
|
|
Self {
|
|
|
|
expires_at,
|
|
|
|
yielded_once: false,
|
|
|
|
}
|
2020-12-26 23:44:53 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn after(duration: Duration) -> Self {
|
|
|
|
Self {
|
|
|
|
expires_at: Instant::now() + duration,
|
2020-12-30 00:56:32 +01:00
|
|
|
yielded_once: false,
|
2020-12-26 23:44:53 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Unpin for Timer {}
|
|
|
|
|
|
|
|
impl Future for Timer {
|
|
|
|
type Output = ();
|
2020-12-30 00:56:32 +01:00
|
|
|
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
|
|
|
if self.yielded_once && self.expires_at <= Instant::now() {
|
2020-12-26 23:44:53 +01:00
|
|
|
Poll::Ready(())
|
|
|
|
} else {
|
2021-02-02 05:14:52 +01:00
|
|
|
unsafe { raw::register_timer(self.expires_at, cx.waker()) };
|
2020-12-30 00:56:32 +01:00
|
|
|
self.yielded_once = true;
|
2020-12-26 23:44:53 +01:00
|
|
|
Poll::Pending
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct Ticker {
|
|
|
|
expires_at: Instant,
|
|
|
|
duration: Duration,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Ticker {
|
|
|
|
pub fn every(duration: Duration) -> Self {
|
|
|
|
let expires_at = Instant::now() + duration;
|
|
|
|
Self {
|
|
|
|
expires_at,
|
|
|
|
duration,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Unpin for Ticker {}
|
|
|
|
|
|
|
|
impl Stream for Ticker {
|
|
|
|
type Item = ();
|
|
|
|
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
|
|
|
|
if self.expires_at <= Instant::now() {
|
|
|
|
let dur = self.duration;
|
|
|
|
self.expires_at += dur;
|
|
|
|
Poll::Ready(Some(()))
|
|
|
|
} else {
|
2021-02-02 05:14:52 +01:00
|
|
|
unsafe { raw::register_timer(self.expires_at, cx.waker()) };
|
2020-12-26 23:44:53 +01:00
|
|
|
Poll::Pending
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|