Skip to content

Instantly share code, notes, and snippets.

@satishbabariya
Created May 9, 2018 15:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save satishbabariya/34c5f6a5cc95c9155b55360bbe8717f7 to your computer and use it in GitHub Desktop.
Save satishbabariya/34c5f6a5cc95c9155b55360bbe8717f7 to your computer and use it in GitHub Desktop.
Event
import Foundation
// A Naïve Event Implementation
// class Event<T> {
//
// typealias EventHandler = T -> ()
//
// private var eventHandlers = [EventHandler]()
//
// func addHandler(handler: EventHandler) {
// eventHandlers.append(handler)
// }
//
// func raise(data: T) {
// for handler in eventHandlers {
// handler(data)
// }
// }
// }
// Full Implementations
// let event = Event<Void>()
// event.addHandler { println("Hello") }
// event.addHandler { println("World") }
// event.raise()
// let event = Event<(String, String)>()
// event.addHandler { a, b in println("Hello \(a), \(b)") }
// let data = ("Colin", "Eberhardt")
// event.raise(data)
/// USE
// func handleEvent(data: (String, String)) {
// print("Hello \(data.0), \(data.1)")
// }
//
// @IBAction func action(_ sender: Any) {
// // create an event
// let event = Events<(String, String)>()
//
// // add a handler
// let handler = event.addHandler(target: self, handler: ViewController.handleEvent)
//
// // raise the event
// event.raise(data: ("String", "String"))
//
// // remove the handler
// handler.dispose()
// }
public class Events<T> {
public typealias EventHandler = (T) -> ()
var eventHandlers = [Invocable]()
public func raise(data: T) {
for handler in eventHandlers {
handler.invoke(data: data)
}
}
public func addHandler<U: AnyObject>(target: U, handler: @escaping (U) -> EventHandler) -> EventsDisposable {
let wrapper = EventHandlerWrapper(target: target,
handler: handler, event: self)
eventHandlers.append(wrapper)
return wrapper
}
}
protocol Invocable: class {
func invoke(data: Any)
}
class EventHandlerWrapper<T: AnyObject, U>: Invocable, EventsDisposable {
weak var target: T?
let handler: (T) -> (U) -> ()
let event: Events<U>
init(target: T?, handler: @escaping (T) -> (U) -> (), event: Events<U>) {
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 }
}
}
public protocol EventsDisposable {
func dispose()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment