Some rework

This commit is contained in:
crschnick 2025-03-18 16:53:15 +00:00
parent 0083ad3739
commit 5c71d2ac23
3 changed files with 51 additions and 14 deletions

View file

@ -144,12 +144,11 @@ public abstract class Comp<S extends CompStructure<?>> {
public Comp<S> visible(ObservableValue<Boolean> o) {
return apply(struc -> {
var region = struc.get();
BindingsHelper.preserve(region, o);
o.subscribe(n -> {
o.subscribe(BindingsHelper.weak(region, n -> {
PlatformThread.runLaterIfNeeded(() -> {
region.setVisible(n);
});
});
}));
});
}
@ -164,8 +163,7 @@ public abstract class Comp<S extends CompStructure<?>> {
public Comp<S> hide(ObservableValue<Boolean> o) {
return apply(struc -> {
var region = struc.get();
BindingsHelper.preserve(region, o);
o.subscribe(n -> {
o.subscribe(BindingsHelper.weak(region, n -> {
PlatformThread.runLaterIfNeeded(() -> {
if (!n) {
region.setVisible(true);
@ -175,7 +173,7 @@ public abstract class Comp<S extends CompStructure<?>> {
region.setManaged(false);
}
});
});
}));
});
}

View file

@ -214,9 +214,9 @@ public abstract class StoreEntryComp extends SimpleComp {
ig.getChildren().setAll(l);
};
update.run();
getWrapper().getActionProviders().addListener((observableValue, actionProviders, t1) -> {
getWrapper().getActionProviders().addListener(BindingsHelper.weak(getWrapper(), (observableValue, actionProviders, t1) -> {
update.run();
});
}));
update.run();
ig.setAlignment(Pos.CENTER_RIGHT);
ig.getStyleClass().add("button-bar");

View file

@ -1,28 +1,40 @@
package io.xpipe.app.util;
import io.xpipe.app.comp.store.StoreEntryComp;
import javafx.beans.binding.Bindings;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.beans.value.WeakChangeListener;
import lombok.Value;
import java.lang.ref.WeakReference;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;
import java.util.function.Function;
@SuppressWarnings("InfiniteLoopStatement")
public class BindingsHelper {
private static final Set<ReferenceEntry> REFERENCES = new HashSet<>();
private static final Map<WeakReference<?>, ReferenceEntry> REFERENCES = new HashMap<>();
static {
ThreadHelper.createPlatformThread("referenceGC", true, () -> {
while (true) {
synchronized (REFERENCES) {
REFERENCES.removeIf(ReferenceEntry::canGc);
REFERENCES.values().removeIf(referenceEntry -> {
var r = referenceEntry.canGc();
if (!r) {
return false;
}
// System.out.println("Freed " + referenceEntry.getSource().get() + " -> " + referenceEntry.getTarget());
return true;
});
}
ThreadHelper.sleep(1000);
@ -33,12 +45,39 @@ public class BindingsHelper {
.start();
}
public static void preserve(Object source, Object target) {
public static WeakReference<?> preserve(Object source, Object target) {
synchronized (REFERENCES) {
REFERENCES.add(new ReferenceEntry(new WeakReference<>(source), target));
var ref = new WeakReference<>(source);
var v = new ReferenceEntry(ref, target);
REFERENCES.put(ref, v);
return ref;
}
}
public static <T> WeakChangeListener<T> weak(Object source, ChangeListener<T> listener) {
preserve(source, source);
var weak = new WeakChangeListener<>(listener);
return weak;
}
@SuppressWarnings("unchecked")
public static <T> Consumer<T> weak(Object source, Consumer<T> listener) {
var ref = preserve(source, listener);
return (T item) -> {
var v = ref.get();
if (v == null) {
return;
}
var c = REFERENCES.get(ref);
if (c == null) {
return;
}
((Consumer<T>) c.getTarget()).accept(item);
};
}
public static <T, U> ObservableValue<U> map(
ObservableValue<T> observableValue, Function<? super T, ? extends U> mapper) {
return Bindings.createObjectBinding(