es_entity/clock/mod.rs
1//! Time abstraction for es-entity with support for real and manual time.
2//!
3//! This crate provides a unified interface for time operations that works
4//! identically whether using real time or manual time for testing.
5//!
6//! # Overview
7//!
8//! The main type is [`ClockHandle`], a cheap-to-clone handle that provides:
9//! - `now()` - Get current time (synchronous, fast)
10//! - `sleep(duration)` - Sleep for a duration
11//! - `timeout(duration, future)` - Timeout a future
12//!
13//! For manual clocks, a [`ClockController`] is also provided for controlling time.
14//!
15//! # Clock Types
16//!
17//! - **Realtime**: Uses system clock and tokio timers
18//! - **Manual**: Time only advances via explicit `advance()` calls
19//!
20//! # Example
21//!
22//! ```rust
23//! use es_entity::clock::ClockHandle;
24//! use std::time::Duration;
25//!
26//! // Production: use real time
27//! let clock = ClockHandle::realtime();
28//!
29//! // Testing: use manual clock
30//! let (clock, ctrl) = ClockHandle::manual();
31//!
32//! // Same interface regardless of clock type
33//! let now = clock.now();
34//! ```
35//!
36//! # Deterministic Testing
37//!
38//! In manual mode, time only advances when you call `advance()`.
39//! Wake events are processed in chronological order, so tasks always see
40//! the correct time when they wake:
41//!
42//! ```rust
43//! use es_entity::clock::ClockHandle;
44//! use std::time::Duration;
45//!
46//! # async fn example() {
47//! let (clock, ctrl) = ClockHandle::manual();
48//!
49//! let clock2 = clock.clone();
50//! tokio::spawn(async move {
51//! clock2.sleep(Duration::from_secs(3600)).await; // 1 hour
52//! // When this wakes, clock2.now() == start + 1 hour
53//! // (even if advance() jumped further)
54//! });
55//!
56//! // Advance 1 day - but the task wakes at exactly +1 hour
57//! ctrl.advance(Duration::from_secs(86400)).await;
58//! # }
59//! ```
60
61#![cfg_attr(feature = "fail-on-warnings", deny(warnings))]
62#![cfg_attr(feature = "fail-on-warnings", deny(clippy::all))]
63#![forbid(unsafe_code)]
64
65mod controller;
66mod global;
67mod handle;
68mod inner;
69mod manual;
70mod realtime;
71mod sleep;
72
73// Re-export public API
74pub use controller::ClockController;
75pub use global::Clock;
76pub use handle::{ClockHandle, Elapsed};
77pub use sleep::{ClockSleep, ClockTimeout};