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}