From 8b3847eb3e879c39f0136e745351af7e4645d743 Mon Sep 17 00:00:00 2001 From: NathanSWard Date: Sun, 30 May 2021 00:59:16 -0600 Subject: [PATCH] fix Assets being set a 'changed' each frame --- crates/bevy_asset/src/asset_server.rs | 6 ++++-- crates/bevy_asset/src/assets.rs | 6 +++++- crates/bevy_asset/src/loader.rs | 4 ++-- crates/bevy_ecs/src/event.rs | 23 +++++++++++++++++++++++ 4 files changed, 34 insertions(+), 5 deletions(-) diff --git a/crates/bevy_asset/src/asset_server.rs b/crates/bevy_asset/src/asset_server.rs index edef868d891a6..c553be3e4a52b 100644 --- a/crates/bevy_asset/src/asset_server.rs +++ b/crates/bevy_asset/src/asset_server.rs @@ -5,7 +5,7 @@ use crate::{ RefChange, RefChangeChannel, SourceInfo, SourceMeta, }; use anyhow::Result; -use bevy_ecs::system::Res; +use bevy_ecs::system::{Res, ResMut}; use bevy_log::warn; use bevy_tasks::TaskPool; use bevy_utils::{HashMap, Uuid}; @@ -466,7 +466,9 @@ impl AssetServer { } } - pub(crate) fn update_asset_storage(&self, assets: &mut Assets) { + // Note: this takes a `ResMut>` to ensure change detection does not get + // triggered unless the `Assets` collection is actually updated. + pub(crate) fn update_asset_storage(&self, mut assets: ResMut>) { let asset_lifecycles = self.server.asset_lifecycles.read(); let asset_lifecycle = asset_lifecycles.get(&T::TYPE_UUID).unwrap(); let mut asset_sources_guard = None; diff --git a/crates/bevy_asset/src/assets.rs b/crates/bevy_asset/src/assets.rs index dfc14417f91ce..299be3e3b9530 100644 --- a/crates/bevy_asset/src/assets.rs +++ b/crates/bevy_asset/src/assets.rs @@ -177,7 +177,11 @@ impl Assets { mut events: EventWriter>, mut assets: ResMut>, ) { - events.send_batch(assets.events.drain()) + // Check if the events are empty before calling `drain`. + // As `drain` triggers change detection. + if !assets.events.is_empty() { + events.send_batch(assets.events.drain()) + } } pub fn len(&self) -> usize { diff --git a/crates/bevy_asset/src/loader.rs b/crates/bevy_asset/src/loader.rs index f941add077b42..825eab38a459e 100644 --- a/crates/bevy_asset/src/loader.rs +++ b/crates/bevy_asset/src/loader.rs @@ -203,7 +203,7 @@ impl Default for AssetLifecycleChannel { /// Updates the [Assets] collection according to the changes queued up by [AssetServer]. pub fn update_asset_storage_system( asset_server: Res, - mut assets: ResMut>, + assets: ResMut>, ) { - asset_server.update_asset_storage(&mut assets); + asset_server.update_asset_storage(assets); } diff --git a/crates/bevy_ecs/src/event.rs b/crates/bevy_ecs/src/event.rs index 975afcf164b89..11de10b34d084 100644 --- a/crates/bevy_ecs/src/event.rs +++ b/crates/bevy_ecs/src/event.rs @@ -342,6 +342,12 @@ impl Events { self.events_b.clear(); } + /// Returns true if there are no events in this collection. + #[inline] + pub fn is_empty(&self) -> bool { + self.events_a.is_empty() && self.events_b.is_empty() + } + /// Creates a draining iterator that removes all events. pub fn drain(&mut self) -> impl Iterator + '_ { self.reset_start_event_count(); @@ -557,4 +563,21 @@ mod tests { .iter(&events) .eq([TestEvent { i: 0 }, TestEvent { i: 1 }].iter())); } + + #[test] + fn test_events_empty() { + let mut events = Events::::default(); + assert!(events.is_empty()); + + events.send(TestEvent { i: 0 }); + assert!(!events.is_empty()); + + events.update(); + assert!(!events.is_empty()); + + // events are only empty after the second call to update + // due to double buffering. + events.update(); + assert!(events.is_empty()); + } }