Skip to content

Instantly share code, notes, and snippets.

@hartbit
Last active January 22, 2019 15:31
Show Gist options
  • Save hartbit/581dd55f2e3bf1b00f064683ca3f543e to your computer and use it in GitHub Desktop.
Save hartbit/581dd55f2e3bf1b00f064683ca3f543e to your computer and use it in GitHub Desktop.
import RxSwift
import RxCocoa
final class Value<T>: ObservableType {
private let subject: BehaviorSubject<T>
var value: T {
get {
return try! subject.value()
}
set {
subject.onNext(newValue)
}
}
init(value: T) {
self.subject = BehaviorSubject(value: value)
}
func subscribe<O: ObserverType>(_ observer: O) -> Disposable where O.E == E {
return subject.subscribe(observer)
}
func asObservable() -> Observable<T> {
return subject.asObservable()
}
}
final class ComputedValue<T>: ObservableType {
private let subject: BehaviorSubject<T>
private let disposable: Disposable
var value: T {
return try! subject.value()
}
init<A>(_ values: [Value<A>], _ transform: @escaping ([A]) -> T) {
subject = BehaviorSubject(value: transform(values.map({ $0.value })))
disposable = Observable.combineLatest(values).map(transform).bind(to: subject)
}
init<A>(_ value: Value<A>, _ transform: @escaping (A) -> T) {
subject = BehaviorSubject(value: transform(value.value))
disposable = value.asObservable().map(transform).bind(to: subject)
}
init<A, B>(_ value1: Value<A>, _ value2: Value<B>, _ transform: @escaping (A, B) -> T) {
subject = BehaviorSubject(value: transform(value1.value, value2.value))
disposable = Observable.combineLatest(
value1.asObservable(),
value2.asObservable(),
resultSelector: transform).bind(to: subject)
}
// ... More overloads
func subscribe<O: ObserverType>(_ observer: O) -> Disposable where O.E == E {
return subject.subscribe(observer)
}
func asObservable() -> Observable<T> {
return subject.asObservable()
}
}
let value1 = Value<Int>(value: 4)
let value2 = Value<Int>(value: 9)
let sum = ComputedValue<Int>(value1, value2, { $0 + $1 })
print(sum.value) // 13
value1.value = 11
print(sum.value) // 20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment