Skip to content
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

[Merged by Bors] - Allow access to non-send resource through World::resource_scope #6113

Closed
wants to merge 7 commits into from

Conversation

Pietrek14
Copy link
Contributor

@Pietrek14 Pietrek14 commented Sep 27, 2022

Objective

Relaxes the trait bound for World::resource_scope to allow non-send resources. Fixes #6037.

Solution

No big changes in code had to be made. Added a check so that the non-send resources won't be accessed from a different thread.


Changelog

  • World::resource_scope accepts non-send resources now
  • World::resource_scope verifies non-send access if the resource is non-send
  • Two new tests are added, one for valid use of World::resource_scope with a non-send resource, and one for invalid use (calling it from a different thread, resulting in panic)

@hymm hymm self-requested a review September 27, 2022 17:38
@alice-i-cecile alice-i-cecile added A-ECS Entities, components, systems, and events C-Usability A simple quality-of-life change that makes Bevy easier to use labels Sep 27, 2022
#[test]
fn non_send_resource_scope() {
let mut world = World::default();
world.insert_non_send_resource(A(0));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should probably use a different resource type that is deliberately not Send.

@alice-i-cecile
Copy link
Member

A small nit about the tests, but the logic itself looks sensible to me. Very nice first contribution!

}

#[test]
#[should_panic]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can probably use #[should_panic(expected = "fill this in with some error text")] here.

// Should result in a panic
world.resource_scope(|world: &mut World, mut value: Mut<A>| {
value.0 += 1;
assert!(!world.contains_resource::<A>());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you need this assert here? The test should panic before hitting this line.

});
});

assert_eq!(world.get_non_send_resource::<A>().unwrap().0, 1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above here.

@Pietrek14
Copy link
Contributor Author

Thanks for the feedback, I think it's fixed now.

Comment on lines 1292 to 1296
});

if let Err(err) = thread.join() {
panic!("{}", err.downcast::<String>().unwrap());
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
});
if let Err(err) = thread.join() {
panic!("{}", err.downcast::<String>().unwrap());
}
}).join().unwrap();

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to do it that way, but then the panic message doesn't match the expected one ("called Result::unwrap() on an Err value: Any { .. }" instead of "attempted to access NonSend resource bevy_ecs::tests::NonSend off of the main thread").

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's sad that that doesn't contain the actual error message. This approach looks fine then. Just made a small suggestion above.

crates/bevy_ecs/src/lib.rs Outdated Show resolved Hide resolved
Co-authored-by: Mike <mike.hsu@gmail.com>
Copy link
Member

@DJMcNab DJMcNab left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems reasonable to me.

The pr should have a Changelog section I think, but this isn't a breaking change so shouldn't need a migration guide.

@@ -78,6 +79,9 @@ mod tests {
#[derive(Component, Debug, PartialEq, Eq, Clone, Copy)]
struct C;

#[derive(Default)]
struct NonSend(usize, PhantomData<*mut ()>);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not ideal that this shadows the name of the 'real' NonSend.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed it to NonSendA

@@ -1149,14 +1149,27 @@ impl World {
/// });
/// assert_eq!(world.get_resource::<A>().unwrap().0, 2);
/// ```
pub fn resource_scope<R: Resource, U>(&mut self, f: impl FnOnce(&mut World, Mut<R>) -> U) -> U {
pub fn resource_scope<
R: 'static, /* The resource doesn't need to be Send nor Sync. */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really we should remove the Send/Sync supertraits on resources, because the fact that you can add anything as a non send resource is a bit messy.

But this is fine for now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you should open another issue about it, since it's out of the scope of this PR.

@hymm hymm added the S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it label Sep 28, 2022
Copy link
Member

@alice-i-cecile alice-i-cecile left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bors r+

bors bot pushed a commit that referenced this pull request Sep 28, 2022
)

# Objective

Relaxes the trait bound for `World::resource_scope` to allow non-send resources. Fixes #6037.

## Solution

No big changes in code had to be made. Added a check so that the non-send resources won't be accessed from a different thread.

---

## Changelog
 - `World::resource_scope` accepts non-send resources now
 - `World::resource_scope` verifies non-send access if the resource is non-send
 - Two new tests are added, one for valid use of `World::resource_scope` with a non-send resource, and one for invalid use (calling it from a different thread, resulting in panic)

Co-authored-by: Dawid Piotrowski <41804418+Pietrek14@users.noreply.github.com>
@bors bors bot changed the title Allow access to non-send resource through World::resource_scope [Merged by Bors] - Allow access to non-send resource through World::resource_scope Sep 28, 2022
@bors bors bot closed this Sep 28, 2022
james7132 pushed a commit to james7132/bevy that referenced this pull request Oct 19, 2022
…vyengine#6113)

# Objective

Relaxes the trait bound for `World::resource_scope` to allow non-send resources. Fixes bevyengine#6037.

## Solution

No big changes in code had to be made. Added a check so that the non-send resources won't be accessed from a different thread.

---

## Changelog
 - `World::resource_scope` accepts non-send resources now
 - `World::resource_scope` verifies non-send access if the resource is non-send
 - Two new tests are added, one for valid use of `World::resource_scope` with a non-send resource, and one for invalid use (calling it from a different thread, resulting in panic)

Co-authored-by: Dawid Piotrowski <41804418+Pietrek14@users.noreply.github.com>
james7132 pushed a commit to james7132/bevy that referenced this pull request Oct 28, 2022
…vyengine#6113)

# Objective

Relaxes the trait bound for `World::resource_scope` to allow non-send resources. Fixes bevyengine#6037.

## Solution

No big changes in code had to be made. Added a check so that the non-send resources won't be accessed from a different thread.

---

## Changelog
 - `World::resource_scope` accepts non-send resources now
 - `World::resource_scope` verifies non-send access if the resource is non-send
 - Two new tests are added, one for valid use of `World::resource_scope` with a non-send resource, and one for invalid use (calling it from a different thread, resulting in panic)

Co-authored-by: Dawid Piotrowski <41804418+Pietrek14@users.noreply.github.com>
ItsDoot pushed a commit to ItsDoot/bevy that referenced this pull request Feb 1, 2023
…vyengine#6113)

# Objective

Relaxes the trait bound for `World::resource_scope` to allow non-send resources. Fixes bevyengine#6037.

## Solution

No big changes in code had to be made. Added a check so that the non-send resources won't be accessed from a different thread.

---

## Changelog
 - `World::resource_scope` accepts non-send resources now
 - `World::resource_scope` verifies non-send access if the resource is non-send
 - Two new tests are added, one for valid use of `World::resource_scope` with a non-send resource, and one for invalid use (calling it from a different thread, resulting in panic)

Co-authored-by: Dawid Piotrowski <41804418+Pietrek14@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-ECS Entities, components, systems, and events C-Usability A simple quality-of-life change that makes Bevy easier to use S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add resource_scope variant for nonsend resources
4 participants