aboutsummaryrefslogtreecommitdiff
path: root/runtime/src/main
diff options
context:
space:
mode:
authorshedaniel <daniel@shedaniel.me>2022-12-09 02:08:47 +0800
committershedaniel <daniel@shedaniel.me>2022-12-09 02:08:47 +0800
commitdc6351d3b4893c316854f7a9fc6f8d95320046ee (patch)
treea74dc043393b9f228473766cb7ce126cf080c206 /runtime/src/main
parent00029913ffe72ee1b6cdff64ffe1fd9e56ac15a1 (diff)
parent2caa595aa94d46ddaefc5ecdb79f7ec834f7eae8 (diff)
downloadRoughlyEnoughItems-dc6351d3b4893c316854f7a9fc6f8d95320046ee.tar.gz
RoughlyEnoughItems-dc6351d3b4893c316854f7a9fc6f8d95320046ee.tar.bz2
RoughlyEnoughItems-dc6351d3b4893c316854f7a9fc6f8d95320046ee.zip
Merge remote-tracking branch 'origin/9.x-1.19' into feature/1.19.3
# Conflicts: # runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringRulesScreen.java
Diffstat (limited to 'runtime/src/main')
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java72
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigObjectImpl.java2
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringRulesScreen.java50
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/FilteringContextImpl.java51
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/BasicFilteringRuleImpl.java199
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/SearchFilteringRuleType.java7
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/ScreenOverlayImpl.java14
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/AbstractDisplayViewingScreen.java4
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/CompositeDisplayViewingScreen.java8
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/DefaultDisplayViewingScreen.java54
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/ConfigButtonWidget.java2
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/CraftableFilterButtonWidget.java2
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/TabContainerWidget.java155
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/history/DisplayHistoryWidget.java8
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/search/OverlaySearchField.java6
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/EntryRegistryImpl.java73
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/EntryRegistryList.java13
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/EntryRegistryListImpl.java206
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/EntryRegistryListener.java6
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/FilteredEntryList.java43
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/FilteringLogic.java107
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/NormalEntryRegistryList.java115
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/PreFilteredEntryList.java266
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/ReloadingEntryRegistryList.java107
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/plugin/client/runtime/DefaultClientRuntimePlugin.java3
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/plugin/test/REITestPlugin.java42
26 files changed, 1076 insertions, 539 deletions
diff --git a/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java b/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java
index 01e4fc1fd..16558a54e 100644
--- a/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java
+++ b/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java
@@ -24,6 +24,8 @@
package me.shedaniel.rei;
import com.google.common.collect.Lists;
+import com.mojang.blaze3d.systems.RenderSystem;
+import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.serialization.DataResult;
import dev.architectury.event.Event;
import dev.architectury.event.EventFactory;
@@ -88,6 +90,7 @@ import net.fabricmc.api.Environment;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.components.EditBox;
import net.minecraft.client.gui.components.ImageButton;
+import net.minecraft.client.gui.components.events.GuiEventListener;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
import net.minecraft.client.gui.screens.inventory.CraftingScreen;
@@ -385,23 +388,64 @@ public class RoughlyEnoughItemsCoreClient {
ClientScreenInputEvent.CHAR_TYPED_PRE.register((minecraftClient, screen, character, keyCode) -> {
if (shouldReturn(screen) || screen instanceof DisplayScreen)
return EventResult.pass();
- if (screen.getFocused() != null && screen.getFocused() instanceof EditBox || (screen.getFocused() instanceof RecipeBookComponent && ((RecipeBookComponent) screen.getFocused()).searchBox != null && ((RecipeBookComponent) screen.getFocused()).searchBox.isFocused()))
- if (!REIRuntimeImpl.getSearchField().isFocused())
- return EventResult.pass();
+ if (!REIRuntimeImpl.getSearchField().isFocused()) {
+ GuiEventListener focused = screen.getFocused();
+ if (focused != null) {
+ if (focused instanceof EditBox editBox && editBox.isFocused()) return EventResult.pass();
+ if (focused instanceof RecipeBookComponent book && book.searchBox != null && book.searchBox.isFocused()) return EventResult.pass();
+ }
+ }
resetFocused(screen);
if (getOverlay().charTyped(character, keyCode)
&& resetFocused(screen))
return EventResult.interruptFalse();
return EventResult.pass();
});
- ClientGuiEvent.RENDER_POST.register((screen, matrices, mouseX, mouseY, delta) -> {
+ int[] rendered = {0};
+ ClientGuiEvent.RENDER_PRE.register((screen, matrices, mouseX, mouseY, delta) -> {
+ if (shouldReturn(screen))
+ return EventResult.pass();
+ rendered[0] = 0;
+ return EventResult.pass();
+ });
+ ClientGuiEvent.RENDER_CONTAINER_BACKGROUND.register((screen, matrices, mouseX, mouseY, delta) -> {
if (shouldReturn(screen))
return;
+ rendered[0] = 1;
resetFocused(screen);
if (!(screen instanceof DisplayScreen)) {
getOverlay().render(matrices, mouseX, mouseY, delta);
}
+ resetFocused(screen);
+ });
+ ClientGuiEvent.RENDER_CONTAINER_FOREGROUND.register((screen, matrices, mouseX, mouseY, delta) -> {
+ if (shouldReturn(screen))
+ return;
+ rendered[0] = 2;
+ resetFocused(screen);
+ PoseStack poseStack = RenderSystem.getModelViewStack();
+ poseStack.pushPose();
+ poseStack.translate(-screen.leftPos, -screen.topPos, 0.0);
+ RenderSystem.applyModelViewMatrix();
((ScreenOverlayImpl) getOverlay()).lateRender(matrices, mouseX, mouseY, delta);
+ poseStack.popPose();
+ RenderSystem.applyModelViewMatrix();
+ resetFocused(screen);
+ });
+ ClientGuiEvent.RENDER_POST.register((screen, matrices, mouseX, mouseY, delta) -> {
+ if (shouldReturn(screen) || rendered[0] == 2)
+ return;
+ if (screen instanceof AbstractContainerScreen) {
+ InternalLogger.getInstance().warn("Screen " + screen.getClass().getName() + " did not render background and foreground! This might cause rendering issues!");
+ }
+ resetFocused(screen);
+ if (rendered[0] == 0 && !(screen instanceof DisplayScreen)) {
+ getOverlay().render(matrices, mouseX, mouseY, delta);
+ }
+ rendered[0] = 1;
+ if (rendered[0] == 1) {
+ ((ScreenOverlayImpl) getOverlay()).lateRender(matrices, mouseX, mouseY, delta);
+ }
resetFocused(screen);
});
ClientScreenInputEvent.MOUSE_DRAGGED_PRE.register((minecraftClient, screen, mouseX1, mouseY1, button, mouseX2, mouseY2) -> {
@@ -422,9 +466,13 @@ public class RoughlyEnoughItemsCoreClient {
return EventResult.interruptFalse();
}
}
- if (screen.getFocused() != null && screen.getFocused() instanceof EditBox || (screen.getFocused() instanceof RecipeBookComponent && ((RecipeBookComponent) screen.getFocused()).searchBox != null && ((RecipeBookComponent) screen.getFocused()).searchBox.isFocused()))
- if (!REIRuntimeImpl.getSearchField().isFocused())
- return EventResult.pass();
+ if (!REIRuntimeImpl.getSearchField().isFocused()) {
+ GuiEventListener focused = screen.getFocused();
+ if (focused != null) {
+ if (focused instanceof EditBox editBox && editBox.isFocused()) return EventResult.pass();
+ if (focused instanceof RecipeBookComponent book && book.searchBox != null && book.searchBox.isFocused()) return EventResult.pass();
+ }
+ }
resetFocused(screen);
if (getOverlay().keyPressed(i, i1, i2)
&& resetFocused(screen))
@@ -434,9 +482,13 @@ public class RoughlyEnoughItemsCoreClient {
ClientScreenInputEvent.KEY_RELEASED_PRE.register((minecraftClient, screen, i, i1, i2) -> {
if (shouldReturn(screen) || screen instanceof DisplayScreen)
return EventResult.pass();
- if (screen.getFocused() != null && screen.getFocused() instanceof EditBox || (screen.getFocused() instanceof RecipeBookComponent && ((RecipeBookComponent) screen.getFocused()).searchBox != null && ((RecipeBookComponent) screen.getFocused()).searchBox.isFocused()))
- if (!REIRuntimeImpl.getSearchField().isFocused())
- return EventResult.pass();
+ if (!REIRuntimeImpl.getSearchField().isFocused()) {
+ GuiEventListener focused = screen.getFocused();
+ if (focused != null) {
+ if (focused instanceof EditBox editBox && editBox.isFocused()) return EventResult.pass();
+ if (focused instanceof RecipeBookComponent book && book.searchBox != null && book.searchBox.isFocused()) return EventResult.pass();
+ }
+ }
resetFocused(screen);
if (getOverlay().keyReleased(i, i1, i2)
&& resetFocused(screen))
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigObjectImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigObjectImpl.java
index d59ece66c..a18d7aeab 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigObjectImpl.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigObjectImpl.java
@@ -684,7 +684,7 @@ public class ConfigObjectImpl implements ConfigObject, ConfigData {
@Comment("Declares how the scrollbar in composite screen should act.") private boolean compositeScrollBarPermanent = false;
private boolean toastDisplayedOnCopyIdentifier = true;
@Comment("Declares whether REI should use compact tabs for categories.") private boolean useCompactTabs = true;
- @Comment("Declares whether REI should use compact tab buttons for categories.") @ConfigEntry.Gui.Excluded private boolean useCompactTabButtons = false;
+ @Comment("Declares whether REI should use compact tab buttons for categories.") private boolean useCompactTabButtons = false;
}
public static class Search {
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringRulesScreen.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringRulesScreen.java
index 14636c4c2..803802ea8 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringRulesScreen.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringRulesScreen.java
@@ -23,13 +23,23 @@
package me.shedaniel.rei.impl.client.config.entries;
+import com.google.common.base.Suppliers;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack;
import me.shedaniel.clothconfig2.gui.widget.DynamicElementListWidget;
+import me.shedaniel.math.Rectangle;
import me.shedaniel.rei.api.client.entry.filtering.FilteringRule;
import me.shedaniel.rei.api.client.entry.filtering.FilteringRuleType;
+import me.shedaniel.rei.api.client.gui.widgets.Widgets;
+import me.shedaniel.rei.api.client.registry.entry.EntryRegistry;
+import me.shedaniel.rei.api.common.util.CollectionUtils;
+import me.shedaniel.rei.impl.client.entry.filtering.FilteringContextType;
import me.shedaniel.rei.impl.client.entry.filtering.rules.ManualFilteringRule;
+import me.shedaniel.rei.impl.client.entry.filtering.rules.SearchFilteringRuleType;
import me.shedaniel.rei.impl.client.gui.InternalTextures;
+import me.shedaniel.rei.impl.client.gui.widget.EntryWidget;
+import me.shedaniel.rei.impl.common.entry.type.FilteringLogic;
+import me.shedaniel.rei.impl.common.util.HashedEntryStackWrapper;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.components.events.GuiEventListener;
@@ -42,11 +52,11 @@ import net.minecraft.network.chat.FormattedText;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.sounds.SoundEvents;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Objects;
+import java.util.*;
+import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
+import java.util.stream.Collectors;
public class FilteringRulesScreen extends Screen {
private final FilteringEntry entry;
@@ -184,7 +194,7 @@ public class FilteringRulesScreen extends Screen {
public DefaultRuleEntry(FilteringRule<?> rule, FilteringEntry entry, Function<Screen, Screen> screenFunction) {
super(rule);
- this.screenFunction = (screenFunction == null ? ((FilteringRuleType<FilteringRule<?>>) rule.getType()).createEntryScreen(rule) : screenFunction);
+ this.screenFunction = Objects.requireNonNullElseGet(screenFunction == null ? ((FilteringRuleType<FilteringRule<?>>) rule.getType()).createEntryScreen(rule) : screenFunction, () -> placeholderScreen(rule));
configureButton = new Button(0, 0, 20, 20, Component.nullToEmpty(null), button -> {
entry.edited = true;
Minecraft.getInstance().setScreen(this.screenFunction.apply(Minecraft.getInstance().screen));
@@ -250,4 +260,36 @@ public class FilteringRulesScreen extends Screen {
return Arrays.asList(configureButton, deleteButton);
}
}
+
+ private static <Cache> Function<Screen, Screen> placeholderScreen(FilteringRule<Cache> r) {
+ class PlaceholderScreen extends FilteringRuleOptionsScreen<FilteringRule<Cache>> {
+ public PlaceholderScreen(Screen parent) {
+ super(r, parent);
+ }
+
+ @Override
+ public void addEntries(Consumer<RuleEntry> entryConsumer) {
+ addEmpty(entryConsumer, 10);
+ Function<Boolean, Component> function = bool -> {
+ return Component.translatable("rule.roughlyenoughitems.filtering.search.show." + bool);
+ };
+ Map<FilteringContextType, Set<HashedEntryStackWrapper>> stacks = FilteringLogic.hidden(FilteringLogic.getRules(), false, false, EntryRegistry.getInstance().getEntryStacks().collect(Collectors.toList()));
+
+ entryConsumer.accept(new SubRulesEntry(rule, () -> function.apply(true),
+ Collections.singletonList(new SearchFilteringRuleType.EntryStacksRuleEntry(rule,
+ Suppliers.ofInstance(CollectionUtils.map(stacks.get(FilteringContextType.SHOWN),
+ stack -> (EntryWidget) Widgets.createSlot(new Rectangle(0, 0, 18, 18)).disableBackground().entry(stack.unwrap().normalize())))))));
+ addEmpty(entryConsumer, 10);
+ entryConsumer.accept(new SubRulesEntry(rule, () -> function.apply(false),
+ Collections.singletonList(new SearchFilteringRuleType.EntryStacksRuleEntry(rule,
+ Suppliers.ofInstance(CollectionUtils.map(stacks.get(FilteringContextType.HIDDEN),
+ stack -> (EntryWidget) Widgets.createSlot(new Rectangle(0, 0, 18, 18)).disableBackground().entry(stack.unwrap().normalize())))))));
+ }
+
+ @Override
+ public void save() {
+ }
+ }
+ return PlaceholderScreen::new;
+ }
}
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/FilteringContextImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/FilteringContextImpl.java
index d0e26a9fc..697bcde63 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/FilteringContextImpl.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/FilteringContextImpl.java
@@ -27,6 +27,7 @@ import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
+import it.unimi.dsi.fastutil.longs.*;
import me.shedaniel.rei.api.client.entry.filtering.FilteringContext;
import me.shedaniel.rei.api.common.entry.EntryStack;
import me.shedaniel.rei.api.common.util.CollectionUtils;
@@ -69,20 +70,35 @@ public class FilteringContextImpl implements FilteringContext {
@Override
public Collection<EntryStack<?>> getHiddenStacks() {
- return getPublicFacing(FilteringContextType.HIDDEN);
+ return getStacksFacing(FilteringContextType.HIDDEN);
}
@Override
public Collection<EntryStack<?>> getShownStacks() {
- return getPublicFacing(FilteringContextType.SHOWN);
+ return getStacksFacing(FilteringContextType.SHOWN);
}
@Override
public Collection<EntryStack<?>> getUnsetStacks() {
- return getPublicFacing(FilteringContextType.DEFAULT);
+ return getStacksFacing(FilteringContextType.DEFAULT);
}
- private Collection<EntryStack<?>> getPublicFacing(FilteringContextType type) {
+ @Override
+ public LongCollection getHiddenExactHashes() {
+ return getHashesFacing(FilteringContextType.HIDDEN);
+ }
+
+ @Override
+ public LongCollection getShownExactHashes() {
+ return getHashesFacing(FilteringContextType.SHOWN);
+ }
+
+ @Override
+ public LongCollection getUnsetExactHashes() {
+ return getHashesFacing(FilteringContextType.DEFAULT);
+ }
+
+ private Collection<EntryStack<?>> getStacksFacing(FilteringContextType type) {
Set<HashedEntryStackWrapper> wrappers = this.stacks.get(type);
if (wrappers == null || wrappers.isEmpty()) return List.of();
return new AbstractSet<>() {
@@ -98,6 +114,33 @@ public class FilteringContextImpl implements FilteringContext {
};
}
+ private LongCollection getHashesFacing(FilteringContextType type) {
+ Set<HashedEntryStackWrapper> wrappers = this.stacks.get(type);
+ if (wrappers == null || wrappers.isEmpty()) return LongSets.emptySet();
+ return new AbstractLongSet() {
+ @Override
+ public LongIterator iterator() {
+ Iterator<HashedEntryStackWrapper> iterator = wrappers.iterator();
+ return new AbstractLongIterator() {
+ @Override
+ public long nextLong() {
+ return iterator.next().hashExact();
+ }
+
+ @Override
+ public boolean hasNext() {
+ return iterator.hasNext();
+ }
+ };
+ }
+
+ @Override
+ public int size() {
+ return wrappers.size();
+ }
+ };
+ }
+
public void handleResult(FilteringResultImpl result) {
Collection<HashedEntryStackWrapper> hiddenStacks = result.hiddenStacks;
Collection<HashedEntryStackWrapper> shownStacks = result.shownStacks;
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/BasicFilteringRuleImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/BasicFilteringRuleImpl.java
index 1d51eb0f2..81aa7b3ab 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/BasicFilteringRuleImpl.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/BasicFilteringRuleImpl.java
@@ -23,133 +23,212 @@
package me.shedaniel.rei.impl.client.entry.filtering.rules;
-import com.google.common.collect.Lists;
import com.mojang.datafixers.util.Pair;
+import com.mojang.datafixers.util.Unit;
+import it.unimi.dsi.fastutil.longs.LongCollection;
+import it.unimi.dsi.fastutil.longs.LongIterator;
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
import it.unimi.dsi.fastutil.longs.LongSet;
+import me.shedaniel.clothconfig2.api.LazyResettable;
import me.shedaniel.rei.api.client.entry.filtering.*;
import me.shedaniel.rei.api.client.entry.filtering.base.BasicFilteringRule;
import me.shedaniel.rei.api.client.plugins.REIClientPlugin;
import me.shedaniel.rei.api.common.entry.EntryStack;
import me.shedaniel.rei.api.common.registry.ReloadStage;
-import me.shedaniel.rei.api.common.util.CollectionUtils;
import me.shedaniel.rei.api.common.util.EntryStacks;
import me.shedaniel.rei.impl.client.util.ThreadCreator;
-import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
-import java.util.concurrent.*;
+import java.util.concurrent.ExecutorService;
+import java.util.function.Supplier;
import java.util.stream.Collectors;
-public enum BasicFilteringRuleImpl implements BasicFilteringRule<Pair<LongSet, LongSet>> {
+public enum BasicFilteringRuleImpl implements BasicFilteringRule<Unit> {
INSTANCE;
private static final ExecutorService EXECUTOR_SERVICE = new ThreadCreator("REI-BasicFiltering").asService();
- private final List<EntryStack<?>> hidden = new ArrayList<>(), shown = new ArrayList<>();
+ private final LongSet hiddenHashes = new LongOpenHashSet(), shownHashes = new LongOpenHashSet();
+ private final List<CachedProvider> hiddenProviders = new ArrayList<>(), shownProviders = new ArrayList<>();
@Override
- public FilteringRuleType<? extends FilteringRule<Pair<LongSet, LongSet>>> getType() {
+ public FilteringRuleType<? extends FilteringRule<Unit>> getType() {
return BasicFilteringRuleType.INSTANCE;
}
@Override
- public Pair<LongSet, LongSet> prepareCache(boolean async) {
- return new Pair<>(prepareCacheFor(hidden, async), prepareCacheFor(shown, async));
- }
-
- @NotNull
- private static LongSet prepareCacheFor(List<EntryStack<?>> stacks, boolean async) {
- if (async) {
- LongSet all = new LongOpenHashSet();
- List<CompletableFuture<LongSet>> completableFutures = Lists.newArrayList();
- for (Iterable<EntryStack<?>> partitionStacks : CollectionUtils.partition(stacks, 100)) {
- completableFutures.add(CompletableFuture.supplyAsync(() -> {
- LongSet output = new LongOpenHashSet();
- for (EntryStack<?> stack : partitionStacks) {
- if (stack != null && !stack.isEmpty()) {
- output.add(EntryStacks.hashExact(stack));
- }
- }
- return output;
- }, EXECUTOR_SERVICE));
- }
- try {
- CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[0])).get(5, TimeUnit.MINUTES);
- } catch (InterruptedException | ExecutionException | TimeoutException e) {
- e.printStackTrace();
- }
- for (CompletableFuture<LongSet> future : completableFutures) {
- LongSet now = future.getNow(null);
- if (now != null) {
- all.addAll(now);
- }
- }
- return all;
- } else {
- return stacks.stream().map(EntryStacks::hashExact).collect(Collectors.toCollection(LongOpenHashSet::new));
+ public Unit prepareCache(boolean async) {
+ for (CachedProvider provider : hiddenProviders) {
+ provider.get();
+ }
+ for (CachedProvider provider : shownProviders) {
+ provider.get();
}
+ return Unit.INSTANCE;
}
@Override
- public FilteringResult processFilteredStacks(FilteringContext context, FilteringResultFactory resultFactory, Pair<LongSet, LongSet> cache, boolean async) {
+ public FilteringResult processFilteredStacks(FilteringContext context, FilteringResultFactory resultFactory, Unit cache, boolean async) {
FilteringResult result = resultFactory.create();
- hideList(context.getShownStacks(), result, async, cache.getFirst());
- hideList(context.getUnsetStacks(), result, async, cache.getFirst());
- showList(context.getHiddenStacks(), result, async, cache.getSecond());
- showList(context.getUnsetStacks(), result, async, cache.getSecond());
+ hideList(context.getShownStacks(), context.getShownExactHashes(), result, async, hiddenHashes);
+ hideList(context.getUnsetStacks(), context.getUnsetExactHashes(), result, async, hiddenHashes);
+
+ for (CachedProvider provider : hiddenProviders) {
+ hideList(context.getShownStacks(), context.getShownExactHashes(), result, async, provider.getExactHashes());
+ hideList(context.getUnsetStacks(), context.getUnsetExactHashes(), result, async, provider.getExactHashes());
+ }
+
+ showList(context.getHiddenStacks(), context.getHiddenExactHashes(), result, async, shownHashes);
+ showList(context.getUnsetStacks(), context.getUnsetExactHashes(), result, async, shownHashes);
+
+ for (CachedProvider provider : shownProviders) {
+ showList(context.getHiddenStacks(), context.getHiddenExactHashes(), result, async, provider.getExactHashes());
+ showList(context.getUnsetStacks(), context.getUnsetExactHashes(), result, async, provider.getExactHashes());
+ }
+
return result;
}
- private void hideList(Collection<EntryStack<?>> stacks, FilteringResult result, boolean async, LongSet filteredStacks) {
- result.hide((async ? stacks.parallelStream() : stacks.stream()).filter(stack -> filteredStacks.contains(EntryStacks.hashExact(stack))).collect(Collectors.toList()));
+ private void hideList(Collection<EntryStack<?>> stacks, LongCollection hashes, FilteringResult result, boolean async, LongSet filteredStacks) {
+ LongIterator iterator = hashes.iterator();
+ result.hide(stacks.stream()
+ .filter(stack -> filteredStacks.contains(iterator.nextLong()))
+ .collect(Collectors.toList()));
}
- private void showList(Collection<EntryStack<?>> stacks, FilteringResult result, boolean async, LongSet filteredStacks) {
- result.show((async ? stacks.parallelStream() : stacks.stream()).filter(stack -> filteredStacks.contains(EntryStacks.hashExact(stack))).collect(Collectors.toList()));
+ private void showList(Collection<EntryStack<?>> stacks, LongCollection hashes, FilteringResult result, boolean async, LongSet filteredStacks) {
+ LongIterator iterator = hashes.iterator();
+ result.show(stacks.stream()
+ .filter(stack -> filteredStacks.contains(iterator.nextLong()))
+ .collect(Collectors.toList()));
}
@Override
public FilteringResult hide(EntryStack<?> stack) {
- hidden.add(stack);
- shown.remove(stack);
+ long hashExact = EntryStacks.hashExact(stack);
+ hiddenHashes.add(hashExact);
+ shownHashes.remove(hashExact);
+
+ if (!isReloading()) {
+ markDirty(List.of(stack), null);
+ }
+
return this;
}
@Override
public FilteringResult hide(Collection<? extends EntryStack<?>> stacks) {
- hidden.addAll(stacks);
- shown.removeAll(stacks);
+ for (EntryStack<?> stack : stacks) {
+ long hashExact = EntryStacks.hashExact(stack);
+ hiddenHashes.add(hashExact);
+ shownHashes.remove(hashExact);
+ }
+
+ if (!isReloading()) {
+ markDirty((Collection<EntryStack<?>>) stacks, null);
+ }
+
return this;
}
@Override
public FilteringResult show(EntryStack<?> stack) {
- shown.add(stack);
- hidden.remove(stack);
+ long hashExact = EntryStacks.hashExact(stack);
+ shownHashes.add(hashExact);
+ hiddenHashes.remove(hashExact);
+
+ if (!isReloading()) {
+ markDirty(List.of(stack), null);
+ }
+
return this;
}
@Override
public FilteringResult show(Collection<? extends EntryStack<?>> stacks) {
- shown.addAll(stacks);
- hidden.removeAll(stacks);
+ for (EntryStack<?> stack : stacks) {
+ long hashExact = EntryStacks.hashExact(stack);
+ shownHashes.add(hashExact);
+ hiddenHashes.remove(hashExact);
+ }
+
+ if (!isReloading()) {
+ markDirty((Collection<EntryStack<?>>) stacks, null);
+ }
+
return this;
}
@Override
+ public MarkDirty hide(Supplier<Collection<EntryStack<?>>> provider) {
+ CachedProvider cachedProvider = new CachedProvider(provider);
+ shownProviders.remove(cachedProvider);
+ hiddenProviders.add(cachedProvider);
+
+ cachedProvider.markDirty();
+ return cachedProvider;
+ }
+
+ @Override
+ public MarkDirty show(Supplier<Collection<EntryStack<?>>> provider) {
+ CachedProvider cachedProvider = new CachedProvider(provider);
+ hiddenProviders.remove(cachedProvider);
+ shownProviders.add(cachedProvider);
+
+ cachedProvider.markDirty();