org.reactfx.SuccessionReducingStream Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of reactfx Show documentation
Show all versions of reactfx Show documentation
Reactive event streams for JavaFX
package org.reactfx;
import java.util.function.BiFunction;
import java.util.function.Function;
import javafx.beans.binding.BooleanBinding;
import javafx.beans.value.ObservableBooleanValue;
import org.reactfx.util.Timer;
class SuccessionReducingStream extends EventStreamBase implements AwaitingEventStream {
private final EventStream input;
private final Function initial;
private final BiFunction reduction;
private final Timer timer;
private boolean hasEvent = false;
private BooleanBinding pending = null;
private O event = null;
public SuccessionReducingStream(
EventStream input,
Function initial,
BiFunction reduction,
Function timerFactory) {
this.input = input;
this.initial = initial;
this.reduction = reduction;
this.timer = timerFactory.apply(this::handleTimeout);
}
@Override
public ObservableBooleanValue pendingProperty() {
if(pending == null) {
pending = new BooleanBinding() {
@Override
protected boolean computeValue() {
return hasEvent;
}
};
}
return pending;
}
@Override
public boolean isPending() {
return pending != null ? pending.get() : hasEvent;
}
@Override
protected final Subscription observeInputs() {
return input.subscribe(this::handleEvent);
}
private void handleEvent(I i) {
if(hasEvent) {
event = reduction.apply(event, i);
} else {
assert event == null;
event = initial.apply(i);
hasEvent = true;
invalidatePending();
}
timer.restart();
}
private void handleTimeout() {
assert hasEvent;
hasEvent = false;
O toEmit = event;
event = null;
emit(toEmit);
invalidatePending();
}
private void invalidatePending() {
if(pending != null) {
pending.invalidate();
}
}
}