PartialEq and Eq based change detection
- Dominant language
- Rust
- Stars
- 48.2k
- Forks
- 4.8k
- Avg merge
- 3d 16h
- Merged PRs (30d)
- 171
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 to `PartialEq`)
- `Eq` (only mark as changed if the new and old values are not equal according to `Eq`)
- disabled (avoids storing change tick information completely)
The default should be set according to the following rules:
1. If the type has no fields (it is a unit struct or an enum with a single variant), change detection is disabled.
2. 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?
https://github.com/bevyengine/bevy/pull/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.
2. If `Eq` is derived, use that impl.
3. 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](https://discord.com/channels/691052431525675048/692572690833473578/1006223439603965962) about the error-prone nature of change detection.
This design will make it much safer to use change detection with non-idempotent operations.
Contributor guide
Research direction
Start by reviewing prerequisite issue #5577, the Component and Resource derive macros, and the Mut wrapper described in the issue. Define the four configurable strategies and their defaults, including cached comparisons for PartialEq/Eq and no change ticks when disabled; done means each strategy and the stated unit-type defaults work consistently.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- game-dev
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100