|
15 | 15 | */ |
16 | 16 | package rx.internal.util; |
17 | 17 |
|
18 | | -import rx.Observable; |
19 | | -import rx.Subscriber; |
| 18 | +import rx.*; |
| 19 | +import rx.Scheduler.Worker; |
| 20 | +import rx.functions.Action0; |
| 21 | +import rx.internal.schedulers.EventLoopsScheduler; |
20 | 22 |
|
21 | 23 | public final class ScalarSynchronousObservable<T> extends Observable<T> { |
22 | 24 |
|
@@ -49,5 +51,70 @@ public void call(Subscriber<? super T> s) { |
49 | 51 | public T get() { |
50 | 52 | return t; |
51 | 53 | } |
| 54 | + /** |
| 55 | + * Customized observeOn/subscribeOn implementation which emits the scalar |
| 56 | + * value directly or with less overhead on the specified scheduler. |
| 57 | + * @param scheduler the target scheduler |
| 58 | + * @return the new observable |
| 59 | + */ |
| 60 | + public Observable<T> scalarScheduleOn(Scheduler scheduler) { |
| 61 | + if (scheduler instanceof EventLoopsScheduler) { |
| 62 | + EventLoopsScheduler es = (EventLoopsScheduler) scheduler; |
| 63 | + return create(new DirectScheduledEmission<T>(es, t)); |
| 64 | + } |
| 65 | + return create(new NormalScheduledEmission<T>(scheduler, t)); |
| 66 | + } |
| 67 | + |
| 68 | + /** Optimized observeOn for scalar value observed on the EventLoopsScheduler. */ |
| 69 | + static final class DirectScheduledEmission<T> implements OnSubscribe<T> { |
| 70 | + private final EventLoopsScheduler es; |
| 71 | + private final T value; |
| 72 | + DirectScheduledEmission(EventLoopsScheduler es, T value) { |
| 73 | + this.es = es; |
| 74 | + this.value = value; |
| 75 | + } |
| 76 | + @Override |
| 77 | + public void call(final Subscriber<? super T> child) { |
| 78 | + child.add(es.scheduleDirect(new ScalarSynchronousAction<T>(child, value))); |
| 79 | + } |
| 80 | + } |
| 81 | + /** Emits a scalar value on a general scheduler. */ |
| 82 | + static final class NormalScheduledEmission<T> implements OnSubscribe<T> { |
| 83 | + private final Scheduler scheduler; |
| 84 | + private final T value; |
| 85 | + |
| 86 | + NormalScheduledEmission(Scheduler scheduler, T value) { |
| 87 | + this.scheduler = scheduler; |
| 88 | + this.value = value; |
| 89 | + } |
| 90 | + |
| 91 | + @Override |
| 92 | + public void call(final Subscriber<? super T> subscriber) { |
| 93 | + Worker worker = scheduler.createWorker(); |
| 94 | + subscriber.add(worker); |
| 95 | + worker.schedule(new ScalarSynchronousAction<T>(subscriber, value)); |
| 96 | + } |
| 97 | + } |
| 98 | + /** Action that emits a single value when called. */ |
| 99 | + static final class ScalarSynchronousAction<T> implements Action0 { |
| 100 | + private final Subscriber<? super T> subscriber; |
| 101 | + private final T value; |
52 | 102 |
|
| 103 | + private ScalarSynchronousAction(Subscriber<? super T> subscriber, |
| 104 | + T value) { |
| 105 | + this.subscriber = subscriber; |
| 106 | + this.value = value; |
| 107 | + } |
| 108 | + |
| 109 | + @Override |
| 110 | + public void call() { |
| 111 | + try { |
| 112 | + subscriber.onNext(value); |
| 113 | + } catch (Throwable t) { |
| 114 | + subscriber.onError(t); |
| 115 | + return; |
| 116 | + } |
| 117 | + subscriber.onCompleted(); |
| 118 | + } |
| 119 | + } |
53 | 120 | } |
0 commit comments