/* * Copyright 2015 Fabio Collini. * * 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 it.cosenonjaviste.mv2m.rx; import java.util.ArrayList; import java.util.List; import rx.Observable; import rx.Observer; import rx.functions.Action0; import rx.functions.Action1; import rx.observables.ConnectableObservable; import rx.subscriptions.CompositeSubscription; public class RxHolder { private SchedulerManager schedulerManager; private final CompositeSubscription connectableSubscriptions = new CompositeSubscription(); private CompositeSubscription subscriptions = new CompositeSubscription(); protected final List<ObservableWithObserver> observables = new ArrayList<>(); public RxHolder(SchedulerManager schedulerManager) { this.schedulerManager = schedulerManager; } public <T> void subscribe(final Action1<Boolean> loadingAction, Observable<T> observable, Action1<? super T> onNext, Action1<Throwable> onError) { subscribe(loadingAction, observable, onNext, onError, null); } public <T> void subscribe(Observable<T> observable, Action1<? super T> onNext, Action1<Throwable> onError) { subscribe(observable, onNext, onError, null); } public <T> void subscribe(Observable<T> observable, final Action1<? super T> onNext, final Action1<Throwable> onError, final Action0 onCompleted) { subscribe(null, observable, onNext, onError, onCompleted); } public <T> void subscribe(final Action1<Boolean> loadingAction, Observable<T> observable, final Action1<? super T> onNext, final Action1<Throwable> onError, final Action0 onCompleted) { if (loadingAction != null) { loadingAction.call(true); } ConnectableObservable<T> replay = observable.compose(new Observable.Transformer<T, T>() { @Override public Observable<T> call(Observable<T> observable1) { return schedulerManager.bindObservable(observable1).doOnError(new Action1<Throwable>() { @Override public void call(Throwable t) { schedulerManager.logException(t); } }); } }).replay(); connectableSubscriptions.add(replay.connect()); final ObservableWithObserver<T> observableWithObserver = new ObservableWithObserver<>(replay); final Observer<T> observer = new Observer<T>() { @Override public void onCompleted() { try { if (onCompleted != null) { onCompleted.call(); } if (loadingAction != null) { loadingAction.call(false); } observables.remove(observableWithObserver); } catch (RuntimeException e) { schedulerManager.logException(e); throw e; } } @Override public void onError(Throwable e) { try { if (onError != null) { onError.call(e); } if (loadingAction != null) { loadingAction.call(false); } } catch (RuntimeException ex) { schedulerManager.logException(ex); throw ex; } finally { observables.remove(observableWithObserver); } } @Override public void onNext(T t) { try { if (onNext != null) { onNext.call(t); } } catch (RuntimeException e) { schedulerManager.logException(e); throw e; } } }; observableWithObserver.observer = observer; observables.add(observableWithObserver); subscribe(observableWithObserver); } private <T> void subscribe(final ObservableWithObserver<T> observableWithObserver) { subscriptions.add( observableWithObserver.observable .subscribe(observableWithObserver.observer) ); } public void resubscribePendingObservable() { if (!observables.isEmpty()) { ArrayList<ObservableWithObserver> observableCopy = new ArrayList<>(observables); for (ObservableWithObserver<?> observableWithObserver : observableCopy) { subscribe(observableWithObserver); } } } public void pause() { subscriptions.unsubscribe(); subscriptions = new CompositeSubscription(); } public void destroy() { connectableSubscriptions.unsubscribe(); } public CompositeSubscription getSubscriptions() { return subscriptions; } private static class ObservableWithObserver<T> { public final ConnectableObservable<T> observable; public Observer<T> observer; public ObservableWithObserver(ConnectableObservable<T> observable) { this.observable = observable; } } }