From f25eba19a95aa8b33d7d86064c5af7f23bf75daa Mon Sep 17 00:00:00 2001 From: slprime Date: Mon, 23 Feb 2026 09:17:31 +0200 Subject: [PATCH] Remove Generated Favorites from Accepts Followings Tooltip --- .../java/codechicken/nei/FavoriteRecipes.java | 45 +++-- .../codechicken/nei/ItemCraftablesPanel.java | 3 +- .../java/codechicken/nei/PositionedStack.java | 2 +- .../java/codechicken/nei/SearchField.java | 1 - .../java/codechicken/nei/SubsetWidget.java | 163 ++++++------------ .../AcceptsFollowingTooltipLineHandler.java | 4 +- .../nei/recipe/NEIRecipeWidget.java | 17 +- 7 files changed, 102 insertions(+), 133 deletions(-) diff --git a/src/main/java/codechicken/nei/FavoriteRecipes.java b/src/main/java/codechicken/nei/FavoriteRecipes.java index 34f292e86..6dd517aad 100644 --- a/src/main/java/codechicken/nei/FavoriteRecipes.java +++ b/src/main/java/codechicken/nei/FavoriteRecipes.java @@ -125,8 +125,7 @@ public void execute() { } FavoriteRecipes.autoFavorites = storage; - SubsetWidget.updateHiddenItems(); - ItemList.updateFilter.restart(); + updateSubsetVisibility(); } protected List getOutputs(IRecipeHandler handler, int recipeIndex) { @@ -139,10 +138,11 @@ protected List getOutputs(IRecipeHandler handler, int recipeInd private static final FavoriteStorage manualFavorites = new FavoriteStorage(); private static FavoriteStorage autoFavorites = new FavoriteStorage(); private static File favoriteFile; + private static int revision = 0; static { API.addSubset("Favorites.Manual", manualFavorites::contains); - API.addSubset("Favorites.Generated", stack -> autoFavorites.contains(stack)); + API.addSubset("Favorites.Generated", stack -> FavoriteRecipes.autoFavorites.contains(stack)); } private FavoriteRecipes() {} @@ -254,18 +254,12 @@ private static void loadData() { } loadAutoGeneratedRecipes(); - - SubsetWidget.updateHiddenItems(); - ItemList.updateFilter.restart(); } - public static RecipeId getFavorite(ItemStack stack) { - + public static RecipeId getManualFavorite(ItemStack stack) { if (NEIClientConfig.favoritesEnabled() && stack != null) { - final RecipeId recipeId = manualFavorites.getRecipeId(stack); - return recipeId != null ? recipeId : autoFavorites.getRecipeId(stack); + return manualFavorites.getRecipeId(stack); } - return null; } @@ -276,6 +270,16 @@ public static ItemStack getManualFavorite(RecipeId recipeId) { return null; } + public static RecipeId getFavorite(ItemStack stack) { + + if (NEIClientConfig.favoritesEnabled() && stack != null) { + final RecipeId recipeId = manualFavorites.getRecipeId(stack); + return recipeId != null ? recipeId : autoFavorites.getRecipeId(stack); + } + + return null; + } + public static ItemStack getFavorite(RecipeId recipeId) { if (NEIClientConfig.favoritesEnabled() && recipeId != null) { @@ -295,6 +299,10 @@ public static void reload() { load(); } + public static boolean containsManual(ItemStack stack) { + return getManualFavorite(stack) != null; + } + public static boolean contains(ItemStack stack) { return getFavorite(stack) != null; } @@ -309,8 +317,7 @@ public static void setFavorite(ItemStack stack, RecipeId recipeId) { manualFavorites.add(stack, recipeId); } - SubsetWidget.updateHiddenItems(); - ItemList.updateFilter.restart(); + updateSubsetVisibility(); } public static void loadAutoGeneratedRecipes() { @@ -321,13 +328,17 @@ public static void loadAutoGeneratedRecipes() { singleRecipeFavoritesTask.stop(); autoFavorites.clear(); - SubsetWidget.updateHiddenItems(); - ItemList.updateFilter.restart(); + updateSubsetVisibility(); } } - public static boolean isAutogenerated(RecipeId recipeId) { - return autoFavorites.getItemStack(recipeId) != null; + protected static void updateSubsetVisibility() { + SubsetWidget.updateHiddenItems(); + FavoriteRecipes.revision++; + } + + public static int getRevision() { + return revision; } public static void save() { diff --git a/src/main/java/codechicken/nei/ItemCraftablesPanel.java b/src/main/java/codechicken/nei/ItemCraftablesPanel.java index 110921b9e..78f7e86af 100644 --- a/src/main/java/codechicken/nei/ItemCraftablesPanel.java +++ b/src/main/java/codechicken/nei/ItemCraftablesPanel.java @@ -117,7 +117,8 @@ public List getMask() { .entrySet().stream() .sorted( Map.Entry.comparingByKey( - Comparator.comparing(FavoriteRecipes::contains).reversed() + Comparator.comparing(FavoriteRecipes::containsManual) + .thenComparing(FavoriteRecipes::contains).reversed() .thenComparing(ItemSorter.instance))) .limit(maxSlotIndex).collect(Collectors.toList()); int slotIndex = 0; diff --git a/src/main/java/codechicken/nei/PositionedStack.java b/src/main/java/codechicken/nei/PositionedStack.java index 0ca72612c..c2fe0d8b7 100644 --- a/src/main/java/codechicken/nei/PositionedStack.java +++ b/src/main/java/codechicken/nei/PositionedStack.java @@ -104,7 +104,7 @@ public List getFilteredPermutations(ItemFilter additionalFilter) { items = filteringPermutations(items, GuiRecipe.getSearchItemFilter()); items = filteringPermutations(items, additionalFilter); - items.sort(Comparator.comparing(FavoriteRecipes::contains).reversed()); + items.sort(Comparator.comparing(FavoriteRecipes::containsManual).reversed()); return items; } diff --git a/src/main/java/codechicken/nei/SearchField.java b/src/main/java/codechicken/nei/SearchField.java index 62bf87905..c34999fdb 100644 --- a/src/main/java/codechicken/nei/SearchField.java +++ b/src/main/java/codechicken/nei/SearchField.java @@ -222,7 +222,6 @@ public boolean handleClick(int mousex, int mousey, int button) { public void onTextChange(String oldText) { final String newText = text(); if (!newText.equals(oldText)) { - if (newText.length() > 0) NEIClientConfig.logger.debug("Searching for " + newText); NEIClientConfig.setSearchExpression(newText); ItemList.updateFilter.restart(); } diff --git a/src/main/java/codechicken/nei/SubsetWidget.java b/src/main/java/codechicken/nei/SubsetWidget.java index a21e1d74d..2060743f5 100644 --- a/src/main/java/codechicken/nei/SubsetWidget.java +++ b/src/main/java/codechicken/nei/SubsetWidget.java @@ -10,9 +10,6 @@ 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; import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -53,9 +50,7 @@ public class SubsetWidget extends Button implements ItemFilterProvider { protected static final int MARGIN = 2; protected static final char PREFIX = '%'; - protected static ReentrantReadWriteLock hiddenItemLock = new ReentrantReadWriteLock(); - protected static Lock hiddenWriteLock = hiddenItemLock.writeLock(); - protected static Lock hiddenReadLock = hiddenItemLock.readLock(); + private static final Object hiddenLock = new Object(); public static class SubsetTag { @@ -377,11 +372,18 @@ public ItemFilter getFilter(String searchText) { } final AnyMultiItemFilter filter = new AnyMultiItemFilter(); final Set filteredItems = new HashSet<>(); + final List snapshot; - for (SubsetTag tag : tags.values()) { + synchronized (tags) { + snapshot = new ArrayList<>(tags.values()); + } + + for (SubsetTag tag : snapshot) { if (tag.filter != null && matches(tag.path, searchText, pattern)) { - filteredItems.addAll(tag.items); - filter.filters.add(tag.filter); + synchronized (tag.items) { + filteredItems.addAll(tag.items); + filter.filters.add(tag.filter); + } } } @@ -414,6 +416,7 @@ private boolean matches(String name, String searchText, Pattern pattern) { * All operations on this variable should be synchronised. */ private static final ItemStackSet hiddenItems = new ItemStackSet(); + private static final Map tags = new HashMap<>(); private static final SubsetTag root = new SubsetTag(""); protected static boolean enableSearchBySubsets = false; @@ -436,6 +439,7 @@ public static void addTag(SubsetTag tag) { } updateHiddenItems(); + SearchField.searchParser.clearCache(); } } @@ -447,24 +451,14 @@ public static void removeTag(String path) { parentpath -> parentpath.equals(path.toLowerCase()) || parentpath.startsWith(path.toLowerCase() + ".")); updateHiddenItems(); + SearchField.searchParser.clearCache(); } } public static boolean isHidden(ItemStack item) { - try { - if (hiddenReadLock.tryLock(5, TimeUnit.SECONDS)) { - try { - return hiddenItems.contains(item); - } finally { - hiddenReadLock.unlock(); - } - } else { - NEIClientConfig.logger.error("Unable to obtain read lock in 'isHidden'"); - } - } catch (InterruptedException e) { - e.printStackTrace(); + synchronized (hiddenLock) { + return hiddenItems.contains(item); } - return false; } private static List getItems(SubsetTag tag, List items) { @@ -478,90 +472,45 @@ private static List getItems(SubsetTag tag, List items) { } public static void showOnly(SubsetTag tag) { - try { - if (hiddenWriteLock.tryLock(5, TimeUnit.SECONDS)) { - try { - hiddenItems.clear(); - hiddenItems.addAll(getItems(root, new ArrayList<>())); - hiddenItems.removeAll(getItems(tag, new ArrayList<>())); - } finally { - hiddenWriteLock.unlock(); - } - } else { - NEIClientConfig.logger.error("Unable to obtain write lock in 'showOnly'"); - } - - calculateVisibility(); - } catch (InterruptedException e) { - e.printStackTrace(); + synchronized (hiddenLock) { + hiddenItems.clear(); + hiddenItems.addAll(getItems(root, new ArrayList<>())); + hiddenItems.removeAll(getItems(tag, new ArrayList<>())); } + + calculateVisibility(); } public static void setHidden(SubsetTag tag, boolean hidden) { - try { - if (hiddenWriteLock.tryLock(5, TimeUnit.SECONDS)) { - try { - List tagItems = getItems(tag, new ArrayList<>()); + synchronized (hiddenLock) { + final List tagItems = getItems(tag, new ArrayList<>()); - if (hidden) { - hiddenItems.addAll(tagItems); - } else { - hiddenItems.removeAll(tagItems); - } - - } finally { - hiddenWriteLock.unlock(); - } + if (hidden) { + hiddenItems.addAll(tagItems); } else { - NEIClientConfig.logger.error("Unable to obtain write lock in 'setHidden'"); + hiddenItems.removeAll(tagItems); } - - calculateVisibility(); - } catch (InterruptedException e) { - e.printStackTrace(); } + + calculateVisibility(); } public static void setHidden(ItemStack item, boolean hidden) { - try { - if (hiddenWriteLock.tryLock(5, TimeUnit.SECONDS)) { - try { - - if (hidden) { - hiddenItems.add(item); - } else { - hiddenItems.remove(item); - } - - } finally { - hiddenWriteLock.unlock(); - } + synchronized (hiddenLock) { + if (hidden) { + hiddenItems.add(item); } else { - NEIClientConfig.logger.error("Unable to obtain write lock in 'setHidden'"); + hiddenItems.remove(item); } - - calculateVisibility(); - } catch (InterruptedException e) { - e.printStackTrace(); } + calculateVisibility(); } public static void unhideAll() { - try { - if (hiddenWriteLock.tryLock(5, TimeUnit.SECONDS)) { - try { - hiddenItems.clear(); - } finally { - hiddenWriteLock.unlock(); - } - } else { - NEIClientConfig.logger.error("Unable to obtain write lock in 'unhideAll'"); - } - - calculateVisibility(); - } catch (InterruptedException e) { - e.printStackTrace(); + synchronized (hiddenLock) { + hiddenItems.clear(); } + calculateVisibility(); } public static void updateHiddenItems() { @@ -646,29 +595,20 @@ public static void loadHidden() { return; } - try { - if (hiddenWriteLock.tryLock(5, TimeUnit.SECONDS)) { - try { - hiddenItems.clear(); - hiddenItems.addAll(itemList); - } finally { - hiddenWriteLock.unlock(); - } - } else { - NEIClientConfig.logger.error("Unable to obtain second write lock in 'loadHidden'"); - } - } catch (InterruptedException e) { - e.printStackTrace(); + synchronized (hiddenLock) { + hiddenItems.clear(); + hiddenItems.addAll(itemList); } - } public static void saveHidden() { if (NEIClientConfig.world == null) return; final NBTTagList list = new NBTTagList(); - for (ItemStack stack : hiddenItems.values()) { - list.appendTag(stack.writeToNBT(new NBTTagCompound())); + synchronized (hiddenLock) { + for (ItemStack stack : hiddenItems.values()) { + list.appendTag(stack.writeToNBT(new NBTTagCompound())); + } } NEIClientConfig.world.nbt.setTag("hiddenItems", list); @@ -686,14 +626,22 @@ public UpdateStateTask() { public void execute() { try { - final List list = new ArrayList<>(tags.values()); + final List list; + + synchronized (tags) { + list = new ArrayList<>(tags.values()); + } root.clearCache(); list.parallelStream().forEach(tag -> { tag.clearCache(); - ItemList.items.stream().filter(tag.filter::matches) - .collect(Collectors.toCollection(() -> tag.items)); + + if (!(tag.filter instanceof NothingItemFilter)) { + ItemList.items.stream().filter(tag.filter::matches) + .collect(Collectors.toCollection(() -> tag.items)); + } + }); for (SubsetTag tag : list) { @@ -729,6 +677,7 @@ public void execute() { e.printStackTrace(); } + SearchField.searchParser.clearCache(); } } diff --git a/src/main/java/codechicken/nei/recipe/AcceptsFollowingTooltipLineHandler.java b/src/main/java/codechicken/nei/recipe/AcceptsFollowingTooltipLineHandler.java index 13b036eb8..99c15e22d 100644 --- a/src/main/java/codechicken/nei/recipe/AcceptsFollowingTooltipLineHandler.java +++ b/src/main/java/codechicken/nei/recipe/AcceptsFollowingTooltipLineHandler.java @@ -31,7 +31,7 @@ public static AcceptsFollowingTooltipLineHandler of(Object tooltipGUID, List 1) { - items.sort(Comparator.comparing(FavoriteRecipes::contains).reversed()); + items.sort(Comparator.comparing(FavoriteRecipes::containsManual).reversed()); return new AcceptsFollowingTooltipLineHandler(tooltipGUID, items, activeStack, maxRows); } @@ -42,7 +42,7 @@ public static AcceptsFollowingTooltipLineHandler of(Object tooltipGUID, List> permutations = new WeakHashMap<>(); + protected int favoriteRevision = -1; protected boolean update = true; protected int cycleticks = 0; protected int lastcycle = -1; @@ -506,18 +507,26 @@ protected GuiContainer getFirstGui() { protected void updatePermutations() { + if (this.favoriteRevision != FavoriteRecipes.getRevision()) { + this.favoriteRevision = FavoriteRecipes.getRevision(); + this.acceptsFollowingTooltipLineHandler = null; + this.permutations.clear(); + } + for (PositionedStack pStack : getInputs()) { if (pStack.items.length > 1) { - final List permutations = this.permutations - .computeIfAbsent(pStack, stack -> stack.getFilteredPermutations(FavoriteRecipes::contains)); + final List permutations = this.permutations.computeIfAbsent( + pStack, + stack -> stack.getFilteredPermutations(FavoriteRecipes::containsManual)); pStack.setPermutationToRender(permutations.get(this.lastcycle % permutations.size())); } } for (PositionedStack pStack : getCatalysts()) { if (pStack.items.length > 1) { - final List permutations = this.permutations - .computeIfAbsent(pStack, stack -> stack.getFilteredPermutations(FavoriteRecipes::contains)); + final List permutations = this.permutations.computeIfAbsent( + pStack, + stack -> stack.getFilteredPermutations(FavoriteRecipes::containsManual)); pStack.setPermutationToRender(permutations.get(this.lastcycle % permutations.size())); } }