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 >, Object > uidFunction  = (i ) -> ingredientHelper .getUid (i , UidContext .Ingredient );
140- 		Object  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,13 +158,12 @@ 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 )
182- 			.ifPresent (element  -> {
183- 				if  (element .isVisible () != visible ) {
184- 					element .setVisible (visible );
185- 					notifyListenersOfChange ();
186- 				}
187- 			});
161+ 		IListElement <V > match  = this .elementSearch .findElement (ingredient , ingredientHelper );
162+ 		if  (match  != null  && match .isVisible () != visible ) {
163+ 			match .setVisible (visible );
164+ 			invalidateCache ();
165+ 			notifyListenersOfChange ();
166+ 		}
188167	}
189168
190169	@ Override 
@@ -232,31 +211,11 @@ private Stream<ITypedIngredient<?>> getIngredientListUncached(String filterText)
232211			.map (IListElement ::getTypedIngredient );
233212	}
234213
235- 	private  static  <T > Optional <IListElement <T >> checkForMatch (IListElement <?> element , IIngredientType <T > ingredientType , Object  uid , Function <ITypedIngredient <T >, Object > uidFunction ) {
236- 		return  optionalCast (element , ingredientType )
237- 			.filter (cast  -> {
238- 				ITypedIngredient <T > typedIngredient  = cast .getTypedIngredient ();
239- 				Object  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- 
254214	@ Override 
255215	public  <V > void  onIngredientsAdded (IIngredientHelper <V > ingredientHelper , Collection <ITypedIngredient <V >> ingredients ) {
256216		for  (ITypedIngredient <V > value  : ingredients ) {
257- 			Optional <IListElement <V >> matchingElementOptional  = searchForMatchingElement (ingredientHelper , value );
258- 			if  (matchingElementOptional .isPresent ()) {
259- 				IListElement <V > matchingElement  = matchingElementOptional .get ();
217+ 			IListElement <V > matchingElement  = this .elementSearch .findElement (value , ingredientHelper );
218+ 			if  (matchingElement  != null ) {
260219				updateHiddenState (matchingElement );
261220				if  (DebugConfig .isDebugModeEnabled ()) {
262221					LOGGER .debug ("Updated ingredient: {}" , ingredientHelper .getErrorInfo (value .getIngredient ()));
@@ -276,21 +235,7 @@ public <V> void onIngredientsAdded(IIngredientHelper<V> ingredientHelper, Collec
276235
277236	@ Override 
278237	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 ();
238+ 		// ignore this, it's handled by onIngredientVisibilityChanged 
294239	}
295240
296241	private  record  SearchTokens (List <ElementPrefixParser .TokenInfo > toSearch , List <ElementPrefixParser .TokenInfo > toRemove ) {
0 commit comments