bevyengine / bevyengine/bevy

OneOf WorldQuery via a Xor filter, alternative to Enum filtering

Open
#9,649 1 comment 12 reactions 0 assignees View on GitHub
A-ECS C-Feature D-Modest S-Ready-For-Implementation
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?

A somewhat common question in the Bevy Discord involves being able to filter by a component's enum variant:

```rust
enum MyComponent {
Foo,
Bar,
}

fn my_system(query: Query>) {
// ...
}
```

This doesn't work because Rust doesn't represent enum variants as full types. A common alternative is to use marker components instead, but currently you lose out on the mutual exclusivity that standard enums provide.

I propose to add a new `OneOf<(A, B, C, ...)>` WorldQuery similar to `AnyOf`, but backed by a `Xor` filter rather than `Or`.

## What solution would you like?

Similar to how `AnyOf` works:

```rust
// equivalent to `Query<(Option<&A>, Option<&B>, Option<&mut C>), Or<(With, With, With)>>
fn my_system(query: Query>) {}
```

This new `OneOf` should work like:

```rust
// equivalent to `Query<(Option<&A>, Option<&B>, Option<&mut C>), Xor<(With
, With, With)>>
fn my_system(query: Query>) {}
```

Could also look at having an enum return type per arity, like

```rust
enum OneOf2 {
A(A),
B(B),
}

enum OneOf3 {
A(A),
B(B),
C(C),
}

// etc ...
```

**This might be best paired with [Archetype Invariants](https://github.com/bevyengine/rfcs/pull/5).**

## What alternative(s) have you considered?

Use enums and deal with its inherent issues manually.

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.