bevyengine / bevy

A refreshingly simple data-driven game engine built in Rust
https://bevyengine.org
Apache License 2.0
35.22k stars 3.47k forks source link

Replace `Trigger`'s default bundle filtering behavior from an OR to an AND #15325

Open ItsDoot opened 2 hours ago

ItsDoot commented 2 hours ago

What problem does this solve or what need does it fill?

The fact that the B in Trigger<E, B: Bundle> currently means OR instead of AND is confusing enough that it even surprised a maintainer. Everywhere else in bevy, tuples (which bundles can be) mean AND, so we should change Trigger's default behavior.

What solution would you like?

The following code should work (but doesn't currently):

fn my_observer(trigger: Trigger<Foo, (A, B)>) {

}

// This *should not* trigger the above observer:
world.trigger(Foo, world.component::<A>());
// But *this* should:
world.trigger(Foo, (world.component::<A>(), world.component::<B>());

Additional context

Moment of confusion on discord.

alice-i-cecile commented 2 hours ago

We should add a second generic, defaulting to AND, to allow users to get the same behavior back if they want it.

james-j-obrien commented 2 hours ago

Note that the implementation here is difficult as the observer lookup structure does not support this in any way so care will have to be taken not to regress performance when addressing this. I wouldn't consider it straightforward.