Skip to content

Commit 47807de

Browse files
committed
Remove almost all the remaining recipe input cache related capturing lambdas
1 parent eb8c3bc commit 47807de

15 files changed

+219
-112
lines changed

src/main/java/mekanism/common/recipe/IMekanismRecipeTypeProvider.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,24 @@ default Stream<RecipeHolder<RECIPE>> stream(@Nullable Level world) {
4848
*/
4949
@Nullable
5050
default RECIPE findFirst(@Nullable Level world, Predicate<RECIPE> matchCriteria) {
51-
return stream(world).map(RecipeHolder::value).filter(matchCriteria).findFirst().orElse(null);
51+
for (RecipeHolder<RECIPE> recipeRecipeHolder : getRecipes(world)) {
52+
RECIPE value = recipeRecipeHolder.value();
53+
if (matchCriteria.test(value)) {
54+
return value;
55+
}
56+
}
57+
return null;
5258
}
5359

5460
/**
5561
* Checks if this recipe type contains a recipe that matches the given criteria. Prefer using the contains recipe methods in {@link #getInputCache()}.
5662
*/
5763
default boolean contains(@Nullable Level world, Predicate<RECIPE> matchCriteria) {
58-
return stream(world).anyMatch(holder -> matchCriteria.test(holder.value()));
64+
for (RecipeHolder<RECIPE> holder : getRecipes(world)) {
65+
if (matchCriteria.test(holder.value())) {
66+
return true;
67+
}
68+
}
69+
return false;
5970
}
6071
}

src/main/java/mekanism/common/recipe/ingredient/IMultiIngredient.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package mekanism.common.recipe.ingredient;
22

33
import java.util.List;
4+
import java.util.function.BiPredicate;
45
import java.util.function.Predicate;
56
import mekanism.api.recipes.ingredients.InputIngredient;
67
import org.jetbrains.annotations.NotNull;
@@ -14,6 +15,13 @@ public interface IMultiIngredient<TYPE, INGREDIENT extends InputIngredient<@NotN
1415
*/
1516
boolean forEachIngredient(Predicate<INGREDIENT> checker);
1617

18+
/**
19+
* For use in recipe input caching, checks all ingredients even if some match.
20+
*
21+
* @return {@code true} if any ingredient matches.
22+
*/
23+
<DATA> boolean forEachIngredient(DATA data, BiPredicate<DATA, INGREDIENT> checker);
24+
1725
/**
1826
* @apiNote For use in flattening multi ingredients, this should return an immutable view.
1927
*/

src/main/java/mekanism/common/recipe/ingredient/chemical/MultiChemicalStackIngredient.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import java.util.ArrayList;
55
import java.util.Arrays;
66
import java.util.List;
7+
import java.util.function.BiPredicate;
78
import java.util.function.Function;
89
import java.util.function.Predicate;
910
import mekanism.api.chemical.Chemical;
@@ -132,6 +133,15 @@ public boolean forEachIngredient(Predicate<INGREDIENT> checker) {
132133
return result;
133134
}
134135

