Allow filters to take a `Bundle` instead of a singular `Component`, and make the conjunction behavior configurable
- Dominant language
- Rust
- Stars
- 48.2k
- Forks
- 4.8k
- Avg merge
- 3d 16h
- Merged PRs (30d)
- 171
Description
- This issue exists as an evolution of the context surrounding #9215
## What problem does this solve or what need does it fill?
With the merging of #14791, bevy itself is moving away from the usage of `Bundle` structs as a means of adding many components to an entity at once, and recommends (but doesn't require that) ecosystem crates follow suit. Therefore, `Bundle`s are more free to be used in other cases with less of a worry about introducing footguns, since they are being phased out from common usage (but not completely removed).
The most immediate helpful place `Bundle`s would find usage in is filters:
```rust
// Why should we have to write all of this:
Query, With, With)>
// When we should be able to write this:
Query>
// And if we need to `OR` them:
Query, With, With)>>
// We should be able to do:
Query>
```
## What solution would you like?
These filters:
```rust
struct With;
struct Without;
struct Changed;
struct Added;
```
Become:
```rust
struct With;
struct Without;
struct Changed;
struct Added;
```
The additional `Join` generic parameter specifies how the tuple conjunction is performed:
- `All`: `With<(A, B, C), All>` means `With AND With AND With`
- `Any`: `With<(A, B, C), Any>` means `With OR With OR With`
**We should determine if the default conjunction for `Without` should be `Any` instead of `All`.**
Note: `std::any::Any` already exists. We should try to find an alternative naming scheme that doesn't clash with std types or pre-existing bevy types, but we may have to resort to doing so anyways if no better alternative is found.
## What alternative(s) have you considered?
### Bundle tuples only
To reduce controversy, #9255 proposed implementing `With` and other filters only for `Bundle`s made of tuples. I believe this to no longer be necessary as `Bundle`s are being phased out in favor of required components, so it's believed that developers will have less of a draw towards thinking in terms of `Bundle`s (which would have been a poor-man's way of doing OOP).
### Conjunction-first
Previously suggested is a flipping of the filter type and conjunction type:
```rust
Any<(A, B, C), With>
Any<(A, B, C), Without>
All<(A, B, C), With>
// ...
```
However that ran into issues with HKTs (higher kinded types), and is verbose in the single-component case.
## Additional context
- Issue where it was originally removed: #2620
- Related issue regarding bundles in queries: #2252
- Previous issue: #9215
- PR originating from previous issue: #9255
- [Recent discussion on discord](https://discord.com/channels/691052431525675048/749335865876021248/1286506525040312380)
Contributor guide
Research direction
Start by reading the referenced issues #9215, #9255, #2620, and #2252, then examine the existing With, Without, Changed, and Added filter APIs. Resolve the Bundle and conjunction design, including the naming conflict and Without's default behavior; completion requires an agreed API and its implementation.
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
- Needs clarification
- Newbie friendliness
- 25/100