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

org.reactfx.SuspendableEventStream Maven / Gradle / Ivy

There is a newer version: 1.11
Show newest version
package org.reactfx;

import java.util.Deque;
import java.util.NoSuchElementException;
import java.util.function.BiFunction;
import java.util.function.BinaryOperator;
import java.util.function.Consumer;
import java.util.function.Function;

import javafx.beans.value.ObservableValue;

import org.reactfx.util.AccumulatorSize;
import org.reactfx.util.NotificationAccumulator;

/**
 * An event stream whose emission of events can be suspended temporarily. What
 * events, if any, are emitted when emission is resumed depends on the concrete
 * implementation.
 */
public interface SuspendableEventStream extends EventStream, Suspendable {

    /**
     * Returns an event stream that is suspended when the given
     * {@code condition} is {@code true} and emits normally when
     * {@code condition} is {@code false}.
     */
    default EventStream suspendedWhen(ObservableValue condition) {
        return new SuspendedWhenStream<>(this, condition);
    }
}

abstract class SuspendableEventStreamBase
extends SuspendableBase, T, A>
implements ProperEventStream, SuspendableEventStream {

    protected SuspendableEventStreamBase(
            EventStream source,
            NotificationAccumulator, T, A> pn) {
        super(source, pn);
    }
}


final class AccumulativeEventStream extends SuspendableEventStreamBase {
    private final Function size;
    private final Function head;
    private final Function tail;

    AccumulativeEventStream(
            EventStream source,
            Function initialTransformation,
            BiFunction accumulation,
            Function size,
            Function head,
            Function tail) {
        super(source, NotificationAccumulator.accumulativeStreamNotifications(size, head, tail, initialTransformation, accumulation));
        this.size = size;
        this.head = head;
        this.tail = tail;
    }

    @Override
    protected AccumulatorSize sizeOf(A accum) {
        return size.apply(accum);
    }

    @Override
    protected T headOf(A accum) {
        return head.apply(accum);
    }

    @Override
    protected A tailOf(A accum) {
        return tail.apply(accum);
    }
}

/**
 * See {@link EventStream#pausable()}
 */
final class PausableEventStream extends SuspendableEventStreamBase> {

    PausableEventStream(EventStream source) {
        super(source, NotificationAccumulator.queuingStreamNotifications());
    }

    @Override
    protected AccumulatorSize sizeOf(Deque accum) {
        return AccumulatorSize.fromInt(accum.size());
    }

    @Override
    protected T headOf(Deque accum) {
        return accum.getFirst();
    }

    @Override
    protected Deque tailOf(Deque accum) {
        accum.removeFirst();
        return accum;
    }
}


abstract class AbstractReducibleEventStream extends SuspendableEventStreamBase {

    protected AbstractReducibleEventStream(
            EventStream source,
            NotificationAccumulator, T, T> pn) {
        super(source, pn);
    }

    @Override
    protected final AccumulatorSize sizeOf(T accum) {
        return AccumulatorSize.ONE;
    }

    @Override
    protected final T headOf(T accum) {
        return accum;
    }

    @Override
    protected final T tailOf(T accum) {
        throw new NoSuchElementException();
    }
}

/**
 * See {@link EventStream#reducible(BinaryOperator)}
 */
final class ReducibleEventStream extends AbstractReducibleEventStream {

    public ReducibleEventStream(
            EventStream source,
            BinaryOperator reduction) {
        super(source, NotificationAccumulator.reducingStreamNotifications(reduction));
    }
}

/**
 * See {@link EventStream#forgetful()}
 */
final class ForgetfulEventStream extends AbstractReducibleEventStream {

    ForgetfulEventStream(EventStream source) {
        super(source, NotificationAccumulator.retainLatestStreamNotifications());
    }
}


final class SuppressibleEventStream extends SuspendableEventStreamBase {

    SuppressibleEventStream(EventStream source) {
        super(source, NotificationAccumulator.nonAccumulativeStreamNotifications());
    }

    @Override
    protected AccumulatorSize sizeOf(T accum) {
        return AccumulatorSize.ZERO;
    }

    @Override
    protected T headOf(T accum) {
        throw new NoSuchElementException();
    }

    @Override
    protected T tailOf(T accum) {
        throw new NoSuchElementException();
    }

    @Override
    protected T initialAccumulator(T value) {
        return null;
    }

    // Override reduce so that it permits accumulation.
    @Override
    protected T reduce(T accum, T value) {
        return null;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy