@Override public Subscription onSubscribe(Observer<? super TResult> t1) { VirtualList<TIntermediate> values; Throwable error; state.lock(); try { if (!state.done) { state.onSubscription.call(); return state.addReplayer(t1); } values = state.values; error = state.error; } finally { state.unlock(); } // fully replay the subject for (int i = values.start(); i < values.end(); i++) { try { t1.onNext(state.resultSelector.call(values.get(i))); } catch (Throwable t) { t1.onError(t); return Subscriptions.empty(); } } if (error != null) { t1.onError(error); } else { t1.onCompleted(); } return Subscriptions.empty(); }
/** * Add a replayer to the replayers and create a Subscription for it. * * <p>Caller should hold the lock. * * @param obs * @return */ Subscription addReplayer(Observer<? super TResult> obs) { Subscription s = new Subscription() { final AtomicBoolean once = new AtomicBoolean(); @Override public void unsubscribe() { if (once.compareAndSet(false, true)) { remove(this); } } @Override public boolean isUnsubscribed() { return once.get(); } }; Replayer rp = new Replayer(obs, s); replayers.put(s, rp); rp.replayTill(values.start() + values.size()); return s; }