mirror of
https://github.com/xpipe-io/xpipe.git
synced 2026-09-25 01:45:37 +00:00
Various performance fixes
This commit is contained in:
@@ -62,12 +62,6 @@ public class ListBoxViewComp<T> extends Comp<CompStructure<ScrollPane>> {
|
||||
refresh(scroll, vbox, c.getList(), all, cache, true, true);
|
||||
});
|
||||
|
||||
all.addListener((ListChangeListener<? super T>) c -> {
|
||||
synchronized (cache) {
|
||||
cache.keySet().retainAll(c.getList());
|
||||
}
|
||||
});
|
||||
|
||||
if (scrollBar) {
|
||||
scroll.setVbarPolicy(ScrollPane.ScrollBarPolicy.ALWAYS);
|
||||
scroll.skinProperty().subscribe(newValue -> {
|
||||
@@ -178,9 +172,16 @@ public class ListBoxViewComp<T> extends Comp<CompStructure<ScrollPane>> {
|
||||
}
|
||||
|
||||
private void updateVisibilities(ScrollPane scroll, VBox vbox) {
|
||||
int count = 0;
|
||||
for (Node child : vbox.getChildren()) {
|
||||
var v = isVisible(scroll, vbox, child);
|
||||
child.setVisible(v);
|
||||
if (v) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
if (count > 10) {
|
||||
// System.out.println("Visible: " + count);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,6 @@ public class StoreEntryWrapper {
|
||||
private final Property<String> name;
|
||||
private final DataStoreEntry entry;
|
||||
private final Property<Instant> lastAccess;
|
||||
private final Property<Instant> lastAccessApplied = new SimpleObjectProperty<>();
|
||||
private final BooleanProperty disabled = new SimpleBooleanProperty();
|
||||
private final BooleanProperty busy = new SimpleBooleanProperty();
|
||||
private final Property<DataStoreEntry.Validity> validity = new SimpleObjectProperty<>();
|
||||
@@ -104,10 +103,6 @@ public class StoreEntryWrapper {
|
||||
setupListeners();
|
||||
}
|
||||
|
||||
public void applyLastAccess() {
|
||||
this.lastAccessApplied.setValue(lastAccess.getValue());
|
||||
}
|
||||
|
||||
public void moveTo(DataStoreCategory category) {
|
||||
ThreadHelper.runAsync(() -> {
|
||||
DataStorage.get().moveEntryToCategory(entry, category);
|
||||
|
||||
@@ -96,7 +96,7 @@ public class StoreSection {
|
||||
|
||||
var current = mappedSortMode.getValue();
|
||||
if (current != null) {
|
||||
return current.comparator().compare(current.representative(o1), current.representative(o2));
|
||||
return current.comparator().compare(o1, o2);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,19 +1,12 @@
|
||||
package io.xpipe.app.comp.store;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Optional;
|
||||
import java.util.*;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public interface StoreSortMode {
|
||||
|
||||
StoreSortMode ALPHABETICAL_DESC = new StoreSortMode() {
|
||||
@Override
|
||||
public StoreSection representative(StoreSection s) {
|
||||
return s;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
@@ -27,11 +20,6 @@ public interface StoreSortMode {
|
||||
}
|
||||
};
|
||||
StoreSortMode ALPHABETICAL_ASC = new StoreSortMode() {
|
||||
@Override
|
||||
public StoreSection representative(StoreSection s) {
|
||||
return s;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return "alphabetical-asc";
|
||||
@@ -44,10 +32,10 @@ public interface StoreSortMode {
|
||||
.reversed();
|
||||
}
|
||||
};
|
||||
StoreSortMode DATE_DESC = new StoreSortMode() {
|
||||
StoreSortMode DATE_DESC = new StoreSortMode.DateSortMode() {
|
||||
|
||||
private Instant date(StoreSection s) {
|
||||
var la = s.getWrapper().getLastAccessApplied().getValue();
|
||||
protected Instant date(StoreSection s) {
|
||||
var la = s.getWrapper().getLastAccess().getValue();
|
||||
if (la == null) {
|
||||
return Instant.MAX;
|
||||
}
|
||||
@@ -56,35 +44,19 @@ public interface StoreSortMode {
|
||||
}
|
||||
|
||||
@Override
|
||||
public StoreSection representative(StoreSection s) {
|
||||
return Stream.concat(
|
||||
s.getShownChildren().getList().stream()
|
||||
.filter(section -> section.getWrapper()
|
||||
.getEntry()
|
||||
.getValidity()
|
||||
.isUsable())
|
||||
.map(this::representative),
|
||||
Stream.of(s))
|
||||
.max(Comparator.comparing(section -> date(section)))
|
||||
.orElseThrow();
|
||||
protected int compare(Instant s1, Instant s2) {
|
||||
return s2.compareTo(s1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return "date-desc";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Comparator<StoreSection> comparator() {
|
||||
return Comparator.comparing(e -> {
|
||||
return date(e);
|
||||
});
|
||||
}
|
||||
};
|
||||
StoreSortMode DATE_ASC = new StoreSortMode() {
|
||||
StoreSortMode DATE_ASC = new StoreSortMode.DateSortMode() {
|
||||
|
||||
private Instant date(StoreSection s) {
|
||||
var la = s.getWrapper().getLastAccessApplied().getValue();
|
||||
protected Instant date(StoreSection s) {
|
||||
var la = s.getWrapper().getLastAccess().getValue();
|
||||
if (la == null) {
|
||||
return Instant.MIN;
|
||||
}
|
||||
@@ -93,32 +65,16 @@ public interface StoreSortMode {
|
||||
}
|
||||
|
||||
@Override
|
||||
public StoreSection representative(StoreSection s) {
|
||||
return Stream.concat(
|
||||
s.getShownChildren().getList().stream()
|
||||
.filter(section -> section.getWrapper()
|
||||
.getEntry()
|
||||
.getValidity()
|
||||
.isUsable())
|
||||
.map(this::representative),
|
||||
Stream.of(s))
|
||||
.max(Comparator.comparing(section -> date(section)))
|
||||
.orElseThrow();
|
||||
protected int compare(Instant s1, Instant s2) {
|
||||
return s1.compareTo(s2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return "date-asc";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Comparator<StoreSection> comparator() {
|
||||
return Comparator.<StoreSection, Instant>comparing(e -> {
|
||||
return date(e);
|
||||
})
|
||||
.reversed();
|
||||
}
|
||||
};
|
||||
|
||||
List<StoreSortMode> ALL = List.of(ALPHABETICAL_DESC, ALPHABETICAL_ASC, DATE_DESC, DATE_ASC);
|
||||
|
||||
static Optional<StoreSortMode> fromId(String id) {
|
||||
@@ -131,9 +87,54 @@ public interface StoreSortMode {
|
||||
return DATE_ASC;
|
||||
}
|
||||
|
||||
StoreSection representative(StoreSection s);
|
||||
|
||||
String getId();
|
||||
|
||||
Comparator<StoreSection> comparator();
|
||||
|
||||
abstract class DateSortMode implements StoreSortMode {
|
||||
|
||||
private int sortModeIndex = -1;
|
||||
private final Map<StoreSection, StoreSection> cachedRepresentatives = new IdentityHashMap<>();
|
||||
|
||||
private StoreSection computeRepresentative(StoreSection s) {
|
||||
return Stream.concat(
|
||||
s.getShownChildren().getList().stream()
|
||||
.filter(section -> section.getWrapper()
|
||||
.getEntry()
|
||||
.getValidity()
|
||||
.isUsable())
|
||||
.map(this::getRepresentative),
|
||||
Stream.of(s))
|
||||
.max(Comparator.comparing(section -> date(section)))
|
||||
.orElseThrow();
|
||||
}
|
||||
|
||||
private StoreSection getRepresentative(StoreSection s) {
|
||||
if (StoreViewState.get().getSortModeObservable().get() != sortModeIndex) {
|
||||
cachedRepresentatives.clear();
|
||||
sortModeIndex = StoreViewState.get().getSortModeObservable().get();
|
||||
}
|
||||
|
||||
if (cachedRepresentatives.containsKey(s)) {
|
||||
return cachedRepresentatives.get(s);
|
||||
}
|
||||
|
||||
var r = computeRepresentative(s);
|
||||
cachedRepresentatives.put(s, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
protected abstract Instant date(StoreSection s);
|
||||
|
||||
protected abstract int compare(Instant s1, Instant s2);
|
||||
|
||||
@Override
|
||||
public Comparator<StoreSection> comparator() {
|
||||
return (o1, o2) -> {
|
||||
var r1 = getRepresentative(o1);
|
||||
var r2 = getRepresentative(o2);
|
||||
return DateSortMode.this.compare(date(r1), date(r2));
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +36,9 @@ public class StoreViewState {
|
||||
@Getter
|
||||
private final IntegerProperty entriesListUpdateObservable = new SimpleIntegerProperty();
|
||||
|
||||
@Getter
|
||||
private final IntegerProperty sortModeObservable = new SimpleIntegerProperty();
|
||||
|
||||
@Getter
|
||||
private final Property<StoreCategoryWrapper> activeCategory = new SimpleObjectProperty<>();
|
||||
|
||||
@@ -121,7 +124,6 @@ public class StoreViewState {
|
||||
.setAll(FXCollections.observableArrayList(DataStorage.get().getStoreEntries().stream()
|
||||
.map(StoreEntryWrapper::new)
|
||||
.toList()));
|
||||
allEntries.getList().forEach(e -> e.applyLastAccess());
|
||||
categories
|
||||
.getList()
|
||||
.setAll(FXCollections.observableArrayList(DataStorage.get().getStoreCategories().stream()
|
||||
@@ -153,7 +155,7 @@ public class StoreViewState {
|
||||
}
|
||||
|
||||
public void updateDisplay() {
|
||||
allEntries.getList().forEach(e -> e.applyLastAccess());
|
||||
sortModeObservable.setValue(sortModeObservable.get() + 1);
|
||||
toggleStoreListUpdate();
|
||||
}
|
||||
|
||||
@@ -192,7 +194,6 @@ public class StoreViewState {
|
||||
var l = Arrays.stream(entry)
|
||||
.map(StoreEntryWrapper::new)
|
||||
.peek(storeEntryWrapper -> storeEntryWrapper.update())
|
||||
.peek(wrapper -> wrapper.applyLastAccess())
|
||||
.toList();
|
||||
|
||||
// Don't update anything if we have already reset
|
||||
|
||||
@@ -85,9 +85,19 @@ public class DerivedObservableList<T> {
|
||||
target.setAll(newList);
|
||||
}
|
||||
|
||||
private int indexOfFromStart(List<? extends T> list, T value, int start) {
|
||||
for (int i = start; i < list.size(); i++) {
|
||||
if (Objects.equals(list.get(i), value)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private void setContentUnique(List<? extends T> newList) {
|
||||
var listSet = new HashSet<>(list);
|
||||
var newSet = new HashSet<>(newList);
|
||||
|
||||
// Addition
|
||||
if (newSet.containsAll(list)) {
|
||||
var l = new ArrayList<>(newList);
|
||||
@@ -100,7 +110,7 @@ public class DerivedObservableList<T> {
|
||||
|
||||
var start = 0;
|
||||
for (int end = 0; end <= list.size(); end++) {
|
||||
var index = end < list.size() ? newList.indexOf(list.get(end)) : newList.size();
|
||||
var index = end < list.size() ? indexOfFromStart(newList, list.get(end), end) : newList.size();
|
||||
for (; start < index; start++) {
|
||||
list.add(start, newList.get(start));
|
||||
}
|
||||
@@ -133,7 +143,8 @@ public class DerivedObservableList<T> {
|
||||
var cache = new HashMap<T, V>();
|
||||
var l1 = this.<V>createNewDerived();
|
||||
Runnable runnable = () -> {
|
||||
cache.keySet().removeIf(t -> !getList().contains(t));
|
||||
var listSet = new HashSet<>(list);
|
||||
cache.keySet().removeIf(t -> !listSet.contains(t));
|
||||
l1.setContent(list.stream()
|
||||
.map(v -> {
|
||||
if (!cache.containsKey(v)) {
|
||||
|
||||
Reference in New Issue
Block a user