Skip to content

Commit

Permalink
Fix bug where events where not being dropped
Browse files Browse the repository at this point in the history
  • Loading branch information
Dig-Doug committed Jan 25, 2024
1 parent b592a72 commit ee75aa1
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 13 deletions.
4 changes: 3 additions & 1 deletion crates/bevy_app/src/app.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{First, Main, MainSchedulePlugin, Plugin, Plugins, StateTransition};
use crate::{First, FixedPostUpdate, Main, MainSchedulePlugin, Plugin, Plugins, StateTransition};
pub use bevy_derive::AppLabel;
use bevy_ecs::{
prelude::*,
Expand Down Expand Up @@ -507,6 +507,8 @@ impl App {
bevy_ecs::event::event_update_system::<T>
.run_if(bevy_ecs::event::event_update_condition::<T>),
);
self.init_resource::<bevy_ecs::event::EventUpdateSignal<T>>()
.add_systems(FixedPostUpdate, bevy_ecs::event::event_queue_update_system::<T>);
}
self
}
Expand Down
45 changes: 36 additions & 9 deletions crates/bevy_ecs/src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ use std::{
marker::PhantomData,
slice::Iter,
};
use bevy_utils::tracing::error;

/// A type that can be stored in an [`Events<E>`] resource
/// You can conveniently access events using the [`EventReader`] and [`EventWriter`] system parameter.
///
Expand All @@ -33,6 +35,7 @@ pub struct EventId<E: Event> {
}

impl<E: Event> Copy for EventId<E> {}

impl<E: Event> Clone for EventId<E> {
fn clone(&self) -> Self {
*self
Expand Down Expand Up @@ -747,27 +750,51 @@ impl<'a, E: Event> ExactSizeIterator for EventIteratorWithId<'a, E> {
}
}

#[doc(hidden)]
#[derive(Resource)]
pub struct EventUpdateSignal<T: Event> {
signal: bool,
_marker: PhantomData<fn() -> T>,
}

impl<T: Event> Default for EventUpdateSignal<T> {
fn default() -> Self {
Self {
signal: false,
_marker: PhantomData,
}
}
}

#[doc(hidden)]
#[derive(Resource, Default)]
pub struct EventUpdateSignal(bool);
pub struct EventUpdateShouldWaitForFixedUpdate;

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

/// A system that calls [`Events::update`].
pub fn event_update_system<T: Event>(
signal: Option<ResMut<EventUpdateSignal>>,
should_wait: Option<Res<EventUpdateShouldWaitForFixedUpdate>>,
mut should_update: Option<ResMut<EventUpdateSignal<T>>>,
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;
if should_wait.is_some() {
match should_update {
Some(mut should_update) => {
// 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 should_update.signal, false) {
return;
}
}
None => {
error!("EventUpdateSignal<{0}> resource not found but fixed update systems are active. Please add EventUpdateSignal<{0}> as a resource", std::any::type_name::<T>());
}
}
}

Expand Down
5 changes: 2 additions & 3 deletions crates/bevy_time/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ pub mod prelude {
}

use bevy_app::{prelude::*, RunFixedMainLoop};
use bevy_ecs::event::{event_queue_update_system, EventUpdateSignal};
use bevy_ecs::event::{EventUpdateShouldWaitForFixedUpdate};
use bevy_ecs::prelude::*;
use bevy_utils::{tracing::warn, Duration, Instant};
pub use crossbeam_channel::TrySendError;
Expand Down Expand Up @@ -60,8 +60,7 @@ impl Plugin for TimePlugin {
.add_systems(RunFixedMainLoop, run_fixed_main_schedule);

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

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

0 comments on commit ee75aa1

Please sign in to comment.