-
-
Notifications
You must be signed in to change notification settings - Fork 4.4k
Description
Hello everyone!
On https://bevyengine.org/news/bevy-0-4/, there's this code snippet:
// on each update this system runs once and internally iterates over each entity
fn system(time: Res<Time>, query: Query<(Entity, &mut Transform)>) {
for (entity, mut transform) in query.iter_mut() {
// do per-entity logic here
}
}Since iter_mut() takes &mut self, the function parameter should be mut query, no?
Given that, I'll try to fill out the feature template, although it's more of a general API discussion than a concrete request 🙂
What problem does this solve or what need does it fill?
For me, it's not immediately obvious that Query::iter_mut() operates on &mut self, as logically, the query itself is not mutated, but rather the components being queried.
Also, iter() already provides a specific trait bound ReadOnlyFetch, so it cannot be used for mutable queries:
/// Iterates over the query results. This can only be called for read-only queries
#[inline]
pub fn iter(&self) -> QueryIter<'_, Q, F>
where
Q::Fetch: ReadOnlyFetch, // <-- this bound
{
// SAFE: system runs without conflicts with other systems.
// same-system queries have runtime borrow checks when they conflict
unsafe { self.world.query_unchecked() }
}
/// Iterates over the query results
#[inline]
pub fn iter_mut(&mut self) -> QueryIter<'_, Q, F> {
// SAFE: system runs without conflicts with other systems.
// same-system queries have runtime borrow checks when they conflict
unsafe { self.world.query_unchecked() }
}Is the actual reason to enforce unique access (non-aliasing), so that no two mutable queries can run at the same time? The only thing I can imagine here is doing that in a nested loop, and doing so would probably not make sense for iter() queries either.
What solution would you like?
If compatible with safety, allowing iter_mut() on &self could be considered.
If not, we can document the background why &mut self is used.
What alternative(s) have you considered?
Leaving everything as is, fixing the 0.4 release notes and improving documentation.
Additional context
I looked at #753 (aligning with Rust conventions) and #796 (a bug related to safety, although not directly related to this).