Open nicopap opened 1 year ago
Should we consider a generic Not<>
? I don't know how feasible this is though.
Should we consider a generic
Not<>
? I don't know how feasible this is though.
Probably would just be a simple Not<T: ReadOnlyWorldQuery>
that just inverts the output on filter_fetch
. It probably should be noted that it wouldn't be an archetypal filter and would run against the split between With
/Without
.
I took a stab at Not<T>
in #7271, but ran into some issues I could not resolve. matches_component_set
has different "negation behaviours" for With
(out
) and Added
/Changed
: for With
(out
), it must be negated; for Added
/Changed
, it must not be. If individual implementations were implemented for the four "inner" filters, Or
then becomes impossible to generically negate as it's possible to mix With
(out
) and Added
/Changed
within an Or
. One possible solution moving forward is to have an additional trait that defines the negation behaviour.
My implementation also had Not<Added<T>>
imply With<T>
, which is not a logical negation of Added<T>
.
As a user-story, today I tried to do something like the following in order to filter out all the entities that had a component added in the same frame.
Query<&T, Without<Added<T>>>
I was somewhat surprised that this was not supported.
Having set-like operations defined on Query could also be useful to solve similar problems instead with run-time compositions, i.e.
fn system(
a: Query<Entity>
b: Query<Added<&T>
) {
// set difference; C is the set of all entities that satisfy A but
// with the entities that satisfy B removed
let c: Query<Entity> = a - b;
}
NotChanged<T>
andNotAdded<T>
return all entities thatChanged<T>
andAdded<T>
do not.
Changed<T>
and Added<T>
have an implicit With<T>
. Inverting their output won't change that. They'll return the entities that have a T
that wasn't recently changed or added. Their inverses should not include entities matched by Without<T>
.
My implementation also had
Not<Added<T>>
implyWith<T>
, which is not a logical negation ofAdded<T>
.
This would be much clearer if Added<T>
and is_added
were named New<T>
and is_new
(which is what it means). IMO if you ask for "entities whose T
is not new", it doesn't make any sense to include entities that don't even have T
.
It's not the complementary set of entities, but the implied With<T>
is intuitive.
Allows exclusive access based on
Changed
orAdded
component, similar toWith
andWithout
.See https://github.com/bevyengine/bevy/pull/7264#discussion_r1073382489
This is very niche, but might help squeeze out some perfs.
What solution would you like?
Add a
NotChanged<T>
andNotAdded<T>
component that returns all entities that theirChanged
andAdded
counterparts do not return.Am I missing something? It seems possible to discriminate based on those filters. Though it would likely require modifying the
AccessSet
content.What alternative(s) have you considered?
I added a
changed: Query<(), Changed<Transform>>
parameter, and call!changed.contains(&entity)
.Additional context