aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorshedaniel <daniel@shedaniel.me>2023-05-29 14:13:31 +0800
committershedaniel <daniel@shedaniel.me>2023-05-29 14:13:31 +0800
commitc2d352636f871631b1f4d4622b6c28daffef5541 (patch)
treeda7ddce0947e3e2c7879ee6cf8be364f49d16edf
parent8e0aafdf9e16688117bd57e14824d664eb816fa0 (diff)
parent5996c704a0e9312aa02d4d835a59f5efc3ac8b43 (diff)
downloadRoughlyEnoughItems-c2d352636f871631b1f4d4622b6c28daffef5541.tar.gz
RoughlyEnoughItems-c2d352636f871631b1f4d4622b6c28daffef5541.tar.bz2
RoughlyEnoughItems-c2d352636f871631b1f4d4622b6c28daffef5541.zip
Merge remote-tracking branch 'shedaniel/9.x-1.19' into 10.x-1.19.3
# Conflicts: # runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/EntryListSearchManager.java
-rw-r--r--api/src/main/java/me/shedaniel/rei/api/client/search/SearchFilter.java6
-rwxr-xr-xbuild.gradle2
-rw-r--r--forge/build.gradle4
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/ClientHelperImpl.java3
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/SearchFilteringRule.java2
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/DefaultDisplayViewingScreen.java2
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/TabWidget.java13
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/EntryListSearchManager.java59
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/search/OverlaySearchFieldSyntaxHighlighter.java4
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/registry/screen/ScreenRegistryImpl.java6
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/search/AsyncSearchManager.java108
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/search/SearchProviderImpl.java14
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/AlternativeArgument.java9
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/Argument.java256
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/ArgumentCache.java172
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/CompoundArgument.java16
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/search/collapsed/CollapsedEntriesCache.java85
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/util/ThreadCreator.java29
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/EntryRegistryImpl.java4
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/FilteredEntryList.java3
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/PreFilteredEntryList.java55
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/collapsed/CollapsibleEntryRegistryImpl.java63
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/common/util/HashedEntryStackWrapper.java12
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/plugin/client/entry/ItemEntryDefinition.java7
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/plugin/client/runtime/SearchFilterPrepareWatcher.java19
25 files changed, 590 insertions, 363 deletions
diff --git a/api/src/main/java/me/shedaniel/rei/api/client/search/SearchFilter.java b/api/src/main/java/me/shedaniel/rei/api/client/search/SearchFilter.java
index f94266447..7fb37e351 100644
--- a/api/src/main/java/me/shedaniel/rei/api/client/search/SearchFilter.java
+++ b/api/src/main/java/me/shedaniel/rei/api/client/search/SearchFilter.java
@@ -26,6 +26,7 @@ package me.shedaniel.rei.api.client.search;
import me.shedaniel.rei.api.common.entry.EntryStack;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
+import org.jetbrains.annotations.ApiStatus;
import java.util.Collection;
import java.util.function.Predicate;
@@ -80,4 +81,9 @@ public interface SearchFilter extends Predicate<EntryStack<?>> {
*/
default void prepareFilter(Collection<EntryStack<?>> stacks) {
}
+
+ @ApiStatus.Experimental
+ default boolean test(EntryStack<?> stack, long hashExact) {
+ return this.test(stack);
+ }
}
diff --git a/build.gradle b/build.gradle
index 045aacc37..18a3a4456 100755
--- a/build.gradle
+++ b/build.gradle
@@ -141,7 +141,7 @@ task releaseOnCf {
}
def time = df.format(new Date())
def changes = new StringBuilder()
- changes << "## REI v$project.version for $project.supported_version\nUpdated at **$time**.\n![Click here for changelog](https://www.github.com/shedaniel/RoughlyEnoughItems/commits/$branch)"
+ changes << "## REI v$project.version for $project.supported_version\nUpdated at **$time**.\n[Click here for changelog](https://www.github.com/shedaniel/RoughlyEnoughItems/commits/$branch)"
def proc = "git log --max-count=200 --pretty=format:%s".execute()
proc.in.eachLine { line ->
def processedLine = line.toString()
diff --git a/forge/build.gradle b/forge/build.gradle
index 25dd8cc0a..aab987e70 100644
--- a/forge/build.gradle
+++ b/forge/build.gradle
@@ -76,9 +76,9 @@ dependencies {
// modRuntime("curse.maven:immersive-engineering-231951:3721708")
// modRuntime("curse.maven:autoreglib-250363:3326041")
// modRuntime("curse.maven:ars-nouveau-401955:3814106")
- // modRuntime("curse.maven:patchouli-306770:3809917")
+ // modRuntime("curse.maven:patchouli-306770:3843443")
// modRuntime("curse.maven:curios-309927:3748873")
- // modRuntime("software.bernie.geckolib:geckolib-1.18-forge:3.0.22")
+ // modRuntime("software.bernie.geckolib:geckolib-forge-1.18:3.0.57")
// modRuntime("curse.maven:little-logistics-570050:3818773")
// modRuntime("curse.maven:refined-storage-243076:3623324")
// modRuntime("appeng:appliedenergistics2:10.0.1")
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/ClientHelperImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/ClientHelperImpl.java
index c0b633117..88496cef3 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/ClientHelperImpl.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/ClientHelperImpl.java
@@ -134,10 +134,11 @@ public class ClientHelperImpl implements ClientHelper {
@Override
public void appendModIdToTooltips(Tooltip components, String modId) {
final String modName = ClientHelper.getInstance().getModFromModId(modId);
+ int i = 0;
Iterator<Tooltip.Entry> iterator = components.entries().iterator();
while (iterator.hasNext()) {
Tooltip.Entry entry = iterator.next();
- if (entry.isText() && FormattingUtils.stripFormatting(entry.getAsText().getString()).equalsIgnoreCase(modName)) {
+ if (entry.isText() && i++ != 0 && FormattingUtils.stripFormatting(entry.getAsText().getString()).equalsIgnoreCase(modName)) {
iterator.remove();
}
}
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/SearchFilteringRule.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/SearchFilteringRule.java
index a332dd3b0..640c113ec 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/SearchFilteringRule.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/SearchFilteringRule.java
@@ -73,7 +73,7 @@ public class SearchFilteringRule implements FilteringRule<Unit> {
if (show) processList(context.getHiddenStacks(), completableFutures);
else processList(context.getShownStacks(), completableFutures);
try {
- CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[0])).get(10, TimeUnit.SECONDS);
+ CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[0])).get(90, TimeUnit.SECONDS);
} catch (InterruptedException | ExecutionException | TimeoutException e) {
e.printStackTrace();
}
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/DefaultDisplayViewingScreen.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/DefaultDisplayViewingScreen.java
index 7c4567f55..83b6e2434 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/DefaultDisplayViewingScreen.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/DefaultDisplayViewingScreen.java
@@ -454,7 +454,7 @@ public class DefaultDisplayViewingScreen extends AbstractDisplayViewingScreen {
}
ExportRecipeIdentifierToast.addToast(I18n.get("msg.rei.exported_recipe"), I18n.get("msg.rei.exported_recipe.desc"));
}
- minecraft.setScreen(DefaultDisplayViewingScreen.this);
+ minecraft.setScreen(null);
}, Component.translatable("text.rei.ask_to_export", tab.categoryName),
Component.translatable("text.rei.ask_to_export.subtitle", categoryMap.getOrDefault(tab.category, Collections.emptyList()).size())));
}
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/TabWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/TabWidget.java
index 44d972c16..2fbcd2be7 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/TabWidget.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/TabWidget.java
@@ -31,6 +31,7 @@ import me.shedaniel.math.Point;
import me.shedaniel.math.Rectangle;
import me.shedaniel.rei.api.client.ClientHelper;
import me.shedaniel.rei.api.client.REIRuntime;
+import me.shedaniel.rei.api.client.config.ConfigObject;
import me.shedaniel.rei.api.client.gui.Renderer;
import me.shedaniel.rei.api.client.gui.drag.DraggableStack;
import me.shedaniel.rei.api.client.gui.drag.DraggableStackProviderWidget;
@@ -131,10 +132,14 @@ public class TabWidget extends WidgetWithBounds implements DraggableStackProvide
}
private void drawTooltip() {
- if (this.minecraft.options.advancedItemTooltips)
- Tooltip.create(categoryName, Component.literal(category.getIdentifier().toString()).withStyle(ChatFormatting.DARK_GRAY), ClientHelper.getInstance().getFormattedModFromIdentifier(category.getIdentifier())).queue();
- else
- Tooltip.create(categoryName, ClientHelper.getInstance().getFormattedModFromIdentifier(category.getIdentifier())).queue();
+ Tooltip tooltip = Tooltip.create(categoryName);
+ if (this.minecraft.options.advancedItemTooltips) {
+ tooltip.add(Component.literal(category.getIdentifier().toString()).withStyle(ChatFormatting.DARK_GRAY));
+ }
+ if (ConfigObject.getInstance().shouldAppendModNames()) {
+ tooltip.add(ClientHelper.getInstance().getFormattedModFromIdentifier(category.getIdentifier()));
+ }
+ tooltip.queue();
}
@Override
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/EntryListSearchManager.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/EntryListSearchManager.java
index e877943c6..11672222d 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/EntryListSearchManager.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/EntryListSearchManager.java
@@ -24,6 +24,7 @@
package me.shedaniel.rei.impl.client.gui.widget.entrylist;
import com.google.common.base.Stopwatch;
+import com.google.common.collect.Iterators;
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
import it.unimi.dsi.fastutil.longs.LongSet;
import me.shedaniel.rei.api.client.config.ConfigManager;
@@ -35,10 +36,14 @@ import me.shedaniel.rei.api.client.view.Views;
import me.shedaniel.rei.api.common.entry.EntryStack;
import me.shedaniel.rei.api.common.util.EntryStacks;
import me.shedaniel.rei.impl.client.search.AsyncSearchManager;
+import me.shedaniel.rei.impl.client.search.collapsed.CollapsedEntriesCache;
import me.shedaniel.rei.impl.common.InternalLogger;
+import me.shedaniel.rei.impl.common.entry.type.EntryRegistryImpl;
import me.shedaniel.rei.impl.common.entry.type.collapsed.CollapsedStack;
import me.shedaniel.rei.impl.common.entry.type.collapsed.CollapsibleEntryRegistryImpl;
+import me.shedaniel.rei.impl.common.util.HashedEntryStackWrapper;
import net.minecraft.client.Minecraft;
+import net.minecraft.resources.ResourceLocation;
import org.apache.logging.log4j.Level;
import org.jetbrains.annotations.Nullable;
@@ -47,12 +52,12 @@ import java.util.function.BooleanSupplier;
import java.util.function.Consumer;
public class EntryListSearchManager {
- private static final Comparator<? super EntryStack<?>> ENTRY_NAME_COMPARER = Comparator.comparing(stack -> stack.asFormatStrippedText().getString());
- // private static final Comparator<? super EntryStack<?>> ENTRY_GROUP_COMPARER = VersionAdapter.INSTANCE.getEntryGroupComparator();
+ private static final Comparator<? super HashedEntryStackWrapper> ENTRY_NAME_COMPARER = Comparator.comparing(stack -> stack.unwrap().asFormatStrippedText().getString());
+ // private static final Comparator<? super HashedEntryStackWrapper> ENTRY_GROUP_COMPARER = VersionAdapter.INSTANCE.getEntryGroupComparator();
public static final EntryListSearchManager INSTANCE = new EntryListSearchManager();
- private AsyncSearchManager searchManager = new AsyncSearchManager(EntryRegistry.getInstance()::getPreFilteredList, () -> {
+ private final AsyncSearchManager searchManager = new AsyncSearchManager(((EntryRegistryImpl) EntryRegistry.getInstance())::getPreFilteredComplexList, () -> {
boolean checkCraftable = ConfigManager.getInstance().isCraftableOnlyEnabled();
LongSet workingItems = checkCraftable ? new LongOpenHashSet() : null;
if (checkCraftable) {
@@ -60,8 +65,8 @@ public class EntryListSearchManager {
workingItems.add(EntryStacks.hashExact(stack));
}
}
- return checkCraftable ? stack -> workingItems.contains(EntryStacks.hashExact(stack)) : stack -> true;
- }, EntryStack::normalize);
+ return checkCraftable ? stack -> workingItems.contains(stack.hashExact()) : stack -> true;
+ }, HashedEntryStackWrapper::normalize);
public void update(String searchTerm, boolean ignoreLastSearch, Consumer<List</*EntryStack<?> | CollapsedStack*/ Object>> update) {
Stopwatch stopwatch = Stopwatch.createStarted();
@@ -70,21 +75,21 @@ public class EntryListSearchManager {
if (searchManager.isDirty()) {
searchManager.getAsync((list, filter) -> {
if (!filter.getFilter().equals(searchTerm)) return;
- if (searchManager.filter() == null || searchManager.filter() != filter) return;
+ if (searchManager.filter == null || searchManager.filter != filter) return;
InternalLogger.getInstance().log(ConfigObject.getInstance().doDebugSearchTimeRequired() ? Level.INFO : Level.TRACE, "Search \"%s\" Used [%s]: %s", filter.getFilter(), Thread.currentThread().toString(), stopwatch.toString());
- List</*EntryStack<?> | CollapsedStack*/ Object> finalList = collapse(copyAndOrder(list), () -> searchManager.filter() != null && searchManager.filter() == filter);
+ List</*EntryStack<?> | CollapsedStack*/ Object> finalList = collapse(copyAndOrder(list), () -> searchManager.filter != null && searchManager.filter == filter);
InternalLogger.getInstance().log(ConfigObject.getInstance().doDebugSearchTimeRequired() ? Level.INFO : Level.TRACE, "Search \"%s\" Used and Applied [%s]: %s", filter.getFilter(), Thread.currentThread().toString(), stopwatch.stop().toString());
Minecraft.getInstance().submit(() -> {
- if (searchManager.filter() == null || searchManager.filter() != filter) return;
+ if (searchManager.filter == null || searchManager.filter != filter) return;
update.accept(finalList);
});
});
}
}
- private List<EntryStack<?>> copyAndOrder(List<EntryStack<?>> list) {
+ private List<HashedEntryStackWrapper> copyAndOrder(List<HashedEntryStackWrapper> list) {
list = new ArrayList<>(list);
EntryPanelOrdering ordering = ConfigObject.getInstance().getItemListOrdering();
if (ordering == EntryPanelOrdering.NAME)
@@ -98,7 +103,7 @@ public class EntryListSearchManager {
return list;
}
- private List</*EntryStack<?> | CollapsedStack*/ Object> collapse(List<EntryStack<?>> stacks, BooleanSupplier isValid) {
+ private List</*EntryStack<?> | CollapsedStack*/ Object> collapse(List<HashedEntryStackWrapper> stacks, BooleanSupplier isValid) {
CollapsibleEntryRegistryImpl collapsibleRegistry = (CollapsibleEntryRegistryImpl) CollapsibleEntryRegistry.getInstance();
Map<CollapsibleEntryRegistryImpl.Entry, @Nullable CollapsedStack> entries = new HashMap<>();
@@ -106,20 +111,46 @@ public class EntryListSearchManager {
entries.put(entry, null);
}
+ if (entries.isEmpty()) return (List<Object>) (List<?>) new AbstractList<EntryStack<?>>() {
+
+ @Override
+ public int size() {
+ return stacks.size();
+ }
+
+ @Override
+ public EntryStack<?> get(int i) {
+ return stacks.get(i).unwrap();
+ }
+
+ @Override
+ public Iterator<EntryStack<?>> iterator() {
+ return Iterators.transform(stacks.iterator(), HashedEntryStackWrapper::unwrap);
+ }
+ };
if (!isValid.getAsBoolean()) return List.of();
- List</*EntryStack<?> | CollapsedStack*/ Object> list = new ArrayList<>();
+ List</*EntryStack<?> | CollapsedStack*/ Object> list = new ArrayList<>(stacks.size() + 10);
int i = 0;
- for (EntryStack<?> stack : stacks) {
- long hashExact = EntryStacks.hashExact(stack);
+ for (HashedEntryStackWrapper wrapper : stacks) {
+ long hashExact = wrapper.hashExact();
+ EntryStack<?> stack = wrapper.unwrap();
boolean matchedAny = false;
+ Set<ResourceLocation> locations = CollapsedEntriesCache.getInstance().getEntries(hashExact);
for (Map.Entry<CollapsibleEntryRegistryImpl.Entry, @Nullable CollapsedStack> mapEntry : entries.entrySet()) {
CollapsibleEntryRegistryImpl.Entry entry = mapEntry.getKey();
+ boolean matches;
+
+ if (!entry.canCache()) {
+ matches = entry.getMatcher().matches(stack, hashExact);
+ } else {
+ matches = locations != null && locations.contains(entry.getId());
+ }
- if (entry.getMatcher().matches(stack, hashExact)) {
+ if (matches) {
CollapsedStack collapsed = mapEntry.getValue();
if (collapsed == null) {
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/search/OverlaySearchFieldSyntaxHighlighter.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/search/OverlaySearchFieldSyntaxHighlighter.java
index 9391660c6..e039ad7e9 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/search/OverlaySearchFieldSyntaxHighlighter.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/search/OverlaySearchFieldSyntaxHighlighter.java
@@ -54,9 +54,9 @@ public class OverlaySearchFieldSyntaxHighlighter implements Consumer<String> {
}
@Override
- public void addPart(Argument<?, ?> argument, boolean usingGrammar, Collection<IntRange> grammarRanges, int index) {
+ public void addPart(Argument.Builder<?, ?> argument, boolean usingGrammar, Collection<IntRange> grammarRanges, int index) {
if (usingGrammar) {
- int argIndex = ArgumentTypesRegistry.ARGUMENT_TYPE_LIST.indexOf(argument.getArgument()) * 2 + 1;
+ int argIndex = ArgumentTypesRegistry.ARGUMENT_TYPE_LIST.indexOf(argument.getType()) * 2 + 1;
for (int i = argument.start(); i < argument.end(); i++) {
highlighted[i] = (byte) argIndex;
}
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/screen/ScreenRegistryImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/screen/ScreenRegistryImpl.java
index 8e5d76d97..85053fb73 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/screen/ScreenRegistryImpl.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/screen/ScreenRegistryImpl.java
@@ -63,9 +63,9 @@ import java.util.concurrent.CopyOnWriteArrayList;
@Environment(EnvType.CLIENT)
public class ScreenRegistryImpl implements ScreenRegistry {
private Multimap<Class<? extends Screen>, ClickArea<?>> clickAreas = HashMultimap.create();
- private List<DraggableComponentProvider<Screen, Object>> draggableProviders = new ArrayList<>();
- private List<DraggableComponentVisitor<Screen>> draggableVisitors = new ArrayList<>();
- private List<FocusedStackProvider> focusedStackProviders = new ArrayList<>();
+ private List<DraggableComponentProvider<Screen, Object>> draggableProviders = new CopyOnWriteArrayList<>();
+ private List<DraggableComponentVisitor<Screen>> draggableVisitors = new CopyOnWriteArrayList<>();
+ private List<FocusedStackProvider> focusedStackProviders = new CopyOnWriteArrayList<>();
private List<OverlayDecider> deciders = new CopyOnWriteArrayList<>();
private Map<Class<?>, List<OverlayDecider>> cache = new HashMap<>();
private ExclusionZones exclusionZones = new ExclusionZonesImpl();
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/search/AsyncSearchManager.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/search/AsyncSearchManager.java
index 9d418453c..5c7836576 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/search/AsyncSearchManager.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/search/AsyncSearchManager.java
@@ -30,10 +30,8 @@ import me.shedaniel.rei.api.client.search.SearchFilter;
import me.shedaniel.rei.api.client.search.SearchProvider;
import me.shedaniel.rei.api.common.entry.EntryStack;
import me.shedaniel.rei.api.common.util.CollectionUtils;
-import me.shedaniel.rei.impl.client.search.argument.Argument;
-import me.shedaniel.rei.impl.client.search.argument.type.ArgumentType;
import me.shedaniel.rei.impl.client.util.ThreadCreator;
-import org.jetbrains.annotations.Nullable;
+import me.shedaniel.rei.impl.common.util.HashedEntryStackWrapper;
import java.util.AbstractMap;
import java.util.ArrayList;
@@ -46,32 +44,26 @@ import java.util.function.Supplier;
import java.util.function.UnaryOperator;
public class AsyncSearchManager {
- private static final ExecutorService EXECUTOR_SERVICE = new ThreadCreator("REI-AsyncSearchManager").asService();
- private final Supplier<List<EntryStack<?>>> stacksProvider;
- private final Supplier<Predicate<EntryStack<?>>> additionalPredicateSupplier;
- private final UnaryOperator<EntryStack<?>> transformer;
- private ExecutorTuple executor;
- private SearchFilter filter;
- private Map.Entry<List<EntryStack<?>>, SearchFilter> last;
+ private static final ExecutorService EXECUTOR_SERVICE = new ThreadCreator("REI-AsyncSearchManager").asService(Math.min(3, Runtime.getRuntime().availableProcessors()));
+ private final Supplier<List<HashedEntryStackWrapper>> stacksProvider;
+ private final Supplier<Predicate<HashedEntryStackWrapper>> additionalPredicateSupplier;
+ private final UnaryOperator<HashedEntryStackWrapper> transformer;
+ private volatile ExecutorTuple executor;
+ private volatile Map.Entry<List<HashedEntryStackWrapper>, SearchFilter> last;
+ public volatile SearchFilter filter;
- public AsyncSearchManager(Supplier<List<EntryStack<?>>> stacksProvider, Supplier<Predicate<EntryStack<?>>> additionalPredicateSupplier, UnaryOperator<EntryStack<?>> transformer) {
+ public AsyncSearchManager(Supplier<List<HashedEntryStackWrapper>> stacksProvider, Supplier<Predicate<HashedEntryStackWrapper>> additionalPredicateSupplier, UnaryOperator<HashedEntryStackWrapper> transformer) {
this.stacksProvider = stacksProvider;
this.additionalPredicateSupplier = additionalPredicateSupplier;
this.transformer = transformer;
}
public void markDirty() {
- synchronized (AsyncSearchManager.this) {
- this.last = null;
- }
- }
-
- @Nullable
- public SearchFilter filter() {
- return this.filter;
+ this.last = null;
}
- private record ExecutorTuple(SearchFilter filter, CompletableFuture<Map.Entry<List<EntryStack<?>>, SearchFilter>> future) {
+ private record ExecutorTuple(SearchFilter filter,
+ CompletableFuture<Map.Entry<List<HashedEntryStackWrapper>, SearchFilter>> future) {
}
public void updateFilter(String filter) {
@@ -85,12 +77,10 @@ public class AsyncSearchManager {
}
public boolean isDirty() {
- synchronized (AsyncSearchManager.this) {
- return this.last == null || this.last.getValue() != this.filter;
- }
+ return this.last == null || this.last.getValue() != this.filter;
}
- public Future<?> getAsync(BiConsumer<List<EntryStack<?>>, SearchFilter> consumer) {
+ public Future<?> getAsync(BiConsumer<List<HashedEntryStackWrapper>, SearchFilter> consumer) {
if (this.executor == null || this.executor.filter() != filter || isDirty()) {
if (this.executor != null) {
this.executor.future().cancel(Platform.isFabric());
@@ -107,7 +97,7 @@ public class AsyncSearchManager {
}, EXECUTOR_SERVICE))).future();
}
- public List<EntryStack<?>> getNow() {
+ public List<HashedEntryStackWrapper> getNow() {
try {
return get(Runnable::run).get().getKey();
} catch (ExecutionException e) {
@@ -117,18 +107,14 @@ public class AsyncSearchManager {
}
}
- public CompletableFuture<Map.Entry<List<EntryStack<?>>, SearchFilter>> get(Executor executor) {
+ public CompletableFuture<Map.Entry<List<HashedEntryStackWrapper>, SearchFilter>> get(Executor executor) {
if (isDirty()) {
- Map.Entry<List<EntryStack<?>>, SearchFilter> last;
- synchronized (AsyncSearchManager.this) {
- last = this.last;
- }
+ Map.Entry<List<HashedEntryStackWrapper>, SearchFilter> last;
+ last = this.last;
return get(this.filter, this.additionalPredicateSupplier.get(), this.transformer,
this.stacksProvider.get(), last, this, executor)
.thenApply(entry -> {
- synchronized (AsyncSearchManager.this) {
- this.last = entry;
- }
+ this.last = entry;
return entry;
});
}
@@ -136,39 +122,20 @@ public class AsyncSearchManager {
return CompletableFuture.completedFuture(last);
}
- public static CompletableFuture<Map.Entry<List<EntryStack<?>>, SearchFilter>> get(SearchFilter filter, Predicate<EntryStack<?>> additionalPredicate,
- UnaryOperator<EntryStack<?>> transformer, List<EntryStack<?>> stacks, Map.Entry<List<EntryStack<?>>, SearchFilter> last,
+ public static CompletableFuture<Map.Entry<List<HashedEntryStackWrapper>, SearchFilter>> get(SearchFilter filter, Predicate<HashedEntryStackWrapper> additionalPredicate,
+ UnaryOperator<HashedEntryStackWrapper> transformer, List<HashedEntryStackWrapper> stacks, Map.Entry<List<HashedEntryStackWrapper>, SearchFilter> last,
AsyncSearchManager manager, Executor executor) {
int searchPartitionSize = ConfigObject.getInstance().getAsyncSearchPartitionSize();
boolean shouldAsync = ConfigObject.getInstance().shouldAsyncSearch() && stacks.size() > searchPartitionSize * 4;
if (!stacks.isEmpty()) {
- CompletableFuture<Void> preparationFuture = CompletableFuture.completedFuture(null);
-
- if (last == null || last.getValue() != filter) {
- Runnable prepare = () -> {
- if (manager.filter == filter) {
- List<ArgumentType<?, ?>> argumentTypes = ((SearchProviderImpl.SearchFilterImpl) filter).getArgumentTypes();
- Argument.prepareFilter(stacks, argumentTypes, () -> manager.filter() != null && manager.filter() == filter, executor);
- } else {
- throw new CancellationException();
- }
- };
- if (shouldAsync) {
- preparationFuture = CompletableFuture.runAsync(prepare, executor);
- } else {
- prepare.run();
- preparationFuture = CompletableFuture.completedFuture(null);
- }
- }
-
if (shouldAsync) {
- List<CompletableFuture<List<EntryStack<?>>>> futures = Lists.newArrayList();
- for (Iterable<EntryStack<?>> partitionStacks : CollectionUtils.partition(stacks, Math.max(searchPartitionSize, stacks.size() * 3 / Runtime.getRuntime().availableProcessors()))) {
+ List<CompletableFuture<List<HashedEntryStackWrapper>>> futures = Lists.newArrayList();
+ for (Iterable<HashedEntryStackWrapper> partitionStacks : CollectionUtils.partition(stacks, Math.max(searchPartitionSize, stacks.size() * 3 / Runtime.getRuntime().availableProcessors()))) {
futures.add(CompletableFuture.supplyAsync(() -> {
- List<EntryStack<?>> filtered = Lists.newArrayList();
- for (EntryStack<?> stack : partitionStacks) {
- if (stack != null && filter.test(stack) && additionalPredicate.test(stack)) {
+ List<HashedEntryStackWrapper> filtered = Lists.newArrayList();
+ for (HashedEntryStackWrapper stack : partitionStacks) {
+ if (stack != null && filter.test(stack.unwrap(), stack.hashExact()) && additionalPredicate.test(stack)) {
filtered.add(transformer.apply(stack));
}
if (manager.filter != filter) throw new CancellationException();
@@ -176,19 +143,16 @@ public class AsyncSearchManager {
return filtered;
}, executor));
}
- return preparationFuture.thenCompose($ -> CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
- .orTimeout(30, TimeUnit.SECONDS))
+ return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
+ .orTimeout(90, TimeUnit.SECONDS)
.thenApplyAsync($ -> {
- List<EntryStack<?>> list = new ArrayList<>();
+ List<HashedEntryStackWrapper> list = new ArrayList<>();
- if (manager.filter == filter) {
-