import Foundation public protocol CallbackEvent { associatedtype Info var info: Info { get } } public struct CallbackEvents { private init() {} } public struct CallbackManager { fileprivate var observers = [Any]() public init() {} public init(observers: (inout CallbackManager) -> Void) { var manager = CallbackManager() observers(&manager) self = manager } public mutating func on( _: Event.Type = Event.self, _ handler: @escaping (Event.Info) -> Void ) { observers.append(handler) } public mutating func on( _: KeyPath, _ handler: @escaping (Event.Info) -> Void ) { observers.append(handler) } public func send(_ event: Event) { for case let observer as ((Event.Info) -> Void) in observers { observer(event.info) } } func send( _: KeyPath, _ info: Event.Info ) { for case let observer as ((Event.Info) -> Void) in observers { observer(info) } } } public extension [CallbackManager] { func send(_ event: Event) { for cb in self { cb.send(event) } } func send( _ keyPath: KeyPath, _ info: Event.Info ) { for cb in self { cb.send(keyPath, info) } } }