Skip to content
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

Add support for or in ECS querying #162

Closed
tristanpemble opened this issue Aug 13, 2020 · 5 comments
Closed

Add support for or in ECS querying #162

tristanpemble opened this issue Aug 13, 2020 · 5 comments
Labels
A-ECS Entities, components, systems, and events C-Feature A new feature, making something new possible

Comments

@tristanpemble
Copy link
Contributor

tristanpemble commented Aug 13, 2020

In investigating work for #63 it came up that we cannot do an or query right now. The specific query I wanted was:

  • Has A, B, and C
  • And at least one of those changed

It would be nice to be able to use some form of or statement when querying.

@karroffel karroffel added A-ECS Entities, components, systems, and events C-Feature A new feature, making something new possible labels Aug 13, 2020
@Emily
Copy link

Emily commented Aug 17, 2020

Summing up some conversation from the Discord on this topic:

  • Does Any<(Component1, Component2)> make sense?
  • Any seems most obviously valuable when dealing with Changed/Mutated/Added.
  • Perhaps AnyChanged<(C1, C2)> (and mutated/added versions) would make more sense?
  • It seems a little bit weird to implement AnyChanged when a more powerful primitive Any could be implemented.
  • Tuple approach is nice on AnyChanged as it enables many components to be queried at once.
  • How would the Any API look?
  • Query<(C1, Option<C2>)> already exists

I'd like to take a stab at implementing the AnyChanged<(C1, C2, ...)> approach. It'd result in queries that look something like:

fn my_system(query: &mut Query<(Component1, AnyChanged<(Component2, Component3))> {
    for (component1, (component2, component3)) in &mut query.iter() {
        // do stuff

        if component2.changed {
            // do more stuff
        }
    }
}

I'm not sure if adding the changed flag to Changed is really all that helpful, but it's easy to do and shouldn't have much downside -- other than being a bit confusing in a context like Query<Changed<Component1>> where it'd always be set to true.

@Emily
Copy link

Emily commented Aug 17, 2020

Some more Discord conversation summary:

  • adding changed/mutated/added flags to Changed/Mutated/Added can cause some oddities around derefencing
  • use a static fn to access the flag, e.g. if Changed::changed(c1) {
  • also it doesn't really make sense to modify Changed and friends, just use new types
  • naming new types is hard, but it makes more sense than something like let (c1_changed, c2_changed) = AnyChanged::changed(r);

@BimDav
Copy link
Contributor

BimDav commented Aug 17, 2020

Sorry I did not see your recent comments, Emily. I tried a solution using directly the should_skip methods of two queries to implement Either<Query1, Query2>

@Emily
Copy link

Emily commented Aug 18, 2020

Even though I really like the tuple approach I outlined, it has a ton of implementation complexity. @BimDav i think your Either implementation is the right way to go.

@cart
Copy link
Member

cart commented Sep 2, 2020

Closed by #358

@cart cart closed this as completed Sep 2, 2020
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
Projects
None yet
Development

No branches or pull requests

5 participants