Skip to content

EntityMut::get_components_mut. #20273

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

chescock
Copy link
Contributor

Objective

Provide a simple way to get mutable access to multiple components from an EntityMut at the cost of some performance.

This is the API from #13375, but with access checks added. Cart said these checks are "dissatisfying from a perf perspective because Access allocates" in #13375 (comment). But we haven't found a more performant approach, and there are use cases where doing these checks on each call is still fast enough.

Note that unchecked variants were added in #20265.

Solution

Add get_components_mut and into_components_mut to EntityMut and EntityWorldMut. Have them perform the access checks by calling QueryData::update_component_access before calling into_components_mut_unchecked.

@chescock chescock added A-ECS Entities, components, systems, and events C-Usability A targeted quality-of-life change that makes Bevy easier to use S-Needs-Review Needs reviewer attention (from anyone!) to move forward C-Feature A new feature, making something new possible and removed C-Usability A targeted quality-of-life change that makes Bevy easier to use labels Jul 24, 2025
@cBournhonesque
Copy link
Contributor

I'm not sure if this is a good idea; the access checks are precisely the reason why #13375 was not merged.

Adding unsafe variants in #20265 is one thing (since there is no perf cost and the user has to opt-in to using unsafe), but adding this safe API will encourage a lot of users to start using it without necessarily putting thought into the perf implications.

I guess @cart should probably weigh in?

@chescock
Copy link
Contributor Author

I'm not sure if this is a good idea; the access checks are precisely the reason why #13375 was not merged.

Adding unsafe variants in #20265 is one thing (since there is no perf cost and the user has to opt-in to using unsafe), but adding this safe API will encourage a lot of users to start using it without necessarily putting thought into the perf implications.

Yeah, I won't be too surprised if this gets closed, but I think it's worth considering, and I had the code ready. :)

There are plenty of cases where the perf cost won't matter, and there are users who want this functionality even with the cost. And if they wind up in a situation where the performance is a problem, they can switch to the unchecked variants to skip the runtime checks.

(And for code that's really performance sensitive, you even want to avoid the .get::<C>() methods since they do the hash lookup from TypeId to ComponentId on every call. You'll want to cache the ComponentId, either using queries or calling the _by_id methods manually.)

@EmileGr
Copy link

EmileGr commented Jul 25, 2025

adding this safe API will encourage a lot of users to start using it without necessarily putting thought into the perf implications.

I can understand that users may gravitate towards it purely because it's marked as safe. That said, there's no excuse for users not profiling their code and Bevy should not design its API as if users cannot be trusted to do that. Simply document it as being much slower than the unchecked version and let users decide.

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-Feature A new feature, making something new possible S-Needs-Review Needs reviewer attention (from anyone!) to move forward
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants