Last active
November 1, 2016 09:18
-
-
Save junpluse/5f9127801db46ac0cdf6a0564d60c314 to your computer and use it in GitHub Desktop.
Dead simple one-to-many event presentation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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