Some classes can receive different events, so they should conform to EventListener multiple times, each with a different Event type. Something like this:
But then you'd need to change the event emitters as well to emit the new enum not the events they were emitting before, which doesn't make sense as each emitter produces a single type of event not any one of them.
I don’t know your exact use case. If you can share a bit more sample code or context about how you emit and consume these events, I might be able to give you a more suitable solution.
Swift does not have generic protocols. What you have is a protocol with a primary associated type. The evolution proposal for primary associated types acknowledges the difference, but Slava provides a true exploration of the problems that a generic protocols would introduce.
You can reduce boilerplate by implementing a macro, for example:
@attached()
macro Handling<each Param>(types: repeat (each Param).Type) = /*...*/
@Handing(Int.self, Double.self)
class A {
/*...*/
// automatically create a peer member for each `func handle()`
}
It can be implemented using double dispatch. The following code works with @CrystDragon's class A (note A is already a vistor in vistor pattern). I'll omit visitor's protocol for simplicity and use A directly.
protocol Event {
func accept(_ handler: A)
}
struct IntEvent: Event {
let value: Int = 0
func accept(_ handler: A) { handler.handle(value) }
}
struct DoubleEvent: Event {
let value: Double = 0.0
func accept(_ handler: A) { handler.handle(value) }
}
let events: [any Event] = [IntEvent(), DoubleEvent()]
let handler = A()
for e in events {
e.accept(handler)
}