-
-
Notifications
You must be signed in to change notification settings - Fork 3.8k
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
constrain WorldQuery::get_state to only use &Components #13343
constrain WorldQuery::get_state to only use &Components #13343
Conversation
Welcome, new contributor! Please make sure you've read our contributing guide and we look forward to reviewing your pull request shortly ✨ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In terms of trait design, I don't think this is appropriate, given that init_state
, the infallible version of get_state
requires a &mut World
, there may be WorldQuery
implementations that may read other state in the world (i.e. resources, other metadata, etc).
If we were to seal WorldQuery
so that it cannot be externally implemented, this change may make more sense, and it does seem like something that @maniwani was looking into for ABI compatibility. However, without those changes, I don't think this is a limitation we should be imposing without also limiting the scope of init_state
.
That is true, I added this change in the second commit. |
I realized that because |
Since the |
f4a2b5a
to
0637ee4
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with this as an immediately actionable step to address UB. The restriction on get_state fundamentally makes sense to me: queries should generally not be accessing non-component data. I can see a world where additional data (like indexes) are requested, but I would rather lock this down now and then add more careful access.
init_state
should be changed to match, but that doesn't have to happen right now, and frankly probably shouldn't, given that it will require more careful design thought.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, deferring to a later PR SGTM, so long as both make it into 0.14.
…3442) # Objective In #13343, `WorldQuery::get_state` was constrained from `&World` as the argument to `&Components`, but `WorldQuery::init_state` hasn't yet been changed from `&mut World` to match. Fixes #13358 ## Solution Create a wrapper around `&mut Components` and `&mut Storages` that can be obtained from `&mut World` with a `component_initializer` method. This new `ComponentInitializer` re-exposes the API on `&mut Components` minus the `&mut Storages` parameter where it was present. For the `&Components` API, it simply derefs to its `components` field. ## Changelog ### Added The `World::component_initializer` method. The `ComponentInitializer` struct that re-exposes `Components` API. ### Changed `WorldQuery::init_state` now takes `&mut ComponentInitializer` instead of `&mut World`. ## Migration Guide Instead of passing `&mut World` to `WorldQuery::init_state` directly, pass in a mutable reference to the struct returned from `World::component_initializer`.
# Objective Implement a new `AssetChanged` query filter that allows users to query for entities whose related assets may have changed. - Closes #5069 - Unblocks #16420. Currently, `cold-specialization`, a key rendering optimization for unlocking ancillary benefits of the retained render world, is blocked on being unable detect all scenarios in which an entity's mesh/material changes using events and observers. An `AssetChanged` filter will drastically simplify our implementation and be more robust to future changes. Originally implemented by @nicopap in #5080. ## Solution - Adds a new `AssetChanged` query filter that initializes a `AssetChanges<A>` resource that tracks changed assets and ticks in `asset_events`. - ~Reverts #13343 and changes the api of `get_state` to accept `impl Into<UnsafeWorldCell<'w>>` to allow accessing the `AssetChanges<A>` resource.~ - Adds a `AsAssetId` trait used for newtype handle wrappers (e.g. `Mesh3d`) that allows associating a component with the underlying `Asset` it represents. ## Testing - Tests are added for `AssetChanged`. - TBD on performance. We are going to add this `Mesh3d` and `MeshMaterial3d` (etc) in the renderer. Long term wins in render performance this unblocks should swamp tracking overhead for any realistic workload. ## Migration Guide - The `asset_events` system is no longer public. Users should order their systems relative to the `AssetEvents` system set. --------- Co-authored-by: Nicola Papale <nico@nicopap.ch> Co-authored-by: Patrick Walton <pcwalton@mimiga.net> Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com> Co-authored-by: Chris Russell <8494645+chescock@users.noreply.github.com>
# Objective Implement a new `AssetChanged` query filter that allows users to query for entities whose related assets may have changed. - Closes bevyengine#5069 - Unblocks bevyengine#16420. Currently, `cold-specialization`, a key rendering optimization for unlocking ancillary benefits of the retained render world, is blocked on being unable detect all scenarios in which an entity's mesh/material changes using events and observers. An `AssetChanged` filter will drastically simplify our implementation and be more robust to future changes. Originally implemented by @nicopap in bevyengine#5080. ## Solution - Adds a new `AssetChanged` query filter that initializes a `AssetChanges<A>` resource that tracks changed assets and ticks in `asset_events`. - ~Reverts bevyengine#13343 and changes the api of `get_state` to accept `impl Into<UnsafeWorldCell<'w>>` to allow accessing the `AssetChanges<A>` resource.~ - Adds a `AsAssetId` trait used for newtype handle wrappers (e.g. `Mesh3d`) that allows associating a component with the underlying `Asset` it represents. ## Testing - Tests are added for `AssetChanged`. - TBD on performance. We are going to add this `Mesh3d` and `MeshMaterial3d` (etc) in the renderer. Long term wins in render performance this unblocks should swamp tracking overhead for any realistic workload. ## Migration Guide - The `asset_events` system is no longer public. Users should order their systems relative to the `AssetEvents` system set. --------- Co-authored-by: Nicola Papale <nico@nicopap.ch> Co-authored-by: Patrick Walton <pcwalton@mimiga.net> Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com> Co-authored-by: Chris Russell <8494645+chescock@users.noreply.github.com>
# Objective Implement a new `AssetChanged` query filter that allows users to query for entities whose related assets may have changed. - Closes bevyengine#5069 - Unblocks bevyengine#16420. Currently, `cold-specialization`, a key rendering optimization for unlocking ancillary benefits of the retained render world, is blocked on being unable detect all scenarios in which an entity's mesh/material changes using events and observers. An `AssetChanged` filter will drastically simplify our implementation and be more robust to future changes. Originally implemented by @nicopap in bevyengine#5080. ## Solution - Adds a new `AssetChanged` query filter that initializes a `AssetChanges<A>` resource that tracks changed assets and ticks in `asset_events`. - ~Reverts bevyengine#13343 and changes the api of `get_state` to accept `impl Into<UnsafeWorldCell<'w>>` to allow accessing the `AssetChanges<A>` resource.~ - Adds a `AsAssetId` trait used for newtype handle wrappers (e.g. `Mesh3d`) that allows associating a component with the underlying `Asset` it represents. ## Testing - Tests are added for `AssetChanged`. - TBD on performance. We are going to add this `Mesh3d` and `MeshMaterial3d` (etc) in the renderer. Long term wins in render performance this unblocks should swamp tracking overhead for any realistic workload. ## Migration Guide - The `asset_events` system is no longer public. Users should order their systems relative to the `AssetEvents` system set. --------- Co-authored-by: Nicola Papale <nico@nicopap.ch> Co-authored-by: Patrick Walton <pcwalton@mimiga.net> Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com> Co-authored-by: Chris Russell <8494645+chescock@users.noreply.github.com>
Objective
Passing
&World
in theWorldQuery::get_state
method is unnecessary, as all implementations of this method in the engine either only accessComponents
in&World
, or do nothing with it.It can introduce UB by necessitating the creation of a
&World
from aUnsafeWorldCell
.This currently happens in
Query::transmute_lens
, which obtains a&World
from the internalUnsafeWorldCell
solely to pass toget_state
.Query::join
suffers from the same issue.Other cases of UB come from allowing implementors of
WorldQuery
to freely access&World
, like in thebevy-trait-query
crate, where a reference to a resource is obtained inside ofget_state
, potentially aliasing with aResMut
parameter in the same system.WorldQuery::init_state
currently requires&mut World
, which doesn't suffer from these issues.But that too can be changed to receive a wrapper around
&mut Components
and&mut Storages
for consistency in a follow-up PR.Solution
Replace the
&World
parameter inget_state
with&Components
.Changelog
WorldQuery::get_state
now takes&Components
instead of&World
.The
transmute
,transmute_filtered
,join
andjoin_filtered
methods onQueryState
now similarly take&Components
instead of&World
.Migration Guide
Users of
WorldQuery::get_state
ortransmute
,transmute_filtered
,join
andjoin_filtered
methods onQueryState
now need to pass&Components
instead of&World
.&Components
can be trivially obtained from eithercomponents
method on&World
orUnsafeWorldCell
.For implementors of
WorldQuery::get_state
that were accessing more than theComponents
inside&World
and its methods, this is no longer allowed.