1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
//! An example that illustrates how Time is handled in ECS.

use bevy::app::AppExit;
use bevy::prelude::*;

use std::io::{self, BufRead};
use std::time::Duration;

fn banner() {
    println!("This example is meant to intuitively demonstrate how Time works in Bevy.");
    println!();
    println!("Time will be printed in three different schedules in the app:");
    println!("- PreUpdate: real time is printed");
    println!("- FixedUpdate: fixed time step time is printed, may be run zero or multiple times");
    println!("- Update: virtual game time is printed");
    println!();
    println!("Max delta time is set to 5 seconds. Fixed timestep is set to 1 second.");
    println!();
}

fn help() {
    println!("The app reads commands line-by-line from standard input.");
    println!();
    println!("Commands:");
    println!("  empty line: Run app.update() once on the Bevy App");
    println!("  q: Quit the app.");
    println!("  f: Set speed to fast, 2x");
    println!("  n: Set speed to normal, 1x");
    println!("  s: Set speed to slow, 0.5x");
    println!("  p: Pause");
    println!("  u: Unpause");
}

fn runner(mut app: App) -> AppExit {
    banner();
    help();
    let stdin = io::stdin();
    for line in stdin.lock().lines() {
        if let Err(err) = line {
            println!("read err: {:#}", err);
            break;
        }
        match line.unwrap().as_str() {
            "" => {
                app.update();
            }
            "f" => {
                println!("FAST: setting relative speed to 2x");
                app.world_mut()
                    .resource_mut::<Time<Virtual>>()
                    .set_relative_speed(2.0);
            }
            "n" => {
                println!("NORMAL: setting relative speed to 1x");
                app.world_mut()
                    .resource_mut::<Time<Virtual>>()
                    .set_relative_speed(1.0);
            }
            "s" => {
                println!("SLOW: setting relative speed to 0.5x");
                app.world_mut()
                    .resource_mut::<Time<Virtual>>()
                    .set_relative_speed(0.5);
            }
            "p" => {
                println!("PAUSE: pausing virtual clock");
                app.world_mut().resource_mut::<Time<Virtual>>().pause();
            }
            "u" => {
                println!("UNPAUSE: resuming virtual clock");
                app.world_mut().resource_mut::<Time<Virtual>>().unpause();
            }
            "q" => {
                println!("QUITTING!");
                break;
            }
            _ => {
                help();
            }
        }
    }

    AppExit::Success
}

fn print_real_time(time: Res<Time<Real>>) {
    println!(
        "PreUpdate: this is real time clock, delta is {:?} and elapsed is {:?}",
        time.delta(),
        time.elapsed()
    );
}

fn print_fixed_time(time: Res<Time>) {
    println!(
        "FixedUpdate: this is generic time clock inside fixed, delta is {:?} and elapsed is {:?}",
        time.delta(),
        time.elapsed()
    );
}

fn print_time(time: Res<Time>) {
    println!(
        "Update: this is generic time clock, delta is {:?} and elapsed is {:?}",
        time.delta(),
        time.elapsed()
    );
}

fn main() {
    App::new()
        .add_plugins(MinimalPlugins)
        .insert_resource(Time::<Virtual>::from_max_delta(Duration::from_secs(5)))
        .insert_resource(Time::<Fixed>::from_duration(Duration::from_secs(1)))
        .add_systems(PreUpdate, print_real_time)
        .add_systems(FixedUpdate, print_fixed_time)
        .add_systems(Update, print_time)
        .set_runner(runner)
        .run();
}