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,29 +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- 	@ Nullable 
134- 	public  <V > IListElement <V > searchForMatchingElement (
135- 		IIngredientHelper <V > ingredientHelper ,
136- 		ITypedIngredient <V > typedIngredient 
137- 	) {
138- 		V  ingredient  = typedIngredient .getIngredient ();
139- 		IIngredientType <V > type  = typedIngredient .getType ();
140- 		Function <ITypedIngredient <V >, Object > uidFunction  = (i ) -> ingredientHelper .getUid (i , UidContext .Ingredient );
141- 		Object  ingredientUid  = uidFunction .apply (typedIngredient );
142- 		String  lowercaseDisplayName  = DisplayNameUtil .getLowercaseDisplayNameForSearch (ingredient , ingredientHelper );
143- 
144- 		ElementPrefixParser .TokenInfo  tokenInfo  = new  ElementPrefixParser .TokenInfo (lowercaseDisplayName , ElementPrefixParser .NO_PREFIX );
145- 		Set <IListElement <?>> searchResults  = this .elementSearch .getSearchResults (tokenInfo );
146- 		for  (IListElement <?> element  : searchResults ) {
147- 			IListElement <V > match  = checkForMatch (element , type , ingredientUid , uidFunction );
148- 			if  (match  != null ) {
149- 				return  match ;
150- 			}
151- 		}
152- 		return  null ;
128+ 		this .elementSearch .addAll (elementInfos , ingredientManager );
153129	}
154130
155131	@ Override 
@@ -163,12 +139,12 @@ public void updateHidden() {
163139			changed  |= updateHiddenState (element );
164140		}
165141		if  (changed ) {
166- 			ingredientListCached  =  null ;
142+ 			invalidateCache () ;
167143			notifyListenersOfChange ();
168144		}
169145	}
170146
171- 	public  <V > boolean  updateHiddenState (IListElement <V > element ) {
147+ 	private  <V > boolean  updateHiddenState (IListElement <V > element ) {
172148		ITypedIngredient <V > typedIngredient  = element .getTypedIngredient ();
173149		boolean  visible  = this .ingredientVisibility .isIngredientVisible (typedIngredient );
174150		if  (element .isVisible () != visible ) {
@@ -182,9 +158,10 @@ public <V> boolean updateHiddenState(IListElement<V> element) {
182158	public  <V > void  onIngredientVisibilityChanged (ITypedIngredient <V > ingredient , boolean  visible ) {
183159		IIngredientType <V > ingredientType  = ingredient .getType ();
184160		IIngredientHelper <V > ingredientHelper  = ingredientManager .getIngredientHelper (ingredientType );
185- 		IListElement <V > match  = searchForMatchingElement ( ingredientHelper ,  ingredient );
161+ 		IListElement <V > match  = this . elementSearch . findElement ( ingredient ,  ingredientHelper );
186162		if  (match  != null  && match .isVisible () != visible ) {
187163			match .setVisible (visible );
164+ 			invalidateCache ();
188165			notifyListenersOfChange ();
189166		}
190167	}
@@ -234,35 +211,10 @@ private Stream<ITypedIngredient<?>> getIngredientListUncached(String filterText)
234211			.map (IListElement ::getTypedIngredient );
235212	}
236213
237- 	@ Nullable 
238- 	private  static  <T > IListElement <T > checkForMatch (IListElement <?> element , IIngredientType <T > ingredientType , Object  uid , Function <ITypedIngredient <T >, Object > uidFunction ) {
239- 		IListElement <T > cast  = optionalCast (element , ingredientType );
240- 		if  (cast  == null ) {
241- 			return  null ;
242- 		}
243- 		ITypedIngredient <T > typedIngredient  = cast .getTypedIngredient ();
244- 		Object  elementUid  = uidFunction .apply (typedIngredient );
245- 		if  (uid .equals (elementUid )) {
246- 			return  cast ;
247- 		}
248- 		return  null ;
249- 	}
250- 
251- 	@ Nullable 
252- 	private  static  <T > IListElement <T > optionalCast (IListElement <?> element , IIngredientType <T > ingredientType ) {
253- 		ITypedIngredient <?> typedIngredient  = element .getTypedIngredient ();
254- 		if  (typedIngredient .getType () == ingredientType ) {
255- 			@ SuppressWarnings ("unchecked" )
256- 			IListElement <T > cast  = (IListElement <T >) element ;
257- 			return  cast ;
258- 		}
259- 		return  null ;
260- 	}
261- 
262214	@ Override 
263215	public  <V > void  onIngredientsAdded (IIngredientHelper <V > ingredientHelper , Collection <ITypedIngredient <V >> ingredients ) {
264216		for  (ITypedIngredient <V > value  : ingredients ) {
265- 			IListElement <V > matchingElement  = searchForMatchingElement ( ingredientHelper ,  value );
217+ 			IListElement <V > matchingElement  = this . elementSearch . findElement ( value ,  ingredientHelper );
266218			if  (matchingElement  != null ) {
267219				updateHiddenState (matchingElement );
268220				if  (DebugConfig .isDebugModeEnabled ()) {
@@ -283,20 +235,7 @@ public <V> void onIngredientsAdded(IIngredientHelper<V> ingredientHelper, Collec
283235
284236	@ Override 
285237	public  <V > void  onIngredientsRemoved (IIngredientHelper <V > ingredientHelper , Collection <ITypedIngredient <V >> ingredients ) {
286- 		for  (ITypedIngredient <V > typedIngredient  : ingredients ) {
287- 			IListElement <V > matchingElement  = searchForMatchingElement (ingredientHelper , typedIngredient );
288- 			if  (matchingElement  == null ) {
289- 				String  errorInfo  = ingredientHelper .getErrorInfo (typedIngredient .getIngredient ());
290- 				LOGGER .error ("Could not find a matching ingredient to remove: {}" , errorInfo );
291- 			} else  {
292- 				if  (DebugConfig .isDebugModeEnabled ()) {
293- 					LOGGER .debug ("Removed ingredient: {}" , ingredientHelper .getErrorInfo (typedIngredient .getIngredient ()));
294- 				}
295- 				matchingElement .setVisible (false );
296- 			}
297- 		}
298- 
299- 		invalidateCache ();
238+ 		// ignore this, it's handled by onIngredientVisibilityChanged 
300239	}
301240
302241	private  record  SearchTokens (List <ElementPrefixParser .TokenInfo > toSearch , List <ElementPrefixParser .TokenInfo > toRemove ) {
0 commit comments