diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/blast_search_trees/MinecraftMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/blast_search_trees/MinecraftMixin.java index 02443ba0..ebdff6e4 100644 --- a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/blast_search_trees/MinecraftMixin.java +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/blast_search_trees/MinecraftMixin.java @@ -5,7 +5,7 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.searchtree.SearchRegistry; import org.embeddedt.modernfix.ModernFix; import org.embeddedt.modernfix.annotation.ClientOnlyMixin; -import org.embeddedt.modernfix.searchtree.DummySearchTree; +import org.embeddedt.modernfix.searchtree.RecipeBookSearchTree; import org.embeddedt.modernfix.searchtree.SearchTreeProviderRegistry; import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFWErrorCallback; @@ -29,7 +29,7 @@ public class MinecraftMixin { ModernFix.LOGGER.info("Replacing search trees with '{}' provider", provider.getName()); this.searchRegistry.register(SearchRegistry.CREATIVE_NAMES, list -> provider.getSearchTree(false)); this.searchRegistry.register(SearchRegistry.CREATIVE_TAGS, list -> provider.getSearchTree(true)); - this.searchRegistry.register(SearchRegistry.RECIPE_COLLECTIONS, list -> new DummySearchTree<>()); + this.searchRegistry.register(SearchRegistry.RECIPE_COLLECTIONS, list -> new RecipeBookSearchTree(provider.getSearchTree(false))); // grab components for all key mappings in order to prevent them from being loaded off-thread later // this populates the LazyLoadedValues // we also need to suppress GLFW errors to prevent crashes if a key is missing diff --git a/common/src/main/java/org/embeddedt/modernfix/searchtree/RecipeBookSearchTree.java b/common/src/main/java/org/embeddedt/modernfix/searchtree/RecipeBookSearchTree.java new file mode 100644 index 00000000..f4bf16b4 --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/searchtree/RecipeBookSearchTree.java @@ -0,0 +1,64 @@ +package org.embeddedt.modernfix.searchtree; + +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import net.minecraft.client.gui.screens.recipebook.RecipeCollection; +import net.minecraft.client.searchtree.SearchTree; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class RecipeBookSearchTree extends DummySearchTree { + private final SearchTree stackCollector; + private Map> collectionsByItem = null; + private final List allCollections = new ArrayList<>(); + + public RecipeBookSearchTree(SearchTree stackCollector) { + this.stackCollector = stackCollector; + } + + private Map> populateCollectionMap() { + Map> collections = this.collectionsByItem; + if(collections == null) { + collections = new Object2ObjectOpenHashMap<>(); + Map> finalCollection = collections; + for(RecipeCollection collection : allCollections) { + collection.getRecipes().stream().map(recipe -> recipe.getResultItem().getItem()).distinct().forEach(item -> { + finalCollection.computeIfAbsent(item, k -> new ArrayList<>()).add(collection); + }); + } + this.collectionsByItem = collections; + } + return collections; + } + + @Override + public void add(RecipeCollection pObj) { + this.allCollections.add(pObj); + } + + @Override + public void clear() { + this.allCollections.clear(); + } + + @Override + public void refresh() { + this.collectionsByItem = null; + } + + @Override + public List search(String pSearchText) { + // Avoid constructing the recipe collection map until the first real search + if(pSearchText.trim().length() == 0) { + return this.allCollections; + } + List stacks = stackCollector.search(pSearchText); + Map> collections = this.populateCollectionMap(); + return stacks.stream().map(ItemStack::getItem).distinct().flatMap(item -> collections.getOrDefault(item, Collections.emptyList()).stream()).collect(Collectors.toList()); + } +}