Description
What problem does this solve or what need does it fill?
Being able to trigger the same observer with multiple different event types would be useful for code reuse and centralizing related logic. This is different from enum
Event types, which don't allow you to listen to individual variants for separate observers.
What solution would you like?
#[derive(Event)]
struct FooEvent { foo: i32 }
#[derive(Event)]
struct BarEvent { bar: bool }
// I imagine `Or<(A, B)>` would deref into some `enum Or2<A, B> { A(A), B(B) }`
// `Or<(A, B, C)>` would deref into some `enum Or3<A, B, C> { A(A), B(B), C(C) }`
// etc
// Also, I imagine we'll need a separate `world.observe_any_of()`-style method to correctly handle the internal details
world.observe(|trigger: Trigger<Or<(FooEvent, BarEvent)>>| {
match trigger.event() {
Or2::A(FooEvent { foo }) => { /* do something with foo... */ },
Or2::B(BarEvent { bar }) => { /* do something with bar... */ },
}
});
What alternative(s) have you considered?
Use an enum:
#[derive(Event)]
enum MyEvent {
Foo { foo: i32 },
Bar { bar: bool },
}
world.observe(|trigger: Trigger<MyEvent>| {
match trigger.event() {
MyEvent::Foo { foo } => { /* ... */ },
MyEvent::Bar { bar } => { /* ... */ },
}
});
However, that prevents us from listening to only 1 of the event types, or a subset of them.
Additional context
This was mentioned on discord as currently possible, albeit with unsafe APIs, so we should introduce a safe wrapper:
Diddykonga — Today at 8:41 PM
Can observers 'observe' multiple events? if not, then the query would need to be split from the observer at some point.
James 🦃 — Today at 9:02 PM
Observers can absolutely observe multiple events
(unsafely)
nth — Today at 9:03 PM
What does the trigger return for the event?
James 🦃 — Today at 9:04 PM
You have to use unsafe APIs
So you can make the trigger return any type and you just have to promise it's safe
The observer for a query should set the ObserverRunner manually to not pay for system overhead
Diddykonga — Today at 9:06 PM
Right since you cant carry that information via generics, unsafe is the only way (variadics when?)
James 🦃 — Today at 9:06 PM
And the ObserverRunner API just gets a pointer and deferred world
(similar to a hook)
doot — Today at 9:13 PM
I wonder if you could wrap that safely in a Trigger<Either<A, B>> type api
actually probably something like a Trigger<Or<(A, B, C, ...)>>
Metadata
Metadata
Assignees
Labels
Type
Projects
Status