-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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
Add AssetChanged
query filter
#16810
Conversation
Why does this revert the |
Because I didn't know that. Will change it back! |
Separately, how should the resource access in |
|
||
/// Filter that selects entities with a `A` for an asset that changed | ||
/// after the system last ran, where `A` is a component that implements | ||
/// [`AsAssetId`]. |
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.
What about components that store handles to multiple assets of the same type? We don't need to do that right now, but we might have to revisit it later. In my app I have components with handles to dozens of AnimationClip
s for example. I think you could maybe just have AsAssetId
's method return -> impl Iterator<Item = AssetId>
.
This isn't blocking, just a suggestion.
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.
The bigger issue is how to handle the associated type. We might have to use some kind of indirection via UntypedAssetId instead to be able to handle multiple kinds of assets.
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.
Sorry, I also misunderstood you. Multiple assets of the same type should be much easier to handle. I'd been hung up on if, for example we decided to merge mesh and material as has been discussed before.
How would the user forge an id if they do not have access to the underlying type? |
Co-authored-by: Patrick Walton <pcwalton@mimiga.net>
Overall this looks fine to me, but as I mentioned we should have an ECS expert look over the |
crates/bevy_ecs/src/query/state.rs
Outdated
@@ -583,6 +583,16 @@ impl<D: QueryData, F: QueryFilter> QueryState<D, F> { | |||
{ | |||
access.add_component_write(archetype_component_id); | |||
} | |||
if self.component_access.access.has_resource_read(component_id) { |
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.
Oh right, this is an existing soundness bug. Re-adding the tag.
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.
These changes have been removed in favor of @chescock's.
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
# Objective Allow resources to be accessed soundly by `QueryData` and `QueryFilter` implementations. This mostly works today, and is used in `bevy-trait-query` and will be used by #16810. The problem is that the access is not made visible to the executor, so it would be possible for a system with resource access in a query to run concurrently with a system that accesses the resource with `ResMut`, resulting in Undefined Behavior. ## Solution Define calling `add_resource_read` or `add_resource_write` in `WorldQuery::update_component_access` to be a supported way to declare resource access in a query. Modify `QueryState::new_with_access` to check for resource access and report it in `archetype_component_acccess`. Modify `FilteredAccess::is_compatible` to consider resource access conflicting even on queries with disjoint filters.
Co-authored-by: Chris Russell <8494645+chescock@users.noreply.github.com>
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.
Seems fine, with the caveat that as usual I'm not an expert on the ECS guts.
/// This resource is automatically managed by the [`AssetEvents`](crate::AssetEvents) schedule and | ||
/// should not be exposed to the user in order to maintain safety guarantees. Any additional uses of | ||
/// this resource should be carefully audited to ensure that they do not introduce any safety | ||
/// issues. |
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.
When you mean "should not be exposed", what do you mean? Changing the fields?
I ask because usually safety invariants are scoped to be module-private, not crate-private.
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.
This mostly is meant to mean don't make this pub because some asks. It's crate scoped mostly due to code organization, having the filter live in its own file is I think preferable to including all of this code in the root lib file where the asset event system lives simply for the sake of keeping it module private.
# Objective Allow resources to be accessed soundly by `QueryData` and `QueryFilter` implementations. This mostly works today, and is used in `bevy-trait-query` and will be used by bevyengine#16810. The problem is that the access is not made visible to the executor, so it would be possible for a system with resource access in a query to run concurrently with a system that accesses the resource with `ResMut`, resulting in Undefined Behavior. ## Solution Define calling `add_resource_read` or `add_resource_write` in `WorldQuery::update_component_access` to be a supported way to declare resource access in a query. Modify `QueryState::new_with_access` to check for resource access and report it in `archetype_component_acccess`. Modify `FilteredAccess::is_compatible` to consider resource access conflicting even on queries with disjoint filters.
# 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.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. AnAssetChanged
filter will drastically simplify our implementation and be more robust to future changes.Originally implemented by @nicopap in #5080.
Solution
AssetChanged
query filter that initializes aAssetChanges<A>
resource that tracks changed assets and ticks inasset_events
.Reverts constrain WorldQuery::get_state to only use &Components #13343 and changes the api ofget_state
to acceptimpl Into<UnsafeWorldCell<'w>>
to allow accessing theAssetChanges<A>
resource.AsAssetId
trait used for newtype handle wrappers (e.g.Mesh3d
) that allows associating a component with the underlyingAsset
it represents.Testing
AssetChanged
.Mesh3d
andMeshMaterial3d
(etc) in the renderer. Long term wins in render performance this unblocks should swamp tracking overhead for any realistic workload.Migration Guide
asset_events
system is no longer public. Users should order their systems relative to theAssetEvents
system set.