bevyengine / bevyengine/bevy

Feature Request: `Consumer` system runs after all `Observer`s triggered

Open
#22,480 0 comments 1 reaction 0 assignees View on GitHub
A-ECS C-Feature S-Needs-Goal X-Needs-SME
Dominant language
Rust
Stars
48.2k
Forks
4.8k
Avg merge
3d 22h
Merged PRs (30d)
161

Description

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

`Observer` systems can process and modify triggered events, but the execution order can not be controlled.
Except using propagating events or calling `World::trigger_ref` in exclusive systems, there is no workaround to aggregate changes in a defined order.

## What solution would you like?

A `Consumer` is a `System` with a `Post` parameter, which runs after all observers triggered for a given event type.

A `Post` contains the event processed by regular observers. It can take the event in one of the following forms:

1. the ownership of an event by value, which **breaks** usages of `World::trigger_ref`.
2. a mutable reference to an event.
3. a shared read-only reference to an event.

For 1 and 2, `Post` owns the event semantically, which means that only one `Consumer` for one event type is allowed in a world.

I implemented the solution 2 in [my fork]. Here is a minimal usage example:

```rust
let mut world = World::new();

struct MyEvent {
pub data: i32,
}

impl Event for MyEvent {
type Trigger<'a> = GlobalTrigger;

fn consumer_system() -> Option> {
fn my_event_consumer(mut event: Post) {
assert_eq!(event.data, 114514 + 1919810);
event.data /= 2;
}
Some(IntoSystem::into_system(my_event_consumer))
}
}

world.add_observer(|mut e: On| {
e.data += 114514;
});

world.add_observer(|mut e: On| {
e.data += 1919810;
});

let mut event = MyEvent { data: 0 };
world.trigger_ref(&mut event);

assert_eq!(event.data, (114514 + 1919810) / 2);
```

[my fork]: https://github.com/Fachep/bevy/commit/f86fc9fc6c6394af9e29ac9ac50da7d2238a37cd

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.