rx.internal.operators.OnSubscribeCombineLatest Maven / Gradle / Ivy
Show all versions of rxjava-core Show documentation
/**
* Copyright 2014 Netflix, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package rx.internal.operators;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.LinkedList;
import java.util.List;
import rx.Observable;
import rx.Observable.OnSubscribe;
import rx.Subscriber;
import rx.functions.FuncN;
import rx.observers.SerializedSubscriber;
/**
* Returns an Observable that combines the emissions of multiple source observables. Once each
* source Observable has emitted at least one item, combineLatest emits an item whenever any of
* the source Observables emits an item, by combining the latest emissions from each source
* Observable with a specified function.
*
*
*
* @param the common basetype of the source values
* @param the result type of the combinator function
*/
public final class OnSubscribeCombineLatest implements OnSubscribe {
final List extends Observable extends T>> sources;
final FuncN extends R> combinator;
public OnSubscribeCombineLatest(List extends Observable extends T>> sources, FuncN extends R> combinator) {
this.sources = sources;
this.combinator = combinator;
}
@Override
public void call(final Subscriber super R> child) {
if (sources.isEmpty()) {
child.onCompleted();
return;
} else
if (sources.size() == 1) {
sources.get(0).unsafeSubscribe(new Subscriber(child) {
@Override
public void onNext(T t) {
child.onNext(combinator.call(t));
}
@Override
public void onError(Throwable e) {
child.onError(e);
}
@Override
public void onCompleted() {
child.onCompleted();
}
});
return;
}
SerializedSubscriber s = new SerializedSubscriber(child);
List sourceSubscribers = new ArrayList(sources.size());
Collector collector = new Collector(s, sources.size());
for (int i = 0; i < sources.size(); i++) {
SourceSubscriber sourceSub = new SourceSubscriber(i, collector);
child.add(sourceSub);
sourceSubscribers.add(sourceSub);
}
for (int i = 0; i < sources.size(); i++) {
if (!child.isUnsubscribed()) {
sources.get(i).unsafeSubscribe(sourceSubscribers.get(i));
}
}
}
/** Combines values from each source subscriber. */
final class Collector {
final Subscriber s;
/** Guarded by this. */
Object[] collectedValues;
/** Guarded by this. */
final BitSet haveValues;
/** Guarded by this. */
int haveValuesCount;
/** Guarded by this. */
final BitSet completion;
/** Guarded by this. */
int completionCount;
/** Guarded by this. */
boolean emitting;
/** Guarded by this. */
List