Repair Handler Optimization (#1031)

This commit is contained in:
slprime authored and GitHub committed 2026-09-12 20:02:52 +03:00
1 parent 38dc14eca1
commit 6cd7697ca0
1 file changed
+43 -9
@@ -2,13 +2,17 @@ package codechicken.nei.recipe;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import net.minecraft.client.gui.GuiRepair; import net.minecraft.client.gui.GuiRepair;
import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import codechicken.nei.ItemList; import codechicken.nei.ItemList;
@@ -35,14 +39,17 @@ public class RepairRecipeHandler extends TemplateRecipeHandler {
private static class ItemStackKey { private static class ItemStackKey {
private final ItemStack stack; private final ItemStack stack;
private final int hashCode;
public ItemStackKey(ItemStack stack) { public ItemStackKey(ItemStack stack) {
this.stack = stack; this.stack = stack;
this.hashCode = stack.isItemStackDamageable() ? stack.getItem().hashCode()
: 31 * stack.getItem().hashCode() + stack.getItemDamage();
} }
@Override @Override
public int hashCode() { public int hashCode() {
return stack.getItem().hashCode(); return this.hashCode;
} }
@Override @Override
@@ -104,22 +111,48 @@ public class RepairRecipeHandler extends TemplateRecipeHandler {
reloadRepairRecipesTask.restart(); reloadRepairRecipesTask.restart();
} }
private void buildCache() { private static final Set<Integer> knownBrokenItemTypes = ConcurrentHashMap.newKeySet();
final Map<ItemStackKey, RepairPair> recipes = new HashMap<>(); private static volatile List<ItemStack> uniqueMaterials;
for (ItemStack itemstack1 : ItemList.items) { private void buildCache() {
recipes.computeIfAbsent(new ItemStackKey(itemstack1), key -> this.getRepairRecipe(key.stack)); if (cachedRecipes != null) return;
uniqueMaterials = collectUniqueMaterials();
final Map<ItemStackKey, RepairPair> recipes = new ConcurrentHashMap<>();
try {
ItemList.forkJoinPool.submit(
() -> ItemList.items.parallelStream().forEach(
itemstack1 -> recipes
.computeIfAbsent(new ItemStackKey(itemstack1), key -> getRepairRecipe(key.stack))))
.get();
} catch (InterruptedException | ExecutionException e) {
NEIClientConfig.logger.error("Failed to build repair recipe cache", e);
} }
cachedRecipes = recipes.values().stream().filter(recipe -> recipe != null).collect(Collectors.toList()); cachedRecipes = recipes.values().stream().filter(recipe -> recipe != null).collect(Collectors.toList());
} }
private static List<ItemStack> collectUniqueMaterials() {
final Map<Long, ItemStack> unique = new LinkedHashMap<>();
for (ItemStack stack : ItemList.items) {
final long key = ((long) Item.getIdFromItem(stack.getItem()) << 32) | (stack.getItemDamage() & 0xFFFFFFFFL);
unique.putIfAbsent(key, stack);
}
return new ArrayList<>(unique.values());
}
private RepairPair getRepairRecipe(ItemStack itemstack1) { private RepairPair getRepairRecipe(ItemStack itemstack1) {
if (!itemstack1.isItemStackDamageable()) return null; if (!itemstack1.isItemStackDamageable()) return null;
final List<ItemStack> permutations = new ArrayList<>(); final int itemId = Item.getIdFromItem(itemstack1.getItem());
if (knownBrokenItemTypes.contains(itemId)) return null;
for (ItemStack itemstack2 : ItemList.items) { final List<ItemStack> permutations = new ArrayList<>();
final List<ItemStack> candidates = uniqueMaterials != null ? uniqueMaterials : collectUniqueMaterials();
for (ItemStack itemstack2 : candidates) {
try { try {
if (itemstack1.getItem().getIsRepairable(itemstack1, itemstack2)) { if (itemstack1.getItem().getIsRepairable(itemstack1, itemstack2)) {
final ItemStack right = itemstack2.copy(); final ItemStack right = itemstack2.copy();
@@ -127,7 +160,8 @@ public class RepairRecipeHandler extends TemplateRecipeHandler {
permutations.add(right); permutations.add(right);
} }
} catch (Exception e) { } catch (Exception e) {
// Catch exceptions from mods that don't properly implement getIsRepairable knownBrokenItemTypes.add(itemId);
break;
} }
} }