Skip to content

Instantly share code, notes, and snippets.

@davidrft
Last active February 5, 2020 21: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 davidrft/46739a95212e62253dfd6ce266da720a to your computer and use it in GitHub Desktop.
Save davidrft/46739a95212e62253dfd6ce266da720a to your computer and use it in GitHub Desktop.
import Foundation
protocol Notifier: class {
func notify(_ data: Any)
}
protocol Destroyable {
func destroy()
}
class Event<T> {
typealias EventHandler = (T) -> ()
var eventHandlers = [Notifier]()
func notifyObservers(_ data: T) {
eventHandlers.forEach { (eventHandler) in
DispatchQueue.global(qos: .userInitiated).async {
eventHandler.notify(data)
}
}
}
func removeObservers() {
eventHandlers.removeAll()
}
func addHandler(_ handler: @escaping EventHandler) -> Destroyable {
let subscription = Subscription(handler: handler, event: self)
eventHandlers.append(subscription)
return subscription
}
}
class Subscription<T>: Notifier, Destroyable {
let handler: (T) -> ()
let event: Event<T>
init(handler: @escaping (T) -> (),
event: Event<T>) {
self.event = event
self.handler = handler
}
func notify(_ data: Any) {
if let data = data as? T {
handler(data)
}
}
func destroy() {
event.eventHandlers = event.eventHandlers.filter { $0 as AnyObject? !== self}
}
}
class Mailman {
func deliverMailTo(_ house: House) {
house.receiveMail()
}
}
class House {
let mailArrived = Event<String>()
var address = ""
init(address: String) {
self.address = address
}
func receiveMail() {
let date = Date()
let formatter = DateFormatter()
formatter.dateFormat = "HH:mm:ss dd.MM.yyyy"
let dateString = formatter.string(from: date)
mailArrived.notifyObservers(dateString)
}
}
func main() {
let house = House(address: "123 Tardis Ave")
let subscription = house.mailArrived.addHandler({ date in
print("Mail arrived in \(house.address) at \(date)")
})
let mailman = Mailman()
mailman.deliverMailTo(house)
subscription.destroy()
mailman.deliverMailTo(house)
}
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment