bevyengine / bevyengine/bevy

Move `EntityEvent::event_target` to `EntityTargetTrigger`

Open
#21,272 2 comments 0 reactions 0 assignees View on GitHub
A-ECS X-Needs-SME
Dominant language
Rust
Stars
48.2k
Forks
4.8k
Avg merge
3d 22h
Merged PRs (30d)
161

Description

The [Event Rearchitecture PR](https://github.com/bevyengine/bevy/pull/20731) creates a powerful `Trigger` abstraction pattern which allows the trigger to store what it needs to do its job, but `event_target` is currently stored on the `Event` payload.

To me this seems a usability regression from 0.16 and introduces maintenance overhead:
- Every `EntityEvent` must specify an `entity` field which introduces macro magic, creates work for the developer and disallows fieldless events.
- It requires knowing the target at construction, we lose helper methods like `commands.spawn(Foo).trigger(Bar)`
- The `Trigger` depending on and mutating `Event` internals seems at odds with other trigger patterns like `PropagateEntityTrigger::original_event_target` and `AnimationEventTrigger::animation_player`

## Solution

The [Event Rearchitecture PR](https://github.com/bevyengine/bevy/pull/20731) mentions this `EntityTargetTrigger` pattern as an alternative approach. An 'entity event' becomes a regular event with a specific trigger, and the `event_target` is assigned on the trigger not the payload.

```rust
// we could still use `EntityEvent` as an alias for this
#[derive(Event)]
#[event(trigger = EntityTargetTrigger)]
struct MyEvent;

impl EntityWorldMut<'_> {
fn trigger(&mut self, mut ev: E) -> &mut Self {
// the target is assigned here, 0.16 style
let mut trigger = EntityTargetTrigger::new(self.id());
self.trigger_ref(&mut ev, &mut trigger, MaybeLocation::caller());
self
}
```

## Alternatives

- We could encourage users to store an `Entity::PLACEHOLDER` on the `Event` and then assign it in `EntityCommands::trigger` but we've already fought hard to remove patterns like this, see #16029.
- Currently this is not required to be upstreamed. I've implemented `EventTargetTrigger` [for my own crates](https://github.com/mrchantey/beet/blob/bevy-0.17/crates/beet_core/src/bevy_utils/entity_target_trigger.rs) and just dont use `EntityEvent`, so we could point people to a third party crate.

If we were to go ahead with the refactor I'd be happy to open a PR and ensure its ready for `0.17`, otherwise perhaps this issue could serve as a place to clarify the reasoning so people can understand the tradeoff.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.