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

io.reactivex.rxjavafx.transformers.FxObservableTransformers Maven / Gradle / Ivy

There is a newer version: 2.2.2
Show newest version
/**
 * Copyright 2017 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 io.reactivex.rxjavafx.transformers;

import io.reactivex.ObservableOperator;
import io.reactivex.ObservableTransformer;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import io.reactivex.exceptions.Exceptions;
import io.reactivex.functions.Action;
import io.reactivex.functions.Consumer;
import io.reactivex.observers.ResourceObserver;
import javafx.application.Platform;


public final class FxObservableTransformers {
    private FxObservableTransformers() {}

    private static  void runOnFx(T t, Consumer consumer)  {
        Platform.runLater(() -> {
                    try {
                        consumer.accept(t);
                    } catch (Throwable e) {
                        throw Exceptions.propagate(e);
                    }
                }
        );
    }
    private static  void runOnFx(Action action)  {
        Platform.runLater(() -> {
                    try {
                        action.run();
                    } catch (Throwable e) {
                        throw Exceptions.propagate(e);
                    }
                }
        );
    }

    /**
     * Performs a given action for each item on the FX thread
     * @param onNext
     * @param 
     */
    public static  ObservableTransformer doOnNextFx(Consumer onNext) {
        return obs -> obs.doOnNext(t -> runOnFx(t, onNext));
    }

    /**
     * Performs a given action on a Throwable on the FX thread in the event of an onError
     * @param onError
     * @param 
     */
    public static  ObservableTransformer doOnErrorFx(Consumer onError) {
        return obs -> obs.doOnError(e -> runOnFx(e,onError));
    }

    /**
     * Performs a given Action on the FX thread when onCompleted is called
     * @param onCompleted
     * @param 
     */
    public static  ObservableTransformer doOnCompleteFx(Action onCompleted) {
        return obs -> obs.doOnComplete(() -> runOnFx(onCompleted));
    }

    /**
     * Performs a given Action on the FX thread when subscribed to
     * @param subscribe
     * @param 
     */
    public static  ObservableTransformer doOnSubscribeFx(Consumer subscribe) {
        return obs -> obs.doOnSubscribe((d -> runOnFx(d,subscribe)));
    }

    /**
     * Performs the provided onTerminate action on the FX thread
     * @param onTerminate
     * @param 
     */
    public static  ObservableTransformer doOnTerminateFx(Action onTerminate) {
        return obs -> obs.doOnTerminate(() -> runOnFx(onTerminate));
    }

    /**
     * Performs the provided onTerminate action on the FX thread
     * @param onDipsose
     * @param 
     */
    public static  ObservableTransformer doOnDisposeFx(Action onDipsose) {
        return obs -> obs.doOnDispose(() -> runOnFx(onDipsose));
    }

    /**
     * Performs an action on onNext with the provided emission count
     * @param onNext
     * @param 
     */
    public static  ObservableTransformer doOnNextCount(Consumer onNext) {
        return obs -> obs.lift(new OperatorEmissionCounter<>(new CountObserver(onNext,null,null)));
    }

    /**
     * Performs an action on onComplete with the provided emission count
     * @param onComplete
     * @param 
     */
    public static  ObservableTransformer doOnCompleteCount(Consumer onComplete) {
        return obs -> obs.lift(new OperatorEmissionCounter<>(new CountObserver(null,onComplete,null)));
    }

    /**
     * Performs an action on onError with the provided emission count
     * @param onError
     * @param 
     */
    public static  ObservableTransformer doOnErrorCount(Consumer onError) {
        return obs -> obs.lift(new OperatorEmissionCounter<>(new CountObserver(null,null,onError)));
    }

    /**
     * Performs an action on FX thread on onNext with the provided emission count
     * @param onNext
     * @param 
     */
    public static  ObservableTransformer doOnNextCountFx(Consumer onNext) {
        return obs -> obs.compose(doOnNextCount(i -> runOnFx(i,onNext)));
    }

    /**
     * Performs an action on FX thread on onCompleted with the provided emission count
     * @param onComplete
     * @param 
     */
    public static  ObservableTransformer doOnCompleteCountFx(Consumer onComplete) {
        return obs -> obs.compose(doOnCompleteCount(i -> runOnFx(i,onComplete)));
    }

    /**
     * Performs an action on FX thread on onError with the provided emission count
     * @param onError
     * @param 
     */
    public static  ObservableTransformer doOnErrorCountFx(Consumer onError) {
        return obs -> obs.compose(doOnErrorCount(i -> runOnFx(i,onError)));
    }


    private static class OperatorEmissionCounter implements ObservableOperator {

        private final CountObserver ctObserver;

        OperatorEmissionCounter(CountObserver ctObserver) {
            this.ctObserver = ctObserver;
        }

        @Override
        public Observer apply(Observer child) {

            return new ResourceObserver() {
                private int count = 0;
                private boolean done = false;

                @Override
                public void onComplete() {
                    if (done)
                        return;

                    try {
                        if (ctObserver.doOnCompletedCountAction != null)
                            ctObserver.doOnCompletedCountAction.accept(count);
                    } catch (Exception e) {
                        Exceptions.throwIfFatal(e);
                        onError(e);
                        return;
                    }
                    done = true;
                    child.onComplete();
                }

                @Override
                public void onError(Throwable e) {
                    if (done)
                        return;
                    try {
                        if (ctObserver.doOnErrorCountAction != null)
                            ctObserver.doOnErrorCountAction.accept(count);
                    } catch(Exception e1) {
                        Exceptions.throwIfFatal(e1);
                        child.onError(e1);
                    }
                }

                @Override
                public void onNext(T t) {
                    if (done)
                        return;
                    try {
                        if (ctObserver.doOnNextCountAction != null)
                            ctObserver.doOnNextCountAction.accept(++count);
                    } catch(Exception e) {
                        Exceptions.throwIfFatal(e);
                        onError(e);
                        return;
                    }
                    child.onNext(t);
                }
            };
        }
    }
    private static final class CountObserver {
        private final Consumer doOnNextCountAction;
        private final Consumer doOnCompletedCountAction;
        private final Consumer doOnErrorCountAction;

        CountObserver(Consumer doOnNextCountAction, Consumer doOnCompletedCountAction, Consumer doOnErrorCountAction) {
            this.doOnNextCountAction = doOnNextCountAction;
            this.doOnCompletedCountAction = doOnCompletedCountAction;
            this.doOnErrorCountAction = doOnErrorCountAction;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy