From 46293ce1e4c61421e353dc0b0431da67af6b7568 Mon Sep 17 00:00:00 2001 From: Rob Parrett Date: Wed, 18 Jan 2023 17:06:08 +0000 Subject: [PATCH] Fix init_non_send_resource overwriting previous values (#7261) # Objective Repeated calls to `init_non_send_resource` currently overwrite the old value because the wrong storage is being checked. ## Solution Use the correct storage. Add some tests. ## Notes Without the fix, the new test fails with ``` thread 'world::tests::init_non_send_resource_does_not_overwrite' panicked at 'assertion failed: `(left == right)` left: `1`, right: `0`', crates/bevy_ecs/src/world/mod.rs:2267:9 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace test world::tests::init_non_send_resource_does_not_overwrite ... FAILED ``` This was introduced by #7174 and it seems like a fairly straightforward oopsie. --- crates/bevy_ecs/src/world/mod.rs | 39 ++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/crates/bevy_ecs/src/world/mod.rs b/crates/bevy_ecs/src/world/mod.rs index 066268526e..7fe6aecd2b 100644 --- a/crates/bevy_ecs/src/world/mod.rs +++ b/crates/bevy_ecs/src/world/mod.rs @@ -827,7 +827,7 @@ impl World { let component_id = self.components.init_non_send::(); if self .storages - .resources + .non_send_resources .get(component_id) .map_or(true, |data| !data.is_present()) { @@ -2008,7 +2008,7 @@ impl FromWorld for T { #[cfg(test)] mod tests { - use super::World; + use super::{FromWorld, World}; use crate::{ change_detection::DetectChangesMut, component::{ComponentDescriptor, ComponentInfo, StorageType}, @@ -2230,6 +2230,41 @@ mod tests { assert_eq!(DROP_COUNT.load(std::sync::atomic::Ordering::SeqCst), 1); } + #[derive(Resource)] + struct TestFromWorld(u32); + impl FromWorld for TestFromWorld { + fn from_world(world: &mut World) -> Self { + let b = world.resource::(); + Self(b.0) + } + } + + #[test] + fn init_resource_does_not_overwrite() { + let mut world = World::new(); + world.insert_resource(TestResource(0)); + world.init_resource::(); + world.insert_resource(TestResource(1)); + world.init_resource::(); + + let resource = world.resource::(); + + assert_eq!(resource.0, 0); + } + + #[test] + fn init_non_send_resource_does_not_overwrite() { + let mut world = World::new(); + world.insert_resource(TestResource(0)); + world.init_non_send_resource::(); + world.insert_resource(TestResource(1)); + world.init_non_send_resource::(); + + let resource = world.non_send_resource::(); + + assert_eq!(resource.0, 0); + } + #[derive(Component)] struct Foo;