RxSwift/RxSwift/Observables/Implementations/Sample.swift

130 lines
3.3 KiB
Swift

//
// Sample.swift
// RxSwift
//
// Created by Krunoslav Zaher on 5/1/15.
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
//
import Foundation
class SamplerSink<O: ObserverType, ElementType, SampleType where O.E == ElementType>
: ObserverType
, LockOwnerType
, SynchronizedOnType {
typealias E = SampleType
typealias Parent = SampleSequenceSink<O, SampleType>
private let _parent: Parent
var _lock: NSRecursiveLock {
return _parent._lock
}
init(parent: Parent) {
_parent = parent
}
func on(_ event: Event<E>) {
synchronizedOn(event)
}
func _synchronized_on(_ event: Event<E>) {
switch event {
case .next:
if let element = _parent._element {
if _parent._parent._onlyNew {
_parent._element = nil
}
_parent.forwardOn(.next(element))
}
if _parent._atEnd {
_parent.forwardOn(.completed)
_parent.dispose()
}
case .error(let e):
_parent.forwardOn(.error(e))
_parent.dispose()
case .completed:
if let element = _parent._element {
_parent._element = nil
_parent.forwardOn(.next(element))
}
if _parent._atEnd {
_parent.forwardOn(.completed)
_parent.dispose()
}
}
}
}
class SampleSequenceSink<O: ObserverType, SampleType>
: Sink<O>
, ObserverType
, LockOwnerType
, SynchronizedOnType {
typealias Element = O.E
typealias Parent = Sample<Element, SampleType>
private let _parent: Parent
let _lock = NSRecursiveLock()
// state
private var _element = nil as Element?
private var _atEnd = false
private let _sourceSubscription = SingleAssignmentDisposable()
init(parent: Parent, observer: O) {
_parent = parent
super.init(observer: observer)
}
func run() -> Disposable {
_sourceSubscription.disposable = _parent._source.subscribe(self)
let samplerSubscription = _parent._sampler.subscribe(SamplerSink(parent: self))
return Disposables.create(_sourceSubscription, samplerSubscription)
}
func on(_ event: Event<Element>) {
synchronizedOn(event)
}
func _synchronized_on(_ event: Event<Element>) {
switch event {
case .next(let element):
_element = element
case .error:
forwardOn(event)
dispose()
case .completed:
_atEnd = true
_sourceSubscription.dispose()
}
}
}
class Sample<Element, SampleType> : Producer<Element> {
private let _source: Observable<Element>
private let _sampler: Observable<SampleType>
private let _onlyNew: Bool
init(source: Observable<Element>, sampler: Observable<SampleType>, onlyNew: Bool) {
_source = source
_sampler = sampler
_onlyNew = onlyNew
}
override func run<O: ObserverType where O.E == Element>(_ observer: O) -> Disposable {
let sink = SampleSequenceSink(parent: self, observer: observer)
sink.disposable = sink.run()
return sink
}
}