/// An object that has some tear-down logic public protocol Disposable { func dispose() } /// An event provides a mechanism for raising notifications, together with some /// associated data. Multiple function handlers can be added, with each being invoked, /// with the event data, when the event is raised. public class Event { public typealias EventHandler = T -> () private var eventHandlers = [Invocable]() public init() { } /// Raises the event, invoking all handlers public func raise(data: T) { for handler in self.eventHandlers { handler.invoke(data) } } /// Adds the given handler public func addHandler(target: U, handler: (U) -> EventHandler) -> Disposable { let wrapper = EventHandlerWrapper(target: target, handler: handler, event: self) eventHandlers.append(wrapper) return wrapper } } // MARK:- Private // A protocol for a type that can be invoked private protocol Invocable: class { func invoke(data: Any) } // takes a reference to a handler, as a class method, allowing // a weak reference to the owning type. // see: http://oleb.net/blog/2014/07/swift-instance-methods-curried-functions/ private class EventHandlerWrapper : Invocable, Disposable { weak var target: T? let handler: T -> U -> () let event: Event init(target: T?, handler: T -> U -> (), event: Event){ self.target = target self.handler = handler self.event = event; } func invoke(data: Any) -> () { if let t = target { handler(t)(data as U) } } func dispose() { event.eventHandlers = event.eventHandlers.filter { $0 !== self } } }