Remove blast_search_trees
This commit is contained in:
parent
d46d24542f
commit
85740f83af
|
|
@ -6,8 +6,6 @@ architectury {
|
||||||
common(rootProject.enabled_platforms.split(","))
|
common(rootProject.enabled_platforms.split(","))
|
||||||
}
|
}
|
||||||
|
|
||||||
ext.jei_minecraft_version = "1.20.2" /* temporary, till 1.20 releases */
|
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
// We depend on fabric loader here to use the fabric @Environment annotations and get the mixin dependencies
|
// We depend on fabric loader here to use the fabric @Environment annotations and get the mixin dependencies
|
||||||
// Do NOT use other classes from fabric loader
|
// Do NOT use other classes from fabric loader
|
||||||
|
|
@ -20,18 +18,8 @@ dependencies {
|
||||||
modApi("dev.latvian.mods:rhino:${rhino_version}") {
|
modApi("dev.latvian.mods:rhino:${rhino_version}") {
|
||||||
transitive = false
|
transitive = false
|
||||||
}
|
}
|
||||||
modApi("me.shedaniel:RoughlyEnoughItems-api:${rei_version}") {
|
|
||||||
transitive = false
|
|
||||||
}
|
|
||||||
modCompileOnly("me.shedaniel:RoughlyEnoughItems-fabric:${rei_version}") {
|
|
||||||
transitive = false
|
|
||||||
}
|
|
||||||
|
|
||||||
modCompileOnly "curse.maven:spark-361579:${rootProject.spark_version}"
|
modCompileOnly "curse.maven:spark-361579:${rootProject.spark_version}"
|
||||||
// compile against the JEI API but do not include it at runtime
|
|
||||||
modCompileOnly("mezz.jei:jei-${jei_minecraft_version}-common:${jei_version}")
|
|
||||||
modCompileOnly("mezz.jei:jei-${jei_minecraft_version}-gui:${jei_version}")
|
|
||||||
modCompileOnly("mezz.jei:jei-${jei_minecraft_version}-lib:${jei_version}")
|
|
||||||
// Remove the next line if you don't want to depend on the API
|
// Remove the next line if you don't want to depend on the API
|
||||||
// modApi "me.shedaniel:architectury:${rootProject.architectury_version}"
|
// modApi "me.shedaniel:architectury:${rootProject.architectury_version}"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,9 +9,6 @@ import org.embeddedt.modernfix.api.constants.IntegrationConstants;
|
||||||
import org.embeddedt.modernfix.api.entrypoint.ModernFixClientIntegration;
|
import org.embeddedt.modernfix.api.entrypoint.ModernFixClientIntegration;
|
||||||
import org.embeddedt.modernfix.core.ModernFixMixinPlugin;
|
import org.embeddedt.modernfix.core.ModernFixMixinPlugin;
|
||||||
import org.embeddedt.modernfix.platform.ModernFixPlatformHooks;
|
import org.embeddedt.modernfix.platform.ModernFixPlatformHooks;
|
||||||
import org.embeddedt.modernfix.searchtree.JEIBackedSearchTree;
|
|
||||||
import org.embeddedt.modernfix.searchtree.REIBackedSearchTree;
|
|
||||||
import org.embeddedt.modernfix.searchtree.SearchTreeProviderRegistry;
|
|
||||||
import org.embeddedt.modernfix.util.ClassInfoManager;
|
import org.embeddedt.modernfix.util.ClassInfoManager;
|
||||||
import org.embeddedt.modernfix.world.IntegratedWatchdog;
|
import org.embeddedt.modernfix.world.IntegratedWatchdog;
|
||||||
|
|
||||||
|
|
@ -42,8 +39,6 @@ public class ModernFixClient {
|
||||||
if(ModernFixMixinPlugin.instance.isOptionEnabled("feature.branding.F3Screen")) {
|
if(ModernFixMixinPlugin.instance.isOptionEnabled("feature.branding.F3Screen")) {
|
||||||
brandingString = ModernFix.NAME + " " + ModernFixPlatformHooks.INSTANCE.getVersionString();
|
brandingString = ModernFix.NAME + " " + ModernFixPlatformHooks.INSTANCE.getVersionString();
|
||||||
}
|
}
|
||||||
SearchTreeProviderRegistry.register(JEIBackedSearchTree.PROVIDER);
|
|
||||||
SearchTreeProviderRegistry.register(REIBackedSearchTree.PROVIDER);
|
|
||||||
for(String className : ModernFixPlatformHooks.INSTANCE.getCustomModOptions().get(IntegrationConstants.CLIENT_INTEGRATION_CLASS)) {
|
for(String className : ModernFixPlatformHooks.INSTANCE.getCustomModOptions().get(IntegrationConstants.CLIENT_INTEGRATION_CLASS)) {
|
||||||
try {
|
try {
|
||||||
CLIENT_INTEGRATIONS.add((ModernFixClientIntegration)Class.forName(className).getDeclaredConstructor().newInstance());
|
CLIENT_INTEGRATIONS.add((ModernFixClientIntegration)Class.forName(className).getDeclaredConstructor().newInstance());
|
||||||
|
|
|
||||||
|
|
@ -1,94 +0,0 @@
|
||||||
package org.embeddedt.modernfix.common.mixin.perf.blast_search_trees;
|
|
||||||
|
|
||||||
import com.llamalad7.mixinextras.sugar.Local;
|
|
||||||
import net.minecraft.client.ClientRecipeBook;
|
|
||||||
import net.minecraft.client.KeyMapping;
|
|
||||||
import net.minecraft.client.gui.screens.recipebook.RecipeCollection;
|
|
||||||
import net.minecraft.client.multiplayer.SessionSearchTrees;
|
|
||||||
import net.minecraft.client.searchtree.SearchTree;
|
|
||||||
import net.minecraft.world.item.ItemStack;
|
|
||||||
import org.embeddedt.modernfix.ModernFix;
|
|
||||||
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
|
|
||||||
import org.embeddedt.modernfix.searchtree.RecipeBookSearchTree;
|
|
||||||
import org.embeddedt.modernfix.searchtree.SearchTreeProviderRegistry;
|
|
||||||
import org.lwjgl.glfw.GLFW;
|
|
||||||
import org.lwjgl.glfw.GLFWErrorCallback;
|
|
||||||
import org.spongepowered.asm.mixin.Final;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
|
|
||||||
@Mixin(SessionSearchTrees.class)
|
|
||||||
@ClientOnlyMixin
|
|
||||||
public abstract class SessionSearchTreesMixin {
|
|
||||||
@Shadow private CompletableFuture<SearchTree<RecipeCollection>> recipeSearch;
|
|
||||||
@Shadow private CompletableFuture<SearchTree<ItemStack>> creativeByNameSearch;
|
|
||||||
@Shadow @Final private static SessionSearchTrees.Key CREATIVE_NAMES;
|
|
||||||
@Shadow @Final private static SessionSearchTrees.Key CREATIVE_TAGS;
|
|
||||||
private SearchTreeProviderRegistry.Provider mfix$provider;
|
|
||||||
|
|
||||||
@Inject(method = "<init>", at = @At("RETURN"))
|
|
||||||
private void onInit(CallbackInfo ci) {
|
|
||||||
mfix$provider = SearchTreeProviderRegistry.getSearchTreeProvider();
|
|
||||||
if(mfix$provider != null) {
|
|
||||||
ModernFix.LOGGER.info("Replacing search trees with '{}' provider", mfix$provider.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
|
||||||
GLFWErrorCallback oldCb = GLFW.glfwSetErrorCallback(null);
|
|
||||||
for(KeyMapping mapping : KeyMapping.ALL.values()) {
|
|
||||||
mapping.getTranslatedKeyMessage();
|
|
||||||
}
|
|
||||||
GLFW.glfwSetErrorCallback(oldCb);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ModifyArg(method = "updateRecipes", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/multiplayer/SessionSearchTrees;register(Lnet/minecraft/client/multiplayer/SessionSearchTrees$Key;Ljava/lang/Runnable;)V"), index = 1)
|
|
||||||
private Runnable useModernFixRecipeTree(Runnable r, @Local(ordinal = 0, argsOnly = true) ClientRecipeBook clientRecipeBook) {
|
|
||||||
if(mfix$provider == null) {
|
|
||||||
return r;
|
|
||||||
} else {
|
|
||||||
return () -> {
|
|
||||||
List<RecipeCollection> list = clientRecipeBook.getCollections();
|
|
||||||
CompletableFuture<?> old = this.recipeSearch;
|
|
||||||
this.recipeSearch = CompletableFuture.supplyAsync(() -> {
|
|
||||||
return new RecipeBookSearchTree(mfix$provider.getSearchTree(false), list);
|
|
||||||
});
|
|
||||||
old.cancel(true);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ModifyArg(method = "*", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/multiplayer/SessionSearchTrees;register(Lnet/minecraft/client/multiplayer/SessionSearchTrees$Key;Ljava/lang/Runnable;)V"), index = 1)
|
|
||||||
private Runnable useOverridenSearchTreeLogic(SessionSearchTrees.Key key, Runnable r) {
|
|
||||||
if(mfix$provider == null) {
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
if(key == CREATIVE_NAMES) {
|
|
||||||
return () -> {
|
|
||||||
CompletableFuture<?> old = this.creativeByNameSearch;
|
|
||||||
this.creativeByNameSearch = CompletableFuture.supplyAsync(() -> {
|
|
||||||
return mfix$provider.getSearchTree(false);
|
|
||||||
});
|
|
||||||
old.cancel(true);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if(key == CREATIVE_TAGS) {
|
|
||||||
return () -> {
|
|
||||||
CompletableFuture<?> old = this.creativeByNameSearch;
|
|
||||||
this.creativeByNameSearch = CompletableFuture.supplyAsync(() -> {
|
|
||||||
return mfix$provider.getSearchTree(true);
|
|
||||||
});
|
|
||||||
old.cancel(true);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -163,7 +163,6 @@ public class ModernFixEarlyConfig {
|
||||||
.put("mixin.perf.dynamic_resources", false)
|
.put("mixin.perf.dynamic_resources", false)
|
||||||
.put("mixin.feature.direct_stack_trace", false)
|
.put("mixin.feature.direct_stack_trace", false)
|
||||||
.put("mixin.feature.stalled_chunk_load_detection", false)
|
.put("mixin.feature.stalled_chunk_load_detection", false)
|
||||||
.put("mixin.perf.blast_search_trees.force", false)
|
|
||||||
.put("mixin.bugfix.restore_old_dragon_movement", false)
|
.put("mixin.bugfix.restore_old_dragon_movement", false)
|
||||||
.put("mixin.perf.worldgen_allocation", false) // experimental
|
.put("mixin.perf.worldgen_allocation", false) // experimental
|
||||||
.put("mixin.feature.cause_lag_by_disabling_threads", false)
|
.put("mixin.feature.cause_lag_by_disabling_threads", false)
|
||||||
|
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
package org.embeddedt.modernfix.searchtree;
|
|
||||||
|
|
||||||
import net.minecraft.client.searchtree.SearchTree;
|
|
||||||
import net.minecraft.world.item.ItemStack;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dummy search tree that stores nothing and returns nothing on searches.
|
|
||||||
*/
|
|
||||||
public class DummySearchTree<T> implements SearchTree<T> {
|
|
||||||
public DummySearchTree() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<T> search(String pSearchText) {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
static final SearchTreeProviderRegistry.Provider PROVIDER = new SearchTreeProviderRegistry.Provider() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SearchTree<ItemStack> getSearchTree(boolean tag) {
|
|
||||||
return new DummySearchTree<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canUse() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "Dummy";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,109 +0,0 @@
|
||||||
package org.embeddedt.modernfix.searchtree;
|
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
|
||||||
import mezz.jei.api.ingredients.ITypedIngredient;
|
|
||||||
import mezz.jei.gui.ingredients.IngredientFilter;
|
|
||||||
import mezz.jei.gui.ingredients.IngredientFilterApi;
|
|
||||||
import mezz.jei.library.runtime.JeiRuntime;
|
|
||||||
import net.minecraft.client.searchtree.SearchTree;
|
|
||||||
import net.minecraft.world.item.ItemStack;
|
|
||||||
import org.embeddedt.modernfix.ModernFix;
|
|
||||||
import org.embeddedt.modernfix.platform.ModernFixPlatformHooks;
|
|
||||||
|
|
||||||
import java.lang.invoke.MethodHandle;
|
|
||||||
import java.lang.invoke.MethodHandles;
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Uses JEI to handle search tree lookups.
|
|
||||||
*/
|
|
||||||
public class JEIBackedSearchTree extends DummySearchTree<ItemStack> {
|
|
||||||
private final boolean filteringByTag;
|
|
||||||
private String lastSearchText = "";
|
|
||||||
private final List<ItemStack> listCache = new ArrayList<>();
|
|
||||||
|
|
||||||
private static final Field filterField;
|
|
||||||
private static final MethodHandle getIngredientListUncached;
|
|
||||||
|
|
||||||
static {
|
|
||||||
MethodHandle m;
|
|
||||||
Field f;
|
|
||||||
try {
|
|
||||||
Method jeiMethod = IngredientFilter.class.getDeclaredMethod("getIngredientListUncached", String.class);
|
|
||||||
jeiMethod.setAccessible(true);
|
|
||||||
m = MethodHandles.lookup().unreflect(jeiMethod);
|
|
||||||
f = IngredientFilterApi.class.getDeclaredField("ingredientFilter");
|
|
||||||
f.setAccessible(true);
|
|
||||||
} catch(ReflectiveOperationException | RuntimeException | NoClassDefFoundError e) {
|
|
||||||
m = null;
|
|
||||||
f = null;
|
|
||||||
}
|
|
||||||
getIngredientListUncached = m;
|
|
||||||
filterField = f;
|
|
||||||
}
|
|
||||||
|
|
||||||
public JEIBackedSearchTree(boolean filteringByTag) {
|
|
||||||
this.filteringByTag = filteringByTag;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public List<ItemStack> search(String pSearchText) {
|
|
||||||
Optional<JeiRuntime> runtime = JEIRuntimeCapturer.runtime();
|
|
||||||
if(runtime.isPresent()) {
|
|
||||||
IngredientFilterApi iFilterApi = (IngredientFilterApi)runtime.get().getIngredientFilter();
|
|
||||||
IngredientFilter filter;
|
|
||||||
try {
|
|
||||||
filter = (IngredientFilter)filterField.get(iFilterApi);
|
|
||||||
} catch(ReflectiveOperationException e) {
|
|
||||||
ModernFix.LOGGER.error(e);
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
return this.searchJEI(filter, pSearchText);
|
|
||||||
} else {
|
|
||||||
/* Use the default, dummy implementation */
|
|
||||||
return super.search(pSearchText);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<ItemStack> searchJEI(IngredientFilter filter, String pSearchText) {
|
|
||||||
if(!pSearchText.equals(lastSearchText)) {
|
|
||||||
listCache.clear();
|
|
||||||
List<ITypedIngredient<?>> ingredients;
|
|
||||||
String finalSearchTerm = filteringByTag ? ("$" + pSearchText) : pSearchText;
|
|
||||||
try {
|
|
||||||
ingredients = (List<ITypedIngredient<?>>)getIngredientListUncached.invokeExact(filter, finalSearchTerm);
|
|
||||||
} catch(Throwable e) {
|
|
||||||
ModernFix.LOGGER.error("Error searching", e);
|
|
||||||
ingredients = ImmutableList.of();
|
|
||||||
}
|
|
||||||
for(ITypedIngredient<?> ingredient : ingredients) {
|
|
||||||
if(ingredient.getIngredient() instanceof ItemStack) {
|
|
||||||
listCache.add((ItemStack)ingredient.getIngredient());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lastSearchText = pSearchText;
|
|
||||||
}
|
|
||||||
return listCache;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final SearchTreeProviderRegistry.Provider PROVIDER = new SearchTreeProviderRegistry.Provider() {
|
|
||||||
@Override
|
|
||||||
public SearchTree<ItemStack> getSearchTree(boolean tag) {
|
|
||||||
return new JEIBackedSearchTree(tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canUse() {
|
|
||||||
return ModernFixPlatformHooks.INSTANCE.modPresent("jei") && !ModernFixPlatformHooks.INSTANCE.modPresent("emi") && getIngredientListUncached != null && filterField != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "JEI";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
package org.embeddedt.modernfix.searchtree;
|
|
||||||
|
|
||||||
import mezz.jei.api.IModPlugin;
|
|
||||||
import mezz.jei.api.JeiPlugin;
|
|
||||||
import mezz.jei.api.runtime.IJeiRuntime;
|
|
||||||
import mezz.jei.library.runtime.JeiRuntime;
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
import org.embeddedt.modernfix.ModernFix;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
@JeiPlugin
|
|
||||||
public class JEIRuntimeCapturer implements IModPlugin {
|
|
||||||
private static JeiRuntime runtimeHandle = null;
|
|
||||||
|
|
||||||
public static Optional<JeiRuntime> runtime() {
|
|
||||||
return Optional.ofNullable(runtimeHandle);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ResourceLocation getPluginUid() {
|
|
||||||
return ResourceLocation.fromNamespaceAndPath(ModernFix.MODID, "capturer");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onRuntimeAvailable(IJeiRuntime jeiRuntime) {
|
|
||||||
runtimeHandle = (JeiRuntime)jeiRuntime;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onRuntimeUnavailable() {
|
|
||||||
runtimeHandle = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,150 +0,0 @@
|
||||||
package org.embeddedt.modernfix.searchtree;
|
|
||||||
|
|
||||||
import com.google.common.base.Predicates;
|
|
||||||
import me.shedaniel.rei.api.client.registry.entry.EntryRegistry;
|
|
||||||
import me.shedaniel.rei.api.common.entry.EntryStack;
|
|
||||||
import me.shedaniel.rei.api.common.entry.type.VanillaEntryTypes;
|
|
||||||
import me.shedaniel.rei.impl.client.search.AsyncSearchManager;
|
|
||||||
import me.shedaniel.rei.impl.common.entry.type.EntryRegistryImpl;
|
|
||||||
import me.shedaniel.rei.impl.common.util.HashedEntryStackWrapper;
|
|
||||||
import net.minecraft.client.searchtree.SearchTree;
|
|
||||||
import net.minecraft.world.item.ItemStack;
|
|
||||||
import org.embeddedt.modernfix.ModernFix;
|
|
||||||
import org.embeddedt.modernfix.platform.ModernFixPlatformHooks;
|
|
||||||
|
|
||||||
import java.lang.invoke.MethodHandle;
|
|
||||||
import java.lang.invoke.MethodHandles;
|
|
||||||
import java.lang.invoke.MethodType;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
import java.util.function.UnaryOperator;
|
|
||||||
|
|
||||||
public class REIBackedSearchTree extends DummySearchTree<ItemStack> {
|
|
||||||
private final AsyncSearchManager searchManager = createSearchManager();
|
|
||||||
|
|
||||||
private final boolean filteringByTag;
|
|
||||||
private String lastSearchText = "";
|
|
||||||
private final List<ItemStack> listCache = new ArrayList<>();
|
|
||||||
|
|
||||||
public REIBackedSearchTree(boolean filteringByTag) {
|
|
||||||
this.filteringByTag = filteringByTag;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public List<ItemStack> search(String pSearchText) {
|
|
||||||
if(true) {
|
|
||||||
return this.searchREI(pSearchText);
|
|
||||||
} else {
|
|
||||||
/* Use the default, dummy implementation */
|
|
||||||
return super.search(pSearchText);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<ItemStack> searchREI(String pSearchText) {
|
|
||||||
if(!pSearchText.equals(lastSearchText)) {
|
|
||||||
listCache.clear();
|
|
||||||
this.searchManager.updateFilter(pSearchText);
|
|
||||||
List stacks;
|
|
||||||
try {
|
|
||||||
stacks = this.searchManager.getNow();
|
|
||||||
} catch(RuntimeException e) {
|
|
||||||
ModernFix.LOGGER.error("Couldn't search for '" + pSearchText + "'", e);
|
|
||||||
stacks = Collections.emptyList();
|
|
||||||
}
|
|
||||||
for(Object o : stacks) {
|
|
||||||
EntryStack<?> stack;
|
|
||||||
if(o instanceof EntryStack<?>)
|
|
||||||
stack = (EntryStack<?>)o;
|
|
||||||
else if(o instanceof HashedEntryStackWrapper) {
|
|
||||||
stack = ((HashedEntryStackWrapper)o).unwrap();
|
|
||||||
} else {
|
|
||||||
ModernFix.LOGGER.error("Don't know how to handle {}", o.getClass().getName());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(stack.getType() == VanillaEntryTypes.ITEM) {
|
|
||||||
listCache.add(stack.cheatsAs().getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lastSearchText = pSearchText;
|
|
||||||
}
|
|
||||||
return listCache;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
|
||||||
private static AsyncSearchManager createSearchManager() {
|
|
||||||
Method m, normalizeMethod;
|
|
||||||
try {
|
|
||||||
try {
|
|
||||||
m = EntryRegistryImpl.class.getDeclaredMethod("getPreFilteredComplexList");
|
|
||||||
m.setAccessible(true);
|
|
||||||
normalizeMethod = HashedEntryStackWrapper.class.getDeclaredMethod("normalize");
|
|
||||||
normalizeMethod.setAccessible(true);
|
|
||||||
} catch(NoSuchMethodException e) {
|
|
||||||
m = EntryRegistryImpl.class.getDeclaredMethod("getPreFilteredList");
|
|
||||||
m.setAccessible(true);
|
|
||||||
normalizeMethod = EntryStack.class.getDeclaredMethod("normalize");
|
|
||||||
normalizeMethod.setAccessible(true);
|
|
||||||
}
|
|
||||||
final MethodHandle getListMethod = MethodHandles.publicLookup().unreflect(m);
|
|
||||||
final MethodHandle normalize = MethodHandles.publicLookup().unreflect(normalizeMethod);
|
|
||||||
final EntryRegistryImpl registry = (EntryRegistryImpl)EntryRegistry.getInstance();
|
|
||||||
Supplier stackListSupplier = () -> {
|
|
||||||
try {
|
|
||||||
return (List)getListMethod.invokeExact(registry);
|
|
||||||
} catch(Throwable e) {
|
|
||||||
if(e instanceof RuntimeException)
|
|
||||||
throw (RuntimeException)e;
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
UnaryOperator normalizeOperator = o -> {
|
|
||||||
try {
|
|
||||||
return normalize.invoke(o);
|
|
||||||
} catch(Throwable e) {
|
|
||||||
if(e instanceof RuntimeException)
|
|
||||||
throw (RuntimeException)e;
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Supplier<Predicate<Boolean>> shouldShowStack = () -> {
|
|
||||||
return Predicates.alwaysTrue();
|
|
||||||
};
|
|
||||||
try {
|
|
||||||
try {
|
|
||||||
// Old constructor taking Supplier as first arg
|
|
||||||
MethodHandle cn = MethodHandles.publicLookup().findConstructor(AsyncSearchManager.class, MethodType.methodType(void.class, Supplier.class, Supplier.class, UnaryOperator.class));
|
|
||||||
return (AsyncSearchManager)cn.invoke(stackListSupplier, shouldShowStack, normalizeOperator);
|
|
||||||
} catch(NoSuchMethodException e) {
|
|
||||||
// New constructor taking Function as first arg
|
|
||||||
MethodHandle cn = MethodHandles.publicLookup().findConstructor(AsyncSearchManager.class, MethodType.methodType(void.class, Function.class, Supplier.class, UnaryOperator.class));
|
|
||||||
return (AsyncSearchManager)cn.invoke((Function<?, ?>)o -> stackListSupplier.get(), shouldShowStack, normalizeOperator);
|
|
||||||
}
|
|
||||||
} catch(Throwable mhThrowable) {
|
|
||||||
throw new ReflectiveOperationException(mhThrowable);
|
|
||||||
}
|
|
||||||
} catch(ReflectiveOperationException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final SearchTreeProviderRegistry.Provider PROVIDER = new SearchTreeProviderRegistry.Provider() {
|
|
||||||
@Override
|
|
||||||
public SearchTree<ItemStack> getSearchTree(boolean tag) {
|
|
||||||
return new REIBackedSearchTree(tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canUse() {
|
|
||||||
return ModernFixPlatformHooks.INSTANCE.modPresent("roughlyenoughitems");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "REI";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,50 +0,0 @@
|
||||||
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<RecipeCollection> {
|
|
||||||
private final SearchTree<ItemStack> stackCollector;
|
|
||||||
private Map<Item, List<RecipeCollection>> collectionsByItem = null;
|
|
||||||
private final List<RecipeCollection> allCollections;
|
|
||||||
|
|
||||||
public RecipeBookSearchTree(SearchTree<ItemStack> stackCollector, List<RecipeCollection> allCollections) {
|
|
||||||
this.stackCollector = stackCollector;
|
|
||||||
this.allCollections = allCollections;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Map<Item, List<RecipeCollection>> populateCollectionMap() {
|
|
||||||
Map<Item, List<RecipeCollection>> collections = this.collectionsByItem;
|
|
||||||
if(collections == null) {
|
|
||||||
collections = new Object2ObjectOpenHashMap<>();
|
|
||||||
Map<Item, List<RecipeCollection>> finalCollection = collections;
|
|
||||||
for(RecipeCollection collection : allCollections) {
|
|
||||||
collection.getRecipes().stream().map(recipe -> recipe.value().getResultItem(collection.registryAccess()).getItem()).distinct().forEach(item -> {
|
|
||||||
finalCollection.computeIfAbsent(item, k -> new ArrayList<>()).add(collection);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
this.collectionsByItem = collections;
|
|
||||||
}
|
|
||||||
return collections;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<RecipeCollection> search(String pSearchText) {
|
|
||||||
// Avoid constructing the recipe collection map until the first real search
|
|
||||||
if(pSearchText.trim().length() == 0) {
|
|
||||||
return this.allCollections;
|
|
||||||
}
|
|
||||||
List<ItemStack> stacks = stackCollector.search(pSearchText);
|
|
||||||
Map<Item, List<RecipeCollection>> collections = this.populateCollectionMap();
|
|
||||||
return stacks.stream().map(ItemStack::getItem).distinct().flatMap(item -> collections.getOrDefault(item, Collections.emptyList()).stream()).collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
package org.embeddedt.modernfix.searchtree;
|
|
||||||
|
|
||||||
import net.minecraft.client.searchtree.SearchTree;
|
|
||||||
import net.minecraft.world.item.ItemStack;
|
|
||||||
import org.embeddedt.modernfix.core.ModernFixMixinPlugin;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class SearchTreeProviderRegistry {
|
|
||||||
private static final List<Provider> searchTreeProviders = new ArrayList<>();
|
|
||||||
|
|
||||||
public static synchronized Provider getSearchTreeProvider() {
|
|
||||||
for(Provider p : searchTreeProviders) {
|
|
||||||
if(p.canUse())
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
if(ModernFixMixinPlugin.instance.isOptionEnabled("perf.blast_search_trees.force.Registry"))
|
|
||||||
return DummySearchTree.PROVIDER;
|
|
||||||
else
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static synchronized void register(Provider p) {
|
|
||||||
if(p.canUse())
|
|
||||||
searchTreeProviders.add(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface Provider {
|
|
||||||
SearchTree<ItemStack> getSearchTree(boolean tag);
|
|
||||||
boolean canUse();
|
|
||||||
String getName();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -7,10 +7,10 @@ mixinextras_version=0.3.2
|
||||||
mod_id=modernfix
|
mod_id=modernfix
|
||||||
minecraft_version=1.21
|
minecraft_version=1.21
|
||||||
enabled_platforms=fabric,neoforge
|
enabled_platforms=fabric,neoforge
|
||||||
forge_version=21.0.18-beta
|
forge_version=21.0.42-beta
|
||||||
# parchment_version=2023.07.09
|
# parchment_version=2023.07.09
|
||||||
refined_storage_version=4392788
|
refined_storage_version=4392788
|
||||||
jei_version=16.0.0.28
|
jei_version=19.0.0.9
|
||||||
rei_version=13.0.678
|
rei_version=13.0.678
|
||||||
ctm_version=1.20.1-1.1.8+4
|
ctm_version=1.20.1-1.1.8+4
|
||||||
kubejs_version=1902.6.0-build.142
|
kubejs_version=1902.6.0-build.142
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ modId = "neoforge" #mandatory
|
||||||
# Does this dependency have to exist - if not, ordering below must be specified
|
# Does this dependency have to exist - if not, ordering below must be specified
|
||||||
type = "required" #mandatory
|
type = "required" #mandatory
|
||||||
# The version range of the dependency
|
# The version range of the dependency
|
||||||
versionRange = "[21.0.17-beta,)" #mandatory
|
versionRange = "[21.0.42-beta,)" #mandatory
|
||||||
# An ordering relationship for the dependency - BEFORE or AFTER required if the relationship is not mandatory
|
# An ordering relationship for the dependency - BEFORE or AFTER required if the relationship is not mandatory
|
||||||
ordering = "NONE"
|
ordering = "NONE"
|
||||||
# Side this dependency is applied on - BOTH, CLIENT or SERVER
|
# Side this dependency is applied on - BOTH, CLIENT or SERVER
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user