Skip to content

Instantly share code, notes, and snippets.

@morpheby
Created January 22, 2018 07:36
Show Gist options
  • Save morpheby/f4d0e56ff0d2a6e41c6e195f247d5c63 to your computer and use it in GitHub Desktop.
Save morpheby/f4d0e56ff0d2a6e41c6e195f247d5c63 to your computer and use it in GitHub Desktop.
// Example usage:
// class A {
// lazy var event = Observable(self)
// ...
// func doSomeStuff() {
// ...
// event.fire()
// }
// }
// class B {
// let a: A
// init(a: A) {
// self.a = a
// a.event.observe(observer: self) { selfInBlock, a in
// ...
// }
// }
// }
import Foundation
struct ObservationInfo<T: AnyObject, U: AnyObject> {
weak var observer: T?
unowned let observable: Observable<U>
}
typealias ObservationCaller = () -> Bool
/** Provides capability to add alien observers with their own observation context
* Usage:
* Create instance lazy variable (that would be observation container) and assign to it value
* Observable(##your_class##). That would do. To fire just call .fire on the variable.
* To add observer use observe function and pass the observation variable
* as observable.
*/
public class Observable<T: AnyObject> {
public typealias Observant = T
fileprivate var callers: [ObservationCaller] = []
weak var observantWeak: Observant?
public var observant: Observant {
get {
return observantWeak!
}
set {
observantWeak = newValue
}
}
public init(_ observant: Observant) {
self.observant = observant
}
func append(caller: @escaping ObservationCaller) {
self.callers.append(caller)
}
public func fire() {
self.callers = self.callers.filter { c -> Bool in return c() }
}
}
extension Observable {
public func observe<A: AnyObject> (observer: A, fire: @escaping (A, Observant) -> ()) {
let info = ObservationInfo(observer: observer, observable: self)
let caller: ObservationCaller = {
if let observer = info.observer {
fire(observer, info.observable.observant)
return true
} else {
// Apparently, no more observer
return false
}
}
callers.append(caller)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment