aboutsummaryrefslogtreecommitdiff
path: root/runtime
diff options
context:
space:
mode:
authorshedaniel <daniel@shedaniel.me>2021-06-14 20:45:12 +0800
committershedaniel <daniel@shedaniel.me>2021-06-14 20:45:12 +0800
commit3d90cdd1204b6b6a2c57b121cdf82de2448bb951 (patch)
treeef52f2aa6869538c7044c3ebf42a0376b0f32846 /runtime
parent2932350cc1315534c4ee9a8c9fe17a9b0815f2e9 (diff)
downloadRoughlyEnoughItems-3d90cdd1204b6b6a2c57b121cdf82de2448bb951.tar.gz
RoughlyEnoughItems-3d90cdd1204b6b6a2c57b121cdf82de2448bb951.tar.bz2
RoughlyEnoughItems-3d90cdd1204b6b6a2c57b121cdf82de2448bb951.zip
Fix auto crafting patterns & refactor internals providers
Diffstat (limited to 'runtime')
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java101
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java71
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/favorites/DelegatingFavoriteEntryProviderImpl.java115
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/common/entry/DeferringEntryTypeProviderImpl.java107
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/common/entry/EntryIngredientImpl.java90
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/common/entry/EntryStackProviderImpl.java50
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/common/entry/comparison/NbtHasherProviderImpl.java3
7 files changed, 326 insertions, 211 deletions
diff --git a/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java b/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java
index 144479217..fe495d876 100644
--- a/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java
+++ b/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java
@@ -27,12 +27,8 @@ import dev.architectury.platform.Platform;
import dev.architectury.registry.ReloadListenerRegistry;
import dev.architectury.utils.Env;
import dev.architectury.utils.EnvExecutor;
-import me.shedaniel.rei.api.client.gui.Renderer;
-import me.shedaniel.rei.api.common.entry.EntryStack;
import me.shedaniel.rei.api.common.entry.comparison.FluidComparatorRegistry;
import me.shedaniel.rei.api.common.entry.comparison.ItemComparatorRegistry;
-import me.shedaniel.rei.api.common.entry.type.BuiltinEntryTypes;
-import me.shedaniel.rei.api.common.entry.type.EntryDefinition;
import me.shedaniel.rei.api.common.entry.type.EntryType;
import me.shedaniel.rei.api.common.entry.type.EntryTypeRegistry;
import me.shedaniel.rei.api.common.fluid.FluidSupportProvider;
@@ -42,24 +38,19 @@ import me.shedaniel.rei.api.common.plugins.REIPlugin;
import me.shedaniel.rei.api.common.plugins.REIServerPlugin;
import me.shedaniel.rei.api.common.transfer.info.MenuInfoRegistry;
import me.shedaniel.rei.impl.Internals;
-import me.shedaniel.rei.impl.client.entry.type.types.RenderingEntryDefinition;
import me.shedaniel.rei.impl.common.category.CategoryIdentifierImpl;
import me.shedaniel.rei.impl.common.display.DisplaySerializerRegistryImpl;
-import me.shedaniel.rei.impl.common.entry.EmptyEntryStack;
+import me.shedaniel.rei.impl.common.entry.DeferringEntryTypeProviderImpl;
import me.shedaniel.rei.impl.common.entry.EntryIngredientImpl;
-import me.shedaniel.rei.impl.common.entry.TypedEntryStack;
+import me.shedaniel.rei.impl.common.entry.EntryStackProviderImpl;
import me.shedaniel.rei.impl.common.entry.comparison.FluidComparatorRegistryImpl;
import me.shedaniel.rei.impl.common.entry.comparison.ItemComparatorRegistryImpl;
import me.shedaniel.rei.impl.common.entry.comparison.NbtHasherProviderImpl;
-import me.shedaniel.rei.impl.common.entry.type.EntryTypeDeferred;
import me.shedaniel.rei.impl.common.entry.type.EntryTypeRegistryImpl;
-import me.shedaniel.rei.impl.common.entry.type.types.EmptyEntryDefinition;
import me.shedaniel.rei.impl.common.fluid.FluidSupportProviderImpl;
import me.shedaniel.rei.impl.common.plugins.PluginManagerImpl;
import me.shedaniel.rei.impl.common.registry.RecipeManagerContextImpl;
import me.shedaniel.rei.impl.common.transfer.MenuInfoRegistryImpl;
-import net.fabricmc.api.EnvType;
-import net.fabricmc.api.Environment;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.packs.PackType;
import net.minecraft.util.Unit;
@@ -68,9 +59,6 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.ApiStatus;
-import java.util.Map;
-import java.util.Objects;
-import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.UnaryOperator;
@@ -88,87 +76,10 @@ public class RoughlyEnoughItemsCore {
public static void attachCommonInternals() {
CategoryIdentifierImpl.attach();
- Internals.attachInstance((Function<ResourceLocation, EntryType<?>>) new Function<ResourceLocation, EntryType<?>>() {
- ResourceLocation RENDERING_ID = new ResourceLocation("rendering");
- private Map<ResourceLocation, EntryType<?>> typeCache = new ConcurrentHashMap<>();
- private EntryType<Unit> empty;
- @Environment(EnvType.CLIENT)
- private EntryType<Renderer> render;
-
- @Override
- public EntryType<?> apply(ResourceLocation id) {
- if (id.equals(BuiltinEntryTypes.EMPTY_ID)) {
- return typeCache.computeIfAbsent(id, this::emptyType);
- } else if (id.equals(RENDERING_ID) && Platform.getEnv() == EnvType.CLIENT) {
- return typeCache.computeIfAbsent(id, this::renderingType);
- }
- return typeCache.computeIfAbsent(id, EntryTypeDeferred::new);
- }
-
- public EntryType<Unit> emptyType(ResourceLocation id) {
- if (empty == null) {
- int hashCode = id.hashCode();
- empty = new EntryType<>() {
- @Override
- public ResourceLocation getId() {
- return id;
- }
-
- @Override
- public EntryDefinition<Unit> getDefinition() {
- return EmptyEntryDefinition.EMPTY;
- }
-
- @Override
- public int hashCode() {
- return hashCode;
- }
- };
- }
- return empty;
- }
-
- @Environment(EnvType.CLIENT)
- public EntryType<Renderer> renderingType(ResourceLocation id) {
- if (render == null) {
- int hashCode = id.hashCode();
- render = new EntryType<>() {
- @Override
- public ResourceLocation getId() {
- return id;
- }
-
- @Override
- public EntryDefinition<Renderer> getDefinition() {
- return RenderingEntryDefinition.RENDERING;
- }
-
- @Override
- public int hashCode() {
- return hashCode;
- }
- };
- }
- return render;
- }
- }, "entryTypeDeferred");
- Internals.attachInstance(new Internals.EntryStackProvider() {
- @Override
- public EntryStack<Unit> empty() {
- return EmptyEntryStack.EMPTY;
- }
-
- @Override
- public <T> EntryStack<T> of(EntryDefinition<T> definition, T value) {
- if (Objects.equals(definition.getType().getId(), BuiltinEntryTypes.EMPTY_ID)) {
- return empty().cast();
- }
-
- return new TypedEntryStack<>(definition, value);
- }
- }, Internals.EntryStackProvider.class);
- Internals.attachInstance(new NbtHasherProviderImpl(), Internals.NbtHasherProvider.class);
- Internals.attachInstance(EntryIngredientImpl.provide(), Internals.EntryIngredientProvider.class);
+ Internals.attachInstance((Function<ResourceLocation, EntryType<?>>) DeferringEntryTypeProviderImpl.INSTANCE, "entryTypeDeferred");
+ Internals.attachInstance(EntryStackProviderImpl.INSTANCE, Internals.EntryStackProvider.class);
+ Internals.attachInstance(NbtHasherProviderImpl.INSTANCE, Internals.NbtHasherProvider.class);
+ Internals.attachInstance(EntryIngredientImpl.INSTANCE, Internals.EntryIngredientProvider.class);
Internals.attachInstanceSupplier(new PluginManagerImpl<>(
REIPlugin.class,
UnaryOperator.identity(),
diff --git a/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java b/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java
index a8bddc1c3..1985e68b5 100644
--- a/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java
+++ b/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java
@@ -53,6 +53,7 @@ import me.shedaniel.rei.api.common.util.EntryStacks;
import me.shedaniel.rei.impl.ClientInternals;
import me.shedaniel.rei.impl.client.REIRuntimeImpl;
import me.shedaniel.rei.impl.client.config.ConfigManagerImpl;
+import me.shedaniel.rei.impl.client.favorites.DelegatingFavoriteEntryProviderImpl;
import me.shedaniel.rei.impl.client.favorites.FavoriteEntryTypeRegistryImpl;
import me.shedaniel.rei.impl.client.gui.ScreenOverlayImpl;
import me.shedaniel.rei.impl.client.gui.widget.InternalWidgets;
@@ -118,75 +119,7 @@ public class RoughlyEnoughItemsCoreClient {
InternalWidgets.attach();
EmptyEntryDefinition.EmptyRenderer emptyEntryRenderer = new EmptyEntryDefinition.EmptyRenderer();
ClientInternals.attachInstance((Supplier<EntryRenderer<?>>) () -> emptyEntryRenderer, "emptyEntryRenderer");
- ClientInternals.attachInstance((BiFunction<Supplier<FavoriteEntry>, Supplier<CompoundTag>, FavoriteEntry>) (supplier, toJson) -> new FavoriteEntry() {
- FavoriteEntry value = null;
-
- @Override
- public FavoriteEntry getUnwrapped() {
- if (this.value == null) {
- this.value = supplier.get();
- }
- return Objects.requireNonNull(value).getUnwrapped();
- }
-
- @Override
- public UUID getUuid() {
- return getUnwrapped().getUuid();
- }
-
- @Override
- public boolean isInvalid() {
- try {
- return getUnwrapped().isInvalid();
- } catch (Exception e) {
- return true;
- }
- }
-
- @Override
- public Renderer getRenderer(boolean showcase) {
- return getUnwrapped().getRenderer(showcase);
- }
-
- @Override
- public boolean doAction(int button) {
- return getUnwrapped().doAction(button);
- }
-
- @Override
- public Optional<Supplier<Collection<FavoriteMenuEntry>>> getMenuEntries() {
- return getUnwrapped().getMenuEntries();
- }
-
- @Override
- public long hashIgnoreAmount() {
- return getUnwrapped().hashIgnoreAmount();
- }
-
- @Override
- public FavoriteEntry copy() {
- return FavoriteEntry.delegate(supplier, toJson);
- }
-
- @Override
- public ResourceLocation getType() {
- return getUnwrapped().getType();
- }
-
- @Override
- public CompoundTag save(CompoundTag tag) {
- if (toJson == null) {
- return getUnwrapped().save(tag);
- }
-
- return tag.merge(toJson.get());
- }
-
- @Override
- public boolean isSame(FavoriteEntry other) {
- return getUnwrapped().isSame(other.getUnwrapped());
- }
- }, "delegateFavoriteEntry");
+ ClientInternals.attachInstance((BiFunction<Supplier<FavoriteEntry>, Supplier<CompoundTag>, FavoriteEntry>) DelegatingFavoriteEntryProviderImpl::new, "delegateFavoriteEntry");
ClientInternals.attachInstance((Function<CompoundTag, FavoriteEntry>) (object) -> {
String type = object.getString(FavoriteEntry.TYPE_KEY);
ResourceLocation id = new ResourceLocation(type);
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/favorites/DelegatingFavoriteEntryProviderImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/favorites/DelegatingFavoriteEntryProviderImpl.java
new file mode 100644
index 000000000..d58f7e6e4
--- /dev/null
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/favorites/DelegatingFavoriteEntryProviderImpl.java
@@ -0,0 +1,115 @@
+/*
+ * This file is licensed under the MIT License, part of Roughly Enough Items.
+ * Copyright (c) 2018, 2019, 2020, 2021 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.impl.client.favorites;
+
+import me.shedaniel.rei.api.client.favorites.FavoriteEntry;
+import me.shedaniel.rei.api.client.favorites.FavoriteMenuEntry;
+import me.shedaniel.rei.api.client.gui.Renderer;
+import net.minecraft.nbt.CompoundTag;
+import net.minecraft.resources.ResourceLocation;
+
+import java.util.Collection;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.UUID;
+import java.util.function.Supplier;
+
+public class DelegatingFavoriteEntryProviderImpl extends FavoriteEntry {
+ private final Supplier<FavoriteEntry> supplier;
+ private final Supplier<CompoundTag> toJson;
+ private FavoriteEntry value = null;
+
+ public DelegatingFavoriteEntryProviderImpl(Supplier<FavoriteEntry> supplier, Supplier<CompoundTag> toJson) {
+ this.supplier = supplier;
+ this.toJson = toJson;
+ }
+
+ @Override
+ public FavoriteEntry getUnwrapped() {
+ synchronized (this) {
+ if (this.value == null) {
+ this.value = supplier.get();
+ }
+ }
+ return Objects.requireNonNull(value).getUnwrapped();
+ }
+
+ @Override
+ public UUID getUuid() {
+ return getUnwrapped().getUuid();
+ }
+
+ @Override
+ public boolean isInvalid() {
+ try {
+ return getUnwrapped().isInvalid();
+ } catch (Exception e) {
+ return true;
+ }
+ }
+
+ @Override
+ public Renderer getRenderer(boolean showcase) {
+ return getUnwrapped().getRenderer(showcase);
+ }
+
+ @Override
+ public boolean doAction(int button) {
+ return getUnwrapped().doAction(button);
+ }
+
+ @Override
+ public Optional<Supplier<Collection<FavoriteMenuEntry>>> getMenuEntries() {
+ return getUnwrapped().getMenuEntries();
+ }
+
+ @Override
+ public long hashIgnoreAmount() {
+ return getUnwrapped().hashIgnoreAmount();
+ }
+
+ @Override
+ public FavoriteEntry copy() {
+ return FavoriteEntry.delegate(supplier, toJson);
+ }
+
+ @Override
+ public ResourceLocation getType() {
+ return getUnwrapped().getType();
+ }
+
+ @Override
+ public CompoundTag save(CompoundTag tag) {
+ if (toJson == null) {
+ return getUnwrapped().save(tag);
+ }
+
+ return tag.merge(toJson.get());
+ }
+
+ @Override
+ public boolean isSame(FavoriteEntry other) {
+ return getUnwrapped().isSame(other.getUnwrapped());
+ }
+}
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/DeferringEntryTypeProviderImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/DeferringEntryTypeProviderImpl.java
new file mode 100644
index 000000000..930567213
--- /dev/null
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/DeferringEntryTypeProviderImpl.java
@@ -0,0 +1,107 @@
+/*
+ * This file is licensed under the MIT License, part of Roughly Enough Items.
+ * Copyright (c) 2018, 2019, 2020, 2021 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.impl.common.entry;
+
+import dev.architectury.platform.Platform;
+import me.shedaniel.rei.api.client.gui.Renderer;
+import me.shedaniel.rei.api.common.entry.type.BuiltinEntryTypes;
+import me.shedaniel.rei.api.common.entry.type.EntryDefinition;
+import me.shedaniel.rei.api.common.entry.type.EntryType;
+import me.shedaniel.rei.impl.client.entry.type.types.RenderingEntryDefinition;
+import me.shedaniel.rei.impl.common.entry.type.EntryTypeDeferred;
+import me.shedaniel.rei.impl.common.entry.type.types.EmptyEntryDefinition;
+import net.fabricmc.api.EnvType;
+import net.fabricmc.api.Environment;
+import net.minecraft.resources.ResourceLocation;
+import net.minecraft.util.Unit;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Function;
+
+public enum DeferringEntryTypeProviderImpl implements Function<ResourceLocation, EntryType<?>> {
+ INSTANCE;
+ ResourceLocation RENDERING_ID = new ResourceLocation("rendering");
+ private Map<ResourceLocation, EntryType<?>> typeCache = new ConcurrentHashMap<>();
+ private EntryType<Unit> empty;
+ @Environment(EnvType.CLIENT)
+ private EntryType<Renderer> render;
+
+ @Override
+ public EntryType<?> apply(ResourceLocation id) {
+ if (id.equals(BuiltinEntryTypes.EMPTY_ID)) {
+ return typeCache.computeIfAbsent(id, this::emptyType);
+ } else if (id.equals(RENDERING_ID) && Platform.getEnv() == EnvType.CLIENT) {
+ return typeCache.computeIfAbsent(id, this::renderingType);
+ }
+ return typeCache.computeIfAbsent(id, EntryTypeDeferred::new);
+ }
+
+ public EntryType<Unit> emptyType(ResourceLocation id) {
+ if (empty == null) {
+ int hashCode = id.hashCode();
+ empty = new EntryType<>() {
+ @Override
+ public ResourceLocation getId() {
+ return id;
+ }
+
+ @Override
+ public EntryDefinition<Unit> getDefinition() {
+ return EmptyEntryDefinition.EMPTY;
+ }
+
+ @Override
+ public int hashCode() {
+ return hashCode;
+ }
+ };
+ }
+ return empty;
+ }
+
+ @Environment(EnvType.CLIENT)
+ public EntryType<Renderer> renderingType(ResourceLocation id) {
+ if (render == null) {
+ int hashCode = id.hashCode();
+ render = new EntryType<>() {
+ @Override
+ public ResourceLocation getId() {
+ return id;
+ }
+
+ @Override
+ public EntryDefinition<Renderer> getDefinition() {
+ return RenderingEntryDefinition.RENDERING;
+ }
+
+ @Override
+ public int hashCode() {
+ return hashCode;
+ }
+ };
+ }
+ return render;
+ }
+}
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/EntryIngredientImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/EntryIngredientImpl.java
index 1d9214326..e979b6c74 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/EntryIngredientImpl.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/EntryIngredientImpl.java
@@ -35,52 +35,50 @@ import java.util.function.Predicate;
import java.util.function.UnaryOperator;
import java.util.stream.StreamSupport;
-public class EntryIngredientImpl {
- public static Internals.EntryIngredientProvider provide() {
- return new Internals.EntryIngredientProvider() {
- @Override
- public EntryIngredient empty() {
- return EmptyEntryIngredient.EMPTY;
- }
-
- @Override
- public EntryIngredient of(EntryStack<?> stack) {
- return new SingletonEntryIngredient(stack);
- }
-
- @Override
- public EntryIngredient of(EntryStack<?>... stacks) {
- if (stacks.length == 0) return empty();
- if (stacks.length == 1) return of(stacks[0]);
- return _of(stacks);
- }
-
- @Override
- public EntryIngredient of(Iterable<EntryStack<?>> stacks) {
- if (stacks instanceof EntryIngredient) return (EntryIngredient) stacks;
- if (stacks instanceof Collection<EntryStack<?>> collection) {
- int size = collection.size();
- if (size == 0) return empty();
- if (size == 1) return of(stacks.iterator().next());
- return _of(collection.toArray(new EntryStack[0]));
- }
- return _of(StreamSupport.stream(stacks.spliterator(), false).toArray(EntryStack[]::new));
- }
-
- private EntryIngredient _of(EntryStack<?>... stacks) {
- return new ArrayIngredient(stacks);
- }
-
- @Override
- public EntryIngredient.Builder builder() {
- return new EntryIngredientBuilder(0);
- }
-
- @Override
- public EntryIngredient.Builder builder(int initialCapacity) {
- return new EntryIngredientBuilder(initialCapacity);
- }
- };
+public enum EntryIngredientImpl implements Internals.EntryIngredientProvider {
+ INSTANCE;
+
+ @Override
+ public EntryIngredient empty() {
+ return EmptyEntryIngredient.EMPTY;
+ }
+
+ @Override
+ public EntryIngredient of(EntryStack<?> stack) {
+ return new SingletonEntryIngredient(stack);
+ }
+
+ @Override
+ public EntryIngredient of(EntryStack<?>... stacks) {
+ if (stacks.length == 0) return empty();
+ if (stacks.length == 1) return of(stacks[0]);
+ return _of(stacks);
+ }
+
+ @Override
+ public EntryIngredient of(Iterable<EntryStack<?>> stacks) {
+ if (stacks instanceof EntryIngredient) return (EntryIngredient) stacks;
+ if (stacks instanceof Collection<EntryStack<?>> collection) {
+ int size = collection.size();
+ if (size == 0) return empty();
+ if (size == 1) return of(stacks.iterator().next());
+ return _of(collection.toArray(new EntryStack[0]));
+ }
+ return _of(StreamSupport.stream(stacks.spliterator(), false).toArray(EntryStack[]::new));
+ }
+
+ private EntryIngredient _of(EntryStack<?>... stacks) {
+ return new ArrayIngredient(stacks);
+ }
+
+ @Override
+ public EntryIngredient.Builder builder() {
+ return new EntryIngredientBuilder(0);
+ }
+
+ @Override
+ public EntryIngredient.Builder builder(int initialCapacity) {
+ return new EntryIngredientBuilder(initialCapacity);
}
private static class EntryIngredientBuilder implements EntryIngredient.Builder {
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/EntryStackProviderImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/EntryStackProviderImpl.java
new file mode 100644
index 000000000..408a78317
--- /dev/null
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/EntryStackProviderImpl.java
@@ -0,0 +1,50 @@
+/*
+ * This file is licensed under the MIT License, part of Roughly Enough Items.
+ * Copyright (c) 2018, 2019, 2020, 2021 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.impl.common.entry;
+
+import me.shedaniel.rei.api.common.entry.EntryStack;
+import me.shedaniel.rei.api.common.entry.type.BuiltinEntryTypes;
+import me.shedaniel.rei.api.common.entry.type.EntryDefinition;
+import me.shedaniel.rei.impl.Internals;
+import net.minecraft.util.Unit;
+
+import java.util.Objects;
+
+public enum EntryStackProviderImpl implements Internals.EntryStackProvider {
+ INSTANCE;
+
+ @Override
+ public EntryStack<Unit> empty() {
+ return EmptyEntryStack.EMPTY;
+ }
+
+ @Override
+ public <T> EntryStack<T> of(EntryDefinition<T> definition, T value) {
+ if (Objects.equals(definition.getType().getId(), BuiltinEntryTypes.EMPTY_ID)) {
+ return empty().cast();
+ }
+
+ return new TypedEntryStack<>(definition, value);
+ }
+}
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/comparison/NbtHasherProviderImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/comparison/NbtHasherProviderImpl.java
index 89c2653fb..15300ac21 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/comparison/NbtHasherProviderImpl.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/comparison/NbtHasherProviderImpl.java
@@ -35,7 +35,8 @@ import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.function.Predicate;
-public class NbtHasherProviderImpl implements Internals.NbtHasherProvider {
+public enum NbtHasherProviderImpl implements Internals.NbtHasherProvider {
+ INSTANCE;
private final EntryComparator<Tag> defaultHasher = _provide();
@Override