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}