aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorshedaniel <daniel@shedaniel.me>2022-12-18 20:50:56 +0800
committershedaniel <daniel@shedaniel.me>2024-04-16 00:38:17 +0900
commitffe21652b40a93a00f33a27a5ecf41479b48bcd9 (patch)
tree2861df1f563c35c78a1eda7477f6c201eed7ce56
parente6687c01b254bf903d4895aa0bb631b1679d465c (diff)
downloadRoughlyEnoughItems-ffe21652b40a93a00f33a27a5ecf41479b48bcd9.tar.gz
RoughlyEnoughItems-ffe21652b40a93a00f33a27a5ecf41479b48bcd9.tar.bz2
RoughlyEnoughItems-ffe21652b40a93a00f33a27a5ecf41479b48bcd9.zip
Close #1131
-rw-r--r--api/src/main/java/me/shedaniel/rei/api/client/registry/display/DisplayRegistry.java121
-rw-r--r--default-plugin/src/main/java/me/shedaniel/rei/plugin/client/DefaultClientPlugin.java23
-rw-r--r--default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/filler/TippedArrowRecipeFiller.java71
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/registry/display/DisplayRegistryImpl.java47
4 files changed, 221 insertions, 41 deletions
diff --git a/api/src/main/java/me/shedaniel/rei/api/client/registry/display/DisplayRegistry.java b/api/src/main/java/me/shedaniel/rei/api/client/registry/display/DisplayRegistry.java
index fd34e4e84..b708a2e31 100644
--- a/api/src/main/java/me/shedaniel/rei/api/client/registry/display/DisplayRegistry.java
+++ b/api/src/main/java/me/shedaniel/rei/api/client/registry/display/DisplayRegistry.java
@@ -212,7 +212,7 @@ public interface DisplayRegistry extends RecipeManagerContext<REIClientPlugin> {
* Registers a display filler, to be filled during {@link #tryFillDisplay(Object)}.
* <p>
* Vanilla {@link Recipe} are by default filled, display filters
- * can be used to automatically generate displaies for vanilla {@link Recipe}.
+ * can be used to automatically generate displays for vanilla {@link Recipe}.
*
* @param typeClass the type of {@code T}
* @param filler the filler, taking a {@code T} and returning a {@code D}
@@ -227,7 +227,23 @@ public interface DisplayRegistry extends RecipeManagerContext<REIClientPlugin> {
* Registers a display filler, to be filled during {@link #tryFillDisplay(Object)}.
* <p>
* Vanilla {@link Recipe} are by default filled, display filters
- * can be used to automatically generate displaies for vanilla {@link Recipe}.
+ * can be used to automatically generate displays for vanilla {@link Recipe}.
+ *
+ * @param typeClass the type of {@code T}
+ * @param filler the filler, taking a {@code T} and returning a {@code D}
+ * @param <T> the type of object
+ * @param <D> the type of display
+ */
+ @ApiStatus.Experimental
+ default <T extends Recipe<?>, D extends Display> void registerRecipesFiller(Class<T> typeClass, RecipeType<? super T> recipeType, Function<? extends T, @Nullable Collection<? extends D>> filler) {
+ registerRecipesFiller(typeClass, type -> Objects.equals(recipeType, type), filler);
+ }
+
+ /**
+ * Registers a display filler, to be filled during {@link #tryFillDisplay(Object)}.
+ * <p>
+ * Vanilla {@link Recipe} are by default filled, display filters
+ * can be used to automatically generate displays for vanilla {@link Recipe}.
*
* @param typeClass the type of {@code T}
* @param filler the filler, taking a {@code T} and returning a {@code D}
@@ -242,7 +258,23 @@ public interface DisplayRegistry extends RecipeManagerContext<REIClientPlugin> {
* Registers a display filler, to be filled during {@link #tryFillDisplay(Object)}.
* <p>
* Vanilla {@link Recipe} are by default filled, display filters
- * can be used to automatically generate displaies for vanilla {@link Recipe}.
+ * can be used to automatically generate displays for vanilla {@link Recipe}.
+ *
+ * @param typeClass the type of {@code T}
+ * @param filler the filler, taking a {@code T} and returning a {@code D}
+ * @param <T> the type of object
+ * @param <D> the type of display
+ */
+ @ApiStatus.Experimental
+ default <T extends Recipe<?>, D extends Display> void registerRecipesFiller(Class<T> typeClass, Predicate<RecipeType<? super T>> recipeType, Function<? extends T, @Nullable Collection<? extends D>> filler) {
+ registerRecipesFiller(typeClass, recipeType, Predicates.alwaysTrue(), filler);
+ }
+
+ /**
+ * Registers a display filler, to be filled during {@link #tryFillDisplay(Object)}.
+ * <p>
+ * Vanilla {@link Recipe} are by default filled, display filters
+ * can be used to automatically generate displays for vanilla {@link Recipe}.
*
* @param typeClass the type of {@code T}
* @param filler the filler, taking a {@code T} and returning a {@code D}
@@ -257,7 +289,23 @@ public interface DisplayRegistry extends RecipeManagerContext<REIClientPlugin> {
* Registers a display filler, to be filled during {@link #tryFillDisplay(Object)}.
* <p>
* Vanilla {@link Recipe} are by default filled, display filters
- * can be used to automatically generate displaies for vanilla {@link Recipe}.
+ * can be used to automatically generate displays for vanilla {@link Recipe}.
+ *
+ * @param typeClass the type of {@code T}
+ * @param filler the filler, taking a {@code T} and returning a {@code D}
+ * @param <T> the type of object
+ * @param <D> the type of display
+ */
+ @ApiStatus.Experimental
+ default <T extends Recipe<?>, D extends Display> void registerRecipesFiller(Class<T> typeClass, Predicate<RecipeType<? super T>> recipeType, Predicate<? extends T> predicate, Function<? extends T, @Nullable Collection<? extends D>> filler) {
+ registerDisplaysFiller(typeClass, recipe -> recipeType.test((RecipeType<? super T>) recipe.getType()) && ((Predicate<T>) predicate).test(recipe), filler);
+ }
+
+ /**
+ * Registers a display filler, to be filled during {@link #tryFillDisplay(Object)}.
+ * <p>
+ * Vanilla {@link Recipe} are by default filled, display filters
+ * can be used to automatically generate displays for vanilla {@link Recipe}.
*
* @param typeClass the type of {@code T}
* @param filler the filler, taking a {@code T} and returning a {@code D}
@@ -272,7 +320,23 @@ public interface DisplayRegistry extends RecipeManagerContext<REIClientPlugin> {
* Registers a display filler, to be filled during {@link #tryFillDisplay(Object)}.
* <p>
* Vanilla {@link Recipe} are by default filled, display filters
- * can be used to automatically generate displaies for vanilla {@link Recipe}.
+ * can be used to automatically generate displays for vanilla {@link Recipe}.
+ *
+ * @param typeClass the type of {@code T}
+ * @param filler the filler, taking a {@code T} and returning a {@code D}
+ * @param <T> the type of object
+ * @param <D> the type of display
+ */
+ @ApiStatus.Experimental
+ default <T, D extends Display> void registerDisplaysFiller(Class<T> typeClass, Function<? extends T, @Nullable Collection<? extends D>> filler) {
+ registerDisplaysFiller(typeClass, Predicates.alwaysTrue(), filler);
+ }
+
+ /**
+ * Registers a display filler, to be filled during {@link #tryFillDisplay(Object)}.
+ * <p>
+ * Vanilla {@link Recipe} are by default filled, display filters
+ * can be used to automatically generate displays for vanilla {@link Recipe}.
*
* @param typeClass the type of {@code T}
* @param predicate the predicate of {@code T}
@@ -286,7 +350,22 @@ public interface DisplayRegistry extends RecipeManagerContext<REIClientPlugin> {
* Registers a display filler, to be filled during {@link #tryFillDisplay(Object)}.
* <p>
* Vanilla {@link Recipe} are by default filled, display filters
- * can be used to automatically generate displaies for vanilla {@link Recipe}.
+ * can be used to automatically generate displays for vanilla {@link Recipe}.
+ *
+ * @param typeClass the type of {@code T}
+ * @param predicate the predicate of {@code T}
+ * @param filler the filler, taking a {@code T} and returning a {@code D}
+ * @param <T> the type of object
+ * @param <D> the type of display
+ */
+ @ApiStatus.Experimental
+ <T, D extends Display> void registerDisplaysFiller(Class<T> typeClass, Predicate<? extends T> predicate, Function<? extends T, @Nullable Collection<? extends D>> filler);
+
+ /**
+ * Registers a display filler, to be filled during {@link #tryFillDisplay(Object)}.
+ * <p>
+ * Vanilla {@link Recipe} are by default filled, display filters
+ * can be used to automatically generate displays for vanilla {@link Recipe}.
*
* @param typeClass the type of {@code T}
* @param predicate the predicate of {@code T} and reason
@@ -301,7 +380,22 @@ public interface DisplayRegistry extends RecipeManagerContext<REIClientPlugin> {
* Registers a display filler, to be filled during {@link #tryFillDisplay(Object)}.
* <p>
* Vanilla {@link Recipe} are by default filled, display filters
- * can be used to automatically generate displaies for vanilla {@link Recipe}.
+ * can be used to automatically generate displays for vanilla {@link Recipe}.
+ *
+ * @param typeClass the type of {@code T}
+ * @param predicate the predicate of {@code T} and reason
+ * @param filler the filler, taking a {@code T} and returning a {@code D}
+ * @param <T> the type of object
+ * @param <D> the type of display
+ */
+ @ApiStatus.Experimental
+ <T, D extends Display> void registerDisplaysFiller(Class<T> typeClass, BiPredicate<? extends T, DisplayAdditionReasons> predicate, Function<? extends T, @Nullable Collection<? extends D>> filler);
+
+ /**
+ * Registers a display filler, to be filled during {@link #tryFillDisplay(Object)}.
+ * <p>
+ * Vanilla {@link Recipe} are by default filled, display filters
+ * can be used to automatically generate displays for vanilla {@link Recipe}.
*
* @param predicate the predicate of the object
* @param filler the filler, taking an object and returning a {@code D}
@@ -310,6 +404,19 @@ public interface DisplayRegistry extends RecipeManagerContext<REIClientPlugin> {
<D extends Display> void registerFiller(Predicate<?> predicate, Function<?, @Nullable D> filler);
/**
+ * Registers a display filler, to be filled during {@link #tryFillDisplay(Object)}.
+ * <p>
+ * Vanilla {@link Recipe} are by default filled, display filters
+ * can be used to automatically generate displays for vanilla {@link Recipe}.
+ *
+ * @param predicate the predicate of the object
+ * @param filler the filler, taking an object and returning a {@code D}
+ * @param <D> the type of display
+ */
+ @ApiStatus.Experimental
+ <D extends Display> void registerDisplaysFiller(Predicate<?> predicate, Function<?, @Nullable Collection<? extends D>> filler);
+
+ /**
* Tries to fill displays from {@code T}.
*
* @param value the object
diff --git a/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/DefaultClientPlugin.java b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/DefaultClientPlugin.java
index bf1541003..50ffc35ef 100644
--- a/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/DefaultClientPlugin.java
+++ b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/DefaultClientPlugin.java
@@ -29,6 +29,7 @@ import com.google.common.collect.Sets;
import dev.architectury.event.EventResult;
import dev.architectury.networking.NetworkManager;
import dev.architectury.platform.Platform;
+import it.unimi.dsi.fastutil.objects.Object2FloatMap;
import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet;
import it.unimi.dsi.fastutil.objects.ReferenceSet;
import me.shedaniel.math.Rectangle;
@@ -55,6 +56,7 @@ import me.shedaniel.rei.plugin.client.categories.beacon.DefaultBeaconBaseCategor
import me.shedaniel.rei.plugin.client.categories.beacon.DefaultBeaconPaymentCategory;
import me.shedaniel.rei.plugin.client.categories.cooking.DefaultCookingCategory;
import me.shedaniel.rei.plugin.client.categories.crafting.DefaultCraftingCategory;
+import me.shedaniel.rei.plugin.client.categories.crafting.filler.TippedArrowRecipeFiller;
import me.shedaniel.rei.plugin.client.categories.tag.DefaultTagCategory;
import me.shedaniel.rei.plugin.client.exclusionzones.DefaultPotionEffectExclusionZones;
import me.shedaniel.rei.plugin.client.exclusionzones.DefaultRecipeBookExclusionZones;
@@ -73,7 +75,6 @@ import me.shedaniel.rei.plugin.common.displays.cooking.DefaultBlastingDisplay;
import me.shedaniel.rei.plugin.common.displays.cooking.DefaultSmeltingDisplay;
import me.shedaniel.rei.plugin.common.displays.cooking.DefaultSmokingDisplay;
import me.shedaniel.rei.plugin.common.displays.crafting.DefaultCraftingDisplay;
-import me.shedaniel.rei.plugin.common.displays.crafting.DefaultCustomDisplay;
import me.shedaniel.rei.plugin.common.displays.tag.DefaultTagDisplay;
import me.shedaniel.rei.plugin.common.displays.tag.TagNodes;
import net.fabricmc.api.EnvType;
@@ -253,25 +254,7 @@ public class DefaultClientPlugin implements REIClientPlugin, BuiltinClientPlugin
for (Map.Entry<Item, Integer> entry : AbstractFurnaceBlockEntity.getFuel().entrySet()) {
registry.add(new DefaultFuelDisplay(Collections.singletonList(EntryIngredients.of(entry.getKey())), Collections.emptyList(), entry.getValue()));
}
- EntryIngredient arrowStack = EntryIngredient.of(EntryStacks.of(Items.ARROW));
- ReferenceSet<Potion> registeredPotions = new ReferenceOpenHashSet<>();
- EntryRegistry.getInstance().getEntryStacks().filter(entry -> entry.getValueType() == ItemStack.class && entry.<ItemStack>castValue().getItem() == Items.LINGERING_POTION).forEach(entry -> {
- ItemStack itemStack = (ItemStack) entry.getValue();
- Potion potion = PotionUtils.getPotion(itemStack);
- if (registeredPotions.add(potion)) {
- List<EntryIngredient> input = new ArrayList<>();
- for (int i = 0; i < 4; i++)
- input.add(arrowStack);
- input.add(EntryIngredients.of(itemStack));
- for (int i = 0; i < 4; i++)
- input.add(arrowStack);
- ItemStack outputStack = new ItemStack(Items.TIPPED_ARROW, 8);
- PotionUtils.setPotion(outputStack, potion);
- PotionUtils.setCustomEffects(outputStack, PotionUtils.getCustomEffects(itemStack));
- EntryIngredient output = EntryIngredients.of(outputStack);
- registry.add(new DefaultCustomDisplay(null, input, Collections.singletonList(output)));
- }
- });
+ registry.registerRecipesFiller(TippedArrowRecipe.class, RecipeType.CRAFTING, new TippedArrowRecipeFiller()::apply);
if (ComposterBlock.COMPOSTABLES.isEmpty()) {
ComposterBlock.bootStrap();
}
diff --git a/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/filler/TippedArrowRecipeFiller.java b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/filler/TippedArrowRecipeFiller.java
new file mode 100644
index 000000000..014799f6f
--- /dev/null
+++ b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/categories/crafting/filler/TippedArrowRecipeFiller.java
@@ -0,0 +1,71 @@
+/*
+ * This file is licensed under the MIT License, part of Roughly Enough Items.
+ * Copyright (c) 2018, 2019, 2020, 2021, 2022 shedaniel
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package me.shedaniel.rei.plugin.client.categories.crafting.filler;
+
+import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet;
+import it.unimi.dsi.fastutil.objects.ReferenceSet;
+import me.shedaniel.rei.api.client.registry.entry.EntryRegistry;
+import me.shedaniel.rei.api.common.display.Display;
+import me.shedaniel.rei.api.common.entry.EntryIngredient;
+import me.shedaniel.rei.api.common.util.EntryIngredients;
+import me.shedaniel.rei.api.common.util.EntryStacks;
+import me.shedaniel.rei.plugin.common.displays.crafting.DefaultCustomDisplay;
+import net.minecraft.world.item.ItemStack;
+import net.minecraft.world.item.Items;
+import net.minecraft.world.item.alchemy.Potion;
+import net.minecraft.world.item.alchemy.PotionUtils;
+import net.minecraft.world.item.crafting.TippedArrowRecipe;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.function.Function;
+
+public class TippedArrowRecipeFiller implements Function<TippedArrowRecipe, Collection<Display>> {
+ @Override
+ public Collection<Display> apply(TippedArrowRecipe recipe) {
+ EntryIngredient arrowStack = EntryIngredient.of(EntryStacks.of(Items.ARROW));
+ ReferenceSet<Potion> registeredPotions = new ReferenceOpenHashSet<>();
+ List<Display> displays = new ArrayList<>();
+
+ EntryRegistry.getInstance().getEntryStacks().filter(entry -> entry.getValueType() == ItemStack.class && entry.<ItemStack>castValue().getItem() == Items.LINGERING_POTION).forEach(entry -> {
+ ItemStack itemStack = (ItemStack) entry.getValue();
+ Potion potion = PotionUtils.getPotion(itemStack);
+ if (registeredPotions.add(potion)) {
+ List<EntryIngredient> input = new ArrayList<>();
+ for (int i = 0; i < 4; i++)
+ input.add(arrowStack);
+ input.add(EntryIngredients.of(itemStack));
+ for (int i = 0; i < 4; i++)
+ input.add(arrowStack);
+ ItemStack outputStack = new ItemStack(Items.TIPPED_ARROW, 8);
+ PotionUtils.setPotion(outputStack, potion);
+ PotionUtils.setCustomEffects(outputStack, PotionUtils.getCustomEffects(itemStack));
+ displays.add(new DefaultCustomDisplay(recipe, input, List.of(EntryIngredients.of(outputStack))));
+ }
+ });
+
+ return displays;
+ }
+}
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/display/DisplayRegistryImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/display/DisplayRegistryImpl.java
index f8f303408..655466211 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/display/DisplayRegistryImpl.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/display/DisplayRegistryImpl.java
@@ -146,14 +146,31 @@ public class DisplayRegistryImpl extends RecipeManagerContextImpl<REIClientPlugi
}
@Override
+ public <T, D extends Display> void registerDisplaysFiller(Class<T> typeClass, Predicate<? extends T> predicate, Function<? extends T, @Nullable Collection<? extends D>> filler) {
+ registerDisplaysFiller(o -> typeClass.isInstance(o) && ((Predicate<T>) predicate).test((T) o), o -> ((Function<T, Collection<? extends D>>) filler).apply((T) o));
+ }
+
+ @Override
public <T, D extends Display> void registerFiller(Class<T> typeClass, BiPredicate<? extends T, DisplayAdditionReasons> predicate, Function<? extends T, D> filler) {
- fillers.add(new DisplayFiller<>((o, s) -> typeClass.isInstance(o) && ((BiPredicate<Object, DisplayAdditionReasons>) predicate).test(o, s), (Function<Object, D>) filler));
+ fillers.add(DisplayFiller.of((o, s) -> typeClass.isInstance(o) && ((BiPredicate<Object, DisplayAdditionReasons>) predicate).test(o, s), (Function<Object, D>) filler));
+ InternalLogger.getInstance().debug("Added display filter: %s for %s", filler, typeClass.getName());
+ }
+
+ @Override
+ public <T, D extends Display> void registerDisplaysFiller(Class<T> typeClass, BiPredicate<? extends T, DisplayAdditionReasons> predicate, Function<? extends T, @Nullable Collection<? extends D>> filler) {
+ fillers.add(new DisplayFiller<>((o, s) -> typeClass.isInstance(o) && ((BiPredicate<Object, DisplayAdditionReasons>) predicate).test(o, s), (Function<Object, Collection<? extends D>>) filler));
InternalLogger.getInstance().debug("Added display filter: %s for %s", filler, typeClass.getName());
}
@Override
public <D extends Display> void registerFiller(Predicate<?> predicate, Function<?, D> filler) {
- fillers.add(new DisplayFiller<>((o, s) -> ((Predicate<Object>) predicate).test(o), (Function<Object, D>) filler));
+ fillers.add(DisplayFiller.of((o, s) -> ((Predicate<Object>) predicate).test(o), (Function<Object, D>) filler));
+ InternalLogger.getInstance().debug("Added display filter: %s", filler);
+ }
+
+ @Override
+ public <D extends Display> void registerDisplaysFiller(Predicate<?> predicate, Function<?, @Nullable Collection<? extends D>> filler) {
+ fillers.add(new DisplayFiller<>((o, s) -> ((Predicate<Object>) predicate).test(o), (Function<Object, Collection<? extends D>>) filler));
InternalLogger.getInstance().debug("Added display filter: %s", filler);
}
@@ -194,28 +211,27 @@ public class DisplayRegistryImpl extends RecipeManagerContextImpl<REIClientPlugi
@Override
public <T> Collection<Display> tryFillDisplay(T value, DisplayAdditionReason... reason) {
if (value instanceof Display) return Collections.singleton((Display) value);
- List<Display> displays = null;
+ List<Display> out = null;
DisplayAdditionReasons reasons = reason.length == 0 ? DisplayAdditionReasons.Impl.EMPTY : new DisplayAdditionReasons.Impl(reason);
for (DisplayFiller<?> filler : fillers) {
- Display display = tryFillDisplayGenerics(filler, value, reasons);
- if (display != null) {
- if (displays == null) displays = Collections.singletonList(display);
- else {
- if (!(displays instanceof ArrayList)) displays = new ArrayList<>(displays);
- displays.add(display);
+ Collection<Display> displays = tryFillDisplayGenerics(filler, value, reasons);
+ if (displays != null && !displays.isEmpty()) {
+ if (out == null) out = new ArrayList<>();
+ for (Display display : displays) {
+ if (display != null) out.add(display);
}
}
}
- if (displays != null) {
- return displays;
+ if (out != null) {
+ return out;
}
return Collections.emptyList();
}
- private <D extends Display> D tryFillDisplayGenerics(DisplayFiller<D> filler, Object value, DisplayAdditionReasons reasons) {
+ private <D extends Display> Collection<D> tryFillDisplayGenerics(DisplayFiller<? extends D> filler, Object value, DisplayAdditionReasons reasons) {
try {
if (filler.predicate.test(value, reasons)) {
- return filler.mappingFunction.apply(value);
+ return (Collection<D>) filler.mappingFunction.apply(value);
}
} catch (Throwable e) {
throw new RuntimeException("Failed to fill displays!", e);
@@ -233,7 +249,10 @@ public class DisplayRegistryImpl extends RecipeManagerContextImpl<REIClientPlugi
private record DisplayFiller<D extends Display>(
BiPredicate<Object, DisplayAdditionReasons> predicate,
- Function<Object, D> mappingFunction
+ Function<Object, Collection<? extends D>> mappingFunction
) {
+ public static <D extends Display> DisplayFiller<D> of(BiPredicate<Object, DisplayAdditionReasons> predicate, Function<Object, D> mappingFunction) {
+ return new DisplayFiller<>(predicate, o -> Collections.singleton(mappingFunction.apply(o)));
+ }
}
}