What problem does this solve or what need does it fill?
A major pain point of using Handle<Asset> as components in the ECS currently is that the assets pointed-to by the handle can change, and there is no simple way of reacting to changes to the asset in the context of the ECS.
For example: AABB calculation. We have a Handle<Mesh> and Aabb component in the ECS. We want to update Aabb whenever the Mesh for the Handle is updated. The Handle is updated in two circumstances:
The user changes the Handle the entity has by replacing it in a system with a Query<&mut Handle<Mesh>> parameter
The user changes the Mesh in the Assets<Mesh> in a system with a ResMut<Assets<Mesh>> parameter
To react to (1), it's trivial: just add a Changed<Handle<Mesh>> to the system that updates the Aabb.
To react to (2), it becomes harder. The only way to react to asset changes is to use the AssetEvent::Modified { handle: Handle<Mesh> } event. This event only holds a Handle<Mesh>, so you either need to iterate over ALL entities with a Handle<Mesh> and updates the ones that are equal to the Modified field, or keep a HashMap mapping handles to entities, and other gory details required to maintain this HashMap properly.
Most of asset changes are done through (2), which makes it very difficult to react to asset changes in the general case.
Introducing a AssetChanged<A> query filter that is true for entities with a Handle<A> for which the underlying asset got modified since the last time the system ran.
What alternative(s) have you considered?
In the case of Mesh, it seems that moving Aabb calculation to the generation of the Mesh and keeping it as an optional Mesh field is a correct solution. This would fall into the category of "asset pre-processing" which is both possible today (through a constructor) and subject to future possible improvements.
But this is only a specific solution to a specific problem. In general, it seems reasonable to be able to bridge the gap between assets and ECS with such a query filter.
I've closed linked PR #5080 due to its age and inactivity, but it appears this might still be useful work worthy of adoption if anyone's keen! At least, judging by the various cross-issue and PR mentions.
What problem does this solve or what need does it fill?
A major pain point of using
Handle<Asset>
as components in the ECS currently is that the assets pointed-to by the handle can change, and there is no simple way of reacting to changes to the asset in the context of the ECS.For example: AABB calculation. We have a
Handle<Mesh>
andAabb
component in the ECS. We want to updateAabb
whenever theMesh
for theHandle
is updated. TheHandle
is updated in two circumstances:Handle
the entity has by replacing it in a system with aQuery<&mut Handle<Mesh>>
parameterMesh
in theAssets<Mesh>
in a system with aResMut<Assets<Mesh>>
parameterTo react to (1), it's trivial: just add a
Changed<Handle<Mesh>>
to the system that updates theAabb
.To react to (2), it becomes harder. The only way to react to asset changes is to use the
AssetEvent::Modified { handle: Handle<Mesh> }
event. This event only holds aHandle<Mesh>
, so you either need to iterate over ALL entities with aHandle<Mesh>
and updates the ones that are equal to theModified
field, or keep aHashMap
mapping handles to entities, and other gory details required to maintain thisHashMap
properly.Most of asset changes are done through (2), which makes it very difficult to react to asset changes in the general case.
This was observed in https://github.com/bevyengine/bevy/pull/4944 and also in personal project related to scene hot-reloading.
What solution would you like?
Introducing a
AssetChanged<A>
query filter that istrue
for entities with aHandle<A>
for which the underlying asset got modified since the last time the system ran.What alternative(s) have you considered?
In the case of
Mesh
, it seems that moving Aabb calculation to the generation of the Mesh and keeping it as an optionalMesh
field is a correct solution. This would fall into the category of "asset pre-processing" which is both possible today (through a constructor) and subject to future possible improvements.But this is only a specific solution to a specific problem. In general, it seems reasonable to be able to bridge the gap between assets and ECS with such a query filter.
Additional context
See discussions: