package xapi.jre.ui.runtime;
import javafx.beans.InvalidationListener;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableDoubleValue;
import xapi.fu.Notifier;
import xapi.fu.Out1;
import xapi.fu.X_Fu;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.function.IntSupplier;
import java.util.function.LongSupplier;
/**
* Created by James X. Nelson (james @wetheinter.net) on 7/1/16.
*/
public class DoubleSupplierBinding implements ObservableDoubleValue {
private final Out1<Double> value;
private final Map<ChangeListener<? super Number>, Void> changeListeners;
private final Map<InvalidationListener, Void> invalidationListeners;
private DoubleSupplierBinding(Out1<Double> value) {
this.value = value.mapIf(X_Fu::isNull, d->defaultValue());
changeListeners = new IdentityHashMap<>();
invalidationListeners = new IdentityHashMap<>();
}
protected double defaultValue() {
return -1;
}
public static DoubleSupplierBinding valueOf(Out1<Double> value) {
return new DoubleSupplierBinding(value);
}
public static DoubleSupplierBinding valueOf(IntSupplier value) {
return new DoubleSupplierBinding(()->(double)value.getAsInt());
}
public static DoubleSupplierBinding valueOf(LongSupplier value) {
return new DoubleSupplierBinding(()->(double)value.getAsLong());
}
public void invalidate() {
invalidationListeners.keySet()
.forEach(l->l.invalidated(DoubleSupplierBinding.this));
}
public DoubleSupplierBinding bindNotifier(Notifier<? extends Number> notifier) {
notifier.listen((oldV, newV)-> {
// per source code in javafx ExpressionHelper class, we fire invalidations before changes.
invalidate();
changeListeners.keySet()
.forEach(l->l.changed(DoubleSupplierBinding.this, oldV, newV));
}
);
return this;
}
@Override
public double get() {
return value.out1();
}
@Override
public Double getValue() {
return value.out1();
}
@Override
public void addListener(InvalidationListener observer) {
invalidationListeners.put(observer, null);
}
@Override
public void addListener(ChangeListener<? super Number> listener) {
changeListeners.put(listener, null);
}
@Override
public void removeListener(InvalidationListener observer) {
invalidationListeners.put(observer, null);
}
@Override
public void removeListener(ChangeListener<? super Number> listener) {
changeListeners.remove(listener);
}
@Override
public int intValue() {
return value.out1().intValue();
}
@Override
public long longValue() {
return value.out1().longValue();
}
@Override
public float floatValue() {
return value.out1().floatValue();
}
@Override
public double doubleValue() {
return value.out1();
}
}