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    pub fn new(sim: WeakSimWorld, task_id: u64) -> Self {
37        Self {
38            sim,
39            task_id,
40            completed: false,
41        }
42    }
43}
44
45impl Future for SleepFuture {
46    type Output = SimulationResult<()>;
47
48    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
49        // If we've already completed, return immediately
50        if self.completed {
51            return Poll::Ready(Ok(()));
52        }
53
54        // Try to get a reference to the simulation
55        let sim = match self.sim.upgrade() {
56            Ok(sim) => sim,
57            Err(e) => return Poll::Ready(Err(e)),
58        };
59
60        // Check if our wake event has been processed
61        match sim.is_task_awake(self.task_id) {
62            Ok(true) => {
63                // Task has been awakened, mark as completed and return ready
64                self.completed = true;
65                Poll::Ready(Ok(()))
66            }
67            Ok(false) => {
68                // Task hasn't been awakened yet, register waker and return pending
69                match sim.register_task_waker(self.task_id, cx.waker().clone()) {
70                    Ok(()) => Poll::Pending,
71                    Err(e) => Poll::Ready(Err(e)),
72                }
73            }
74            Err(e) => Poll::Ready(Err(e)),
75        }
76    }
77}