Skip to content

OneOf WorldQuery via a Xor filter, alternative to Enum filtering #9649

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
ItsDoot opened this issue Aug 30, 2023 · 1 comment
Open

OneOf WorldQuery via a Xor filter, alternative to Enum filtering #9649

ItsDoot opened this issue Aug 30, 2023 · 1 comment
Labels
A-ECS Entities, components, systems, and events C-Feature A new feature, making something new possible D-Modest A "normal" level of difficulty; suitable for simple features or challenging fixes S-Ready-For-Implementation This issue is ready for an implementation PR. Go for it!

Comments

@ItsDoot
Copy link
Contributor

ItsDoot commented Aug 30, 2023

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:

enum MyComponent {
    Foo,
    Bar,
}

fn my_system(query: Query<Entity, With<MyComponent::Foo>>) {
    // ...
}

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:

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

This new OneOf should work like:

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

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

enum OneOf2<A, B> {
    A(A),
    B(B),
}

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

// etc ...

This might be best paired with Archetype Invariants.

What alternative(s) have you considered?

Use enums and deal with its inherent issues manually.

@ItsDoot ItsDoot added C-Feature A new feature, making something new possible S-Needs-Triage This issue needs to be labelled labels Aug 30, 2023
@ItsDoot ItsDoot changed the title OneOf WorldQuery via a Xor filter OneOf WorldQuery via a Xor filter, alternative to Enum filtering Aug 30, 2023
@alice-i-cecile alice-i-cecile added A-ECS Entities, components, systems, and events and removed S-Needs-Triage This issue needs to be labelled labels Aug 30, 2023
@teohhanhui
Copy link

teohhanhui commented Oct 18, 2024

This is not ergonomic. Bevy could generate marker types for each variant of the enum and they can then be used in the query like Query<Entity, with!(MyEnum::A)>

@BenjaminBrienen BenjaminBrienen added S-Ready-For-Implementation This issue is ready for an implementation PR. Go for it! D-Modest A "normal" level of difficulty; suitable for simple features or challenging fixes labels Oct 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-ECS Entities, components, systems, and events C-Feature A new feature, making something new possible D-Modest A "normal" level of difficulty; suitable for simple features or challenging fixes S-Ready-For-Implementation This issue is ready for an implementation PR. Go for it!
Projects
None yet
Development

No branches or pull requests

4 participants