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

io.reactivex.observable.internal.operators.BlockingObservableMostRecent Maven / Gradle / Ivy

/**
 * Copyright (c) 2016-present, RxJava Contributors.
 *
 * 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 io.reactivex.observable.internal.operators;


import java.util.*;

import io.reactivex.common.internal.utils.ExceptionHelper;
import io.reactivex.observable.ObservableSource;
import io.reactivex.observable.internal.utils.NotificationLite;
import io.reactivex.observable.observers.DefaultObserver;

/**
 * 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.
 * 

* * * @param the value type */ public final class BlockingObservableMostRecent implements Iterable { final ObservableSource source; final T initialValue; public BlockingObservableMostRecent(ObservableSource source, T initialValue) { this.source = source; this.initialValue = initialValue; } @Override public Iterator iterator() { MostRecentObserver mostRecentObserver = new MostRecentObserver(initialValue); /** * Subscribe instead of unsafeSubscribe since this is the final subscribe in the chain * since it is for BlockingObservable. */ source.subscribe(mostRecentObserver); return mostRecentObserver.getIterable(); } static final class MostRecentObserver extends DefaultObserver { volatile Object value; MostRecentObserver(T value) { this.value = NotificationLite.next(value); } @Override public void onComplete() { value = NotificationLite.complete(); } @Override public void onError(Throwable e) { value = NotificationLite.error(e); } @Override public void onNext(T args) { value = NotificationLite.next(args); } /** * The {@link Iterator} return is not thread safe. In other words don't call {@link Iterator#hasNext()} in one * thread expect {@link Iterator#next()} called from a different thread to work. * @return the Iterator */ public MostRecentIterator getIterable() { return new MostRecentIterator(); } final class MostRecentIterator implements java.util.Iterator { /** * buffer to make sure that the state of the iterator doesn't change between calling hasNext() and next(). */ private Object buf; @Override public boolean hasNext() { buf = value; return !NotificationLite.isComplete(buf); } @Override public T next() { try { // if hasNext wasn't called before calling next. if (buf == null) { buf = value; } if (NotificationLite.isComplete(buf)) { throw new NoSuchElementException(); } if (NotificationLite.isError(buf)) { throw ExceptionHelper.wrapOrThrow(NotificationLite.getError(buf)); } return NotificationLite.getValue(buf); } finally { buf = null; } } @Override public void remove() { throw new UnsupportedOperationException("Read only iterator"); } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy