diff options
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 |
