bevyengine / bevyengine/bevy

Implement `DetectChanges` for tuples and derived `SystemParam`s

Open
#13,392 2 comments 0 reactions 0 assignees View on GitHub
A-ECS C-Usability D-Modest X-Contentious
Dominant language
Rust
Stars
48.2k
Forks
4.8k
Avg merge
3d 22h
Merged PRs (30d)
161

Description

## What problem does this solve or what need does it fill?

At the moment `DetectChanges` is implemented for `Res`, `ResMut`, and some other system parameters but not for tuples thereof.

I've rolled some of my own generic system parameters which use `DetectChanges` and the lack of tuple support is very annoying.

For example I have `Cached` which gives you a value `V` which is automatically recalculated only if `R` changes (this is useful if recalculating the value is expensive). This works when `R` is a single resource but it would be lovely if it could also work for tuples of resources and types with `#[derive(SystemParam)]

I have a feeling that the reason this hasn't been done already is that `DetectChanges` has the `last_changed(&self)` method which I'm not sure is possible to calculate for tuples. It would seem trivial - just take the max of the member values - but the way `Tick` works is that it wraps around at a certain number so the highest value is not necessarily the most recent.

## What solution would you like?

The outcome I would like is to be able to call `is_changed()` on tuples like `(Res, ResMut)` and similar, more complex nested tuples and appropriate types with #[derive(SystemParam)]

I don't think there's a way to do this without breaking changes (or an incorrect `last_changed` implementation) but I think the best way to do this would be to split `DetectChanges` into two traits: one for `is_added` and `is_changed` and the other for `last_changed`.

## What alternative(s) have you considered?

- I could be wrong and there is in fact some clever way to determine which member of a set of ticks is the most recent
- The signature of `last_changed` could be changed to take the current tick of the system and that could be used as a reference to deal with the wraparound.
- I can stick with my current solution which is to have my own `DetectChanges2` trait that I've implemented for the types I need. This is quite annoying though as it leads to some extra boilerplate.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.