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.
This commit is contained in:
Rob Parrett 2023-01-18 17:06:08 +00:00
parent d6bfd44f8f
commit 46293ce1e4

View file

@ -827,7 +827,7 @@ impl World {
let component_id = self.components.init_non_send::<R>(); let component_id = self.components.init_non_send::<R>();
if self if self
.storages .storages
.resources .non_send_resources
.get(component_id) .get(component_id)
.map_or(true, |data| !data.is_present()) .map_or(true, |data| !data.is_present())
{ {
@ -2008,7 +2008,7 @@ impl<T: Default> FromWorld for T {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::World; use super::{FromWorld, World};
use crate::{ use crate::{
change_detection::DetectChangesMut, change_detection::DetectChangesMut,
component::{ComponentDescriptor, ComponentInfo, StorageType}, component::{ComponentDescriptor, ComponentInfo, StorageType},
@ -2230,6 +2230,41 @@ mod tests {
assert_eq!(DROP_COUNT.load(std::sync::atomic::Ordering::SeqCst), 1); 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::<TestResource>();
Self(b.0)
}
}
#[test]
fn init_resource_does_not_overwrite() {
let mut world = World::new();
world.insert_resource(TestResource(0));
world.init_resource::<TestFromWorld>();
world.insert_resource(TestResource(1));
world.init_resource::<TestFromWorld>();
let resource = world.resource::<TestFromWorld>();
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::<TestFromWorld>();
world.insert_resource(TestResource(1));
world.init_non_send_resource::<TestFromWorld>();
let resource = world.non_send_resource::<TestFromWorld>();
assert_eq!(resource.0, 0);
}
#[derive(Component)] #[derive(Component)]
struct Foo; struct Foo;