-
-
Notifications
You must be signed in to change notification settings - Fork 3.9k
RemovedComponents can miss removals in 0.14.0-rc2 #13758
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
Milestone
Comments
I believe this is a genuine bug: we changed the backing of RemovedComponents to use double buffered events at some point. It's the weekend right now but bother me if you can't find the PR. |
Looks like that was back in 0.10 #5680 |
Great! Can you turn your example into a test and try to bisect the problem? |
github-merge-queue bot
pushed a commit
that referenced
this issue
Jun 10, 2024
Fixes #13758. # Objective Calling `update` on the main app already calls `clear_trackers`. Calling it again in `SubApps::update` caused RemovedCompenet Events to be cleared earlier than they should be. ## Solution - Don't call clear_trackers an extra time. ## Testing I manually tested the fix with this unit test: ``` #[cfg(test)] mod test { use crate::core::{FrameCount, FrameCountPlugin}; use crate::prelude::*; #[test] fn test_next_frame_removal() { #[derive(Component)] struct Foo; #[derive(Resource)] struct RemovedCount(usize); let mut app = App::new(); app.add_plugins(FrameCountPlugin); app.add_systems(Startup, |mut commands: Commands| { for _ in 0..100 { commands.spawn(Foo); } commands.insert_resource(RemovedCount(0)); }); app.add_systems(First, |counter: Res<FrameCount>| { println!("Frame {}:", counter.0) }); fn detector_system( mut removals: RemovedComponents<Foo>, foos: Query<Entity, With<Foo>>, mut removed_c: ResMut<RemovedCount>, ) { for e in removals.read() { println!(" Detected removed Foo component for {e:?}"); removed_c.0 += 1; } let c = foos.iter().count(); println!(" Total Foos: {}", c); assert_eq!(c + removed_c.0, 100); } fn deleter_system(foos: Query<Entity, With<Foo>>, mut commands: Commands) { foos.iter().next().map(|e| { commands.entity(e).remove::<Foo>(); }); } app.add_systems(Update, (detector_system, deleter_system).chain()); app.update(); app.update(); app.update(); app.update(); } } ```
mockersf
pushed a commit
that referenced
this issue
Jun 10, 2024
Fixes #13758. # Objective Calling `update` on the main app already calls `clear_trackers`. Calling it again in `SubApps::update` caused RemovedCompenet Events to be cleared earlier than they should be. ## Solution - Don't call clear_trackers an extra time. ## Testing I manually tested the fix with this unit test: ``` #[cfg(test)] mod test { use crate::core::{FrameCount, FrameCountPlugin}; use crate::prelude::*; #[test] fn test_next_frame_removal() { #[derive(Component)] struct Foo; #[derive(Resource)] struct RemovedCount(usize); let mut app = App::new(); app.add_plugins(FrameCountPlugin); app.add_systems(Startup, |mut commands: Commands| { for _ in 0..100 { commands.spawn(Foo); } commands.insert_resource(RemovedCount(0)); }); app.add_systems(First, |counter: Res<FrameCount>| { println!("Frame {}:", counter.0) }); fn detector_system( mut removals: RemovedComponents<Foo>, foos: Query<Entity, With<Foo>>, mut removed_c: ResMut<RemovedCount>, ) { for e in removals.read() { println!(" Detected removed Foo component for {e:?}"); removed_c.0 += 1; } let c = foos.iter().count(); println!(" Total Foos: {}", c); assert_eq!(c + removed_c.0, 100); } fn deleter_system(foos: Query<Entity, With<Foo>>, mut commands: Commands) { foos.iter().next().map(|e| { commands.entity(e).remove::<Foo>(); }); } app.add_systems(Update, (detector_system, deleter_system).chain()); app.update(); app.update(); app.update(); app.update(); } } ```
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Bevy version
0.14.0-rc.2
Reproduction Example
Output when using bevy
0.13.2
Output when using bevy `0.14.0-rc.2
Additional information
Swapping the order of
detector_system
anddeleter_system
results in the events showing up as expected.Replacing
remove::<Foo>
with.despawn()
does not change the outcome.The text was updated successfully, but these errors were encountered: