55import  mezz .jei .api .ingredients .IIngredientHelper ;
66import  mezz .jei .api .ingredients .IIngredientType ;
77import  mezz .jei .api .ingredients .ITypedIngredient ;
8- import  mezz .jei .api .ingredients .subtypes .UidContext ;
98import  mezz .jei .api .runtime .IIngredientManager ;
109import  mezz .jei .api .runtime .IIngredientVisibility ;
1110import  mezz .jei .common .config .DebugConfig ;
3332import  java .util .List ;
3433import  java .util .Optional ;
3534import  java .util .Set ;
36- import  java .util .function .Function ;
3735import  java .util .regex .Matcher ;
3836import  java .util .regex .Pattern ;
3937import  java .util .stream .Stream ;
@@ -94,7 +92,7 @@ public IngredientFilter(
9492		}
9593
9694		this .filterTextSource .addListener (filterText  -> {
97- 			ingredientListCached  =  null ;
95+ 			invalidateCache () ;
9896			notifyListenersOfChange ();
9997		});
10098
@@ -113,7 +111,7 @@ public <V> void addIngredient(IListElementInfo<V> info) {
113111		IListElement <V > element  = info .getElement ();
114112		updateHiddenState (element );
115113
116- 		this .elementSearch .add (info );
114+ 		this .elementSearch .add (info ,  ingredientManager );
117115
118116		invalidateCache ();
119117	}
@@ -127,25 +125,7 @@ public void rebuildItemFilter() {
127125		Collection <IListElement <?>> ingredients  = this .elementSearch .getAllIngredients ();
128126		this .elementSearch  = createElementSearch (this .clientConfig , this .elementPrefixParser );
129127		List <IListElementInfo <?>> elementInfos  = IngredientListElementFactory .rebuildList (ingredientManager , ingredients , modIdHelper );
130- 		this .elementSearch .addAll (elementInfos );
131- 	}
132- 
133- 	public  <V > Optional <IListElement <V >> searchForMatchingElement (
134- 		IIngredientHelper <V > ingredientHelper ,
135- 		ITypedIngredient <V > typedIngredient 
136- 	) {
137- 		V  ingredient  = typedIngredient .getIngredient ();
138- 		IIngredientType <V > type  = typedIngredient .getType ();
139- 		Function <ITypedIngredient <V >, String > uidFunction  = (i ) -> ingredientHelper .getUniqueId (i .getIngredient (), UidContext .Ingredient );
140- 		String  ingredientUid  = uidFunction .apply (typedIngredient );
141- 		String  lowercaseDisplayName  = DisplayNameUtil .getLowercaseDisplayNameForSearch (ingredient , ingredientHelper );
142- 
143- 		ElementPrefixParser .TokenInfo  tokenInfo  = new  ElementPrefixParser .TokenInfo (lowercaseDisplayName , ElementPrefixParser .NO_PREFIX );
144- 		return  this .elementSearch .getSearchResults (tokenInfo )
145- 			.stream ()
146- 			.map (elementInfo  -> checkForMatch (elementInfo , type , ingredientUid , uidFunction ))
147- 			.flatMap (Optional ::stream )
148- 			.findFirst ();
128+ 		this .elementSearch .addAll (elementInfos , ingredientManager );
149129	}
150130
151131	@ Override 
@@ -159,12 +139,12 @@ public void updateHidden() {
159139			changed  |= updateHiddenState (element );
160140		}
161141		if  (changed ) {
162- 			ingredientListCached  =  null ;
142+ 			invalidateCache () ;
163143			notifyListenersOfChange ();
164144		}
165145	}
166146
167- 	public  <V > boolean  updateHiddenState (IListElement <V > element ) {
147+ 	private  <V > boolean  updateHiddenState (IListElement <V > element ) {
168148		ITypedIngredient <V > typedIngredient  = element .getTypedIngredient ();
169149		boolean  visible  = this .ingredientVisibility .isIngredientVisible (typedIngredient );
170150		if  (element .isVisible () != visible ) {
@@ -178,10 +158,11 @@ public <V> boolean updateHiddenState(IListElement<V> element) {
178158	public  <V > void  onIngredientVisibilityChanged (ITypedIngredient <V > ingredient , boolean  visible ) {
179159		IIngredientType <V > ingredientType  = ingredient .getType ();
180160		IIngredientHelper <V > ingredientHelper  = ingredientManager .getIngredientHelper (ingredientType );
181- 		searchForMatchingElement ( ingredientHelper ,  ingredient )
161+ 		this . elementSearch . findElement ( ingredient ,  ingredientHelper )
182162			.ifPresent (element  -> {
183163				if  (element .isVisible () != visible ) {
184164					element .setVisible (visible );
165+ 					invalidateCache ();
185166					notifyListenersOfChange ();
186167				}
187168			});
@@ -232,29 +213,10 @@ private Stream<ITypedIngredient<?>> getIngredientListUncached(String filterText)
232213			.map (IListElement ::getTypedIngredient );
233214	}
234215
235- 	private  static  <T > Optional <IListElement <T >> checkForMatch (IListElement <?> element , IIngredientType <T > ingredientType , Object  uid , Function <ITypedIngredient <T >, String > uidFunction ) {
236- 		return  optionalCast (element , ingredientType )
237- 			.filter (cast  -> {
238- 				ITypedIngredient <T > typedIngredient  = cast .getTypedIngredient ();
239- 				String  elementUid  = uidFunction .apply (typedIngredient );
240- 				return  uid .equals (elementUid );
241- 			});
242- 	}
243- 
244- 	private  static  <T > Optional <IListElement <T >> optionalCast (IListElement <?> element , IIngredientType <T > ingredientType ) {
245- 		ITypedIngredient <?> typedIngredient  = element .getTypedIngredient ();
246- 		if  (typedIngredient .getType () == ingredientType ) {
247- 			@ SuppressWarnings ("unchecked" )
248- 			IListElement <T > cast  = (IListElement <T >) element ;
249- 			return  Optional .of (cast );
250- 		}
251- 		return  Optional .empty ();
252- 	}
253- 
254216	@ Override 
255217	public  <V > void  onIngredientsAdded (IIngredientHelper <V > ingredientHelper , Collection <ITypedIngredient <V >> ingredients ) {
256218		for  (ITypedIngredient <V > value  : ingredients ) {
257- 			Optional <IListElement <V >> matchingElementOptional  = searchForMatchingElement ( ingredientHelper ,  value );
219+ 			Optional <IListElement <V >> matchingElementOptional  = this . elementSearch . findElement ( value ,  ingredientHelper );
258220			if  (matchingElementOptional .isPresent ()) {
259221				IListElement <V > matchingElement  = matchingElementOptional .get ();
260222				updateHiddenState (matchingElement );
@@ -276,21 +238,7 @@ public <V> void onIngredientsAdded(IIngredientHelper<V> ingredientHelper, Collec
276238
277239	@ Override 
278240	public  <V > void  onIngredientsRemoved (IIngredientHelper <V > ingredientHelper , Collection <ITypedIngredient <V >> ingredients ) {
279- 		for  (ITypedIngredient <V > typedIngredient  : ingredients ) {
280- 			Optional <IListElement <V >> matchingElementOptional  = searchForMatchingElement (ingredientHelper , typedIngredient );
281- 			if  (matchingElementOptional .isEmpty ()) {
282- 				String  errorInfo  = ingredientHelper .getErrorInfo (typedIngredient .getIngredient ());
283- 				LOGGER .error ("Could not find a matching ingredient to remove: {}" , errorInfo );
284- 			} else  {
285- 				if  (DebugConfig .isDebugModeEnabled ()) {
286- 					LOGGER .debug ("Removed ingredient: {}" , ingredientHelper .getErrorInfo (typedIngredient .getIngredient ()));
287- 				}
288- 				IListElement <V > matchingElement  = matchingElementOptional .get ();
289- 				matchingElement .setVisible (false );
290- 			}
291- 		}
292- 
293- 		invalidateCache ();
241+ 		// ignore this, it's handled by onIngredientVisibilityChanged 
294242	}
295243
296244	private  record  SearchTokens (List <ElementPrefixParser .TokenInfo > toSearch , List <ElementPrefixParser .TokenInfo > toRemove ) {
0 commit comments