aboutsummaryrefslogtreecommitdiff
path: root/runtime/src/main/java/me/shedaniel
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 /runtime/src/main/java/me/shedaniel
parent9c865aff50b8c49e89ee1a7d6319d52cdcdd229a (diff)
downloadRoughlyEnoughItems-2123544fcf3ad7ec6d89e671a993a75737e3a44e.tar.gz
RoughlyEnoughItems-2123544fcf3ad7ec6d89e671a993a75737e3a44e.tar.bz2
RoughlyEnoughItems-2123544fcf3ad7ec6d89e671a993a75737e3a44e.zip
Make filtering more immediate
Diffstat (limited to 'runtime/src/main/java/me/shedaniel')
-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
14 files changed, 812 insertions, 439 deletions
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 %d entries and %d filtered entries", size(), getPreFilteredList().size());
@@ -108,6 +102,11 @@ public class EntryRegistryImpl implements EntryRegistry {
}
@Override
+ public <Cache> void markFilteringRuleDirty(FilteringRule<Cache> cacheFilteringRule, Collection<EntryStack<?>> stacks, @Nullable LongCollection hashes) {
+ this.filteredList.refreshFilteringFor(Set.of(cacheFilteringRule), stacks, hashes);
+ }
+
+ @Override
public int size() {
return registryList.size();
}
@@ -119,12 +118,12 @@ public class EntryRegistryImpl implements EntryRegistry {
@Override
public List<EntryStack<?>> getPreFilteredList() {
- return Collections.unmodifiableList(preFilteredList.getList());
+ return Collections.unmodifiableList(filteredList.getList());
}
@Override
public void refilter() {
- List<EntryStack<?>> stacks = registryList.collect();
+ List<HashedEntryStackWrapper> stacks = registryList.collectHashed();
for (EntryRegistryListener listener : listeners) {
listener.onReFilter(stacks);
@@ -161,7 +160,8 @@ public class EntryRegistryImpl implements EntryRegistry {
@ApiStatus.Internal
@Override
public Collection<EntryStack<?>> refilterNew(boolean warn, Collection<EntryStack<?>> entries) {
- return preFilteredList.refilterNew(warn, entries);
+ if (warn) FilteringLogic.warnFiltering();
+ return FilteringLogic.filter(FilteringLogic.getRules(), false, true, entries);
}
@Override
@@ -236,9 +236,8 @@ public class EntryRegistryImpl implements EntryRegistry {
List<EntryStack<?>> removedStacks = new ArrayList<>();
LongList hashes = registryList.needsHash() ? new LongArrayList() : null;
- boolean removed = registryList.removeIf(stack -> {
+ boolean removed = registryList.removeExactIf((stack, hashExact) -> {
if (((Predicate<EntryStack<?>>) predicate).test(stack)) {
- long hashExact = EntryStacks.hashExact(stack);
entriesHash.remove(hashExact);
removedStacks.add(stack);
if (hashes != null) hashes.add(hashExact);
@@ -259,37 +258,35 @@ public class EntryRegistryImpl implements EntryRegistry {
@Override
public boolean removeEntryExactHashIf(LongPredicate predicate) {
- LongPredicate entryStackPredicate = hash -> {
+ EntryRegistryList.StackFilteringPredicate entryStackPredicate = (stack, hash) -> {
if (predicate.test(hash)) {
entriesHash.remove(hash);
+ for (EntryRegistryListener listener : listeners) {
+ listener.removeEntry(stack, hash);
+ }
return true;
}
return false;
};
- for (EntryRegistryListener listener : listeners) {
- listener.removeEntriesIf(stack -> predicate.test(EntryStacks.hashExact(stack)));
- }
-
return registryList.removeExactIf(entryStackPredicate);
}
@Override
public boolean removeEntryFuzzyHashIf(LongPredicate predicate) {
- Predicate<EntryStack<?>> entryStackPredicate = stack -> {
+ EntryRegistryList.StackFilteringPredicate entryStackPredicate = (stack, hashExact) -> {
if (predicate.test(EntryStacks.hashFuzzy(stack))) {
- entriesHash.remove(EntryStacks.hashExact(stack));
+ entriesHash.remove(hashExact);
+ for (EntryRegistryListener listener : listeners) {
+ listener.removeEntry(stack, hashExact);
+ }
return true;
}
return false;
};
- for (EntryRegistryListener listener : listeners) {
- listener.removeEntriesIf(entryStackPredicate);
- }
-
- return registryList.removeIf(entryStackPredicate);
+ return registryList.removeExactIf(entryStackPredicate);
}
}
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/EntryRegistryList.java b/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/EntryRegistryList.java
index 2672b077a..4d146f94b 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/EntryRegistryList.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/EntryRegistryList.java
@@ -25,10 +25,9 @@ package me.shedaniel.rei.impl.common.entry.type;
import it.unimi.dsi.fastutil.longs.LongList;
import me.shedaniel.rei.api.common.entry.EntryStack;
+import me.shedaniel.rei.impl.common.util.HashedEntryStackWrapper;
import java.util.List;
-import java.util.function.LongPredicate;
-import java.util.function.Predicate;
import java.util.stream.Stream;
public interface EntryRegistryList {
@@ -38,6 +37,8 @@ public interface EntryRegistryList {
List<EntryStack<?>> collect();
+ List<HashedEntryStackWrapper> collectHashed();
+
int indexOf(EntryStack<?> stack);
int lastIndexOf(EntryStack<?> stack);
@@ -52,9 +53,11 @@ public interface EntryRegistryList {
void remove(EntryStack<?> stack, long hashExact);
- boolean removeIf(Predicate<? extends EntryStack<?>> predicate);
-
- boolean removeExactIf(LongPredicate predicate);
+ boolean removeExactIf(StackFilteringPredicate predicate);
boolean needsHash();
+
+ interface StackFilteringPredicate {
+ boolean test(EntryStack<?> stack, long hashExact);
+ }
}
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/EntryRegistryListImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/EntryRegistryListImpl.java
new file mode 100644
index 000000000..d43627aca
--- /dev/null
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/EntryRegistryListImpl.java
@@ -0,0 +1,206 @@
+/*
+ * This file is licensed under the MIT License, part of Roughly Enough Items.
+ * Copyright (c) 2018, 2019, 2020, 2021, 2022 shedaniel
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.