Description
What problem does this solve or what need does it fill?
Currently change detection is hard-coded from userspace all the way to ECS storage. This adds quite a bit of extra effort to maintain it at every level in bevy_ecs. Logically speaking, the change ticks included are always kept parallel to the base storage, and can be seen as a companion component that is always present with every component in the World. If this is the case, it may make sense to actually make the change detection ticks their own component.
This can allow for disabling change detection entirely for types which can remove the memory and CPU overhead for small component types that don't really need it (i.e. usize newtypes or ZSTs).
This would also remove all storage-level special casing required for change detection. For example, moving entities from table to table doesn't require knowledge of the change ticks. It's copied from column to column like any other component.
What solution would you like?
- Remove all special casing for
ComponentTicks
in storage and addChangeTicks<T: Component>
as an engine provided component. - Add Component hooks that automatically add or remove the ticks if the component is added/removed. This can be done via hooks or be the only hard-coded part of this.
- Update
Mut
to fetch both&mut T
and&mut ChangeTicks<T>
. - Add an associated type to
Component
that changesWriteFetch
to retrieve&mut T
when change detection is disabled, andMut<T>
when it isn't. Update the derive macro to enable/disable this behavior. - Update change detection fetches/filters to rely on
Component<Write=Mut<Self>>
What alternative(s) have you considered?
- Leave change detection as it is.
- Alter storage to use
Option<Vec<UnsafeCell<ComponentTicks>>>
instead.