Skip to content

Instantly share code, notes, and snippets.

@cqfd
Last active June 26, 2016 13:11
Show Gist options
  • Save cqfd/385ca9946a53738a771bbc7e42cad102 to your computer and use it in GitHub Desktop.
Save cqfd/385ca9946a53738a771bbc7e42cad102 to your computer and use it in GitHub Desktop.
import RxSwift
import RxSwiftExt
class Signal<Element>: ObservableConvertibleType, DriverConvertibleType {
typealias E = Element
private let _v: Variable<E>
var value: E { return _v.value }
init(initialValue: E, subsequentValues: Observable<E>) {
self._v = Variable(initialValue)
_ = subsequentValues.bindTo(self._v)
}
func asObservable() -> Observable<E> {
return _v.asObservable()
}
func asDriver() -> Driver<E> {
return _v.asDriver()
}
func map<R>(selector: E -> R) -> Signal<R> {
return Signal<R>(initialValue: selector(value), subsequentValues: _v.asObservable().map(selector))
}
func flatMap<R>(selector: E -> Signal<R>) -> Signal<R> {
let initialSignal = selector(value)
let initialValue = initialSignal.value
let subsequentValues = Observable.of(
initialSignal.asObservable().skip(1),
_v.asObservable().skip(1).flatMap(selector)
).merge()
return Signal<R>(initialValue: initialValue, subsequentValues: subsequentValues)
}
func flatMapLatest<R>(selector: E -> Signal<R>) -> Signal<R> {
let initialSignal = selector(value)
let initialValue = initialSignal.value
let subsequentValues = Observable.cascade([
initialSignal.asObservable().skip(1),
_v.asObservable().skip(1).flatMapLatest(selector)
])
return Signal<R>(initialValue: initialValue, subsequentValues: subsequentValues)
}
static func combineLatest<A, B>(a: Signal<A>, _ b: Signal<B>, resultSelector: (A, B) -> E) -> Signal<E> {
let initialValue = resultSelector(a.value, b.value)
let subsequentValues = Observable.combineLatest(
a.asObservable().skip(1), b.asObservable().skip(1),
resultSelector: resultSelector
)
return Signal(initialValue: initialValue, subsequentValues: subsequentValues)
}
static func combineLatest<A, B, C>(a: Signal<A>, _ b: Signal<B>, _ c: Signal<C>, resultSelector: (A, B, C) -> E) -> Signal<E> {
let initialValue = resultSelector(a.value, b.value, c.value)
let subsequentValues = Observable.combineLatest(
a.asObservable().skip(1), b.asObservable().skip(1), c.asObservable().skip(1),
resultSelector: resultSelector
)
return Signal(initialValue: initialValue, subsequentValues: subsequentValues)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment