Skip to main content

moonpool_sim/sim/
sleep.rs

1//! Sleep functionality for simulation time.
2//!
3//! This module provides the ability to sleep in simulation time using async futures
4//! that integrate with the event system. The sleep future will complete when its
5//! corresponding Wake event is processed by the simulation engine.
6
7use std::future::Future;
8use std::pin::Pin;
9use std::task::{Context, Poll};
10
11use crate::{SimulationResult, sim::WeakSimWorld};
12
13/// Future that completes after a specified simulation time duration.
14///
15/// This future integrates with the simulation's event system by:
16/// 1. Scheduling a Wake event for the specified duration
17/// 2. Registering a waker to be called when the event is processed
18/// 3. Returning `Poll::Pending` until the wake event fires
19///
20/// The future will complete with `Ok(())` when the simulation time has advanced
21/// to the scheduled wake time.
22pub struct SleepFuture {
23    /// Weak reference to the simulation world
24    sim: WeakSimWorld,
25    /// Unique identifier for this sleep task
26    task_id: u64,
27    /// Whether this future has already completed
28    completed: bool,
29}
30
31impl SleepFuture {
32    /// Creates a new sleep future.
33    ///
34    /// This is typically called by `SimWorld::sleep()` and should not be
35    /// constructed directly by user code.
36    #[must_use]
37    pub fn new(sim: WeakSimWorld, task_id: u64) -> Self {
38        Self {
39            sim,
40            task_id,
41            completed: false,
42        }
43    }
44}
45
46impl Future for SleepFuture {
47    type Output = SimulationResult<()>;
48
49    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
50        // If we've already completed, return immediately
51        if self.completed {
52            return Poll::Ready(Ok(()));
53        }
54
55        // Try to get a reference to the simulation
56        let sim = match self.sim.upgrade() {
57            Ok(sim) => sim,
58            Err(e) => return Poll::Ready(Err(e)),
59        };
60
61        // Check if our wake event has been processed
62        if sim.is_task_awake(self.task_id) {
63            // Task has been awakened, mark as completed and return ready
64            self.completed = true;
65            Poll::Ready(Ok(()))
66        } else {
67            // Task hasn't been awakened yet, register waker and return pending
68            sim.register_task_waker(self.task_id, cx.waker().clone());
69            Poll::Pending
70        }
71    }
72}