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

rx.operators.OperationMulticast Maven / Gradle / Ivy

There is a newer version: 0.20.7
Show newest version
/**
 * Copyright 2014 Netflix, Inc.
 * 
 * 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 rx.operators;

import rx.Observable;
import rx.Observable.OnSubscribeFunc;
import rx.Observer;
import rx.Subscriber;
import rx.Subscription;
import rx.functions.Action0;
import rx.functions.Func0;
import rx.functions.Func1;
import rx.observables.ConnectableObservable;
import rx.subjects.Subject;
import rx.subscriptions.CompositeSubscription;
import rx.subscriptions.Subscriptions;

public class OperationMulticast {
    public static  ConnectableObservable multicast(Observable source, final Subject subject) {
        return new MulticastConnectableObservable(source, subject);
    }

    private static class MulticastConnectableObservable extends ConnectableObservable {
        private final Object lock = new Object();

        private final Observable source;
        private final Subject subject;

        private Subscription subscription;

        public MulticastConnectableObservable(Observable source, final Subject subject) {
            super(new OnSubscribe() {
                @Override
                public void call(Subscriber observer) {
                    subject.subscribe(observer);
                }
            });
            this.source = source;
            this.subject = subject;
        }

        public Subscription connect() {
            synchronized (lock) {
                if (subscription == null) {
                    subscription = source.subscribe(new Observer() {
                        @Override
                        public void onCompleted() {
                            subject.onCompleted();
                        }

                        @Override
                        public void onError(Throwable e) {
                            subject.onError(e);
                        }

                        @Override
                        public void onNext(T args) {
                            subject.onNext(args);
                        }
                    });
                }
            }

            return Subscriptions.create(new Action0() {
                @Override
                public void call() {
                    synchronized (lock) {
                        if (subscription != null) {
                            subscription.unsubscribe();
                            subscription = null;
                        }
                    }
                }
            });
        }

    }

    /**
     * Returns an observable sequence that contains the elements of a sequence
     * produced by multicasting the source sequence within a selector function.
     * 
     * @param source
     * @param subjectFactory
     * @param selector
     * @return
     * 
     * @see MSDN: Observable.Multicast
     */
    public static  Observable multicast(
            final Observable source,
            final Func0> subjectFactory,
            final Func1, ? extends Observable> selector) {
        return Observable.create(new MulticastSubscribeFunc(source, subjectFactory, selector));
    }

    /** The multicast subscription function. */
    private static final class MulticastSubscribeFunc implements OnSubscribeFunc {
        final Observable source;
        final Func0> subjectFactory;
        final Func1, ? extends Observable> resultSelector;

        public MulticastSubscribeFunc(Observable source,
                Func0> subjectFactory,
                Func1, ? extends Observable> resultSelector) {
            this.source = source;
            this.subjectFactory = subjectFactory;
            this.resultSelector = resultSelector;
        }

        @Override
        public Subscription onSubscribe(Observer t1) {
            Observable observable;
            ConnectableObservable connectable;
            try {
                Subject subject = subjectFactory.call();

                connectable = new MulticastConnectableObservable(source, subject);

                observable = resultSelector.call(connectable);
            } catch (Throwable t) {
                t1.onError(t);
                return Subscriptions.empty();
            }

            CompositeSubscription csub = new CompositeSubscription();

            csub.add(observable.subscribe(new SafeObserver(
                    new SafeObservableSubscription(csub), t1)));
            csub.add(connectable.connect());

            return csub;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy