Confused about the timing of event updates and consumption in Bevy

44 Views Asked by At

I am trying the following code to learn about the Event in the Bevy engine:

use bevy::prelude::*;

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

fn runner(mut app: App) {
    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();
            }
            "u" => {
                println!("UNPAUSE: resuming virtual clock");
                app.world.resource_mut::<Time<Virtual>>().unpause();
            }
            _ => {
                println!("QUITTING!");
                break;
            }
        }
    }
}

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)))
        .insert_resource(Counter(0))
        .add_event::<MyEvent>()
        .add_systems(PreUpdate, print_real_time)
        .add_systems(FixedUpdate, (
            print_fixed_time,
            send_event,
            read_event
        ).chain())
        .add_systems(Update, print_time)
        .set_runner(runner)
        .run();
}

#[derive(Event, Default)]
struct MyEvent;

#[derive(Resource)]
struct Counter(i32);

fn send_event(mut events: EventWriter<MyEvent>, mut counter: ResMut<Counter>) {
    if counter.0 == 0 {
        counter.0 = 1;
        events.send_default();
    }
}

fn read_event(events: EventReader<MyEvent>) {
    println!("events.len: {:?}", events.len());
}

According to my current understanding, the old event queue should be cleared after each call to app.update(). However, when I run the code, I get the following output.

u
UNPAUSE: resuming virtual clock

PreUpdate: this is real time clock, delta is 0ns and elapsed is 0ns
Update: this is generic time clock, delta is 0ns and elapsed is 0ns

PreUpdate: this is real time clock, delta is 339.5194ms and elapsed is 339.5194ms
Update: this is generic time clock, delta is 339.5194ms and elapsed is 339.5194ms

PreUpdate: this is real time clock, delta is 284.6968ms and elapsed is 624.2162ms        
Update: this is generic time clock, delta is 284.6968ms and elapsed is 624.2162ms        

PreUpdate: this is real time clock, delta is 259.5447ms and elapsed is 883.7609ms        
Update: this is generic time clock, delta is 259.5447ms and elapsed is 883.7609ms        

PreUpdate: this is real time clock, delta is 331.6477ms and elapsed is 1.2154086s        
FixedUpdate: this is generic time clock inside fixed, delta is 1s and elapsed is 1s      
events.len: 1
Update: this is generic time clock, delta is 331.6477ms and elapsed is 1.2154086s        

PreUpdate: this is real time clock, delta is 280.329ms and elapsed is 1.4957376s
Update: this is generic time clock, delta is 280.329ms and elapsed is 1.4957376s

PreUpdate: this is real time clock, delta is 304.713ms and elapsed is 1.8004506s
Update: this is generic time clock, delta is 304.713ms and elapsed is 1.8004506s

PreUpdate: this is real time clock, delta is 287.542ms and elapsed is 2.0879926s
FixedUpdate: this is generic time clock inside fixed, delta is 1s and elapsed is 2s      
events.len: 1
Update: this is generic time clock, delta is 287.542ms and elapsed is 2.0879926s

PreUpdate: this is real time clock, delta is 268.0542ms and elapsed is 2.3560468s        
Update: this is generic time clock, delta is 268.0542ms and elapsed is 2.3560468s        

PreUpdate: this is real time clock, delta is 279.7958ms and elapsed is 2.6358426s        
Update: this is generic time clock, delta is 279.7958ms and elapsed is 2.6358426s        

PreUpdate: this is real time clock, delta is 287.9875ms and elapsed is 2.9238301s        
Update: this is generic time clock, delta is 287.9875ms and elapsed is 2.9238301s        

PreUpdate: this is real time clock, delta is 359.947ms and elapsed is 3.2837771s
FixedUpdate: this is generic time clock inside fixed, delta is 1s and elapsed is 3s      
events.len: 0
Update: this is generic time clock, delta is 359.947ms and elapsed is 3.2837771s   
quit
QUITTING!

There are two Updates between the first and second FixedUpdate, yet this does not clear the event queue. Instead, it is after the second FixedUpdate that the event queue is cleared.

On the other hand, if I don't trigger Update so frequently, everything appears to be normal, as shown below:

u
UNPAUSE: resuming virtual clock

PreUpdate: this is real time clock, delta is 0ns and elapsed is 0ns
Update: this is generic time clock, delta is 0ns and elapsed is 0ns

PreUpdate: this is real time clock, delta is 4.3637156s and elapsed is 4.3637156s
FixedUpdate: this is generic time clock inside fixed, delta is 1s and elapsed is 1s
events.len: 1
FixedUpdate: this is generic time clock inside fixed, delta is 1s and elapsed is 2s      
events.len: 1
FixedUpdate: this is generic time clock inside fixed, delta is 1s and elapsed is 3s      
events.len: 1
FixedUpdate: this is generic time clock inside fixed, delta is 1s and elapsed is 4s      
events.len: 1
Update: this is generic time clock, delta is 4.3637156s and elapsed is 4.3637156s        

PreUpdate: this is real time clock, delta is 1.3086969s and elapsed is 5.6724125s        
FixedUpdate: this is generic time clock inside fixed, delta is 1s and elapsed is 5s      
events.len: 1
Update: this is generic time clock, delta is 1.3086969s and elapsed is 5.6724125s        

PreUpdate: this is real time clock, delta is 998.9384ms and elapsed is 6.6713509s        
FixedUpdate: this is generic time clock inside fixed, delta is 1s and elapsed is 6s      
events.len: 0
Update: this is generic time clock, delta is 998.9384ms and elapsed is 6.6713509s        
quit
QUITTING!

The event queue is cleared after the second Update.

Hope someone could shed some light on this for me.

1

There are 1 best solutions below

1
youzheyin On

I post the same question on gitbub and have got the answer.

For short, this is not the final form of the event system but just a stopgap. Only use the event system when you are certain to the behaviour.