aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--forge/build.gradle7
-rw-r--r--runtime-engine/default-runtime-plugin/src/main/java/me/shedaniel/rei/plugin/test/REITestPlugin.java16
-rw-r--r--runtime-engine/entries/src/main/java/me/shedaniel/rei/impl/client/entry/type/EntryRegistryImpl.java6
-rw-r--r--runtime-engine/filtering-entries/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/BasicFilteringRuleImpl.java9
-rw-r--r--runtime-engine/filtering-entries/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/ManualFilteringRule.java10
-rw-r--r--runtime-engine/filtering-entries/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/SearchFilteringRule.java9
-rw-r--r--runtime-engine/menu-info/src/main/java/me/shedaniel/rei/impl/common/transfer/MenuInfoRegistryImpl.java25
-rw-r--r--runtime-engine/search/src/main/java/me/shedaniel/rei/impl/client/search/argument/Argument.java41
-rw-r--r--runtime-engine/search/src/main/java/me/shedaniel/rei/impl/client/search/method/InputMethodRegistryImpl.java2
-rw-r--r--runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/entries/EntryListSearchManager.java22
-rw-r--r--runtime-frontend/overlay/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/dragging/DraggingContextImpl.java4
-rw-r--r--shared-internals/src/main/java/me/shedaniel/rei/impl/client/search/AsyncSearchManager.java190
-rw-r--r--shared-internals/src/main/java/me/shedaniel/rei/impl/client/search/SearchManager.java7
-rw-r--r--shared-internals/src/main/java/me/shedaniel/rei/impl/client/util/ThreadCreator.java64
14 files changed, 300 insertions, 112 deletions
diff --git a/forge/build.gradle b/forge/build.gradle
index 962677d6e..584222009 100644
--- a/forge/build.gradle
+++ b/forge/build.gradle
@@ -49,12 +49,6 @@ processServerComponentResources {
}
loom {
- launches {
- all {
- arg "--mixin", "rei-jei-internals-workaround.mixins.json"
- }
- }
-
forge {
mixinConfig "rei.mixins.json"
}
@@ -70,6 +64,7 @@ dependencies {
shadowCommon(project(path: it, configuration: "transformProductionForge")) { transitive false }
}
+ modRuntime("curse.maven:lazy-dfu-forge-460819:3544496")
// modRuntime("curse.maven:chiselsbits-231095:3492889")
// modRuntime("curse.maven:jumbofurnace-390880:3120970")
// modRuntime("curse.maven:cyclic-239286:3221427")
diff --git a/runtime-engine/default-runtime-plugin/src/main/java/me/shedaniel/rei/plugin/test/REITestPlugin.java b/runtime-engine/default-runtime-plugin/src/main/java/me/shedaniel/rei/plugin/test/REITestPlugin.java
index 7eed62ba2..6ed68874e 100644
--- a/runtime-engine/default-runtime-plugin/src/main/java/me/shedaniel/rei/plugin/test/REITestPlugin.java
+++ b/runtime-engine/default-runtime-plugin/src/main/java/me/shedaniel/rei/plugin/test/REITestPlugin.java
@@ -27,9 +27,11 @@ import com.google.common.collect.ImmutableList;
import me.shedaniel.rei.api.client.favorites.FavoriteEntry;
import me.shedaniel.rei.api.client.favorites.FavoriteEntryType;
import me.shedaniel.rei.api.client.plugins.REIClientPlugin;
+import me.shedaniel.rei.api.client.registry.entry.CollapsibleEntryRegistry;
import me.shedaniel.rei.api.client.registry.entry.EntryRegistry;
import me.shedaniel.rei.api.common.entry.EntryStack;
import me.shedaniel.rei.api.common.entry.comparison.ItemComparatorRegistry;
+import me.shedaniel.rei.api.common.entry.type.VanillaEntryTypes;
import me.shedaniel.rei.api.common.plugins.PluginManager;
import me.shedaniel.rei.api.common.registry.ReloadStage;
import me.shedaniel.rei.api.common.util.EntryStacks;
@@ -39,6 +41,7 @@ import net.fabricmc.api.Environment;
import net.minecraft.client.Minecraft;
import net.minecraft.core.Registry;
import net.minecraft.nbt.CompoundTag;
+import net.minecraft.network.chat.TextComponent;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
@@ -61,7 +64,7 @@ public class REITestPlugin implements REIClientPlugin {
@Override
public void registerEntries(EntryRegistry registry) {
- int times = 100;
+ int times = 10;
for (Item item : Registry.ITEM) {
EntryStack<ItemStack> base = EntryStacks.of(item);
registry.addEntriesAfter(base, IntStream.range(0, times).mapToObj(value -> transformStack(EntryStacks.of(item))).collect(Collectors.toList()));
@@ -75,6 +78,17 @@ public class REITestPlugin implements REIClientPlugin {
}
@Override
+ public void registerCollapsibleEntries(CollapsibleEntryRegistry registry) {
+ int i = 0;
+ for (Item item : Registry.ITEM) {
+ if (i++ % 10 != 0)
+ continue;
+ registry.group(Registry.ITEM.getKey(item), new TextComponent(Registry.ITEM.getKey(item).toString()),
+ stack -> stack.getType() == VanillaEntryTypes.ITEM && stack.<ItemStack>castValue().is(item));
+ }
+ }
+
+ @Override
public void registerItemComparators(ItemComparatorRegistry registry) {
registry.registerNbt(Registry.ITEM.stream().toArray(Item[]::new));
}
diff --git a/runtime-engine/entries/src/main/java/me/shedaniel/rei/impl/client/entry/type/EntryRegistryImpl.java b/runtime-engine/entries/src/main/java/me/shedaniel/rei/impl/client/entry/type/EntryRegistryImpl.java
index 266dfd47d..6b59b2418 100644
--- a/runtime-engine/entries/src/main/java/me/shedaniel/rei/impl/client/entry/type/EntryRegistryImpl.java
+++ b/runtime-engine/entries/src/main/java/me/shedaniel/rei/impl/client/entry/type/EntryRegistryImpl.java
@@ -192,7 +192,11 @@ public class EntryRegistryImpl implements EntryRegistry {
if (afterEntry != null) {
int index = registryList.lastIndexOf(afterEntry);
- registryList.addAll(index, filtered, hashes);
+ if (index != -1) {
+ registryList.addAll(index, filtered, hashes);
+ } else {
+ registryList.addAll(filtered, hashes);
+ }
} else registryList.addAll(filtered, hashes);
for (EntryRegistryListener listener : listeners) {
diff --git a/runtime-engine/filtering-entries/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/BasicFilteringRuleImpl.java b/runtime-engine/filtering-entries/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/BasicFilteringRuleImpl.java
index a1a8b7558..1d51eb0f2 100644
--- a/runtime-engine/filtering-entries/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/BasicFilteringRuleImpl.java
+++ b/runtime-engine/filtering-entries/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/BasicFilteringRuleImpl.java
@@ -34,19 +34,18 @@ 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.CompletableFuture;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
+import java.util.concurrent.*;
import java.util.stream.Collectors;
public enum BasicFilteringRuleImpl implements BasicFilteringRule<Pair<LongSet, LongSet>> {
INSTANCE;
+ private static final ExecutorService EXECUTOR_SERVICE = new ThreadCreator("REI-BasicFiltering").asService();
private final List<EntryStack<?>> hidden = new ArrayList<>(), shown = new ArrayList<>();
@Override
@@ -73,7 +72,7 @@ public enum BasicFilteringRuleImpl implements BasicFilteringRule<Pair<LongSet, L
}
}
return output;
- }));
+ }, EXECUTOR_SERVICE));
}
try {
CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[0])).get(5, TimeUnit.MINUTES);
diff --git a/runtime-engine/filtering-entries/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/ManualFilteringRule.java b/runtime-engine/filtering-entries/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/ManualFilteringRule.java
index dcc1c9500..b7e06da86 100644
--- a/runtime-engine/filtering-entries/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/ManualFilteringRule.java
+++ b/runtime-engine/filtering-entries/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/ManualFilteringRule.java
@@ -32,16 +32,16 @@ import me.shedaniel.rei.api.client.entry.filtering.*;
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.util.ThreadCreator;
import java.util.Collection;
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.stream.Collectors;
public class ManualFilteringRule implements FilteringRule<LongSet> {
+ private static final ExecutorService EXECUTOR_SERVICE = new ThreadCreator("REI-ManualFiltering").asService();
+
@Override
public FilteringRuleType<? extends FilteringRule<LongSet>> getType() {
return ManualFilteringRuleType.INSTANCE;
@@ -61,7 +61,7 @@ public class ManualFilteringRule implements FilteringRule<LongSet> {
}
}
return output;
- }));
+ }, EXECUTOR_SERVICE));
}
try {
CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[0])).get(5, TimeUnit.MINUTES);
diff --git a/runtime-engine/filtering-entries/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/SearchFilteringRule.java b/runtime-engine/filtering-entries/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/SearchFilteringRule.java
index 9ab987936..035f0f868 100644
--- a/runtime-engine/filtering-entries/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/SearchFilteringRule.java
+++ b/runtime-engine/filtering-entries/src/main/java/me/shedaniel/rei/impl/client/entry/filtering/rules/SearchFilteringRule.java
@@ -30,6 +30,7 @@ import me.shedaniel.rei.api.client.entry.filtering.*;
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.util.ThreadCreator;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.util.StringUtil;
@@ -37,13 +38,11 @@ import net.minecraft.util.Unit;
import java.util.Collection;
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.Supplier;
public class SearchFilteringRule implements FilteringRule<Unit> {
+ private static final ExecutorService EXECUTOR_SERVICE = new ThreadCreator("REI-SearchFiltering").asService();
String filterStr;
Supplier<SearchFilter> filter;
boolean show;
@@ -101,7 +100,7 @@ public class SearchFilteringRule implements FilteringRule<Unit> {
}
}
return output;
- }));
+ }, EXECUTOR_SERVICE));
}
}
}
diff --git a/runtime-engine/menu-info/src/main/java/me/shedaniel/rei/impl/common/transfer/MenuInfoRegistryImpl.java b/runtime-engine/menu-info/src/main/java/me/shedaniel/rei/impl/common/transfer/MenuInfoRegistryImpl.java
index dfbf67866..875ce19c3 100644
--- a/runtime-engine/menu-info/src/main/java/me/shedaniel/rei/impl/common/transfer/MenuInfoRegistryImpl.java
+++ b/runtime-engine/menu-info/src/main/java/me/shedaniel/rei/impl/common/transfer/MenuInfoRegistryImpl.java
@@ -32,6 +32,7 @@ import me.shedaniel.rei.api.common.transfer.info.MenuInfo;
import me.shedaniel.rei.api.common.transfer.info.MenuInfoProvider;
import me.shedaniel.rei.api.common.transfer.info.MenuInfoRegistry;
import me.shedaniel.rei.api.common.transfer.info.MenuSerializationContext;
+import me.shedaniel.rei.impl.common.InternalLogger;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.nbt.CompoundTag;
@@ -53,11 +54,28 @@ public class MenuInfoRegistryImpl implements MenuInfoRegistry {
map.computeIfAbsent(category, id -> Maps.newLinkedHashMap())
.computeIfAbsent(menuClass, c -> Lists.newArrayList())
.add(menuInfo);
+ InternalLogger.getInstance().debug("Added menu info for %s [%s]: %s", menuClass, category, menuInfo);
}
@Override
public <D extends Display> void registerGeneric(Predicate<CategoryIdentifier<?>> categoryPredicate, MenuInfoProvider<?, D> menuInfo) {
- mapGeneric.computeIfAbsent(categoryPredicate, id -> Lists.newArrayList()).add(menuInfo);
+ mapGeneric.computeIfAbsent(new Predicate<>() {
+ @Override
+ public boolean test(CategoryIdentifier<?> categoryIdentifier) {
+ return categoryPredicate.test(categoryIdentifier);
+ }
+
+ @Override
+ public int hashCode() {
+ return System.identityHashCode(this);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return this == obj;
+ }
+ }, id -> Lists.newArrayList()).add(menuInfo);
+ InternalLogger.getInstance().debug("Added generic menu info for: %s", menuInfo);
}
@Override
@@ -122,6 +140,11 @@ public class MenuInfoRegistryImpl implements MenuInfoRegistry {
}
@Override
+ public void endReload() {
+ InternalLogger.getInstance().debug("Registered %d menu infos", infoSize());
+ }
+
+ @Override
public void acceptPlugin(REIServerPlugin plugin) {
plugin.registerMenuInfo(this);
}
diff --git a/runtime-engine/search/src/main/java/me/shedaniel/rei/impl/client/search/argument/Argument.java b/runtime-engine/search/src/main/java/me/shedaniel/rei/impl/client/search/argument/Argument.java
index 8724af7d1..d4bd7b6e1 100644
--- a/runtime-engine/search/src/main/java/me/shedaniel/rei/impl/client/search/argument/Argument.java
+++ b/runtime-engine/search/src/main/java/me/shedaniel/rei/impl/client/search/argument/Argument.java
@@ -47,6 +47,8 @@ import me.shedaniel.rei.api.common.util.EntryStacks;
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.client.util.ThreadCreator;
+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;
@@ -60,10 +62,7 @@ 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.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -71,6 +70,7 @@ import java.util.regex.Pattern;
@ApiStatus.Internal
@Environment(EnvType.CLIENT)
public class Argument<T, R> {
+ private static final ExecutorService EXECUTOR_SERVICE = new ThreadCreator("REI-ArgumentCache").asService();
public static final Short2ObjectMap<Long2ObjectMap<Object>> SEARCH_CACHE = Short2ObjectMaps.synchronize(new Short2ObjectOpenHashMap<>());
private static final Object NO_CACHE = new Object();
private static final AtomicReference<String> lastLanguage = new AtomicReference<>();
@@ -264,7 +264,7 @@ public class Argument<T, R> {
}
public static Long prepareStart = null;
- public static Collection<EntryStack<?>> prepareStacks = null;
+ public static List<HashedEntryStackWrapper> prepareStacks = null;
public static IntIntPair prepareStage = null;
public static IntIntPair[] currentStages = null;
@@ -272,22 +272,34 @@ public class Argument<T, R> {
if (prepareStage != null || currentStages != null) return;
try {
prepareStart = Util.getEpochMillis();
- prepareStacks = stacks;
+ Long2ObjectMap<Object>[] caches = CollectionUtils.map(argumentTypes, Argument::getSearchCache).toArray(Long2ObjectMap[]::new);
+ prepareStacks = CollectionUtils.mapAndFilter(stacks, stack -> {
+ for (Long2ObjectMap<Object> cache : caches) {
+ if (!cache.containsKey(stack.hashExact())) {
+ return true;
+ }
+ }
+
+ return false;
+ }, HashedEntryStackWrapper::new);
+ if (prepareStacks.isEmpty()) {
+ return;
+ }
+ InternalLogger.getInstance().trace("Preparing " + prepareStacks.size() + " stacks for search arguments");
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;
+ boolean async = ConfigObject.getInstance().shouldAsyncSearch() && prepareStacks.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());
+ IntIntPair currentStage = currentStages[prepareStage.firstInt() - 1] = new IntIntMutablePair(0, prepareStacks.size());
if (async) {
- for (Collection<HashedEntryStackWrapper> partitionStacks : CollectionUtils.partition(hashedStacks, searchPartitionSize)) {
+ for (Collection<HashedEntryStackWrapper> partitionStacks : CollectionUtils.partition(prepareStacks, searchPartitionSize)) {
CompletableFuture<Long2ObjectMap<Object>> future = CompletableFuture.supplyAsync(() -> {
Long2ObjectMap<Object> out = new Long2ObjectArrayMap<>(searchPartitionSize + 1);
for (HashedEntryStackWrapper stack : partitionStacks) {
@@ -300,14 +312,14 @@ public class Argument<T, R> {
}
}
return out;
- }).whenComplete((objectLong2ObjectMap, throwable) -> {
+ }, EXECUTOR_SERVICE).whenComplete((objectLong2ObjectMap, throwable) -> {
currentStage.first(currentStage.firstInt() + partitionStacks.size());
});
futures.add(future);
pairs.add(Pair.of(argumentType, future));
}
} else {
- for (HashedEntryStackWrapper stack : hashedStacks) {
+ for (HashedEntryStackWrapper stack : prepareStacks) {
currentStage.first(currentStage.firstInt() + 1);
if (map.get(stack.hashExact()) == null) {
@@ -324,14 +336,17 @@ public class Argument<T, R> {
if (async) {
try {
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).get(30, TimeUnit.SECONDS);
- } catch (InterruptedException | ExecutionException | TimeoutException e) {
+ } catch (ExecutionException | TimeoutException e) {
e.printStackTrace();
+ } catch (InterruptedException ignore) {
}
for (Pair<ArgumentType<?, ?>, CompletableFuture<Long2ObjectMap<Object>>> pair : pairs) {
Long2ObjectMap<Object> now = pair.second().getNow(null);
if (now != null) getSearchCache(pair.left()).putAll(now);
}
}
+
+ InternalLogger.getInstance().debug("Prepared " + prepareStacks.size() + " stacks for search arguments in " + (Util.getEpochMillis() - prepareStart) + "ms");
} finally {
prepareStart = null;
prepareStacks = null;
diff --git a/runtime-engine/search/src/main/java/me/shedaniel/rei/impl/client/search/method/InputMethodRegistryImpl.java b/runtime-engine/search/src/main/java/me/shedaniel/rei/impl/client/search/method/InputMethodRegistryImpl.java
index 532792d8e..0a04608be 100644
--- a/runtime-engine/search/src/main/java/me/shedaniel/rei/impl/client/search/method/InputMethodRegistryImpl.java
+++ b/runtime-engine/search/src/main/java/me/shedaniel/rei/impl/client/search/method/InputMethodRegistryImpl.java
@@ -99,7 +99,7 @@ public class InputMethodRegistryImpl implements InputMethodRegistry {
}).join();
service.shutdown();
- InternalLogger.getInstance().debug("Registered %d input methods: ", inputMethods.size(),
+ InternalLogger.getInstance().debug("Registered %d input methods: %s", inputMethods.size(),
inputMethods.values().stream().map(inputMethod -> inputMethod.getName().getString()).collect(Collectors.joining(", ")));
}
diff --git a/runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/entries/EntryListSearchManager.java b/runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/entries/EntryListSearchManager.java
index 2be121ddf..da2ab2eaf 100644
--- a/runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/entries/EntryListSearchManager.java
+++ b/runtime-frontend/overlay-entries/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/entries/EntryListSearchManager.java
@@ -32,7 +32,6 @@ import me.shedaniel.rei.api.client.gui.config.EntryPanelOrdering;
import me.shedaniel.rei.api.client.registry.entry.CollapsibleEntry;
import me.shedaniel.rei.api.client.registry.entry.CollapsibleEntryRegistry;
import me.shedaniel.rei.api.client.registry.entry.EntryRegistry;
-import me.shedaniel.rei.api.client.search.SearchFilter;
import me.shedaniel.rei.api.client.view.Views;
import me.shedaniel.rei.api.common.entry.EntryStack;
import me.shedaniel.rei.api.common.entry.type.VanillaEntryTypes;
@@ -47,6 +46,7 @@ import org.apache.logging.log4j.Level;
import org.jetbrains.annotations.Nullable;
import java.util.*;
+import java.util.function.BooleanSupplier;
import java.util.function.Consumer;
public class EntryListSearchManager {
@@ -78,12 +78,16 @@ public class EntryListSearchManager {
if (ignoreLastSearch) searchManager.markDirty();
searchManager.updateFilter(searchTerm);
if (searchManager.isDirty()) {
- searchManager.getAsync(list -> {
- List</*EntryStack<?> | CollapsedStack*/ Object> finalList = collapse(copyAndOrder(list));
+ searchManager.getAsync((list, filter) -> {
+ if (!filter.getFilter().equals(searchTerm)) return;
+ if (searchManager.getSearchFilter() == null || searchManager.getSearchFilter() != 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.getSearchFilter() != null && searchManager.getSearchFilter() == filter);
- InternalLogger.getInstance().log(ConfigObject.getInstance().doDebugSearchTimeRequired() ? Level.INFO : Level.TRACE, "Search Used: %s", stopwatch.stop().toString());
+ 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().executeBlocking(() -> {
+ Minecraft.getInstance().submit(() -> {
+ if (searchManager.getSearchFilter() == null || searchManager.getSearchFilter() != filter) return;
update.accept(finalList);
});
});
@@ -104,7 +108,7 @@ public class EntryListSearchManager {
return list;
}
- private List</*EntryStack<?> | CollapsedStack*/ Object> collapse(List<EntryStack<?>> stacks) {
+ private List</*EntryStack<?> | CollapsedStack*/ Object> collapse(List<EntryStack<?>> stacks, BooleanSupplier isValid) {
CollapsibleEntryRegistry collapsibleRegistry = CollapsibleEntryRegistry.getInstance();
Map<CollapsibleEntry, @Nullable CollapsedStack> entries = new HashMap<>();
@@ -112,8 +116,12 @@ public class EntryListSearchManager {
entries.put(entry, null);
}
+ if (!isValid.getAsBoolean()) return List.of();
+
List</*EntryStack<?> | CollapsedStack*/ Object> list = new ArrayList<>();
+ int i = 0;
+
for (EntryStack<?> stack : stacks) {
long hashExact = EntryStacks.hashExact(stack);
boolean matchedAny = false;
@@ -138,6 +146,8 @@ public class EntryListSearchManager {
}
}
+ if (i++ % 50 == 0 && !isValid.getAsBoolean()) return List.of();
+
if (!matchedAny) {
list.add(stack);
}
diff --git a/runtime-frontend/overlay/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/dragging/DraggingContextImpl.java b/runtime-frontend/overlay/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/dragging/DraggingContextImpl.java
index e041e4daf..3e579a207 100644
--- a/runtime-frontend/overlay/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/dragging/DraggingContextImpl.java
+++ b/runtime-frontend/overlay/src/main/java/me/shedaniel/rei/impl/client/gui/overlay/dragging/DraggingContextImpl.java
@@ -166,6 +166,10 @@ public class DraggingContextImpl extends Widget implements DraggingContext<Scree
@Override
public boolean mouseReleased(double d, double e, int i) {
+ if (i != 0) {
+ return false;
+ }
+ drop();
return false;
}
diff --git a/shared-internals/src/main/java/me/shedaniel/rei/impl/client/search/AsyncSearchManager.java b/shared-internals/src/main/java/me/shedaniel/rei/impl/client/search/AsyncSearchManager.java
index 0fb426a34..442fda91c 100644
--- a/shared-internals/src/main/java/me/shedaniel/rei/impl/client/search/AsyncSearchManager.java
+++ b/shared-internals/src/main/java/me/shedaniel/rei/impl/client/search/AsyncSearchManager.java
@@ -24,31 +24,33 @@
package me.shedaniel.rei.impl.client.search;
import com.google.common.collect.Lists;
+import dev.architectury.platform.Platform;
import me.shedaniel.rei.api.client.config.ConfigObject;
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.util.ThreadCreator;
import org.jetbrains.annotations.Nullable;
+import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
import java.util.concurrent.*;
-import java.util.function.Consumer;
+import java.util.function.BiConsumer;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.function.UnaryOperator;
public class AsyncSearchManager implements SearchManager {
+ 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 Predicate<EntryStack<?>> additionalPredicate;
+ private ExecutorTuple executor;
private SearchFilter filter;
- private boolean dirty = false;
- private boolean filterDirty = false;
- private CompletableFuture<List<EntryStack<?>>> future;
- private List<EntryStack<?>> last;
+ private Map.Entry<List<EntryStack<?>>, SearchFilter> last;
public AsyncSearchManager(Supplier<List<EntryStack<?>>> stacksProvider, Supplier<Predicate<EntryStack<?>>> additionalPredicateSupplier, UnaryOperator<EntryStack<?>> transformer) {
this.stacksProvider = stacksProvider;
@@ -58,95 +60,157 @@ public class AsyncSearchManager implements SearchManager {
@Override
public void markDirty() {
- this.dirty = true;
+ synchronized (AsyncSearchManager.this) {
+ this.last = null;
+ }
}
- @Override
- public void markFilterDirty() {
- this.filterDirty = true;
+ private record ExecutorTuple(SearchFilter filter, CompletableFuture<Map.Entry<List<EntryStack<?>>, SearchFilter>> future) {
}
@Override
public void updateFilter(String filter) {
if (this.filter == null || !this.filter.getFilter().equals(filter)) {
+ if (this.executor != null) {
+ this.executor.future().cancel(Platform.isFabric());
+ }
+ this.executor = null;
this.filter = SearchProvider.getInstance().createFilter(filter);
- markDirty();
- markFilterDirty();
}
}
@Override
public boolean isDirty() {
- return last == null || dirty;
+ synchronized (AsyncSearchManager.this) {
+ return this.last == null || this.last.getValue() != this.filter;
+ }
}
@Override
- public boolean isFilterDirty() {
- return filterDirty;
+ public Future<?> getAsync(BiConsumer<List<EntryStack<?>>, SearchFilter> consumer) {
+ if (this.executor == null || this.executor.filter() != filter) {
+ if (this.executor != null) {
+ this.executor.future().cancel(Platform.isFabric());
+ }
+ this.executor = new ExecutorTuple(filter, get(EXECUTOR_SERVICE));
+ }
+ SearchFilter savedFilter = filter;
+ return (this.executor = new ExecutorTuple(this.executor.filter(), this.executor.future().thenApplyAsync(result -> {
+ if (savedFilter == filter) {
+ consumer.accept(result.getKey(), result.getValue());
+ }
+
+ return result;
+ }, EXECUTOR_SERVICE))).future();
}
@Override
- 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)
- .exceptionally(throwable -> {
- throwable.printStackTrace();
- return null;
- });
+ public List<EntryStack<?>> get() {
+ return getNow();
+ }
+
+ public List<EntryStack<?>> getNow() {
+ try {
+ return get(Runnable::run).get().getKey();
+ } catch (ExecutionException e) {
+ throw new RuntimeException(e);
+ } catch (InterruptedException | CancellationException e) {
+ return Lists.newArrayList();
}
- return future.thenAccept(consumer);
}
- @Override
- public List<EntryStack<?>> get() {
+ public CompletableFuture<Map.Entry<List<EntryStack<?>>, SearchFilter>> get(Executor executor) {
if (isDirty()) {
- this.additionalPredicate = additionalPredicateSupplier.get();
- int searchPartitionSize = ConfigObject.getInstance().getAsyncSearchPartitionSize();
- List<EntryStack<?>> stacks = stacksProvider.get();
- last = new ArrayList<>();
+ Map.Entry<List<EntryStack<?>>, SearchFilter> last;
+ synchronized (AsyncSearchManager.this)