Skip to content

Commit

Permalink
allow multiple build actions per recipemap (GregTechCEu#2278)
Browse files Browse the repository at this point in the history
  • Loading branch information
TechLord22 authored Mar 28, 2024
1 parent aff043c commit edbdaf4
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 60 deletions.
17 changes: 17 additions & 0 deletions src/main/java/gregtech/api/recipes/RecipeBuildAction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package gregtech.api.recipes;

import org.jetbrains.annotations.NotNull;

@FunctionalInterface
public interface RecipeBuildAction<R extends RecipeBuilder<R>> {

/**
* Process a RecipeBuilder to perform an action with.
* <p>
* <strong>Do not call {@link RecipeBuilder#buildAndRegister()} on the passed builder.</strong>
* It is safe to do so only on other builders, i.e. created through {@link RecipeBuilder#copy()}.
*
* @param builder the builder to utilize
*/
void accept(@NotNull R builder);
}
46 changes: 31 additions & 15 deletions src/main/java/gregtech/api/recipes/RecipeBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@
import gregtech.api.recipes.chance.output.ChancedOutputLogic;
import gregtech.api.recipes.chance.output.impl.ChancedFluidOutput;
import gregtech.api.recipes.chance.output.impl.ChancedItemOutput;
import gregtech.api.recipes.ingredients.*;
import gregtech.api.recipes.ingredients.GTRecipeFluidInput;
import gregtech.api.recipes.ingredients.GTRecipeInput;
import gregtech.api.recipes.ingredients.GTRecipeItemInput;
import gregtech.api.recipes.ingredients.GTRecipeOreInput;
import gregtech.api.recipes.ingredients.IntCircuitIngredient;
import gregtech.api.recipes.ingredients.nbtmatch.NBTCondition;
import gregtech.api.recipes.ingredients.nbtmatch.NBTMatcher;
import gregtech.api.recipes.recipeproperties.CleanroomProperty;
Expand Down Expand Up @@ -43,11 +47,17 @@
import it.unimi.dsi.fastutil.ints.IntList;
import it.unimi.dsi.fastutil.ints.IntLists;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.MustBeInvokedByOverriders;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.*;
import java.util.function.Consumer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
* @see Recipe
Expand All @@ -74,9 +84,8 @@ public class RecipeBuilder<R extends RecipeBuilder<R>> {
protected GTRecipeCategory category;
protected boolean isCTRecipe = false;
protected int parallel = 0;
protected Consumer<R> onBuildAction = null;
protected EnumValidationResult recipeStatus = EnumValidationResult.VALID;
protected IRecipePropertyStorage recipePropertyStorage = null;
protected @Nullable IRecipePropertyStorage recipePropertyStorage = null;
protected boolean recipePropertyStorageErrored = false;

protected RecipeBuilder() {
Expand Down Expand Up @@ -125,8 +134,8 @@ protected RecipeBuilder(RecipeBuilder<R> recipeBuilder) {
this.EUt = recipeBuilder.EUt;
this.hidden = recipeBuilder.hidden;
this.category = recipeBuilder.category;
this.onBuildAction = recipeBuilder.onBuildAction;
this.recipePropertyStorage = recipeBuilder.recipePropertyStorage;
this.recipePropertyStorage = recipeBuilder.recipePropertyStorage == null ? null :
recipeBuilder.recipePropertyStorage.copy();
if (this.recipePropertyStorage != null) {
this.recipePropertyStorage = this.recipePropertyStorage.copy();
}
Expand Down Expand Up @@ -933,19 +942,26 @@ protected static String getRequiredString(int max, int actual, @NotNull String t
return out;
}

protected R onBuild(Consumer<R> consumer) {
this.onBuildAction = consumer;
return (R) this;
}

/**
* @deprecated Obsolete. Does not need calling.
*/
@ApiStatus.Obsolete
@ApiStatus.ScheduledForRemoval(inVersion = "2.9")
@Deprecated
protected R invalidateOnBuildAction() {
this.onBuildAction = null;
return (R) this;
}

/**
* Build and register the recipe, if valid.
* <strong>Do not call outside of the
* {@link net.minecraftforge.event.RegistryEvent.Register<net.minecraft.item.crafting.IRecipe>} event for recipes.
* </strong>
*/
@MustBeInvokedByOverriders
public void buildAndRegister() {
if (onBuildAction != null) {
onBuildAction.accept((R) this);
for (RecipeBuildAction<R> action : recipeMap.getBuildActions()) {
action.accept((R) this);
}
ValidationResult<Recipe> validationResult = build();
recipeMap.addRecipe(validationResult);
Expand Down
55 changes: 45 additions & 10 deletions src/main/java/gregtech/api/recipes/RecipeMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@

import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundEvent;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fml.common.Optional.Method;
Expand All @@ -59,6 +60,7 @@
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.UnmodifiableView;
import stanhebben.zenscript.annotations.Optional;
import stanhebben.zenscript.annotations.ZenClass;
import stanhebben.zenscript.annotations.ZenGetter;
Expand All @@ -75,9 +77,7 @@
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
import java.util.function.Consumer;
import java.util.function.DoubleSupplier;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -124,9 +124,9 @@ public class RecipeMap<R extends RecipeBuilder<R>> {

private final Map<GTRecipeCategory, List<Recipe>> recipeByCategory = new Object2ObjectOpenHashMap<>();

private Consumer<R> onRecipeBuildAction;
protected SoundEvent sound;
private RecipeMap<?> smallRecipeMap;
private final Map<ResourceLocation, RecipeBuildAction<R>> recipeBuildActions = new Object2ObjectOpenHashMap<>();
protected @Nullable SoundEvent sound;
private @Nullable RecipeMap<?> smallRecipeMap;

/**
* Create and register new instance of RecipeMap with specified properties. All
Expand All @@ -140,7 +140,7 @@ public class RecipeMap<R extends RecipeBuilder<R>> {
* @param defaultRecipeBuilder the default RecipeBuilder for the RecipeMap
* @param isHidden if the RecipeMap should have a category in JEI
*
* @deprecated {@link #RecipeMap(String, RecipeBuilder, Function, int, int, int, int)}
* @deprecated {@link RecipeMap#RecipeMap(String, R, RecipeMapUIFunction, int, int, int, int)}
*/
@ApiStatus.ScheduledForRemoval(inVersion = "2.9")
@Deprecated
Expand Down Expand Up @@ -169,7 +169,7 @@ public RecipeMap(@NotNull String unlocalizedName,
* @param defaultRecipeBuilder the default RecipeBuilder for the RecipeMap
* @param isHidden if the RecipeMap should have a category in JEI
*
* @deprecated {@link #RecipeMap(String, RecipeBuilder, Function, int, int, int, int)}
* @deprecated {@link RecipeMap#RecipeMap(String, R, RecipeMapUIFunction, int, int, int, int)}
*/
@ApiStatus.ScheduledForRemoval(inVersion = "2.9")
@Deprecated
Expand Down Expand Up @@ -311,11 +311,46 @@ public RecipeMap<R> setChanceFunction(@NotNull ChanceBoostFunction function) {
return this;
}

public RecipeMap<R> onRecipeBuild(Consumer<R> consumer) {
onRecipeBuildAction = consumer;
/**
* Add a recipe build action to be performed upon this RecipeMap's builder's recipe registration.
*
* @param name the unique name of the action
* @param action the action to perform
* @return this
*/
public RecipeMap<R> onRecipeBuild(@NotNull ResourceLocation name, @NotNull RecipeBuildAction<R> action) {
if (recipeBuildActions.containsKey(name)) {
throw new IllegalArgumentException("Cannot register RecipeBuildAction with duplicate name: " + name);
}
recipeBuildActions.put(name, action);
return this;
}

/**
* @param name the name of the build action to remove
*/
public void removeBuildAction(@NotNull ResourceLocation name) {
recipeBuildActions.remove(name);
}

/**
* Add a recipe build action to be performed upon this RecipeMap's builder's recipe registration.
*
* @param actions the actions to perform
*/
@ApiStatus.Internal
protected void onRecipeBuild(@NotNull Map<ResourceLocation, RecipeBuildAction<R>> actions) {
recipeBuildActions.putAll(actions);
}

/**
* @return the build actions for this RecipeMap's default RecipeBuilder
*/
@ApiStatus.Internal
protected @UnmodifiableView @NotNull Collection<@NotNull RecipeBuildAction<R>> getBuildActions() {
return this.recipeBuildActions.values();
}

public RecipeMap<R> allowEmptyOutput() {
this.allowEmptyOutput = true;
return this;
Expand Down Expand Up @@ -1326,7 +1361,7 @@ public String getUnlocalizedName() {
}

public R recipeBuilder() {
return recipeBuilderSample.copy().onBuild(onRecipeBuildAction);
return recipeBuilderSample.copy();
}

/**
Expand Down
26 changes: 26 additions & 0 deletions src/main/java/gregtech/api/recipes/RecipeMapBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,17 @@
import gregtech.api.recipes.ui.RecipeMapUI;
import gregtech.api.recipes.ui.RecipeMapUIFunction;

import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundEvent;

import it.unimi.dsi.fastutil.bytes.Byte2ObjectArrayMap;
import it.unimi.dsi.fastutil.bytes.Byte2ObjectMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Map;

import static gregtech.api.recipes.ui.RecipeMapUI.computeOverlayKey;

public class RecipeMapBuilder<B extends RecipeBuilder<B>> {
Expand Down Expand Up @@ -41,6 +45,8 @@ public class RecipeMapBuilder<B extends RecipeBuilder<B>> {
private SoundEvent sound;
private boolean allowEmptyOutputs;

private @Nullable Map<ResourceLocation, RecipeBuildAction<B>> buildActions;

/**
* @param unlocalizedName the name of the recipemap
* @param defaultRecipeBuilder the default recipe builder of the recipemap
Expand Down Expand Up @@ -247,6 +253,23 @@ public RecipeMapBuilder(@NotNull String unlocalizedName, @NotNull B defaultRecip
return this;
}

/**
* Add a recipe build action to be performed upon this RecipeMap's builder's recipe registration.
*
* @param name the unique name of the action
* @param action the action to perform
* @return this
*/
public @NotNull RecipeMapBuilder<B> onBuild(@NotNull ResourceLocation name, @NotNull RecipeBuildAction<B> action) {
if (buildActions == null) {
buildActions = new Object2ObjectOpenHashMap<>();
} else if (buildActions.containsKey(name)) {
throw new IllegalArgumentException("Cannot register RecipeBuildAction with duplicate name: " + name);
}
buildActions.put(name, action);
return this;
}

/**
* <strong>Do not call this twice. RecipeMapBuilders are not re-usable.</strong>
*
Expand All @@ -260,6 +283,9 @@ public RecipeMapBuilder(@NotNull String unlocalizedName, @NotNull B defaultRecip
if (allowEmptyOutputs) {
recipeMap.allowEmptyOutput();
}
if (buildActions != null) {
recipeMap.onRecipeBuild(buildActions);
}
return recipeMap;
}
}
Loading

0 comments on commit edbdaf4

Please sign in to comment.