All Downloads are FREE. Search and download functionalities are using the official Maven repository.

rx.internal.operators.BlockingOperatorMostRecent Maven / Gradle / Ivy

There is a newer version: 0.20.7
Show newest version
/**
 * 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.Iterator;

import rx.Observable;
import rx.Subscriber;
import rx.exceptions.Exceptions;

/**
 * Returns an Iterable that always returns the item most recently emitted by an Observable, or a
 * seed value if no item has yet been emitted.
 * 

* */ public final class BlockingOperatorMostRecent { /** * Returns an {@code Iterable} that always returns the item most recently emitted by the {@code Observable}. * * @param source * the source {@code Observable} * @param initialValue * a default item to return from the {@code Iterable} if {@code source} has not yet emitted any * items * @return an {@code Iterable} that always returns the item most recently emitted by {@code source}, or * {@code initialValue} if {@code source} has not yet emitted any items */ public static Iterable mostRecent(final Observable source, final T initialValue) { return new Iterable() { @Override public Iterator iterator() { MostRecentObserver mostRecentObserver = new MostRecentObserver(initialValue); final MostRecentIterator nextIterator = new MostRecentIterator(mostRecentObserver); /** * Subscribe instead of unsafeSubscribe since this is the final subscribe in the chain * since it is for BlockingObservable. */ source.subscribe(mostRecentObserver); return nextIterator; } }; } private static class MostRecentIterator implements Iterator { private final MostRecentObserver observer; private MostRecentIterator(MostRecentObserver observer) { this.observer = observer; } @Override public boolean hasNext() { return !observer.isCompleted(); } @Override public T next() { if (observer.getThrowable() != null) { throw Exceptions.propagate(observer.getThrowable()); } return observer.getRecentValue(); } @Override public void remove() { throw new UnsupportedOperationException("Read only iterator"); } } private static class MostRecentObserver extends Subscriber { static final NotificationLite nl = NotificationLite.instance(); volatile Object value; private MostRecentObserver(T value) { this.value = nl.next(value); } @Override public void onCompleted() { value = nl.completed(); } @Override public void onError(Throwable e) { value = nl.error(e); } @Override public void onNext(T args) { value = nl.next(args); } private boolean isCompleted() { return nl.isCompleted(value); } private Throwable getThrowable() { Object v = value; return nl.isError(v) ? nl.getError(v) : null; } @SuppressWarnings("unchecked") private T getRecentValue() { return (T)value; } } }