Skip to content

Instantly share code, notes, and snippets.

@xxKRASHxx
Last active June 8, 2018 08:08
Show Gist options
  • Save xxKRASHxx/494b04f3d850ee0d0b53f5b6259f90f6 to your computer and use it in GitHub Desktop.
Save xxKRASHxx/494b04f3d850ee0d0b53f5b6259f90f6 to your computer and use it in GitHub Desktop.
Notification mechanism
public class Token {
public typealias DisposeAction = () -> Void
private let action: DisposeAction
private var isDisposed: Bool = false
public init(action: @escaping DisposeAction) { self.action = action }
private func innerDispose() {
guard !isDisposed else { return }
isDisposed = true
action()
}
public func dispose() { innerDispose() }
deinit { innerDispose() }
}
public class Pipe<Element> {
public let signal = Signal<Element>()
public func dispatch(_ value: Element) {
signal.dispatch(value)
}
public init() {}
}
public class Signal<Element> {
public typealias Callback = (Element) -> Void
private var callbacks = [:] as [Int: Callback]
private var nextID = 0
fileprivate func dispatch(_ value: Element) {
callbacks.forEach { $1(value) }
}
public func onUpdate(_ callback: @escaping Callback) -> Token {
let id = nextID
nextID += 1
callbacks[id] = callback
return Token { [weak self] in self?.callbacks[id] = nil }
}
}
@xxKRASHxx
Copy link
Author

xxKRASHxx commented Nov 21, 2017

Example of usage:

  let producer = Pipe<Int>()

  let signal1 = producer.signal
  let signal2 = producer.signal
  
  signal1.onUpdate { value in print("signal 1 callback 1: \(value)") }
  signal1.onUpdate { value in print("signal 1 callback 2: \(value)") }
  
  let token = signal2.onUpdate { value in print("signal 2: \(value)") }
  
  (1...3).forEach(producer.dispatch)
  
  token.dispose()
  producer.dispatch(666)

will print:

signal 1 callback 1: 1
signal 1 callback 2: 1
signal 2: 1
signal 1 callback 1: 2
signal 1 callback 2: 2
signal 2: 2
signal 1 callback 1: 3
signal 1 callback 2: 3
signal 2: 3
signal 1 callback 1: 666
signal 1 callback 2: 666

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment