chron/lib.rs
1//! This crate provides a game loop with a fixed timestep.
2//!
3//! The game loop comes in the form of the [`Clock`] iterator.
4//!
5//! ## Examples
6//!
7//! ```
8//! use chron::{Clock, Tick};
9//!
10//! use std::num::NonZeroU32;
11//!
12//! # fn main() { test().unwrap(); }
13//! # fn test() -> Option<()> {
14//! let updates_per_second = NonZeroU32::new(50)?;
15//! let frames_per_second = NonZeroU32::new(60)?;
16//!
17//! let clock = Clock::new(updates_per_second)
18//! .max_frame_rate(frames_per_second)
19//! .max_updates_per_frame(3);
20//!
21//! for tick in clock {
22//! match tick {
23//! Tick::Update => {
24//! // ...
25//! # break;
26//! }
27//! Tick::Render { interpolation } => {
28//! // ...
29//! }
30//! }
31//! }
32//! # Some(())
33//! # }
34//! ```
35//!
36//! ## Features
37//!
38//! ### Fixed Timestep
39//!
40//! A `Clock` emits two types of events:
41//!
42//! - An [`Update`] indicates that it is time to update the game logic.
43//! - A [`Render`] indicates that it is time to render a new frame.
44//!
45//! The `Clock` tries to emit `Update` events at a fixed interval, for example `60` times per
46//! second. `Render` events, on the other hand, are emitted in-between updates with no specific
47//! target frame rate. By default, the frame rate is unlocked, that means as many frames as
48//! possible, but it may optionally be limited (see below).
49//!
50//! ### Frame Rate Limiter
51//!
52//! The frame rate limiter can prevent the game from running at unnecessarily high frame rates.
53//!
54//! This features only set the maximum frame rate. The `Clock` will emit fewer `Render` events if
55//! this is required to maintain the specified *updates per second*.
56//!
57//! > Note: The frame rate limiter uses [`std::thread::sleep`]. Its accuracy may or may not be good
58//! > enough, depending on the platform.
59//!
60//! See [`Clock::max_frame_rate`] for more.
61//!
62//! ### Prevent Infinite Update Loops
63//!
64//! When the `Clock` cannot maintain the specified *updates per second* (for example because
65//! updates are taking too long) it has to play catch-up by only emitting updates and **no**
66//! renders. Such an *infinite update loop* can be prevented by automatically inserting a `Render`
67//! event after every `N` `Update` events. This prevents the game from never rendering at all, at
68//! the cost of slowing down even more.
69//!
70//! See [`Clock::max_updates_per_frame`] for more.
71//!
72//! [`Render`]: Tick::Render
73//! [`Update`]: Tick::Update
74
75#![warn(missing_docs)]
76
77pub mod clock;
78
79#[doc(inline)]
80pub use crate::clock::{Clock, Tick};