136+
@Override
137+
public <DATA> boolean forEachIngredient(DATA data, BiPredicate<DATA, INGREDIENT> checker) {
138+
boolean result = false;
139+
for (INGREDIENT ingredient : ingredients) {
140+
result |= checker.test(data, ingredient);
141+
}
142+
return result;
143+
}
144+
135145
@Override
136146
public void write(FriendlyByteBuf buffer) {
137147
buffer.writeEnum(IngredientType.MULTI);

src/main/java/mekanism/common/recipe/ingredient/creator/FluidStackIngredientCreator.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import java.util.Collections;
99
import java.util.List;
1010
import java.util.Objects;
11+
import java.util.function.BiPredicate;
1112
import java.util.function.Function;
1213
import java.util.function.Predicate;
1314
import java.util.stream.Stream;
@@ -390,6 +391,15 @@ public boolean forEachIngredient(Predicate<FluidStackIngredient> checker) {
390391
return result;
391392
}
392393

394+
@Override
395+
public <DATA> boolean forEachIngredient(DATA data, BiPredicate<DATA, FluidStackIngredient> checker) {
396+
boolean result = false;
397+
for (FluidStackIngredient ingredient : ingredients) {
398+
result |= checker.test(data, ingredient);
399+
}
400+
return result;
401+
}
402+
393403
@Override
394404
public final List<FluidStackIngredient> getIngredients() {
395405
return List.of(ingredients);

src/main/java/mekanism/common/recipe/ingredient/creator/ItemStackIngredientCreator.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import java.util.Collections;
99
import java.util.List;
1010
import java.util.Objects;
11+
import java.util.function.BiPredicate;
1112
import java.util.function.Function;
1213
import java.util.function.Predicate;
1314
import java.util.stream.Stream;
@@ -279,6 +280,15 @@ public boolean forEachIngredient(Predicate<SingleItemStackIngredient> checker) {
279280
return result;
280281
}
281282

283+
@Override
284+
public <DATA> boolean forEachIngredient(DATA data, BiPredicate<DATA, SingleItemStackIngredient> checker) {
285+
boolean result = false;
286+
for (SingleItemStackIngredient ingredient : ingredients) {
287+
result |= checker.test(data, ingredient);
288+
}
289+
return result;
290+
}
291+
282292
@Override
283293
public final List<SingleItemStackIngredient> getIngredients() {
284294
return List.of(ingredients);

src/main/java/mekanism/common/recipe/lookup/cache/AbstractInputRecipeCache.java

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
package mekanism.common.recipe.lookup.cache;
22

3-
import java.util.Collection;
43
import java.util.List;
54
import java.util.Set;
65
import java.util.function.Function;
7-
import java.util.function.Predicate;
86
import mekanism.api.recipes.MekanismRecipe;
97
import mekanism.api.recipes.ingredients.InputIngredient;
108
import mekanism.common.recipe.MekanismRecipeType;
@@ -48,21 +46,6 @@ protected void initCacheIfNeeded(@Nullable Level world) {
4846
*/
4947
protected abstract void initCache(List<RecipeHolder<RECIPE>> recipes);
5048

51-
/**
52-
* Helper to filter a potentially null collection of recipes by a given predicate.
53-
*/
54-
@Nullable
55-
protected RECIPE findFirstRecipe(@Nullable Collection<RECIPE> recipes, Predicate<RECIPE> matchCriteria) {
56-
if (recipes != null) {
57-
for (RECIPE recipe : recipes) {
58-
if (matchCriteria.test(recipe)) {
59-
return recipe;
60-
}
61-
}
62-
}
63-
return null;
64-
}
65-
6649
/**
6750
* Helper to check if a cache contains a given input, or if not, if the complex recipe fallback set contains a matching recipe.
6851
*/
@@ -105,8 +88,10 @@ INGREDIENT_2 extends InputIngredient<INPUT_2>, CACHE_2 extends IInputCache<INPUT
10588
}
10689
initCacheIfNeeded(world);
10790
//Note: If cache 1 contains input 1 then we only need to test the type of input 2 as we already know input 1 matches
108-
if (cache1.contains(input1, recipe -> input2Extractor.apply(recipe).testType(input2))) {
109-
return true;
91+
for (RECIPE recipe : cache1.getRecipes(input1)) {
92+
if (input2Extractor.apply(recipe).testType(input2)) {
93+
return true;
94+
}
11095
}
11196
//Our quick lookup 1 cache does not contain it, check any recipes where the 1 ingredient was complex
11297
for (RECIPE recipe : complexIngredients1) {

src/main/java/mekanism/common/recipe/lookup/cache/ChemicalCrystallizerInputRecipeCache.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import java.util.List;
66
import java.util.Map;
77
import java.util.Set;
8-
import java.util.function.Predicate;
98
import mekanism.api.chemical.Chemical;
109
import mekanism.api.chemical.ChemicalStack;
1110
import mekanism.api.chemical.ChemicalType;
@@ -125,10 +124,20 @@ public ChemicalCrystallizerRecipe findFirstRecipe(@Nullable Level world, BoxedCh
125124
@Nullable
126125
@SuppressWarnings("unchecked")
127126
private <CHEMICAL extends Chemical<CHEMICAL>, STACK extends ChemicalStack<CHEMICAL>> ChemicalCrystallizerRecipe findFirstRecipe(ChemicalType type, STACK stack) {
128-
Predicate<ChemicalCrystallizerRecipe> matchPredicate = recipe -> ((ChemicalStackIngredient<CHEMICAL, STACK>) recipe.getInput()).test(stack);
129127
ChemicalInputCache<CHEMICAL, STACK, ChemicalCrystallizerRecipe> cache = (ChemicalInputCache<CHEMICAL, STACK, ChemicalCrystallizerRecipe>) typeBasedCache.get(type);
130-
ChemicalCrystallizerRecipe recipe = cache.findFirstRecipe(stack, matchPredicate);
131-
return recipe == null ? findFirstRecipe(typeBasedComplexRecipes.get(type), matchPredicate) : recipe;
128+
ChemicalCrystallizerRecipe recipe = findFirstRecipe(stack, cache.getRecipes(stack));
129+
return recipe == null ? findFirstRecipe(stack, typeBasedComplexRecipes.get(type)) : recipe;
130+
}
131+
132+
@Nullable
133+
@SuppressWarnings("unchecked")
134+
private <CHEMICAL extends Chemical<CHEMICAL>, STACK extends ChemicalStack<CHEMICAL>> ChemicalCrystallizerRecipe findFirstRecipe(STACK input, Iterable<ChemicalCrystallizerRecipe> recipes) {
135+
for (ChemicalCrystallizerRecipe recipe : recipes) {
136+
if (((ChemicalStackIngredient<CHEMICAL, STACK>) recipe.getInput()).test(input)) {
137+
return recipe;
138+
}
139+
}
140+
return null;
132141
}
133142

134143
@Override

src/main/java/mekanism/common/recipe/lookup/cache/DoubleInputRecipeCache.java

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -144,16 +144,25 @@ public RECIPE findFirstRecipe(@Nullable Level world, INPUT_A inputA, INPUT_B inp
144144
return null;
145145
}
146146
initCacheIfNeeded(world);
147-
Predicate<RECIPE> matchPredicate = r -> r.test(inputA, inputB);
148147
//Lookup a recipe from the specified input map
149148
RECIPE recipe;
150149
if (useCacheA) {
151-
recipe = cacheA.findFirstRecipe(inputA, matchPredicate);
150+
recipe = findFirstRecipe(inputA, inputB, cacheA.getRecipes(inputA));
152151
} else {
153-
recipe = cacheB.findFirstRecipe(inputB, matchPredicate);
152+
recipe = findFirstRecipe(inputA, inputB, cacheB.getRecipes(inputB));
154153
}
155154
// if there is no recipe, then check if any of our complex recipes (either a or b being complex) match
156-
return recipe == null ? findFirstRecipe(complexRecipes, matchPredicate) : recipe;
155+
return recipe == null ? findFirstRecipe(inputA, inputB, complexRecipes) : recipe;
156+
}
157+
158+
@Nullable
159+
private RECIPE findFirstRecipe(INPUT_A inputA, INPUT_B inputB, Iterable<RECIPE> recipes) {
160+
for (RECIPE recipe : recipes) {
161+
if (recipe.test(inputA, inputB)) {
162+
return recipe;
163+
}
164+
}
165+
return null;
157166
}
158167

159168
/**
@@ -175,18 +184,31 @@ public RECIPE findTypeBasedRecipe(@Nullable Level world, INPUT_A inputA, INPUT_B
175184
return null;
176185
}
177186
initCacheIfNeeded(world);
178-
Predicate<RECIPE> matchPredicate;
179187
if (cacheB.isEmpty(inputB)) {
180188
//If b is empty, lookup by A and our match criteria
181-
matchPredicate = matchCriteria;
189+
RECIPE recipe = cacheA.findFirstRecipe(inputA, matchCriteria);
190+
if (recipe == null) {
191+
for (RECIPE complexRecipe : complexRecipes) {
192+
if (inputAExtractor.apply(complexRecipe).testType(inputA) && matchCriteria.test(complexRecipe)) {
193+
return complexRecipe;
194+
}
195+
}
196+
}
182197
} else {
183-
matchPredicate = recipe -> inputBExtractor.apply(recipe).testType(inputB) && matchCriteria.test(recipe);
184-
}
185-
RECIPE recipe = cacheA.findFirstRecipe(inputA, matchPredicate);
186-
if (recipe == null) {
187-
return findFirstRecipe(complexRecipes, r -> inputAExtractor.apply(r).testType(inputA) && matchPredicate.test(r));
198+
for (RECIPE recipe : cacheA.getRecipes(inputA)) {
199+
if (inputBExtractor.apply(recipe).testType(inputB) && matchCriteria.test(recipe)) {
200+
return recipe;
201+
}
202+
}
203+
for (RECIPE complexRecipe : complexRecipes) {
204+
if (inputAExtractor.apply(complexRecipe).testType(inputA)) {
205+
if (inputBExtractor.apply(complexRecipe).testType(inputB) && matchCriteria.test(complexRecipe)) {
206+
return complexRecipe;
207+
}
208+
}
209+
}
188210
}
189-
return recipe;
211+
return null;
190212
}
191213

192214
@Override

src/main/java/mekanism/common/recipe/lookup/cache/EitherSideInputRecipeCache.java

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import java.util.Set;
66
import java.util.function.BiPredicate;
77
import java.util.function.Function;
8-
import java.util.function.Predicate;
98
import mekanism.api.recipes.MekanismRecipe;
109
import mekanism.api.recipes.ingredients.InputIngredient;
1110
import mekanism.common.recipe.MekanismRecipeType;
@@ -92,18 +91,18 @@ public boolean containsInput(@Nullable Level world, INPUT inputA, INPUT inputB)
9291
// secondary validation we check inputB first as we know the recipe contains inputA as one of the
9392
// inputs, but we want to make sure that we only mark it as valid if the same input is on both sides
9493
// if the recipe combines two of the same type of ingredient
95-
if (cache.contains(inputA, recipe -> {
96-
INGREDIENT ingredientA = inputAExtractor.apply(recipe);
97-
INGREDIENT ingredientB = inputBExtractor.apply(recipe);
98-
return ingredientB.testType(inputB) && ingredientA.testType(inputA) || ingredientA.testType(inputB) && ingredientB.testType(inputA);
99-
})) {
94+
if (containsInput(inputA, inputB, cache.getRecipes(inputA))) {
10095
return true;
10196
}
10297
//Our quick lookup cache does not contain it, check any recipes where the ingredients are complex
103-
for (RECIPE complexRecipe : complexRecipes) {
104-
INGREDIENT ingredientA = inputAExtractor.apply(complexRecipe);
105-
INGREDIENT ingredientB = inputBExtractor.apply(complexRecipe);
106-
if (ingredientA.testType(inputA) && ingredientB.testType(inputB) || ingredientB.testType(inputA) && ingredientA.testType(inputB)) {
98+
return containsInput(inputA, inputB, complexRecipes);
99+
}
100+
101+
private boolean containsInput(INPUT inputA, INPUT inputB, Iterable<RECIPE> recipes) {
102+
for (RECIPE recipe : recipes) {
103+
INGREDIENT ingredientA = inputAExtractor.apply(recipe);
104+
INGREDIENT ingredientB = inputBExtractor.apply(recipe);
105+
if (ingredientB.testType(inputB) && ingredientA.testType(inputA) || ingredientA.testType(inputB) && ingredientB.testType(inputA)) {
107106
return true;
108107
}
109108
}
@@ -126,12 +125,21 @@ public RECIPE findFirstRecipe(@Nullable Level world, INPUT inputA, INPUT inputB)
126125
return null;
127126
}
128127
initCacheIfNeeded(world);
129-
//Note: The recipe's test method checks both directions
130-
Predicate<RECIPE> matchPredicate = r -> r.test(inputA, inputB);
131128
//Lookup a recipe from the input map
132-
RECIPE recipe = cache.findFirstRecipe(inputA, matchPredicate);
129+
RECIPE recipe = findFirstRecipe(inputA, inputB, cache.getRecipes(inputA));
133130
// if there is no recipe, then check if any of our complex recipes match
134-
return recipe == null ? findFirstRecipe(complexRecipes, matchPredicate) : recipe;
131+
return recipe == null ? findFirstRecipe(inputA, inputB, complexRecipes) : recipe;
132+
}
133+
134+
@Nullable
135+
private RECIPE findFirstRecipe(INPUT inputA, INPUT inputB, Iterable<RECIPE> recipes) {
136+
for (RECIPE recipe : recipes) {
137+
//Note: The recipe's test method checks both directions
138+
if (recipe.test(inputA, inputB)) {
139+
return recipe;
140+
}
141+
}
142+
return null;
135143
}
136144

137145
@Override

src/main/java/mekanism/common/recipe/lookup/cache/RotaryInputRecipeCache.java

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import java.util.HashSet;
44
import java.util.List;
55
import java.util.Set;
6-
import java.util.function.Predicate;
76
import mekanism.api.chemical.gas.Gas;
87
import mekanism.api.chemical.gas.GasStack;
98
import mekanism.api.recipes.RotaryRecipe;
@@ -78,9 +77,18 @@ public RotaryRecipe findFirstRecipe(@Nullable Level world, FluidStack input) {
7877
return null;
7978
}
8079
initCacheIfNeeded(world);
81-
Predicate<RotaryRecipe> matchPredicate = recipe -> recipe.test(input);
82-
RotaryRecipe recipe = fluidInputCache.findFirstRecipe(input, matchPredicate);
83-
return recipe == null ? findFirstRecipe(complexFluidInputRecipes, matchPredicate) : recipe;
80+
RotaryRecipe recipe = findFirstRecipe(input, fluidInputCache.getRecipes(input));
81+
return recipe == null ? findFirstRecipe(input, complexFluidInputRecipes) : recipe;
82+
}
83+
84+
@Nullable
85+
private RotaryRecipe findFirstRecipe(FluidStack input, Iterable<RotaryRecipe> recipes) {
86+
for (RotaryRecipe recipe : recipes) {
87+
if (recipe.test(input)) {
88+
return recipe;
89+
}
90+
}
91+
return null;
8492
}
8593

8694
/**
@@ -98,9 +106,18 @@ public RotaryRecipe findFirstRecipe(@Nullable Level world, GasStack input) {
98106
return null;
99107
}
100108
initCacheIfNeeded(world);
101-
Predicate<RotaryRecipe> matchPredicate = recipe -> recipe.test(input);
102-
RotaryRecipe recipe = gasInputCache.findFirstRecipe(input, matchPredicate);
103-
return recipe == null ? findFirstRecipe(complexGasInputRecipes, matchPredicate) : recipe;
109+
RotaryRecipe recipe = findFirstRecipe(input, gasInputCache.getRecipes(input));
110+
return recipe == null ? findFirstRecipe(input, complexGasInputRecipes) : recipe;
111+
}
112+
113+
@Nullable
114+
private RotaryRecipe findFirstRecipe(GasStack input, Iterable<RotaryRecipe> recipes) {
115+
for (RotaryRecipe recipe : recipes) {
116+
if (recipe.test(input)) {
117+
return recipe;
118+
}
119+
}
120+
return null;
104121
}
105122

106123
@Override

0 commit comments

Comments
 (0)