/
Observable.swift
89 lines (68 loc) · 2.1 KB
/
Observable.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import Foundation
public class Observable<T> {
public typealias Observer = (T, T?) -> Void
private var observers: [Int: (Observer, DispatchQueue?)] = [:]
private var uniqueID = (0...).makeIterator()
fileprivate let lock: Lock = Mutex()
fileprivate var _value: T {
didSet {
let newValue = _value
observers.values.forEach { observer, dispatchQueue in
if let dispatchQueue = dispatchQueue {
dispatchQueue.async {
observer(newValue, oldValue)
}
} else {
observer(newValue, oldValue)
}
}
}
}
public var wrappedValue: T {
return _value
}
fileprivate var _onDispose: () -> Void
public init(_ value: T, onDispose: @escaping () -> Void = {}) {
self._value = value
self._onDispose = onDispose
}
public init(wrappedValue: T) {
self._value = wrappedValue
self._onDispose = {}
}
public func observe(_ queue: DispatchQueue? = nil, _ observer: @escaping Observer) -> Disposable {
lock.lock()
defer { lock.unlock() }
let id = uniqueID.next()!
observers[id] = (observer, queue)
observer(wrappedValue, nil)
let disposable = Disposable { [weak self] in
self?.observers[id] = nil
self?._onDispose()
}
return disposable
}
public func removeAllObservers() {
observers.removeAll()
}
@available(*, deprecated, renamed: "asObservable")
public func asImmutable() -> Observable<T> {
return self
}
public func asObservable() -> Observable<T> {
return self
}
}
@propertyWrapper
public class MutableObservable<T>: Observable<T> {
override public var wrappedValue: T {
get {
return _value
}
set {
lock.lock()
defer { lock.unlock() }
_value = newValue
}
}
}