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

org.reactfx.collection.ListReduction Maven / Gradle / Ivy

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

import java.util.function.BinaryOperator;

import javafx.beans.value.ObservableValue;
import javafx.collections.ObservableList;
import javafx.scene.control.IndexRange;

import org.reactfx.Subscription;
import org.reactfx.util.Experimental;
import org.reactfx.util.FingerTree;
import org.reactfx.util.ToSemigroup;
import org.reactfx.value.Val;
import org.reactfx.value.ValBase;

class ListReduction extends ValBase {
    private final ObservableList input;
    private final BinaryOperator reduction;
    private final ToSemigroup monoid;

    private FingerTree tree = null;

    ListReduction(
            ObservableList input,
            BinaryOperator reduction) {
        this.input = input;
        this.reduction = reduction;
        monoid = new ToSemigroup() {

            @Override
            public T apply(T t) {
                return t;
            }

            @Override
            public T reduce(T left, T right) {
                return reduction.apply(left, right);
            }
        };
    }

    @Override
    protected Subscription connect() {
        assert tree == null;
        tree = FingerTree.mkTree(input, monoid);
        return LiveList.observeChanges(input, ch -> {
            for(ListModification mod: ch) {
                FingerTree left = tree.split(mod.getFrom())._1;
                FingerTree right = tree.split(mod.getFrom() + mod.getRemovedSize())._2;
                FingerTree middle = FingerTree.mkTree(mod.getAddedSubList(), monoid);
                tree = left.join(middle).join(right);
            }
            invalidate();
        })
        .and(() -> tree = null);
    }

    protected int getFrom(int max) {
        return 0;
    }

    protected int getTo(int max) {
        return max;
    }

    @Override
    protected final T computeValue() {
        if(isObservingInputs()) {
            assert tree != null;
            int max = tree.getLeafCount();
            return tree.getSummaryBetween(getFrom(max), getTo(max)).orElse(null);
        } else {
            assert tree == null;
            int max = input.size();
            return input.subList(getFrom(max), getTo(max))
                    .stream().reduce(reduction).orElse(null);
        }
    }
}


@Experimental
class ListRangeReduction extends ListReduction {
    private final ObservableValue range;

    ListRangeReduction(
            ObservableList input,
            ObservableValue range,
            BinaryOperator reduction) {
        super(input, reduction);
        this.range = range;
    }

    @Override
    protected Subscription connect() {
        return super.connect().and(Val.observeInvalidations(range, obs -> invalidate()));
    }

    @Override
    protected int getFrom(int max) {
        return Math.min(range.getValue().getStart(), max);
    }

    @Override
    protected int getTo(int max) {
        return Math.min(range.getValue().getEnd(), max);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy