Skip to content

Wait until FixedUpdate can see events before dropping them #10077

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Nov 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions crates/bevy_app/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ impl Default for App {
app.init_resource::<AppTypeRegistry>();

app.add_plugins(MainSchedulePlugin);

app.add_event::<AppExit>();

#[cfg(feature = "bevy_ci_testing")]
Expand Down
26 changes: 24 additions & 2 deletions crates/bevy_ecs/src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -733,8 +733,30 @@ impl<'a, E: Event> ExactSizeIterator for EventIteratorWithId<'a, E> {
}
}

/// A system that calls [`Events::update`] once per frame.
pub fn event_update_system<T: Event>(mut events: ResMut<Events<T>>) {
#[doc(hidden)]
#[derive(Resource, Default)]
pub struct EventUpdateSignal(bool);

/// A system that queues a call to [`Events::update`].
pub fn event_queue_update_system(signal: Option<ResMut<EventUpdateSignal>>) {
if let Some(mut s) = signal {
s.0 = true;
}
}

/// A system that calls [`Events::update`].
pub fn event_update_system<T: Event>(
signal: Option<ResMut<EventUpdateSignal>>,
mut events: ResMut<Events<T>>,
) {
if let Some(mut s) = signal {
// If we haven't got a signal to update the events, but we *could* get such a signal
// return early and update the events later.
if !std::mem::replace(&mut s.0, false) {
return;
}
}

events.update();
}

Expand Down
13 changes: 8 additions & 5 deletions crates/bevy_time/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,18 @@ pub use time::*;
pub use timer::*;
pub use virt::*;

use bevy_ecs::system::{Res, ResMut};
use bevy_utils::{tracing::warn, Duration, Instant};
pub use crossbeam_channel::TrySendError;
use crossbeam_channel::{Receiver, Sender};

pub mod prelude {
//! The Bevy Time Prelude.
#[doc(hidden)]
pub use crate::{Fixed, Real, Time, Timer, TimerMode, Virtual};
}

use bevy_app::{prelude::*, RunFixedUpdateLoop};
use bevy_ecs::event::{event_queue_update_system, EventUpdateSignal};
use bevy_ecs::prelude::*;
use bevy_utils::{tracing::warn, Duration, Instant};
pub use crossbeam_channel::TrySendError;
use crossbeam_channel::{Receiver, Sender};

/// Adds time functionality to Apps.
#[derive(Default)]
Expand Down Expand Up @@ -60,6 +59,10 @@ impl Plugin for TimePlugin {
)
.add_systems(RunFixedUpdateLoop, run_fixed_update_schedule);

// ensure the events are not dropped until `FixedUpdate` systems can observe them
app.init_resource::<EventUpdateSignal>()
.add_systems(FixedUpdate, event_queue_update_system);

#[cfg(feature = "bevy_ci_testing")]
if let Some(ci_testing_config) = app
.world
Expand Down