aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/src/main/java/me/shedaniel/rei/api/client/search/SearchFilter.java10
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/ReloadPluginsEntry.java26
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryListWidget.java32
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryWidget.java6
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/search/AsyncSearchManager.java34
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/search/SearchProviderImpl.java16
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/Argument.java113
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/type/AlwaysMatchingArgumentType.java8
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/type/ArgumentType.java5
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/type/IdentifierArgumentType.java25
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/type/ModArgumentType.java22
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/type/RegexArgumentType.java13
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/type/TagArgumentType.java33
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/type/TextArgumentType.java12
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/type/TooltipArgumentType.java31
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/plugin/client/runtime/DefaultClientRuntimePlugin.java1
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/plugin/client/runtime/SearchFilterPrepareWatcher.java80
-rw-r--r--runtime/src/main/resources/assets/roughlyenoughitems/lang/cs_cz.json7
-rwxr-xr-xruntime/src/main/resources/assets/roughlyenoughitems/lang/en_us.json3
-rw-r--r--runtime/src/main/resources/assets/roughlyenoughitems/lang/fr_fr.json21
-rw-r--r--runtime/src/main/resources/assets/roughlyenoughitems/lang/lol_us.json2
-rw-r--r--runtime/src/main/resources/assets/roughlyenoughitems/lang/pt_br.json47
-rw-r--r--runtime/src/main/resources/assets/roughlyenoughitems/lang/ru_ru.json200
-rw-r--r--runtime/src/main/resources/assets/roughlyenoughitems/lang/zh_cn.json39
-rw-r--r--runtime/src/main/resources/assets/roughlyenoughitems/lang/zh_tw.json26
25 files changed, 586 insertions, 226 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 2038b7cdb..80b4987df 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
@@ -27,6 +27,7 @@ import me.shedaniel.rei.api.common.entry.EntryStack;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
+import java.util.Collection;
import java.util.function.Predicate;
/**
@@ -70,4 +71,13 @@ public interface SearchFilter extends Predicate<EntryStack<?>> {
* @return the original filter
*/
String getFilter();
+
+ /**
+ * Prepares the following stacks for matching, this could help to speed up the matching process.<br>
+ * However, this is not required.
+ *
+ * @param stacks the stacks to prepare
+ */
+ default void prepareFilter(Collection<EntryStack<?>> stacks) {
+ }
}
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/ReloadPluginsEntry.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/ReloadPluginsEntry.java
index ad1d13cd5..fd715ede5 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/ReloadPluginsEntry.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/entries/ReloadPluginsEntry.java
@@ -31,6 +31,7 @@ import me.shedaniel.rei.RoughlyEnoughItemsCore;
import me.shedaniel.rei.RoughlyEnoughItemsCoreClient;
import me.shedaniel.rei.api.common.plugins.PluginManager;
import me.shedaniel.rei.impl.client.gui.screen.ConfigReloadingScreen;
+import me.shedaniel.rei.impl.client.search.argument.Argument;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.chat.NarratorChatListener;
import net.minecraft.client.gui.components.AbstractWidget;
@@ -48,7 +49,7 @@ import java.util.Optional;
@ApiStatus.Internal
public class ReloadPluginsEntry extends AbstractConfigListEntry<Unit> {
private int width;
- private AbstractWidget buttonWidget = new Button(0, 0, 0, 20, NarratorChatListener.NO_TITLE, button -> {
+ private AbstractWidget reloadPluginsButton = new Button(0, 0, 0, 20, NarratorChatListener.NO_TITLE, button -> {
RoughlyEnoughItemsCore.PERFORMANCE_LOGGER.clear();
RoughlyEnoughItemsCoreClient.reloadPlugins(null, null);
}) {
@@ -62,12 +63,16 @@ public class ReloadPluginsEntry extends AbstractConfigListEntry<Unit> {
}
}
};
- private List<AbstractWidget> children = ImmutableList.of(buttonWidget);
+ private AbstractWidget reloadSearchButton = new Button(0, 0, 0, 20, NarratorChatListener.NO_TITLE, button -> {
+ Argument.SEARCH_CACHE.clear();
+ });
+ private List<AbstractWidget> children = ImmutableList.of(reloadPluginsButton, reloadSearchButton);
public ReloadPluginsEntry(int width) {
super(NarratorChatListener.NO_TITLE, false);
this.width = width;
- buttonWidget.setMessage(new TranslatableComponent("text.rei.reload_config"));
+ reloadPluginsButton.setMessage(new TranslatableComponent("text.rei.reload_config"));
+ reloadSearchButton.setMessage(new TranslatableComponent("text.rei.reload_search"));
}
@Override
@@ -89,11 +94,16 @@ public class ReloadPluginsEntry extends AbstractConfigListEntry<Unit> {
public void render(PoseStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
super.render(matrices, index, y, x, entryWidth, entryHeight, mouseX, mouseY, isSelected, delta);
Window window = Minecraft.getInstance().getWindow();
- this.buttonWidget.active = this.isEditable();
- this.buttonWidget.y = y;
- this.buttonWidget.x = x + entryWidth / 2 - width / 2;
- this.buttonWidget.setWidth(width);
- this.buttonWidget.render(matrices, mouseX, mouseY, delta);
+ this.reloadPluginsButton.active = this.isEditable();
+ this.reloadPluginsButton.y = y;
+ this.reloadPluginsButton.setWidth(width / 2 - 6);
+ this.reloadPluginsButton.x = x + entryWidth / 2 - width / 2;
+ this.reloadPluginsButton.render(matrices, mouseX, mouseY, delta);
+ this.reloadSearchButton.active = this.isEditable() && !Argument.SEARCH_CACHE.isEmpty();
+ this.reloadSearchButton.y = y;
+ this.reloadSearchButton.setWidth(width / 2 - 6);
+ this.reloadSearchButton.x = x + entryWidth / 2 + 3;
+ this.reloadSearchButton.render(matrices, mouseX, mouseY, delta);
}
@Override
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryListWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryListWidget.java
index 8d0e8b291..28f6e2ca5 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryListWidget.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryListWidget.java
@@ -88,6 +88,7 @@ import org.apache.commons.lang3.mutable.MutableLong;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
@@ -508,26 +509,29 @@ public class EntryListWidget extends WidgetWithBounds implements OverlayListWidg
if (ignoreLastSearch) searchManager.markDirty();
searchManager.updateFilter(searchTerm);
if (searchManager.isDirty()) {
- List<EntryStack<?>> list = searchManager.get();
- EntryPanelOrdering ordering = ConfigObject.getInstance().getItemListOrdering();
- if (ordering == EntryPanelOrdering.NAME)
- list.sort(ENTRY_NAME_COMPARER);
- if (ordering == EntryPanelOrdering.GROUPS)
- list.sort(ENTRY_GROUP_COMPARER);
- if (!ConfigObject.getInstance().isItemListAscending()) {
- Collections.reverse(list);
- }
- allStacks = list;
+ searchManager.getAsync(list -> {
+ list = new ArrayList<>(list);
+ EntryPanelOrdering ordering = ConfigObject.getInstance().getItemListOrdering();
+ if (ordering == EntryPanelOrdering.NAME)
+ list.sort(ENTRY_NAME_COMPARER);
+ if (ordering == EntryPanelOrdering.GROUPS)
+ list.sort(ENTRY_GROUP_COMPARER);
+ if (!ConfigObject.getInstance().isItemListAscending()) {
+ Collections.reverse(list);
+ }
+ allStacks = list;
+
+ if (ConfigObject.getInstance().doDebugSearchTimeRequired()) {
+ RoughlyEnoughItemsCore.LOGGER.info("Search Used: %s", stopwatch.stop().toString());
+ }
+ updateEntriesPosition();
+ });
}
debugTime = ConfigObject.getInstance().doDebugRenderTimeRequired();
FavoritesListWidget favorites = ScreenOverlayImpl.getFavoritesListWidget();
if (favorites != null) {
favorites.updateSearch();
}
- if (ConfigObject.getInstance().doDebugSearchTimeRequired()) {
- RoughlyEnoughItemsCore.LOGGER.info("Search Used: %s", stopwatch.stop().toString());
- }
- updateEntriesPosition();
}
public boolean matches(EntryStack<?> stack) {
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryWidget.java
index a20825496..3f9cfe4cc 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryWidget.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryWidget.java
@@ -59,10 +59,7 @@ import net.minecraft.util.Mth;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
+import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -230,6 +227,7 @@ public class EntryWidget extends Slot implements DraggableStackProviderWidget {
@Override
public EntryWidget entry(EntryStack<?> stack) {
+ Objects.requireNonNull(stack);
if (entryStacks.isEmpty()) {
entryStacks = Collections.singletonList(stack);
} else {
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 9e1a8934d..b1bc2ecd5 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
@@ -38,10 +38,8 @@ import me.shedaniel.rei.api.common.util.EntryStacks;
import java.util.ArrayList;
import java.util.List;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
+import java.util.concurrent.*;
+import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.function.UnaryOperator;
@@ -53,6 +51,8 @@ public class AsyncSearchManager {
private Predicate<EntryStack<?>> additionalPredicate;
private SearchFilter filter;
private boolean dirty = false;
+ private boolean filterDirty = false;
+ private CompletableFuture<List<EntryStack<?>>> future;
private List<EntryStack<?>> last;
public AsyncSearchManager(Supplier<List<EntryStack<?>>> stacksProvider, Supplier<Predicate<EntryStack<?>>> additionalPredicateSupplier, UnaryOperator<EntryStack<?>> transformer) {
@@ -78,10 +78,15 @@ public class AsyncSearchManager {
this.dirty = true;
}
+ public void markFilterDirty() {
+ this.filterDirty = true;
+ }
+
public void updateFilter(String filter) {
if (this.filter == null || !this.filter.getFilter().equals(filter)) {
this.filter = SearchProvider.getInstance().createFilter(filter);
markDirty();
+ markFilterDirty();
}
}
@@ -89,6 +94,22 @@ public class AsyncSearchManager {
return last == null || dirty;
}
+ public boolean isFilterDirty() {
+ return filterDirty;
+ }
+
+ public Future<Void> getAsync(Consumer<List<EntryStack<?>>> consumer) {
+ if (future == null || future.isCancelled() || future.isDone() || future.isCompletedExceptionally()) {
+ if (future != null) future.cancel(true);
+ future = CompletableFuture.supplyAsync(this::get)
+ .exceptionally(throwable -> {
+ throwable.printStackTrace();
+ return null;
+ });
+ }
+ return future.thenAccept(consumer);
+ }
+
public List<EntryStack<?>> get() {
if (isDirty()) {
this.additionalPredicate = additionalPredicateSupplier.get();
@@ -97,6 +118,11 @@ public class AsyncSearchManager {
last = new ArrayList<>();
if (!stacks.isEmpty()) {
+ if (filterDirty) {
+ filter.prepareFilter(stacks);
+ filterDirty = false;
+ }
+
if (ConfigObject.getInstance().shouldAsyncSearch() && stacks.size() > searchPartitionSize * 4) {
List<CompletableFuture<List<EntryStack<?>>>> futures = Lists.newArrayList();
for (Iterable<EntryStack<?>> partitionStacks : CollectionUtils.partition(stacks, searchPartitionSize)) {
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/search/SearchProviderImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/search/SearchProviderImpl.java
index f91005c45..9a3948a86 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/search/SearchProviderImpl.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/search/SearchProviderImpl.java
@@ -26,14 +26,18 @@ package me.shedaniel.rei.impl.client.search;
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.impl.client.search.argument.AlternativeArgument;
import me.shedaniel.rei.impl.client.search.argument.Argument;
import me.shedaniel.rei.impl.client.search.argument.CompoundArgument;
+import me.shedaniel.rei.impl.client.search.argument.type.ArgumentType;
import me.shedaniel.rei.impl.client.util.CrashReportUtils;
import net.minecraft.CrashReport;
import net.minecraft.CrashReportCategory;
+import java.util.Collection;
import java.util.List;
import java.util.Objects;
+import java.util.stream.Collectors;
public class SearchProviderImpl implements SearchProvider {
@Override
@@ -49,10 +53,17 @@ public class SearchProviderImpl implements SearchProvider {
public static class SearchFilterImpl implements SearchFilter {
private final List<CompoundArgument> arguments;
private final String filter;
+ private final List<ArgumentType<?, ?>> argumentTypes;
public SearchFilterImpl(List<CompoundArgument> arguments, String searchTerm) {
this.arguments = arguments;
this.filter = searchTerm;
+ this.argumentTypes = arguments.stream()
+ .flatMap(CompoundArgument::stream)
+ .flatMap(AlternativeArgument::stream)
+ .map(Argument::getArgument)
+ .distinct()
+ .collect(Collectors.toList());
}
@Override
@@ -72,6 +83,11 @@ public class SearchProviderImpl implements SearchProvider {
}
@Override
+ public void prepareFilter(Collection<EntryStack<?>> stacks) {
+ Argument.prepareFilter(stacks, argumentTypes);
+ }
+
+ @Override
public String getFilter() {
return filter;
}
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/Argument.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/Argument.java
index 7366f869a..0844257ad 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/Argument.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/Argument.java
@@ -25,27 +25,33 @@ package me.shedaniel.rei.impl.client.search.argument;
import com.google.common.base.MoreObjects;
import com.google.common.collect.Lists;
+import it.unimi.dsi.fastutil.Pair;
+import it.unimi.dsi.fastutil.ints.IntIntMutablePair;
+import it.unimi.dsi.fastutil.ints.IntIntPair;
+import it.unimi.dsi.fastutil.longs.Long2ObjectArrayMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectMaps;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.shorts.Short2ObjectMap;
import it.unimi.dsi.fastutil.shorts.Short2ObjectMaps;
import it.unimi.dsi.fastutil.shorts.Short2ObjectOpenHashMap;
+import me.shedaniel.rei.api.client.config.ConfigObject;
import me.shedaniel.rei.api.client.gui.config.SearchMode;
import me.shedaniel.rei.api.common.entry.EntryStack;
+import me.shedaniel.rei.api.common.util.CollectionUtils;
import me.shedaniel.rei.api.common.util.EntryStacks;
import me.shedaniel.rei.impl.client.search.IntRange;
import me.shedaniel.rei.impl.client.search.argument.type.AlwaysMatchingArgumentType;
import me.shedaniel.rei.impl.client.search.argument.type.ArgumentType;
import me.shedaniel.rei.impl.client.search.argument.type.ArgumentTypesRegistry;
import me.shedaniel.rei.impl.client.search.result.ArgumentApplicableResult;
+import me.shedaniel.rei.impl.common.util.HashedEntryStackWrapper;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
+import net.minecraft.Util;
import net.minecraft.client.Minecraft;
import net.minecraft.util.Unit;
import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.mutable.Mutable;
-import org.apache.commons.lang3.mutable.MutableObject;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
@@ -53,6 +59,10 @@ import java.util.Collection;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -178,12 +188,11 @@ public class Argument<T, R> {
if (!Objects.equals(lastLanguage.getAndSet(newLanguage), newLanguage)) {
SEARCH_CACHE.clear();
}
- Mutable<?> mutable = new MutableObject<>();
a:
for (CompoundArgument arguments : compoundArguments) {
for (AlternativeArgument argument : arguments) {
- if (!matches(stack, argument, mutable)) {
+ if (!matches(stack, argument)) {
continue a;
}
}
@@ -194,12 +203,12 @@ public class Argument<T, R> {
return false;
}
- private static <T, R, Z, B> boolean matches(EntryStack<?> stack, AlternativeArgument alternativeArgument, Mutable<?> mutable) {
+ private static <T, R, Z, B> boolean matches(EntryStack<?> stack, AlternativeArgument alternativeArgument) {
if (alternativeArgument.isEmpty()) return true;
long hashExact = EntryStacks.hashExact(stack);
for (Argument<?, ?> argument : alternativeArgument) {
- if (matches((short) argument.getArgument().getIndex(), argument.getArgument(), mutable, stack, hashExact, argument.getText(), argument.filterData) == argument.isRegular()) {
+ if (matches(argument.getArgument(), stack, hashExact, argument.getText(), argument.filterData) == argument.isRegular()) {
return true;
}
}
@@ -207,18 +216,98 @@ public class Argument<T, R> {
return false;
}
- private static <T, R, Z, B> boolean matches(short argumentIndex, ArgumentType<T, B> argumentType, Mutable<Z> data, EntryStack<?> stack, long hashExact, String filter, R filterData) {
+ private static Long2ObjectMap<Object> getSearchCache(ArgumentType<?, ?> argumentType) {
+ short argumentIndex = (short) argumentType.getIndex();
Long2ObjectMap<Object> map = SEARCH_CACHE.get(argumentIndex);
if (map == null) {
SEARCH_CACHE.put(argumentIndex, map = Long2ObjectMaps.synchronize(new Long2ObjectOpenHashMap<>()));
}
- Z value = (Z) map.get(hashExact);
- data.setValue(value);
- boolean matches = argumentType.matches((Mutable<B>) data, stack, filter, (T) filterData);
+ return map;
+ }
+
+ private static <T, R, B> boolean matches(ArgumentType<T, B> argumentType, EntryStack<?> stack, long hashExact, String filter, R filterData) {
+ Long2ObjectMap<Object> map = getSearchCache(argumentType);
+ B value = (B) map.get(hashExact);
if (value == null) {
- map.put(hashExact, data.getValue());
+ value = argumentType.cacheData(stack);
+ map.put(hashExact, value);
}
- return matches;
+ return argumentType.matches(value, stack, filter, (T) filterData);
+ }
+
+ public static Long prepareStart = null;
+ public static Collection<EntryStack<?>> prepareStacks = null;
+ public static IntIntPair prepareStage = null;
+ public static IntIntPair[] currentStages = null;
+
+ public static void prepareFilter(Collection<EntryStack<?>> stacks, Collection<ArgumentType<?, ?>> argumentTypes) {
+ if (prepareStage != null || currentStages != null) return;
+ prepareStart = Util.getEpochMillis();
+ prepareStacks = stacks;
+ prepareStage = new IntIntMutablePair(0, argumentTypes.size());
+ currentStages = new IntIntPair[argumentTypes.size()];
+ List<HashedEntryStackWrapper> hashedStacks = CollectionUtils.map(stacks, HashedEntryStackWrapper::new);
+ int searchPartitionSize = ConfigObject.getInstance().getAsyncSearchPartitionSize();
+ boolean async = ConfigObject.getInstance().shouldAsyncSearch() && stacks.size() > searchPartitionSize * 4;
+ List<CompletableFuture<Long2ObjectMap<Object>>> futures = Lists.newArrayList();
+ List<Pair<ArgumentType<?, ?>, CompletableFuture<Long2ObjectMap<Object>>>> pairs = Lists.newArrayList();
+
+ for (ArgumentType<?, ?> argumentType : argumentTypes) {
+ prepareStage.first(prepareStage.firstInt() + 1);
+ Long2ObjectMap<Object> map = getSearchCache(argumentType);
+ IntIntPair currentStage = currentStages[prepareStage.firstInt() - 1] = new IntIntMutablePair(0, hashedStacks.size());
+
+ if (async) {
+ for (Collection<HashedEntryStackWrapper> partitionStacks : CollectionUtils.partition(hashedStacks, searchPartitionSize)) {
+ CompletableFuture<Long2ObjectMap<Object>> future = CompletableFuture.supplyAsync(() -> {
+ Long2ObjectMap<Object> out = new Long2ObjectArrayMap<>(searchPartitionSize + 1);
+ for (HashedEntryStackWrapper stack : partitionStacks) {
+ if (map.get(stack.hashExact()) == null) {
+ Object data = argumentType.cacheData(stack.unwrap());
+
+ if (data != null) {
+ out.put(stack.hashExact(), data);
+ }
+ }
+ }
+ return out;
+ }).whenComplete((objectLong2ObjectMap, throwable) -> {
+ currentStage.first(currentStage.firstInt() + partitionStacks.size());
+ });
+ futures.add(future);
+ pairs.add(Pair.of(argumentType, future));
+ }
+ } else {
+ for (HashedEntryStackWrapper stack : hashedStacks) {
+ currentStage.first(currentStage.firstInt() + 1);
+
+ if (map.get(stack.hashExact()) == null) {
+ Object data = argumentType.cacheData(stack.unwrap());
+
+ if (data != null) {
+ map.put(stack.hashExact(), data);
+ }
+ }
+ }
+ }
+ }
+
+ if (async) {
+ try {
+ CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).get(10, TimeUnit.SECONDS);
+ } catch (InterruptedException | ExecutionException | TimeoutException e) {
+ e.printStackTrace();
+ }
+ for (Pair<ArgumentType<?, ?>, CompletableFuture<Long2ObjectMap<Object>>> pair : pairs) {
+ Long2ObjectMap<Object> now = pair.second().getNow(null);
+ if (now != null) getSearchCache(pair.left()).putAll(now);
+ }
+ }
+
+ prepareStart = null;
+ prepareStacks = null;
+ prepareStage = null;
+ currentStages = null;
}
public ArgumentType<?, ?> getArgument() {
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/type/AlwaysMatchingArgumentType.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/type/AlwaysMatchingArgumentType.java
index 5d498b95e..ee15b8496 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/type/AlwaysMatchingArgumentType.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/type/AlwaysMatchingArgumentType.java
@@ -28,7 +28,6 @@ import me.shedaniel.rei.impl.client.search.result.ArgumentApplicableResult;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.util.Unit;
-import org.apache.commons.lang3.mutable.Mutable;
import org.jetbrains.annotations.ApiStatus;
@ApiStatus.Internal
@@ -42,7 +41,12 @@ public final class AlwaysMatchingArgumentType extends ArgumentType<Unit, Unit> {
}
@Override
- public boolean matches(Mutable<Unit> data, EntryStack<?> stack, String searchText, Unit filterData) {
+ public Unit cacheData(EntryStack<?> stack) {
+ return null;
+ }
+
+ @Override
+ public boolean matches(Unit data, EntryStack<?> stack, String searchText, Unit filterData) {
return true;
}
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/type/ArgumentType.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/type/ArgumentType.java
index f196f8854..7e0e75348 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/type/ArgumentType.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/type/ArgumentType.java
@@ -29,7 +29,6 @@ import me.shedaniel.rei.impl.client.search.result.ArgumentApplicableResult;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.network.chat.Style;
-import org.apache.commons.lang3.mutable.Mutable;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
@@ -83,7 +82,9 @@ public abstract class ArgumentType<T, R> {
return ArgumentApplicableResult.notApplicable();
}
- public abstract boolean matches(Mutable<R> data, EntryStack<?> stack, String searchText, T filterData);
+ public abstract R cacheData(EntryStack<?> stack);
+
+ public abstract boolean matches(R data, EntryStack<?> stack, String searchText, T filterData);
public abstract T prepareSearchFilter(String searchText);
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/type/IdentifierArgumentType.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/type/IdentifierArgumentType.java
index f490cac7a..350f3b6e6 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/type/IdentifierArgumentType.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/type/IdentifierArgumentType.java
@@ -32,7 +32,6 @@ import net.minecraft.network.chat.Style;
import net.minecraft.network.chat.TextColor;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.Unit;
-import org.apache.commons.lang3.mutable.Mutable;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
@@ -65,21 +64,19 @@ public final class IdentifierArgumentType extends ArgumentType<Unit, String> {
}
@Override
- public boolean matches(Mutable<String> data, EntryStack<?> stack, String searchText, Unit filterData) {
- if (data.getValue() == null) {
- ResourceLocation identifier = stack.getIdentifier();
- if (identifier == null) {
- data.setValue(EMPTY);
- } else {
- String s = identifier.getPath();
- if (s.isEmpty()) {
- data.setValue(EMPTY);
- } else {
- data.setValue(s);
- }
+ public String cacheData(EntryStack<?> stack) {
+ ResourceLocation identifier = stack.getIdentifier();
+ if (identifier != null) {
+ String s = identifier.getPath();
+ if (!s.isEmpty()) {
+ return s;
}
}
- String identifier = data.getValue();
+ return EMPTY;
+ }
+
+ @Override
+ public boolean matches(String identifier, EntryStack<?> stack, String searchText, Unit filterData) {
return !identifier.isEmpty() && identifier.contains(searchText);
}
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/type/ModArgumentType.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/type/ModArgumentType.java
index 458b5156b..06e8d35fc 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/type/ModArgumentType.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument