From 6142d4cc6d9aa620e342aa82d07097189bec2903 Mon Sep 17 00:00:00 2001 From: slprime <31038811+slprime@users.noreply.github.com> Date: Wed, 14 May 2025 03:13:17 +0300 Subject: [PATCH] Subset: Memory Optimization (#626) Co-authored-by: slprime --- .../java/codechicken/nei/SubsetWidget.java | 12 +- .../java/codechicken/nei/api/ItemInfo.java | 115 ++++++------------ .../nei/guihook/GuiContainerManager.java | 4 +- 3 files changed, 51 insertions(+), 80 deletions(-) diff --git a/src/main/java/codechicken/nei/SubsetWidget.java b/src/main/java/codechicken/nei/SubsetWidget.java index 8f750a0e..72886501 100644 --- a/src/main/java/codechicken/nei/SubsetWidget.java +++ b/src/main/java/codechicken/nei/SubsetWidget.java @@ -4,9 +4,11 @@ import java.awt.Point; import java.util.ArrayList; import java.util.Comparator; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantReadWriteLock; @@ -356,16 +358,18 @@ public class SubsetWidget extends Button implements ItemFilterProvider, IContain private static class DefaultParserProvider implements ISearchParserProvider { public ItemFilter getFilter(String searchText) { - final AnyMultiItemFilter filter = new AnyMultiItemFilter(); final String pathPart = searchText.replaceAll("\\s+", "").toLowerCase(); + final AnyMultiItemFilter filter = new AnyMultiItemFilter(); + final Set filteredItems = new HashSet<>(); for (SubsetTag tag : tags.values()) { if (tag.filter != null && tag.path.contains(pathPart)) { + filteredItems.addAll(tag.items); filter.filters.add(tag.filter); } } - return filter; + return stack -> filteredItems.contains(stack) || !ItemList.items.contains(stack) && filter.matches(stack); } public char getPrefix() { @@ -585,13 +589,13 @@ public class SubsetWidget extends Button implements ItemFilterProvider, IContain public void execute() { try { - List list = new ArrayList<>(tags.values()); + final List list = new ArrayList<>(tags.values()); root.clearCache(); list.parallelStream().forEach(tag -> { tag.clearCache(); - ItemList.items.stream().filter(tag.filter::matches).map(ItemStack::copy) + ItemList.items.stream().filter(tag.filter::matches) .collect(Collectors.toCollection(() -> tag.items)); }); diff --git a/src/main/java/codechicken/nei/api/ItemInfo.java b/src/main/java/codechicken/nei/api/ItemInfo.java index aad06c28..5ccae709 100644 --- a/src/main/java/codechicken/nei/api/ItemInfo.java +++ b/src/main/java/codechicken/nei/api/ItemInfo.java @@ -5,6 +5,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; +import java.util.Map; import java.util.Map.Entry; import net.minecraft.block.Block; @@ -268,7 +269,8 @@ public class ItemInfo { @SuppressWarnings("unchecked") private static void parseModItems() { - HashMap modSubsets = new HashMap<>(); + final Map modSubsets = new HashMap<>(); + for (Item item : (Iterable) Item.itemRegistry) { UniqueIdentifier ident = null; try { @@ -280,14 +282,12 @@ public class ItemInfo { continue; } - String modId = ident.modId; - itemOwners.put(item, modId); - ItemStackSet itemset = modSubsets.get(modId); - if (itemset == null) modSubsets.put(modId, itemset = new ItemStackSet()); - itemset.with(item); + itemOwners.put(item, ident.modId); + modSubsets.computeIfAbsent(ident.modId, i -> new ItemStackSet()).with(item); } API.addSubset("Mod.Minecraft", modSubsets.remove("minecraft")); + for (Entry entry : modSubsets.entrySet()) { ModContainer mc = FMLCommonHandler.instance().findContainerFor(entry.getKey()); if (mc == null) NEIClientConfig.logger.error("Missing container for " + entry.getKey()); @@ -323,44 +323,29 @@ public class ItemInfo { } private static void addDefaultDropDowns() { + final Item mob_spawner = Item.getItemFromBlock(Blocks.mob_spawner); API.addSubset("Items", item -> Block.getBlockFromItem(item.getItem()) == Blocks.air); API.addSubset("Blocks", item -> Block.getBlockFromItem(item.getItem()) != Blocks.air); - API.addSubset("Blocks.MobSpawners", ItemStackSet.of(Blocks.mob_spawner)); + API.addSubset("Blocks.MobSpawners", item -> item.getItem() == mob_spawner); } @SuppressWarnings("unchecked") private static void searchItems() { - ItemStackSet tools = new ItemStackSet(); - ItemStackSet picks = new ItemStackSet(); - ItemStackSet shovels = new ItemStackSet(); - ItemStackSet axes = new ItemStackSet(); - ItemStackSet hoes = new ItemStackSet(); - ItemStackSet swords = new ItemStackSet(); - ItemStackSet chest = new ItemStackSet(); - ItemStackSet helmets = new ItemStackSet(); - ItemStackSet legs = new ItemStackSet(); - ItemStackSet boots = new ItemStackSet(); - ItemStackSet other = new ItemStackSet(); - ItemStackSet ranged = new ItemStackSet(); - ItemStackSet food = new ItemStackSet(); - ItemStackSet potioningredients = new ItemStackSet(); - - ArrayList creativeTabRanges = new ArrayList<>(CreativeTabs.creativeTabArray.length); - List stackList = new LinkedList<>(); + final Map creativeTabRanges = new HashMap<>(); + final List stackList = new LinkedList<>(); for (Item item : (Iterable) Item.itemRegistry) { if (item == null) continue; for (CreativeTabs itemTab : item.getCreativeTabs()) { if (itemTab != null) { - while (itemTab.getTabIndex() >= creativeTabRanges.size()) creativeTabRanges.add(null); - ItemStackSet set = creativeTabRanges.get(itemTab.getTabIndex()); - if (set == null) creativeTabRanges.set(itemTab.getTabIndex(), set = new ItemStackSet()); + final ItemStackSet itemset = creativeTabRanges + .computeIfAbsent(itemTab.getTabIndex(), i -> new ItemStackSet()); try { stackList.clear(); item.getSubItems(item, itemTab, stackList); - for (ItemStack stack : stackList) set.add(stack); + itemset.addAll(stackList); } catch (Exception e) { NEIClientConfig.logger .error("Error loading sub-items for: " + item + ". Tab: " + itemTab.getTabLabel(), e); @@ -368,41 +353,13 @@ public class ItemInfo { } } - if (item.isDamageable()) { - tools.with(item); - if (item instanceof ItemPickaxe) picks.with(item); - else if (item instanceof ItemSpade) shovels.with(item); - else if (item instanceof ItemAxe) axes.with(item); - else if (item instanceof ItemHoe) hoes.with(item); - else if (item instanceof ItemSword) swords.with(item); - else if (item instanceof ItemArmor) switch (((ItemArmor) item).armorType) { - case 0: - helmets.with(item); - break; - case 1: - chest.with(item); - break; - case 2: - legs.with(item); - break; - case 3: - boots.with(item); - break; - } - else if (item == Items.arrow || item == Items.bow) ranged.with(item); - else if (item == Items.fishing_rod || item == Items.flint_and_steel || item == Items.shears) - other.with(item); - } - - if (item instanceof ItemFood) food.with(item); - try { - LinkedList subItems = new LinkedList<>(); + final List subItems = new LinkedList<>(); item.getSubItems(item, null, subItems); + for (ItemStack stack : subItems) { if (item.isPotionIngredient(stack) && item.getPotionEffect(stack) != null) { BrewingRecipeHandler.ingredients.add(stack); - potioningredients.add(stack); } } @@ -410,25 +367,33 @@ public class ItemInfo { NEIClientConfig.logger.error("Error loading brewing ingredients for: " + item, e); } } - API.addSubset("Items.Tools.Pickaxes", picks); - API.addSubset("Items.Tools.Shovels", shovels); - API.addSubset("Items.Tools.Axes", axes); - API.addSubset("Items.Tools.Hoes", hoes); - API.addSubset("Items.Tools.Other", other); - API.addSubset("Items.Weapons.Swords", swords); - API.addSubset("Items.Weapons.Ranged", ranged); - API.addSubset("Items.Armor.Chestplates", chest); - API.addSubset("Items.Armor.Leggings", legs); - API.addSubset("Items.Armor.Helmets", helmets); - API.addSubset("Items.Armor.Boots", boots); - API.addSubset("Items.Food", food); - API.addSubset("Items.Potions.Ingredients", potioningredients); + + API.addSubset("Items.Tools.Pickaxes", item -> item.getItem() instanceof ItemPickaxe); + API.addSubset("Items.Tools.Shovels", item -> item.getItem() instanceof ItemSpade); + API.addSubset("Items.Tools.Axes", item -> item.getItem() instanceof ItemAxe); + API.addSubset("Items.Tools.Hoes", item -> item.getItem() instanceof ItemHoe); + API.addSubset( + "Items.Tools.Other", + item -> item.getItem() == Items.fishing_rod || item.getItem() == Items.flint_and_steel + || item.getItem() == Items.shears); + API.addSubset("Items.Weapons.Swords", item -> item.getItem() instanceof ItemSword); + API.addSubset("Items.Weapons.Ranged", item -> item.getItem() == Items.arrow || item.getItem() == Items.bow); + API.addSubset("Items.Armor.Helmets", item -> item.getItem() instanceof ItemArmor armor && armor.armorType == 0); + API.addSubset( + "Items.Armor.Chestplates", + item -> item.getItem() instanceof ItemArmor armor && armor.armorType == 1); + API.addSubset( + "Items.Armor.Leggings", + item -> item.getItem() instanceof ItemArmor armor && armor.armorType == 2); + API.addSubset("Items.Armor.Boots", item -> item.getItem() instanceof ItemArmor armor && armor.armorType == 3); + API.addSubset("Items.Food", item -> item.getItem() instanceof ItemFood); + API.addSubset("Items.Potions.Ingredients", BrewingRecipeHandler.ingredients); for (CreativeTabs tab : CreativeTabs.creativeTabArray) { - if (tab.getTabIndex() >= creativeTabRanges.size()) continue; - ItemStackSet set = creativeTabRanges.get(tab.getTabIndex()); - if (set != null && !set.isEmpty()) - API.addSubset("CreativeTabs." + I18n.format(tab.getTranslatedTabLabel()), set); + final ItemStackSet itemset = creativeTabRanges.get(tab.getTabIndex()); + if (itemset != null && !itemset.isEmpty()) { + API.addSubset("CreativeTabs." + I18n.format(tab.getTranslatedTabLabel()), itemset); + } } BrewingRecipeHandler.searchPotions(); diff --git a/src/main/java/codechicken/nei/guihook/GuiContainerManager.java b/src/main/java/codechicken/nei/guihook/GuiContainerManager.java index 3f2d6104..34e5e82b 100644 --- a/src/main/java/codechicken/nei/guihook/GuiContainerManager.java +++ b/src/main/java/codechicken/nei/guihook/GuiContainerManager.java @@ -180,7 +180,9 @@ public class GuiContainerManager { namelist.set(0, stack.getRarity().rarityColor.toString() + namelist.get(0)); for (int i = 1; i < namelist.size(); i++) { - namelist.set(i, EnumChatFormatting.GRAY + namelist.get(i) + EnumChatFormatting.RESET); + if (!namelist.get(i).startsWith(GuiDraw.TOOLTIP_HANDLER)) { + namelist.set(i, EnumChatFormatting.GRAY + namelist.get(i) + EnumChatFormatting.RESET); + } } return namelist;