vexide_async/time.rs
1//! Utilities for tracking time.
2//!
3//! This module provides a types for executing code after a set period of time.
4//!
5//! - [`Sleep`] is a future that does no work and completes at a specific [`Instant`]
6//! in time.
7//! - [`sleep`] and [`sleep_until`] provide ways to yield control away from a future
8//! for or until a specific instant in time.
9
10use core::{
11 future::Future,
12 pin::Pin,
13 task::{Context, Poll},
14 time::Duration,
15};
16use std::time::Instant;
17
18use crate::{executor::EXECUTOR, reactor::Sleeper};
19
20/// A future that will complete after a certain instant is reached in time.
21///
22/// This type is returned by the [`sleep`] and [`sleep_until`] functions.
23#[derive(Debug)]
24#[must_use = "futures do nothing unless you `.await` or poll them"]
25pub struct Sleep(Instant);
26
27impl Future for Sleep {
28 type Output = ();
29
30 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> core::task::Poll<Self::Output> {
31 if Instant::now() > self.0 {
32 Poll::Ready(())
33 } else {
34 EXECUTOR.with(|ex| {
35 ex.with_reactor(|reactor| {
36 reactor.sleepers.push(Sleeper {
37 deadline: self.0,
38 waker: cx.waker().clone(),
39 });
40 });
41 });
42
43 Poll::Pending
44 }
45 }
46}
47
48/// Waits until `duration` has elapsed.
49///
50/// This function returns a future that will complete after the given
51/// duration, effectively yielding the current task for a period of time.
52///
53/// Equivalent to `sleep_until(Instant::now() + duration)`.
54///
55/// # Examples
56///
57/// ```
58/// println!("See you in 5 minutes.");
59/// sleep(Duration::from_secs(300)).await;
60/// println!("Hello again!");
61/// ```
62pub fn sleep(duration: Duration) -> Sleep {
63 Sleep(Instant::now() + duration)
64}
65
66/// Waits until `deadline` is reached.
67///
68/// This function returns a future that will complete once a given
69/// `Instant` in time has been reached.
70///
71/// # Examples
72///
73/// ```
74/// let now = Instant::now();
75/// let deadline = now + Duration::from_secs(2); // 5 minutes in the future
76///
77/// println!("See you in 5 minutes.");
78/// sleep_until(deadline).await;
79/// println!("Hello again!");
80/// ```
81pub const fn sleep_until(deadline: Instant) -> Sleep {
82 Sleep(deadline)
83}