diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/lazy_search_tree_registry/SearchRegistryMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/lazy_search_tree_registry/SearchRegistryMixin.java new file mode 100644 index 00000000..b9ab980f --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/lazy_search_tree_registry/SearchRegistryMixin.java @@ -0,0 +1,17 @@ +package org.embeddedt.modernfix.common.mixin.perf.lazy_search_tree_registry; + +import net.minecraft.client.searchtree.SearchRegistry; +import org.embeddedt.modernfix.annotation.ClientOnlyMixin; +import org.embeddedt.modernfix.searchtree.LazySearchTree; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyVariable; + +@Mixin(SearchRegistry.class) +@ClientOnlyMixin +public class SearchRegistryMixin { + @ModifyVariable(method = "register", at = @At("HEAD"), ordinal = 0, argsOnly = true) + private SearchRegistry.TreeBuilderSupplier useLazyBuilder(SearchRegistry.TreeBuilderSupplier supplier) { + return LazySearchTree.decorate(supplier); + } +} diff --git a/common/src/main/java/org/embeddedt/modernfix/searchtree/LazySearchTree.java b/common/src/main/java/org/embeddedt/modernfix/searchtree/LazySearchTree.java new file mode 100644 index 00000000..af54daa8 --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/searchtree/LazySearchTree.java @@ -0,0 +1,60 @@ +package org.embeddedt.modernfix.searchtree; + +import com.google.common.base.Stopwatch; +import net.minecraft.client.searchtree.RefreshableSearchTree; +import net.minecraft.client.searchtree.SearchRegistry; +import org.embeddedt.modernfix.ModernFix; + +import java.util.List; +import java.util.function.Function; + +public class LazySearchTree implements RefreshableSearchTree { + private final List contents; + private final Function, RefreshableSearchTree> treeBuilder; + + private volatile RefreshableSearchTree realTree; + + public LazySearchTree(List contents, Function, RefreshableSearchTree> treeBuilder) { + this.contents = contents; + this.treeBuilder = treeBuilder; + } + + private RefreshableSearchTree getRealTree() { + var t = realTree; + if (t == null) { + synchronized (this) { + t = realTree; + if (t == null) { + ModernFix.LOGGER.info("Building search tree for {} items (this may take a while)...", contents.size()); + Stopwatch s = Stopwatch.createStarted(); + t = this.treeBuilder.apply(contents); + t.refresh(); + s.stop(); + ModernFix.LOGGER.info("Building search tree for {} items took {}", contents.size(), s); + realTree = t; + } + } + } + return t; + } + + @Override + public List search(String query) { + if (query.isEmpty()) { + return this.contents; + } + return getRealTree().search(query); + } + + @Override + public void refresh() { + var t = this.realTree; + if (t != null) { + t.refresh(); + } + } + + public static SearchRegistry.TreeBuilderSupplier decorate(SearchRegistry.TreeBuilderSupplier originalSupplier) { + return list -> new LazySearchTree<>(list, originalSupplier); + } +} diff --git a/common/src/main/resources/modernfix.accesswidener b/common/src/main/resources/modernfix.accesswidener index 225fee71..05d46ae1 100644 --- a/common/src/main/resources/modernfix.accesswidener +++ b/common/src/main/resources/modernfix.accesswidener @@ -63,4 +63,5 @@ accessible field net/minecraft/client/renderer/entity/EnderDragonRenderer$Dragon accessible method net/minecraft/world/level/block/state/StateDefinition appendPropertyCodec (Lcom/mojang/serialization/MapCodec;Ljava/util/function/Supplier;Ljava/lang/String;Lnet/minecraft/world/level/block/state/properties/Property;)Lcom/mojang/serialization/MapCodec; accessible class net/minecraft/world/item/crafting/Ingredient$Value -accessible class net/minecraft/world/item/crafting/Ingredient$ItemValue \ No newline at end of file +accessible class net/minecraft/world/item/crafting/Ingredient$ItemValue +accessible class net/minecraft/client/searchtree/SearchRegistry$TreeEntry \ No newline at end of file