2121import io .reactivex .Observable ;
2222import io .reactivex .internal .util .ExceptionHelper ;
2323import io .reactivex .observers .DisposableObserver ;
24+ import io .reactivex .plugins .RxJavaPlugins ;
2425
2526/**
2627 * Wait for and iterate over the latest values of the source observable. If the source works faster than the
2728 * iterator, values may be skipped, but not the {@code onError} or {@code onComplete} events.
29+ * @param <T> the value type
2830 */
29- public enum BlockingObservableLatest {
30- ;
31-
32- /**
33- * Returns an {@code Iterable} that blocks until or unless the {@code Observable} emits an item that has not
34- * been returned by the {@code Iterable}, then returns that item.
35- *
36- * @param <T> the value type
37- * @param source
38- * the source {@code Observable}
39- * @return an {@code Iterable} that blocks until or unless the {@code Observable} emits an item that has not
40- * been returned by the {@code Iterable}, then returns that item
41- */
42- public static <T > Iterable <T > latest (final ObservableSource <? extends T > source ) {
43- return new Iterable <T >() {
44- @ Override
45- public Iterator <T > iterator () {
46- LatestObserverIterator <T > lio = new LatestObserverIterator <T >();
47-
48- @ SuppressWarnings ("unchecked" )
49- Observable <Notification <T >> materialized = Observable .wrap ((ObservableSource <T >)source ).materialize ();
50-
51- materialized .subscribe (lio );
52- return lio ;
53- }
54- };
31+ public final class BlockingObservableLatest <T > implements Iterable <T > {
32+
33+ final ObservableSource <T > source ;
34+
35+ public BlockingObservableLatest (ObservableSource <T > source ) {
36+ this .source = source ;
37+ }
38+
39+ @ Override
40+ public Iterator <T > iterator () {
41+ BlockingObservableLatestIterator <T > lio = new BlockingObservableLatestIterator <T >();
42+
43+ Observable <Notification <T >> materialized = Observable .wrap (source ).materialize ();
44+
45+ materialized .subscribe (lio );
46+ return lio ;
5547 }
5648
57- /** Observer of source, iterator for output. */
58- static final class LatestObserverIterator <T > extends DisposableObserver <Notification <T >> implements Iterator <T > {
49+ static final class BlockingObservableLatestIterator <T > extends DisposableObserver <Notification <T >> implements Iterator <T > {
5950 // iterator's notification
6051 Notification <T > iteratorNotification ;
6152
@@ -73,7 +64,7 @@ public void onNext(Notification<T> args) {
7364
7465 @ Override
7566 public void onError (Throwable e ) {
76- // not expected
67+ RxJavaPlugins . onError ( e );
7768 }
7869
7970 @ Override
@@ -86,22 +77,20 @@ public boolean hasNext() {
8677 if (iteratorNotification != null && iteratorNotification .isOnError ()) {
8778 throw ExceptionHelper .wrapOrThrow (iteratorNotification .getError ());
8879 }
89- if (iteratorNotification == null || iteratorNotification .isOnNext ()) {
90- if (iteratorNotification == null ) {
91- try {
92- notify .acquire ();
93- } catch (InterruptedException ex ) {
94- dispose ();
95- Thread .currentThread ().interrupt ();
96- iteratorNotification = Notification .createOnError (ex );
97- throw ExceptionHelper .wrapOrThrow (ex );
98- }
99-
100- Notification <T > n = value .getAndSet (null );
101- iteratorNotification = n ;
102- if (n .isOnError ()) {
103- throw ExceptionHelper .wrapOrThrow (n .getError ());
104- }
80+ if (iteratorNotification == null ) {
81+ try {
82+ notify .acquire ();
83+ } catch (InterruptedException ex ) {
84+ dispose ();
85+ Thread .currentThread ().interrupt ();
86+ iteratorNotification = Notification .createOnError (ex );
87+ throw ExceptionHelper .wrapOrThrow (ex );
88+ }
89+
90+ Notification <T > n = value .getAndSet (null );
91+ iteratorNotification = n ;
92+ if (n .isOnError ()) {
93+ throw ExceptionHelper .wrapOrThrow (n .getError ());
10594 }
10695 }
10796 return iteratorNotification .isOnNext ();
@@ -110,11 +99,9 @@ public boolean hasNext() {
11099 @ Override
111100 public T next () {
112101 if (hasNext ()) {
113- if (iteratorNotification .isOnNext ()) {
114- T v = iteratorNotification .getValue ();
115- iteratorNotification = null ;
116- return v ;
117- }
102+ T v = iteratorNotification .getValue ();
103+ iteratorNotification = null ;
104+ return v ;
118105 }
119106 throw new NoSuchElementException ();
120107 }
@@ -123,6 +110,5 @@ public T next() {
123110 public void remove () {
124111 throw new UnsupportedOperationException ("Read-only iterator." );
125112 }
126-
127113 }
128114}
0 commit comments