aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorshedaniel <daniel@shedaniel.me>2022-11-27 17:50:11 +0800
committershedaniel <daniel@shedaniel.me>2022-11-27 18:05:58 +0800
commit2123544fcf3ad7ec6d89e671a993a75737e3a44e (patch)
treed9f47994a2d3f715914eaa703ad05c55aba274b5
parent9c865aff50b8c49e89ee1a7d6319d52cdcdd229a (diff)
downloadRoughlyEnoughItems-2123544fcf3ad7ec6d89e671a993a75737e3a44e.tar.gz
RoughlyEnoughItems-2123544fcf3ad7ec6d89e671a993a75737e3a44e.tar.bz2
RoughlyEnoughItems-2123544fcf3ad7ec6d89e671a993a75737e3a44e.zip
Make filtering more immediate
-rw-r--r--api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/FilteringContext.java25
-rw-r--r--api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/FilteringRule.java22
-rw-r--r--api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/base/BasicFilteringRule.java12
-rw-r--r--api/src/main/java/me/shedaniel/rei/api/client/registry/entry/EntryRegistry.java5
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/FilteringRulesScreen.java20
-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/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
18 files changed, 876 insertions, 439 deletions
diff --git a/api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/FilteringContext.java b/api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/FilteringContext.java
index d46709af9..8cf2179e0 100644
--- a/api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/FilteringContext.java
+++ b/api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/FilteringContext.java
@@ -23,6 +23,7 @@
package me.shedaniel.rei.api.client.entry.filtering;
+import it.unimi.dsi.fastutil.longs.LongCollection;
import me.shedaniel.rei.api.common.entry.EntryStack;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@@ -53,4 +54,28 @@ public interface FilteringContext {
* @return the list of stacks that are previously marked as hidden from other filtering rules.
*/
Collection<EntryStack<?>> getHiddenStacks();
+
+ /**
+ * Returns the list of hashes that are previously marked as <b>shown</b> from other filtering rules.
+ *
+ * @return the list of hashes that are previously marked as shown from other filtering rules.
+ */
+ @ApiStatus.Experimental
+ LongCollection getShownExactHashes();
+
+ /**
+ * Returns the list of hashes that are previously marked as <b>hidden</b> from other filtering rules.
+ *
+ * @return the list of hashes that are previously marked as hidden from other filtering rules.
+ */
+ @ApiStatus.Experimental
+ LongCollection getUnsetExactHashes();
+
+ /**
+ * Returns the list of hashes that are previously marked as <b>hidden</b> from other filtering rules.
+ *
+ * @return the list of hashes that are previously marked as hidden from other filtering rules.
+ */
+ @ApiStatus.Experimental
+ LongCollection getHiddenExactHashes();
}
diff --git a/api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/FilteringRule.java b/api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/FilteringRule.java
index 1f3cb5b50..a133de686 100644
--- a/api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/FilteringRule.java
+++ b/api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/FilteringRule.java
@@ -23,9 +23,15 @@
package me.shedaniel.rei.api.client.entry.filtering;
+import it.unimi.dsi.fastutil.longs.LongCollection;
+import me.shedaniel.rei.api.client.registry.entry.EntryRegistry;
+import me.shedaniel.rei.api.common.entry.EntryStack;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
/**
* A filtering rule type that is used to filter the entries on the entry panel,
@@ -63,4 +69,20 @@ public interface FilteringRule<Cache> {
* @return the result of the processing
*/
FilteringResult processFilteredStacks(FilteringContext context, FilteringResultFactory resultFactory, Cache cache, boolean async);
+
+ /**
+ * Returns whether the entry registry is in its reloading phase.
+ * Registration after the reloading phase will be slow and may not be reflected immediately.
+ *
+ * @return whether the entry registry is in its reloading phase
+ */
+ @ApiStatus.NonExtendable
+ default boolean isReloading() {
+ return EntryRegistry.getInstance().isReloading();
+ }
+
+ @ApiStatus.NonExtendable
+ default void markDirty(Collection<EntryStack<?>> stacks, @Nullable LongCollection hashes) {
+ EntryRegistry.getInstance().markFilteringRuleDirty(this, stacks, hashes);
+ }
} \ No newline at end of file
diff --git a/api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/base/BasicFilteringRule.java b/api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/base/BasicFilteringRule.java
index 26b2986c2..4800a430e 100644
--- a/api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/base/BasicFilteringRule.java
+++ b/api/src/main/java/me/shedaniel/rei/api/client/entry/filtering/base/BasicFilteringRule.java
@@ -26,11 +26,15 @@ package me.shedaniel.rei.api.client.entry.filtering.base;
import me.shedaniel.rei.api.client.entry.filtering.FilteringResult;
import me.shedaniel.rei.api.client.entry.filtering.FilteringRule;
import me.shedaniel.rei.api.client.plugins.REIClientPlugin;
+import me.shedaniel.rei.api.common.entry.EntryStack;
import me.shedaniel.rei.api.common.registry.Reloadable;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import org.jetbrains.annotations.ApiStatus;
+import java.util.Collection;
+import java.util.function.Supplier;
+
/**
* The basic filtering rule that can be used to filter entries,
* without registering a new filtering rule type, for external
@@ -41,4 +45,12 @@ import org.jetbrains.annotations.ApiStatus;
@ApiStatus.Experimental
@Environment(EnvType.CLIENT)
public interface BasicFilteringRule<Cache> extends Reloadable<REIClientPlugin>, FilteringRule<Cache>, FilteringResult {
+ MarkDirty hide(Supplier<Collection<EntryStack<?>>> provider);
+
+ MarkDirty show(Supplier<Collection<EntryStack<?>>> provider);
+
+ @ApiStatus.NonExtendable
+ interface MarkDirty {
+ void markDirty();
+ }
}
diff --git a/api/src/main/java/me/shedaniel/rei/api/client/registry/entry/EntryRegistry.java b/api/src/main/java/me/shedaniel/rei/api/client/registry/entry/EntryRegistry.java
index 63ed14d72..9e4713957 100644
--- a/api/src/main/java/me/shedaniel/rei/api/client/registry/entry/EntryRegistry.java
+++ b/api/src/main/java/me/shedaniel/rei/api/client/registry/entry/EntryRegistry.java
@@ -23,6 +23,8 @@
package me.shedaniel.rei.api.client.registry.entry;
+import it.unimi.dsi.fastutil.longs.LongCollection;
+import me.shedaniel.rei.api.client.entry.filtering.FilteringRule;
import me.shedaniel.rei.api.client.plugins.REIClientPlugin;
import me.shedaniel.rei.api.common.entry.EntryStack;
import me.shedaniel.rei.api.common.plugins.PluginManager;
@@ -207,4 +209,7 @@ public interface EntryRegistry extends Reloadable<REIClientPlugin> {
* @return whether the registry is in its reloading phase
*/
boolean isReloading();
+
+ @ApiStatus.Experimental
+ <Cache> void markFilteringRuleDirty(FilteringRule<Cache> cacheFilteringRule, Collection<EntryStack<?>> stacks, @Nullable LongCollection hashes);
}
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 624ba0315..6c6d4cceb 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
@@ -33,12 +33,13 @@ 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.FilteringContextImpl;
-import me.shedaniel.rei.impl.client.entry.filtering.FilteringResultImpl;
+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;
@@ -54,6 +55,7 @@ import net.minecraft.sounds.SoundEvents;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;
+import java.util.stream.Collectors;
public class FilteringRulesScreen extends Screen {
private final FilteringEntry entry;
@@ -268,21 +270,19 @@ public class FilteringRulesScreen extends Screen {
public void addEntries(Consumer<RuleEntry> entryConsumer) {
addEmpty(entryConsumer, 10);
Function<Boolean, Component> function = bool -> {
- return new TranslatableComponent("rule.roughlyenoughitems.filtering.search.show." + bool);
+ return Component.translatable("rule.roughlyenoughitems.filtering.search.show." + bool);
};
- FilteringContextImpl context = new FilteringContextImpl(EntryRegistry.getInstance().getEntryStacks().toList());
- rule.processFilteredStacks(context, () -> new FilteringResultImpl(new ArrayList<>(), new ArrayList<>()),
- rule.prepareCache(false), false);
+ 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(context.getShownStacks(),
- stack -> (EntryWidget) Widgets.createSlot(new Rectangle(0, 0, 18, 18)).disableBackground().entry(stack.normalize())))))));
+ 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(context.getHiddenStacks(),
- stack -> (EntryWidget) Widgets.createSlot(new Rectangle(0, 0, 18, 18)).disableBackground().entry(stack.normalize())))))));
+ Suppliers.ofInstance(CollectionUtils.map(stacks.get(FilteringContextType.HIDDEN),
+ stack -> (EntryWidget) Widgets.createSlot(new Rectangle(0, 0, 18, 18)).disableBackground().entry(stack.unwrap().normalize())))))));
}
@Override
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();
+ return cachedProvider;
+ }
+
+ @Override
public ReloadStage getStage() {
return ReloadStage.START;
}
@Override
public void startReload() {
- hidden.clear();
- shown.clear();
+ hiddenHashes.clear();
+ shownHashes.clear();
+ hiddenProviders.clear();
+ shownProviders.clear();
}
@Override
public void acceptPlugin(REIClientPlugin plugin) {
plugin.registerBasicEntryFiltering(this);
}
+
+ private class CachedProvider implements MarkDirty {
+ private final Supplier<Collection<EntryStack<?>>> provider;
+ private final LazyResettable<Pair<Collection<EntryStack<?>>, LongSet>> cache = new LazyResettable<>(this::compose);
+
+ private CachedProvider(Supplier<Collection<EntryStack<?>>> provider) {
+ this.provider = provider;
+ }
+
+ @Override
+ public void markDirty() {
+ Pair<Collection<EntryStack<?>>, LongSet> prev = this.cache.get();
+ this.cache.reset();
+ Pair<Collection<EntryStack<?>>, LongSet> next = this.cache.get();
+ BasicFilteringRuleImpl.this.markDirty(prev.getFirst(), prev.getSecond());
+ BasicFilteringRuleImpl.this.markDirty(next.getFirst(), next.getSecond());
+ }
+
+ public Collection<EntryStack<?>> get() {
+ return this.cache.get().getFirst();
+ }
+
+ public LongSet getExactHashes() {
+ return this.cache.get().getSecond();
+ }
+
+ private Pair<Collection<EntryStack<?>>, LongSet> compose() {
+ Collection<EntryStack<?>> stacks = this.provider.get();
+ LongSet hashes = new LongOpenHashSet(stacks.size());
+ for (EntryStack<?> stack : stacks) {
+ hashes.add(EntryStacks.hashExact(stack));
+ }
+ return Pair.of(stacks, hashes);
+ }
+ }
}
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/EntryRegistryImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/EntryRegistryImpl.java
index af9f4ddb3..11d8e0501 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/EntryRegistryImpl.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/EntryRegistryImpl.java
@@ -24,11 +24,9 @@
package me.shedaniel.rei.impl.common.entry.type;
import com.google.common.collect.Lists;
-import it.unimi.dsi.fastutil.longs.LongArrayList;
-import it.unimi.dsi.fastutil.longs.LongList;
-import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
-import it.unimi.dsi.fastutil.longs.LongSet;
+import it.unimi.dsi.fastutil.longs.*;
import me.shedaniel.rei.api.client.REIRuntime;
+import me.shedaniel.rei.api.client.entry.filtering.FilteringRule;
import me.shedaniel.rei.api.client.overlay.ScreenOverlay;
import me.shedaniel.rei.api.client.plugins.REIClientPlugin;
import me.shedaniel.rei.api.client.registry.entry.EntryRegistry;
@@ -40,6 +38,7 @@ 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.common.InternalLogger;
+import me.shedaniel.rei.impl.common.util.HashedEntryStackWrapper;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.core.NonNullList;
@@ -58,16 +57,15 @@ import java.util.stream.Stream;
@Environment(EnvType.CLIENT)
public class EntryRegistryImpl implements EntryRegistry {
public List<EntryRegistryListener> listeners = Lists.newCopyOnWriteArrayList();
- private PreFilteredEntryList preFilteredList;
- private EntryRegistryList registryList;
+ private final EntryRegistryList registryList = new EntryRegistryListImpl();
+ private FilteredEntryList filteredList;
private LongSet entriesHash;
private boolean reloading;
public EntryRegistryImpl() {
- registryList = new NormalEntryRegistryList();
- entriesHash = new LongOpenHashSet();
- preFilteredList = new PreFilteredEntryList(this);
- listeners.add(preFilteredList);
+ this.entriesHash = new LongOpenHashSet();
+ this.filteredList = new PreFilteredEntryList(this, this.registryList);
+ this.listeners.add(this.filteredList);
}
@Override
@@ -82,21 +80,17 @@ public class EntryRegistryImpl implements EntryRegistry {
@Override
public void startReload() {
- listeners.clear();
- registryList = new ReloadingEntryRegistryList();
- entriesHash = new LongOpenHashSet();
- preFilteredList = new PreFilteredEntryList(this);
- listeners.add(preFilteredList);
- reloading = true;
+ this.listeners.clear();
+ this.registryList.collectHashed().clear();
+ this.entriesHash = new LongOpenHashSet();
+ this.filteredList = new PreFilteredEntryList(this, this.registryList);
+ this.listeners.add(filteredList);
+ this.reloading = true;
}
@Override
public void endReload() {
- reloading = false;
- if (!(registryList instanceof ReloadingEntryRegistryList)) {
- throw new IllegalStateException("Expected ReloadingEntryRegistryList, got " + registryList.getClass().getName());
- }
- registryList = new NormalEntryRegistryList(registryList.stream().filter(((Predicate<EntryStack<?>>) EntryStack::isEmpty).negate()));
+ this.reloading = false;
refilter();
REIRuntime.getInstance().getOverlay().ifPresent(ScreenOverlay::queueReloadOverlay);
InternalLogger.getInstance().debug("Reloaded entry registry with %