aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/gregtech/api/logic
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/gregtech/api/logic')
-rw-r--r--src/main/java/gregtech/api/logic/ComplexParallelProcessingLogic.java7
-rw-r--r--src/main/java/gregtech/api/logic/ProcessingLogic.java174
2 files changed, 90 insertions, 91 deletions
diff --git a/src/main/java/gregtech/api/logic/ComplexParallelProcessingLogic.java b/src/main/java/gregtech/api/logic/ComplexParallelProcessingLogic.java
index 05d39cd02c..3c7974db9e 100644
--- a/src/main/java/gregtech/api/logic/ComplexParallelProcessingLogic.java
+++ b/src/main/java/gregtech/api/logic/ComplexParallelProcessingLogic.java
@@ -6,6 +6,7 @@ import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.FluidStack;
import gregtech.api.multitileentity.multiblock.base.Controller;
+import gregtech.api.recipe.RecipeMap;
import gregtech.api.util.GT_OverclockCalculator;
import gregtech.api.util.GT_ParallelHelper;
import gregtech.api.util.GT_Recipe;
@@ -13,7 +14,7 @@ import gregtech.api.util.GT_Recipe;
public class ComplexParallelProcessingLogic {
protected Controller<?> tileEntity;
- protected GT_Recipe.GT_Recipe_Map recipeMap;
+ protected RecipeMap<?> recipeMap;
protected boolean hasPerfectOverclock;
protected final int maxComplexParallels;
protected final ItemStack[][] outputItems;
@@ -30,7 +31,7 @@ public class ComplexParallelProcessingLogic {
this(null, maxComplexParallels);
}
- public ComplexParallelProcessingLogic(GT_Recipe.GT_Recipe_Map recipeMap, int maxComplexParallels) {
+ public ComplexParallelProcessingLogic(RecipeMap<?> recipeMap, int maxComplexParallels) {
this.maxComplexParallels = maxComplexParallels;
this.recipeMap = recipeMap;
inputItems = new ItemStack[maxComplexParallels][];
@@ -44,7 +45,7 @@ public class ComplexParallelProcessingLogic {
isFluidVoidProtected = new boolean[maxComplexParallels];
}
- public ComplexParallelProcessingLogic setRecipeMap(GT_Recipe.GT_Recipe_Map recipeMap) {
+ public ComplexParallelProcessingLogic setRecipeMap(RecipeMap<?> recipeMap) {
this.recipeMap = recipeMap;
return this;
}
diff --git a/src/main/java/gregtech/api/logic/ProcessingLogic.java b/src/main/java/gregtech/api/logic/ProcessingLogic.java
index 803abafbe3..6b9f2d454f 100644
--- a/src/main/java/gregtech/api/logic/ProcessingLogic.java
+++ b/src/main/java/gregtech/api/logic/ProcessingLogic.java
@@ -2,6 +2,7 @@ package gregtech.api.logic;
import java.util.List;
import java.util.function.Supplier;
+import java.util.stream.Stream;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -13,15 +14,13 @@ import org.jetbrains.annotations.NotNull;
import gregtech.api.interfaces.tileentity.IRecipeLockable;
import gregtech.api.interfaces.tileentity.IVoidable;
+import gregtech.api.recipe.RecipeMap;
import gregtech.api.recipe.check.CheckRecipeResult;
import gregtech.api.recipe.check.CheckRecipeResultRegistry;
-import gregtech.api.recipe.check.FindRecipeResult;
-import gregtech.api.recipe.check.RecipeValidator;
import gregtech.api.recipe.check.SingleRecipeCheck;
import gregtech.api.util.GT_OverclockCalculator;
import gregtech.api.util.GT_ParallelHelper;
import gregtech.api.util.GT_Recipe;
-import gregtech.api.util.GT_Recipe.GT_Recipe_Map;
/**
* Logic class to calculate result of recipe check from inputs, based on recipemap.
@@ -31,9 +30,9 @@ public class ProcessingLogic {
protected IVoidable machine;
protected IRecipeLockable recipeLockableMachine;
- protected Supplier<GT_Recipe_Map> recipeMapSupplier;
+ protected Supplier<RecipeMap<?>> recipeMapSupplier;
protected GT_Recipe lastRecipe;
- protected GT_Recipe_Map lastRecipeMap;
+ protected RecipeMap<?> lastRecipeMap;
protected ItemStack specialSlotItem;
protected ItemStack[] inputItems;
protected ItemStack[] outputItems;
@@ -146,11 +145,11 @@ public class ProcessingLogic {
return this;
}
- public ProcessingLogic setRecipeMap(GT_Recipe_Map recipeMap) {
+ public ProcessingLogic setRecipeMap(RecipeMap<?> recipeMap) {
return setRecipeMapSupplier(() -> recipeMap);
}
- public ProcessingLogic setRecipeMapSupplier(Supplier<GT_Recipe_Map> supplier) {
+ public ProcessingLogic setRecipeMapSupplier(Supplier<RecipeMap<?>> supplier) {
this.recipeMapSupplier = supplier;
return this;
}
@@ -263,7 +262,7 @@ public class ProcessingLogic {
*/
@Nonnull
public CheckRecipeResult process() {
- GT_Recipe_Map recipeMap;
+ RecipeMap<?> recipeMap;
if (recipeMapSupplier == null) {
recipeMap = null;
} else {
@@ -278,6 +277,13 @@ public class ProcessingLogic {
maxParallel = maxParallelSupplier.get();
}
+ if (inputItems == null) {
+ inputItems = new ItemStack[0];
+ }
+ if (inputFluids == null) {
+ inputFluids = new FluidStack[0];
+ }
+
if (isRecipeLocked && recipeLockableMachine != null && recipeLockableMachine.getSingleRecipeCheck() != null) {
// Recipe checker is already built, we'll use it
SingleRecipeCheck singleRecipeCheck = recipeLockableMachine.getSingleRecipeCheck();
@@ -287,55 +293,39 @@ public class ProcessingLogic {
return CheckRecipeResultRegistry.NO_RECIPE;
}
- return processRecipe(
+ return validateAndCalculateRecipe(
recipeLockableMachine.getSingleRecipeCheck()
- .getRecipe());
+ .getRecipe()).checkRecipeResult;
}
- FindRecipeResult findRecipeResult = findRecipe(recipeMap);
- // If processRecipe is not overridden, advanced recipe validation logic is used, and we can reuse calculations.
- if (findRecipeResult.hasRecipeValidator()) {
- RecipeValidator recipeValidator = findRecipeResult.getRecipeValidator();
-
- // There are two cases:
- // 1 - there are actually no matching recipes
- // 2 - there are some matching recipes, but we rejected it due to our advanced validation (e.g. OUTPUT_FULL)
- if (findRecipeResult.getState() == FindRecipeResult.State.NOT_FOUND
- && recipeValidator.getFirstCheckResult() != null) {
- // Here we're handling case 2
- // If there are matching recipes but our validation rejected them,
- // we should return a first one to display a proper error in the machine GUI
- return recipeValidator.getFirstCheckResult();
+ Stream<GT_Recipe> matchedRecipes = findRecipeMatches(recipeMap);
+ Iterable<GT_Recipe> recipeIterable = matchedRecipes::iterator;
+ CheckRecipeResult checkRecipeResult = CheckRecipeResultRegistry.NO_RECIPE;
+ for (GT_Recipe matchedRecipe : recipeIterable) {
+ CalculationResult foundResult = validateAndCalculateRecipe(matchedRecipe);
+ if (foundResult.successfullyConsumedInputs) {
+ // Successfully found and set recipe, so return it
+ return foundResult.checkRecipeResult;
}
-
- // If everything is ok, reuse our calculations
- if (recipeValidator.isExecutedAtLeastOnce() && findRecipeResult.isSuccessful()) {
- return applyRecipe(
- findRecipeResult.getRecipeNonNull(),
- recipeValidator.getLastParallelHelper(),
- recipeValidator.getLastOverclockCalculator(),
- recipeValidator.getLastCheckResult());
+ if (foundResult.checkRecipeResult != CheckRecipeResultRegistry.NO_RECIPE) {
+ // Recipe failed in interesting way, so remember that and continue searching
+ checkRecipeResult = foundResult.checkRecipeResult;
}
}
-
- if (!findRecipeResult.isSuccessful()) {
- return CheckRecipeResultRegistry.NO_RECIPE;
- }
-
- return processRecipe(findRecipeResult.getRecipeNonNull());
+ return checkRecipeResult;
}
/**
- * Checks if supplied recipe is valid for process.
- * If so, additionally performs input consumption, output calculation with parallel, and overclock calculation.
+ * Checks if supplied recipe is valid for process. This involves voltage check, output full check. If successful,
+ * additionally performs input consumption, output calculation with parallel, and overclock calculation.
*
* @param recipe The recipe which will be checked and processed
*/
@Nonnull
- protected CheckRecipeResult processRecipe(@Nonnull GT_Recipe recipe) {
+ private CalculationResult validateAndCalculateRecipe(@Nonnull GT_Recipe recipe) {
CheckRecipeResult result = validateRecipe(recipe);
if (!result.wasSuccessful()) {
- return result;
+ return CalculationResult.ofFailure(result);
}
GT_ParallelHelper helper = createParallelHelper(recipe);
@@ -343,19 +333,20 @@ public class ProcessingLogic {
helper.setCalculator(calculator);
helper.build();
- return applyRecipe(recipe, helper, calculator, result);
+ if (!helper.getResult()
+ .wasSuccessful()) {
+ return CalculationResult.ofFailure(helper.getResult());
+ }
+
+ return CalculationResult.ofSuccess(applyRecipe(recipe, helper, calculator, result));
}
/**
- * Applies the recipe and calculated parameters
+ * Check has been succeeded, so it applies the recipe and calculated parameters.
+ * At this point, inputs have been already consumed.
*/
private CheckRecipeResult applyRecipe(@NotNull GT_Recipe recipe, GT_ParallelHelper helper,
GT_OverclockCalculator calculator, CheckRecipeResult result) {
- if (!helper.getResult()
- .wasSuccessful()) {
- return helper.getResult();
- }
-
if (recipe.mCanBeBuffered) {
lastRecipe = recipe;
} else {
@@ -398,30 +389,31 @@ public class ProcessingLogic {
}
/**
- * Override if you don't work with regular gt recipe maps
+ * Finds a list of matched recipes. At this point no additional check to the matched recipe has been done.
+ * <p>
+ * Override {@link #validateRecipe} to have custom check.
+ * <p>
+ * Override this method if it doesn't work with normal recipemaps.
*/
@Nonnull
- protected FindRecipeResult findRecipe(@Nullable GT_Recipe_Map map) {
- if (map == null) return FindRecipeResult.NOT_FOUND;
-
- RecipeValidator recipeValidator = new RecipeValidator(
- this::validateRecipe,
- this::createParallelHelper,
- this::createOverclockCalculator);
-
- FindRecipeResult findRecipeResult = map.findRecipeWithResult(
- lastRecipe,
- recipeValidator,
- false,
- false,
- amperageOC ? availableVoltage * availableAmperage : availableVoltage,
- inputFluids,
- specialSlotItem,
- inputItems);
-
- findRecipeResult.setRecipeValidator(recipeValidator);
+ protected Stream<GT_Recipe> findRecipeMatches(@Nullable RecipeMap<?> map) {
+ if (map == null) {
+ return Stream.empty();
+ }
+ return map.findRecipeQuery()
+ .items(inputItems)
+ .fluids(inputFluids)
+ .specialSlot(specialSlotItem)
+ .cachedRecipe(lastRecipe)
+ .findAll();
+ }
- return findRecipeResult;
+ /**
+ * Override to do additional check for found recipe if needed.
+ */
+ @Nonnull
+ protected CheckRecipeResult validateRecipe(@Nonnull GT_Recipe recipe) {
+ return CheckRecipeResultRegistry.SUCCESSFUL;
}
/**
@@ -443,24 +435,6 @@ public class ProcessingLogic {
}
/**
- * Override to do additional check for finding recipe if needed, mainly for special value of the recipe.
- */
- @Nonnull
- protected CheckRecipeResult validateRecipe(@Nonnull GT_Recipe recipe) {
- return CheckRecipeResultRegistry.SUCCESSFUL;
- }
-
- /**
- * Use {@link #createOverclockCalculator(GT_Recipe)}
- */
- @Nonnull
- @Deprecated
- protected GT_OverclockCalculator createOverclockCalculator(@Nonnull GT_Recipe recipe,
- @Nullable GT_ParallelHelper helper) {
- return createOverclockCalculator(recipe);
- }
-
- /**
* Override to tweak overclock logic if needed.
*/
@Nonnull
@@ -514,4 +488,28 @@ public class ProcessingLogic {
}
// endregion
+
+ /**
+ * Represents the status of check recipe calculation. {@link #successfullyConsumedInputs} does not necessarily mean
+ * {@link #checkRecipeResult} being successful, when duration or power is overflowed. Being failure means
+ * recipe cannot meet requirements and recipe search should be continued if possible.
+ */
+ protected final static class CalculationResult {
+
+ public final boolean successfullyConsumedInputs;
+ public final CheckRecipeResult checkRecipeResult;
+
+ public static CalculationResult ofSuccess(CheckRecipeResult checkRecipeResult) {
+ return new CalculationResult(true, checkRecipeResult);
+ }
+
+ public static CalculationResult ofFailure(CheckRecipeResult checkRecipeResult) {
+ return new CalculationResult(false, checkRecipeResult);
+ }
+
+ private CalculationResult(boolean successfullyConsumedInputs, CheckRecipeResult checkRecipeResult) {
+ this.successfullyConsumedInputs = successfullyConsumedInputs;
+ this.checkRecipeResult = checkRecipeResult;
+ }
+ }
}