-
-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Shortcut for With
and Without
#9255
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
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code looks good to me.
This is a welcome addition -- I've always found it surprising that this didn't work already, it just feels natural to be able to filter multiple components at once like this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR implements a proposition to make
With<(A, B, C)>
andWithout<(A, B, C)>
a shortcut for(With<A>, With<B>, With<C>)
and(Without<A>, Without<B>, Without<C>)
to help reduce verbosity of queries.
From my perspective, this would introduce inconsistent behavior in the Without
case. In both the normal query and With
cases, (A, B, C)
means A AND B AND C
, while Without<(A, B, C)>
translates to NOT A AND NOT B AND NOT C
instead of NOT (A AND B AND C)
. Applying De Morgan's law, Without<(A, B, C)>
actually translates to Or<(Without<A>, Without<B>, Without<C>)>
.
|
||
/// This macro implements `WorldQuery` and `ReadOnlyWorldQuery` for a filter | ||
/// so that `Filter<(A, B, C)>` acts as a shortcut for `(Filter<A>, Filter<B>, Filter<C>)`. | ||
macro_rules! impl_filter_tuple_to_tuple_filter { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This macro and the two invocations adds yet another set of tuple pyramids, which can add a lot of additional code to compile. Can you check the difference in compile time for bevy_ecs
before and after this change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With the changes, bevy_ecs
took about half a second longer to compile.
rustc 1.71.0 (8ede3aae2 2023-07-12)
Host: x86_64-pc-windows-msvc
Target: x86_64-pc-windows-msvc
In terms of logic and since But if we break this relation between
The only thing lost is that
|
I think CI is broken, it fails with the message
My last commit update the test function only. There is no reason for my previous commit to pass but not this one. Also, I can build locally. |
I think it could be both argued that:
I see three options:
With the third option we could also similarly have
I would be more in favor of this last option, and this last naming convention |
I don't see this as being the case. IMO This idea of using tuples to create var args is also in line with how it's used everywhere else in bevy. EDIT: Making |
Yeah, I first thought
It does apply. This shortcut to reduce "boilerplate" breaks predictable assumptions some users will make. We could decide to stop trying to apply boolean algebra if we think this shortcut is useful enough to outweigh that, but we still need to decide that first. If this change goes through, subtle logic bugs that were not possible before will be. I think lots of users will confuse (edit: I'm not sure how I feel about this. I think I'd prefer not making this change, but I don't have a strong opinion on it.)
🤔 I could get behind an explicit |
I’m in favor of deprecating the use of implicit-AND tuples and moving toward explicit |
Another option:
|
Note from the future: variable tuple args mean OR in triggers now. |
Mentioned issue is closed, 2 years old/stale PR, merge conflicts |
Objective
This PR implements a proposition to make
With<(A, B, C)>
andWithout<(A, B, C)>
a shortcut for(With<A>, With<B>, With<C>)
and(Without<A>, Without<B>, Without<C>)
to help reduce verbosity of queries.With<Bundle>
orWithout<Bundle>
are still disallowed as it's considered an anti-pattern.Solution
Implements
WorldQuery
andReadOnlyWorldQuery
forFilter<(T0, T1, ...)>
that delegate to<(Fitler<T0>, Filter<T1>, ...) as WorldQuery>
, whereFilter
isWith
orWithout
.Changelog
(With<A>, With<B>, With<C>)
and(Without<A>, Without<B>, Without<C>)
can be simplified intoWith<(A, B, C)>
andWithout<(A, B, C)>
respectively.