Skip to content

Instantly share code, notes, and snippets.

@junpluse
Last active November 1, 2016 09:18
Show Gist options
  • Save junpluse/5f9127801db46ac0cdf6a0564d60c314 to your computer and use it in GitHub Desktop.
Save junpluse/5f9127801db46ac0cdf6a0564d60c314 to your computer and use it in GitHub Desktop.
Dead simple one-to-many event presentation
//
// EventPresenter.swift
//
// Created by Jun Tanaka on 2016/10/27.
// Copyright © 2016 Jun Tanaka. All rights reserved.
//
import Foundation
private struct EventObserver<Event> {
let queue: DispatchQueue?
let closure: (Event) -> Void
}
public final class EventPresenter<Event> {
private var _observers = Dictionary<UUID, EventObserver<Event>>()
private let _observersQueue = DispatchQueue(label: "com.junpluse.EventPresenter._observersQueue")
public init() {}
public func addObserver(on queue: DispatchQueue? = nil, closure: @escaping (Event) -> Void) -> EventObservingToken {
let key = UUID()
let token = EventObservingToken { [weak self] in
self?._observersQueue.sync {
self?._observers[key] = nil
}
}
let observer = EventObserver(queue: queue, closure: closure)
_observersQueue.sync {
_observers[key] = observer
}
return token
}
public func present(_ event: Event) {
let observers = _observersQueue.sync { _observers }
observers.values.forEach { observer in
if let queue = observer.queue {
queue.async { observer.closure(event) }
} else {
observer.closure(event)
}
}
}
}
public final class EventObservingToken {
private var _disposable: (() -> Void)?
private let _disposebleQueue = DispatchQueue(label: "com.junpluse.EventObservingToken._disposableQueue")
fileprivate init(disposable: @escaping () -> Void) {
_disposebleQueue.sync { _disposable = disposable }
}
deinit {
invalidate()
}
public func invalidate() {
let disposable: (() -> Void)? = _disposebleQueue.sync {
let d = _disposable
_disposable = nil
return d
}
disposable?()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment