-
-
Notifications
You must be signed in to change notification settings - Fork 4.1k
Description
What problem does this solve or what need does it fill?
Change detection can be accidentally triggered, as it occurs via DerefMut
.
What solution would you like?
Once #5577 is complete, add the ability to configure the change detection strategy via a macro associated with the Component
and Resource
derives.
There should be 4 options:
DerefMut
(current strategy)PartialEq
(only mark as changed if the new and old values are not equal according toPartialEq
)Eq
(only mark as changed if the new and old values are not equal according toEq
)- disabled (avoids storing change tick information completely)
The default should be set according to the following rules:
- If the type has no fields (it is a unit struct or an enum with a single variant), change detection is disabled.
- Otherwise use
DerefMut
change detection.
This quasi-specialization should be achievable by setting an associated constant for the trait.
In order to get the PartialEq
/ Eq
strategy to work, we'll need to cache the last value for the data in the Mut
wrapper, and then compare to it when determining whether or not to actually update the change tick.
What alternative(s) have you considered?
#5373 is a manual workaround, but is both hard to discover and must be used everywhere a value is mutated. It's likely correct to add even if the design in this issue is merged however.
We could make PartialEq and Eq change detection automatically be enabled.
- If
Eq
is derived, use that impl. - If only
PartialEq
is derived, use that impl.
However, this is not a complete solution, as it does not work with manual impls.
Furthermore, this will double the memory cost of storage for that component / resource , which I'm reluctant to do implicitly.
Additional context
@aevyrie has expressed concerns about the error-prone nature of change detection.
This design will make it much safer to use change detection with non-idempotent operations.