Description
What problem does this solve or what need does it fill?
bevy-trait-query
is a really important feature to support and improve, and hopefully eventually do in-house. For that, we need to have the concept of component groups (a set of components that share some functionality). The most common of these would be dyn MyTrait
groups where all components that register as implementing MyTrait
get added to the group. Speculatively, other groups may be possible. For example HasU32AtOffset8
(or something) or a group of BothTraits(&dyn MyTrait1, &dyn MyTrait2)
. Currently, these groups are not supported in the ECS, and bevy-trait-query
layers them on top via resources. That has the unfortunate side effect that components need to be registered by hand prior to a query being made.
What solution would you like?
Lets make a ComponentGroup(Vec<ComponentId>)
and include it in Components
, allowing it to be registered. When a component is registered, it also adds itself to the groups it's in, and when a group is registered, it also registers any foreign components that are in the group.
Then, we add to Access
and FilteredAccess
a groups
field, which tracks what groups each access needs. The groups don't need to be checked for conflicts; rather, the group's components are flattened into the Access
like normal. When a component is registered to an existing group, all the access sets with that group need to re-check for conflicts and flatten the new component into it's list.
That means access lists can change at runtime! And simply registering a component can make two previously non-conflicting access sets conflict. It can even make an existing access set conflict with itself! This is conceptually unavoidable (I think), but it has some annoying consequences. For example, we can't statically compute access sets (or at least, we need to have a path to re-compute them).
What alternative(s) have you considered?
We could just require all components to be registered before the first system is created, but that conflicts with a lot of design goals, ex: #17564. This is what bevy-trait-query
does now, and it doesn't exactly scream, "ERGONOMICS!"
We could not flatten the structure in Access
, but that would mean requiring &Components
to check for conflicts. And conflicts could still arise from new registrations.
Additional context
This has had a little discussion on discord. But I think this is an important enough issue to be, well, an issue. We definitely need to work out a design for this.