From 1f6137d24153b62c42da129ce5d6373bbf78ee34 Mon Sep 17 00:00:00 2001 From: shedaniel Date: Mon, 14 Dec 2020 00:10:26 +0800 Subject: The big refactor Signed-off-by: shedaniel --- .../java/me/shedaniel/rei/api/BuiltinPlugin.java | 4 +- .../java/me/shedaniel/rei/api/ClientHelper.java | 23 +- .../java/me/shedaniel/rei/api/ConfigObject.java | 2 +- .../java/me/shedaniel/rei/api/EntryRegistry.java | 20 +- .../main/java/me/shedaniel/rei/api/EntryStack.java | 302 +++++---------------- .../me/shedaniel/rei/api/FocusedStackProvider.java | 2 +- .../me/shedaniel/rei/api/LiveRecipeGenerator.java | 4 +- .../java/me/shedaniel/rei/api/OverlayDecider.java | 2 +- .../java/me/shedaniel/rei/api/RecipeCategory.java | 10 +- .../java/me/shedaniel/rei/api/RecipeDisplay.java | 7 +- .../java/me/shedaniel/rei/api/RecipeHelper.java | 28 +- .../main/java/me/shedaniel/rei/api/Renderer.java | 20 ++ .../me/shedaniel/rei/api/TextRepresentable.java | 7 - .../shedaniel/rei/api/TransferRecipeDisplay.java | 3 +- .../rei/api/entry/AbstractEntryRenderer.java | 6 + .../shedaniel/rei/api/entry/AbstractRenderer.java | 16 ++ .../rei/api/entry/BatchEntryRenderer.java | 38 +++ .../shedaniel/rei/api/entry/BuiltinEntryTypes.java | 14 + .../shedaniel/rei/api/entry/ComparisonContext.java | 36 +++ .../shedaniel/rei/api/entry/EntryDefinition.java | 55 ++++ .../me/shedaniel/rei/api/entry/EntryRenderer.java | 15 + .../me/shedaniel/rei/api/entry/EntryStacks.java | 164 +++++++++++ .../java/me/shedaniel/rei/api/entry/EntryType.java | 25 ++ .../shedaniel/rei/api/entry/EntryTypeBridge.java | 11 + .../shedaniel/rei/api/entry/EntryTypeRegistry.java | 24 ++ .../shedaniel/rei/api/entry/VanillaEntryTypes.java | 12 + .../shedaniel/rei/api/favorites/FavoriteEntry.java | 3 +- .../rei/api/fluid/FluidSupportProvider.java | 7 +- .../me/shedaniel/rei/api/fractions/Fraction.java | 186 ------------- .../me/shedaniel/rei/api/plugins/REIPluginV0.java | 8 + .../shedaniel/rei/api/subsets/SubsetsRegistry.java | 12 +- .../java/me/shedaniel/rei/api/widgets/Slot.java | 6 +- .../shedaniel/rei/gui/config/AppearanceTheme.java | 2 +- .../rei/gui/config/ConfigButtonPosition.java | 2 +- .../rei/gui/config/DisplayPanelLocation.java | 2 +- .../me/shedaniel/rei/gui/entries/RecipeEntry.java | 36 --- .../shedaniel/rei/gui/entries/RecipeRenderer.java | 44 +++ .../rei/gui/entries/SimpleRecipeEntry.java | 160 ----------- .../rei/gui/entries/SimpleRecipeRenderer.java | 159 +++++++++++ .../main/java/me/shedaniel/rei/impl/Internals.java | 25 +- .../java/me/shedaniel/rei/impl/RenderingEntry.java | 71 ++--- .../me/shedaniel/rei/utils/CollectionUtils.java | 29 +- .../rei/utils/EntryStackCompoundList.java | 21 ++ .../me/shedaniel/rei/utils/EntryStackList.java | 20 ++ 44 files changed, 871 insertions(+), 772 deletions(-) create mode 100644 RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/Renderer.java create mode 100644 RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/entry/AbstractEntryRenderer.java create mode 100644 RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/entry/AbstractRenderer.java create mode 100644 RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/entry/BatchEntryRenderer.java create mode 100644 RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/entry/BuiltinEntryTypes.java create mode 100644 RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/entry/ComparisonContext.java create mode 100644 RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/entry/EntryDefinition.java create mode 100644 RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/entry/EntryRenderer.java create mode 100644 RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/entry/EntryStacks.java create mode 100644 RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/entry/EntryType.java create mode 100644 RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/entry/EntryTypeBridge.java create mode 100644 RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/entry/EntryTypeRegistry.java create mode 100644 RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/entry/VanillaEntryTypes.java delete mode 100644 RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/fractions/Fraction.java delete mode 100644 RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/gui/entries/RecipeEntry.java create mode 100644 RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/gui/entries/RecipeRenderer.java delete mode 100644 RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/gui/entries/SimpleRecipeEntry.java create mode 100644 RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/gui/entries/SimpleRecipeRenderer.java create mode 100644 RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/utils/EntryStackCompoundList.java create mode 100644 RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/utils/EntryStackList.java (limited to 'RoughlyEnoughItems-api/src/main/java') diff --git a/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/BuiltinPlugin.java b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/BuiltinPlugin.java index 057ac2613..f0d3b112a 100644 --- a/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/BuiltinPlugin.java +++ b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/BuiltinPlugin.java @@ -62,9 +62,9 @@ public interface BuiltinPlugin { void registerBrewingRecipe(Ingredient input, Ingredient ingredient, ItemStack output); - void registerInformation(List entryStacks, Component name, UnaryOperator> textBuilder); + void registerInformation(List> entryStacks, Component name, UnaryOperator> textBuilder); - default void registerInformation(EntryStack entryStack, Component name, UnaryOperator> textBuilder) { + default void registerInformation(EntryStack entryStack, Component name, UnaryOperator> textBuilder) { registerInformation(Collections.singletonList(entryStack), name, textBuilder); } } diff --git a/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/ClientHelper.java b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/ClientHelper.java index ddb17e63f..36b61033a 100644 --- a/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/ClientHelper.java +++ b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/ClientHelper.java @@ -35,7 +35,6 @@ import net.minecraft.network.chat.Component; import net.minecraft.network.chat.TextComponent; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -76,11 +75,7 @@ public interface ClientHelper { * @param stack the stack to cheat in * @return whether it failed */ - boolean tryCheatingEntry(EntryStack stack); - - default boolean tryCheatingStack(ItemStack stack) { - return tryCheatingEntry(EntryStack.create(stack)); - } + boolean tryCheatingEntry(EntryStack stack); /** * Gets the mod from an item @@ -190,13 +185,13 @@ public interface ClientHelper { @NotNull Set getCategories(); - ViewSearchBuilder addRecipesFor(EntryStack stack); + ViewSearchBuilder addRecipesFor(EntryStack stack); - @NotNull List getRecipesFor(); + @NotNull List> getRecipesFor(); - ViewSearchBuilder addUsagesFor(EntryStack stack); + ViewSearchBuilder addUsagesFor(EntryStack stack); - @NotNull List getUsagesFor(); + @NotNull List> getUsagesFor(); ViewSearchBuilder setPreferredOpenedCategory(@Nullable ResourceLocation category); @@ -205,15 +200,15 @@ public interface ClientHelper { ViewSearchBuilder fillPreferredOpenedCategory(); - ViewSearchBuilder setInputNotice(@Nullable EntryStack stack); + ViewSearchBuilder setInputNotice(@Nullable EntryStack stack); @Nullable - EntryStack getInputNotice(); + EntryStack getInputNotice(); - ViewSearchBuilder setOutputNotice(@Nullable EntryStack stack); + ViewSearchBuilder setOutputNotice(@Nullable EntryStack stack); @Nullable - EntryStack getOutputNotice(); + EntryStack getOutputNotice(); @NotNull Map, List> buildMap(); diff --git a/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/ConfigObject.java b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/ConfigObject.java index d193b1bc4..d8210bbc2 100644 --- a/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/ConfigObject.java +++ b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/ConfigObject.java @@ -139,7 +139,7 @@ public interface ConfigObject { @ApiStatus.Experimental List getFavoriteEntries(); - List getFilteredStacks(); + List> getFilteredStacks(); @ApiStatus.Experimental boolean shouldAsyncSearch(); diff --git a/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/EntryRegistry.java b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/EntryRegistry.java index 369862794..d93701e09 100644 --- a/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/EntryRegistry.java +++ b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/EntryRegistry.java @@ -50,10 +50,10 @@ public interface EntryRegistry { } @NotNull - Stream getEntryStacks(); + Stream> getEntryStacks(); @NotNull - List getPreFilteredList(); + List> getPreFilteredList(); @ApiStatus.Experimental void refilter(); @@ -70,7 +70,7 @@ public interface EntryRegistry { @NotNull ItemStack[] getAllStacksFromItem(@NotNull Item item); - default void registerEntry(@NotNull EntryStack stack) { + default void registerEntry(@NotNull EntryStack stack) { registerEntryAfter(null, stack); } @@ -80,7 +80,7 @@ public interface EntryRegistry { * @param afterEntry the stack to put after * @param stack the stack to register */ - void registerEntryAfter(@Nullable EntryStack afterEntry, @NotNull EntryStack stack); + void registerEntryAfter(@Nullable EntryStack afterEntry, @NotNull EntryStack stack); /** * Registers multiple stacks to the item list @@ -88,7 +88,7 @@ public interface EntryRegistry { * @param afterStack the stack to put after * @param stacks the stacks to register */ - default void registerEntriesAfter(@Nullable EntryStack afterStack, @NotNull EntryStack... stacks) { + default void registerEntriesAfter(@Nullable EntryStack afterStack, @NotNull EntryStack... stacks) { registerEntriesAfter(afterStack, Arrays.asList(stacks)); } @@ -98,14 +98,14 @@ public interface EntryRegistry { * @param afterStack the stack to put after * @param stacks the stacks to register */ - void registerEntriesAfter(@Nullable EntryStack afterStack, @NotNull Collection<@NotNull ? extends EntryStack> stacks); + void registerEntriesAfter(@Nullable EntryStack afterStack, @NotNull Collection<@NotNull ? extends EntryStack> stacks); /** * Registers multiple stacks to the item list * * @param stacks the stacks to register */ - default void registerEntries(@NotNull EntryStack... stacks) { + default void registerEntries(@NotNull EntryStack... stacks) { registerEntriesAfter(null, stacks); } @@ -115,11 +115,11 @@ public interface EntryRegistry { * @param stack the stack to check * @return whether the stack has been registered */ - boolean alreadyContain(EntryStack stack); + boolean alreadyContain(EntryStack stack); @ApiStatus.Experimental - void removeEntry(EntryStack stack); + void removeEntry(EntryStack stack); @ApiStatus.Experimental - void removeEntryIf(Predicate stackPredicate); + void removeEntryIf(Predicate> stackPredicate); } diff --git a/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/EntryStack.java b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/EntryStack.java index fb117d3b8..19204804f 100644 --- a/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/EntryStack.java +++ b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/EntryStack.java @@ -23,145 +23,57 @@ package me.shedaniel.rei.api; -import com.google.common.collect.ImmutableList; import com.google.gson.JsonElement; import com.google.gson.JsonObject; -import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.serialization.Dynamic; import com.mojang.serialization.JsonOps; -import me.shedaniel.math.Point; -import me.shedaniel.math.Rectangle; -import me.shedaniel.rei.api.fluid.FluidSupportProvider; -import me.shedaniel.rei.api.fractions.Fraction; -import me.shedaniel.rei.api.widgets.Tooltip; +import me.shedaniel.architectury.utils.Fraction; +import me.shedaniel.rei.api.entry.ComparisonContext; +import me.shedaniel.rei.api.entry.EntryDefinition; +import me.shedaniel.rei.api.entry.EntryRenderer; +import me.shedaniel.rei.api.entry.EntryType; import me.shedaniel.rei.impl.Internals; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.resources.language.I18n; -import net.minecraft.core.Registry; -import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.NbtOps; import net.minecraft.nbt.TagParser; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.GsonHelper; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.crafting.Ingredient; -import net.minecraft.world.level.ItemLike; -import net.minecraft.world.level.material.Fluid; +import net.minecraft.util.Unit; import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Optional; import java.util.function.Function; import java.util.function.Supplier; -import java.util.stream.Stream; @Environment(EnvType.CLIENT) -public interface EntryStack extends TextRepresentable { - - static EntryStack empty() { +public interface EntryStack extends TextRepresentable, Renderer { + static EntryStack empty() { return Internals.getEntryStackProvider().empty(); } - static EntryStack create(Fluid fluid) { - return Internals.getEntryStackProvider().fluid(fluid); - } - - static EntryStack create(Fluid fluid, int amount) { - return create(fluid, Fraction.ofWhole(amount)); - } - - static EntryStack create(Fluid fluid, double amount) { - return create(fluid, Fraction.from(amount)); - } - - static EntryStack create(Fluid fluid, Fraction amount) { - return Internals.getEntryStackProvider().fluid(fluid, amount); - } - - static EntryStack create(ItemStack stack) { - return Internals.getEntryStackProvider().item(stack); - } - - static EntryStack create(ItemLike item) { - return create(new ItemStack(item)); - } - - static List ofItems(Collection stacks) { - if (stacks.size() == 0) return Collections.emptyList(); - if (stacks.size() == 1) return Collections.singletonList(create(stacks.iterator().next())); - EntryStack[] result = new EntryStack[stacks.size()]; - int i = 0; - for (ItemLike stack : stacks) { - result[i] = create(stack); - i++; - } - return Arrays.asList(result); - } - - static List ofItemStacks(Collection stacks) { - if (stacks.size() == 0) return Collections.emptyList(); - if (stacks.size() == 1) { - ItemStack stack = stacks.iterator().next(); - if (stack.isEmpty()) return Collections.emptyList(); - return Collections.singletonList(create(stack)); - } - List result = new ArrayList<>(stacks.size()); - for (ItemStack stack : stacks) { - result.add(create(stack)); - } - return ImmutableList.copyOf(result); - } - - static List ofIngredient(Ingredient ingredient) { - if (ingredient.isEmpty()) return Collections.emptyList(); - ItemStack[] matchingStacks = ingredient.getItems(); - if (matchingStacks.length == 0) return Collections.emptyList(); - if (matchingStacks.length == 1) return Collections.singletonList(create(matchingStacks[0])); - List result = new ArrayList<>(matchingStacks.length); - for (ItemStack matchingStack : matchingStacks) { - if (!matchingStack.isEmpty()) - result.add(create(matchingStack)); - } - return ImmutableList.copyOf(result); + static EntryStack of(EntryDefinition definition, T value) { + return Internals.getEntryStackProvider().of(definition, value); } - static List> ofIngredients(List ingredients) { - if (ingredients.size() == 0) return Collections.emptyList(); - if (ingredients.size() == 1) { - Ingredient ingredient = ingredients.get(0); - if (ingredient.isEmpty()) return Collections.emptyList(); - return Collections.singletonList(ofIngredient(ingredient)); - } - boolean emptyFlag = true; - List> result = new ArrayList<>(ingredients.size()); - for (int i = ingredients.size() - 1; i >= 0; i--) { - Ingredient ingredient = ingredients.get(i); - if (emptyFlag && ingredient.isEmpty()) continue; - result.add(0, ofIngredient(ingredient)); - emptyFlag = false; - } - return ImmutableList.copyOf(result); + static EntryStack of(EntryType type, T value) { + return of(type.getDefinition(), value); } @ApiStatus.Internal - static EntryStack readFromJson(JsonElement jsonElement) { + static EntryStack readFromJson(JsonElement jsonElement) { try { JsonObject obj = jsonElement.getAsJsonObject(); - switch (GsonHelper.getAsString(obj, "type")) { - case "stack": - return EntryStack.create(ItemStack.of(TagParser.parseTag(obj.get("nbt").getAsString()))); - case "item": - return EntryStack.create(ItemStack.of((CompoundTag) Dynamic.convert(JsonOps.INSTANCE, NbtOps.INSTANCE, obj))); - case "fluid": - return EntryStack.create(Registry.FLUID.get(ResourceLocation.tryParse(obj.get("id").getAsString()))); - case "empty": - return EntryStack.empty(); - default: - throw new IllegalArgumentException("Invalid Entry Type!"); - } + EntryType type = EntryType.deferred(new ResourceLocation(GsonHelper.getAsString(obj, "type"))); + Object o = type.getDefinition().fromTag(TagParser.parseTag(obj.toString())); + return EntryStack.of(type, o); } catch (Exception e) { e.printStackTrace(); return EntryStack.empty(); @@ -172,158 +84,69 @@ public interface EntryStack extends TextRepresentable { @Nullable default JsonElement toJson() { try { - switch (getType()) { - case ITEM: - JsonObject obj1 = Dynamic.convert(NbtOps.INSTANCE, JsonOps.INSTANCE, getItemStack().save(new CompoundTag())).getAsJsonObject(); - obj1.addProperty("type", "item"); - return obj1; - case FLUID: - Optional optionalIdentifier = getIdentifier(); - if (!optionalIdentifier.isPresent()) - throw new NullPointerException("Invalid Fluid: " + toString()); - JsonObject obj2 = new JsonObject(); - obj2.addProperty("type", "fluid"); - obj2.addProperty("id", optionalIdentifier.get().toString()); - return obj2; - case EMPTY: - JsonObject obj3 = new JsonObject(); - obj3.addProperty("type", "empty"); - return obj3; - default: - throw new IllegalArgumentException("Invalid Entry Type!"); - } + JsonObject object = Dynamic.convert(NbtOps.INSTANCE, JsonOps.INSTANCE, getDefinition().toTag(this, getValue())).getAsJsonObject(); + object.addProperty("type", getType().getId().toString()); + return object; } catch (Exception e) { e.printStackTrace(); return null; } } - static Stream copyItemToFluids(EntryStack stack) { - return FluidSupportProvider.getInstance().itemToFluids(stack); - } + @NotNull + EntryDefinition getDefinition(); - Optional getIdentifier(); - - EntryStack.Type getType(); - - default int getAmount() { - return getAccurateAmount().intValue(); + @NotNull + default EntryType getType() { + return getDefinition().getType(); } - Fraction getAccurateAmount(); - - default double getFloatingAmount() { - return getAccurateAmount().doubleValue(); + @NotNull + default Class getValueType() { + return getDefinition().getValueType(); } - default void setAmount(int amount) { - setAmount(Fraction.ofWhole(amount)); + @NotNull + default EntryRenderer getRenderer() { + return getDefinition().getRenderer(); } - default void setFloatingAmount(double amount) { - setAmount(Fraction.from(amount)); - } + Optional getIdentifier(); + + Fraction getAmount(); void setAmount(Fraction amount); boolean isEmpty(); - EntryStack copy(); + EntryStack copy(); @ApiStatus.Internal - default EntryStack rewrap() { + default EntryStack rewrap() { return copy(); } - Object getObject(); - - boolean equals(EntryStack stack, boolean ignoreTags, boolean ignoreAmount); + @Deprecated + int hashCode(); - boolean equalsIgnoreTagsAndAmount(EntryStack stack); + int hash(ComparisonContext context); - boolean equalsIgnoreTags(EntryStack stack); + boolean equals(EntryStack other, ComparisonContext context); - boolean equalsIgnoreAmount(EntryStack stack); + @Deprecated + boolean equals(Object o); - boolean equalsAll(EntryStack stack); + T getValue(); - /** - * {@link #hashCode()} for {@link #equalsAll(EntryStack)}. - */ - default int hashOfAll() { - return hashCode(); - } + EntryStack setting(Settings settings, R value); - /** - * {@link #hashCode()} for {@link #equalsIgnoreAmount(EntryStack)} - */ - default int hashIgnoreAmount() { - return hashCode(); - } + EntryStack removeSetting(Settings settings); - /** - * {@link #hashCode()} for {@link #equalsIgnoreTags(EntryStack)} - */ - default int hashIgnoreTags() { - return hashCode(); - } + EntryStack clearSettings(); - /** - * {@link #hashCode()} for {@link #equalsIgnoreTagsAndAmount(EntryStack)} - */ - default int hashIgnoreAmountAndTags() { - return hashCode(); - } + R get(Settings settings); - int getZ(); - - void setZ(int z); - - default ItemStack getItemStack() { - if (getType() == Type.ITEM) - return (ItemStack) getObject(); - return null; - } - - default Item getItem() { - if (getType() == Type.ITEM) - return ((ItemStack) getObject()).getItem(); - return null; - } - - default Fluid getFluid() { - if (getType() == Type.FLUID) - return (Fluid) getObject(); - return null; - } - - EntryStack setting(Settings settings, T value); - - EntryStack removeSetting(Settings settings); - - EntryStack clearSettings(); - - default EntryStack addSetting(Settings settings, T value) { - return setting(settings, value); - } - - T get(Settings settings); - - @Nullable - default Tooltip getTooltip(Point mouse) { - return null; - } - - void render(PoseStack matrices, Rectangle bounds, int mouseX, int mouseY, float delta); - - enum Type { - ITEM, - FLUID, - EMPTY, - RENDER - } - - class Settings { + class Settings { @ApiStatus.Internal private static final List> SETTINGS = new ArrayList<>(); @@ -335,26 +158,26 @@ public interface EntryStack extends TextRepresentable { public static final Settings> TOOLTIP_ENABLED = new Settings<>(TRUE); public static final Settings> TOOLTIP_APPEND_MOD = new Settings<>(TRUE); public static final Settings> RENDER_COUNTS = new Settings<>(TRUE); - public static final Settings>> TOOLTIP_APPEND_EXTRA = new Settings<>(stack -> Collections.emptyList()); - public static final Settings> COUNTS = new Settings<>(stack -> null); + public static final Settings, List>> TOOLTIP_APPEND_EXTRA = new Settings<>(stack -> Collections.emptyList()); + public static final Settings, String>> COUNTS = new Settings<>(stack -> null); private static short nextId; - private T defaultValue; + private R defaultValue; private short id; @ApiStatus.Internal - public Settings(T defaultValue) { + public Settings(R defaultValue) { this.defaultValue = defaultValue; this.id = nextId++; SETTINGS.add(this); } @ApiStatus.Internal - public static Settings getById(short id) { - return (Settings) SETTINGS.get(id); + public static Settings getById(short id) { + return (Settings) SETTINGS.get(id); } - public T getDefaultValue() { + public R getDefaultValue() { return defaultValue; } @@ -365,15 +188,16 @@ public interface EntryStack extends TextRepresentable { public static class Fluid { // Return null to disable - public static final Settings> AMOUNT_TOOLTIP = new Settings<>(stack -> I18n.get("tooltip.rei.fluid_amount", stack.simplifyAmount().getAccurateAmount())); + public static final Settings, String>> AMOUNT_TOOLTIP = new Settings<>(stack -> I18n.get("tooltip.rei.fluid_amount", stack.simplifyAmount().getAmount())); private Fluid() { } } + } - default EntryStack simplifyAmount() { - setAmount(getAccurateAmount().simplify()); + default EntryStack simplifyAmount() { + setAmount(getAmount().simplify()); return this; } } diff --git a/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/FocusedStackProvider.java b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/FocusedStackProvider.java index 6fc26ca55..be0446f8c 100644 --- a/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/FocusedStackProvider.java +++ b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/FocusedStackProvider.java @@ -36,5 +36,5 @@ public interface FocusedStackProvider { } @NotNull - InteractionResultHolder provide(Screen screen); + InteractionResultHolder> provide(Screen screen); } diff --git a/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/LiveRecipeGenerator.java b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/LiveRecipeGenerator.java index 6c57bda5a..a4612eda3 100644 --- a/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/LiveRecipeGenerator.java +++ b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/LiveRecipeGenerator.java @@ -35,11 +35,11 @@ public interface LiveRecipeGenerator { */ ResourceLocation getCategoryIdentifier(); - default Optional> getRecipeFor(EntryStack entry) { + default Optional> getRecipeFor(EntryStack entry) { return Optional.empty(); } - default Optional> getUsageFor(EntryStack entry) { + default Optional> getUsageFor(EntryStack entry) { return Optional.empty(); } diff --git a/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/OverlayDecider.java b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/OverlayDecider.java index a4907147d..1eac57611 100644 --- a/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/OverlayDecider.java +++ b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/OverlayDecider.java @@ -32,7 +32,7 @@ import static net.minecraft.world.InteractionResult.PASS; public interface OverlayDecider { boolean isHandingScreen(Class screen); - default InteractionResult shouldScreenBeOverlayed(Class screen) { + default InteractionResult shouldScreenBeOverlaid(Class screen) { return InteractionResult.PASS; } diff --git a/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/RecipeCategory.java b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/RecipeCategory.java index 87e243e85..cda7af1e6 100644 --- a/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/RecipeCategory.java +++ b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/RecipeCategory.java @@ -25,8 +25,8 @@ package me.shedaniel.rei.api; import me.shedaniel.math.Rectangle; import me.shedaniel.rei.api.widgets.Widgets; -import me.shedaniel.rei.gui.entries.RecipeEntry; -import me.shedaniel.rei.gui.entries.SimpleRecipeEntry; +import me.shedaniel.rei.gui.entries.RecipeRenderer; +import me.shedaniel.rei.gui.entries.SimpleRecipeRenderer; import me.shedaniel.rei.gui.widget.Widget; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; @@ -54,7 +54,7 @@ public interface RecipeCategory { * @return the renderer of the icon */ @NotNull - default EntryStack getLogo() { + default Renderer getLogo() { return EntryStack.empty(); } @@ -74,8 +74,8 @@ public interface RecipeCategory { */ @ApiStatus.OverrideOnly @NotNull - default RecipeEntry getSimpleRenderer(T recipe) { - return SimpleRecipeEntry.from(recipe::getInputEntries, recipe::getResultingEntries); + default RecipeRenderer getSimpleRenderer(T recipe) { + return SimpleRecipeRenderer.from(recipe::getInputEntries, recipe::getResultingEntries); } /** diff --git a/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/RecipeDisplay.java b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/RecipeDisplay.java index c99eb50a3..582fd09da 100644 --- a/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/RecipeDisplay.java +++ b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/RecipeDisplay.java @@ -36,13 +36,13 @@ public interface RecipeDisplay { * @return a list of inputs */ @NotNull - List> getInputEntries(); + List>> getInputEntries(); /** * @return a list of outputs */ @NotNull - List> getResultingEntries(); + List>> getResultingEntries(); /** * Gets the required items used in craftable filters @@ -50,7 +50,7 @@ public interface RecipeDisplay { * @return the list of required items */ @NotNull - default List> getRequiredEntries() { + default List>> getRequiredEntries() { return Collections.emptyList(); } @@ -71,5 +71,4 @@ public interface RecipeDisplay { default Optional getRecipeLocation() { return Optional.empty(); } - } diff --git a/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/RecipeHelper.java b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/RecipeHelper.java index b0c61e380..74351ceda 100644 --- a/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/RecipeHelper.java +++ b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/RecipeHelper.java @@ -59,7 +59,7 @@ public interface RecipeHelper { @Nullable @ApiStatus.Internal - EntryStack getScreenFocusedStack(Screen screen); + EntryStack getScreenFocusedStack(Screen screen); List getSortedAutoCraftingHandler(); @@ -73,7 +73,7 @@ public interface RecipeHelper { /** * @return a list of sorted recipes */ - List getAllSortedRecipes(); + List> getAllSortedRecipes(); /** * Gets all craftable items from materials. @@ -81,7 +81,7 @@ public interface RecipeHelper { * @param inventoryItems the materials * @return the list of craftable entries */ - List findCraftableEntriesByItems(Iterable inventoryItems); + List> findCraftableEntriesByItems(Iterable> inventoryItems); /** * Gets all craftable items from materials. @@ -89,8 +89,8 @@ public interface RecipeHelper { * @param inventoryItems the materials * @return the list of craftable entries */ - default List findCraftableEntriesByItems(List inventoryItems) { - return findCraftableEntriesByItems((Iterable) inventoryItems); + default List> findCraftableEntriesByItems(List> inventoryItems) { + return findCraftableEntriesByItems((Iterable>) inventoryItems); } /** @@ -118,7 +118,7 @@ public interface RecipeHelper { * @param category the category * @param workingStations the working stations */ - void registerWorkingStations(ResourceLocation category, List... workingStations); + void registerWorkingStations(ResourceLocation category, List>... workingStations); /** * Registers the working stations of a category @@ -126,9 +126,9 @@ public interface RecipeHelper { * @param category the category * @param workingStations the working stations */ - void registerWorkingStations(ResourceLocation category, EntryStack... workingStations); + void registerWorkingStations(ResourceLocation category, EntryStack... workingStations); - List> getWorkingStations(ResourceLocation category); + List>> getWorkingStations(ResourceLocation category); /** * Registers a recipe display. @@ -145,7 +145,7 @@ public interface RecipeHelper { * @param stack the stack to be crafted * @return the map of recipes */ - Map, List> getRecipesFor(EntryStack stack); + Map, List> getRecipesFor(EntryStack stack); RecipeCategory getCategory(ResourceLocation identifier); @@ -169,7 +169,7 @@ public interface RecipeHelper { * @param stack the stack to be used * @return the map of recipes */ - Map, List> getUsagesFor(EntryStack stack); + Map, List> getUsagesFor(EntryStack stack); /** * Gets the optional of the auto crafting button area from a category @@ -238,8 +238,6 @@ public interface RecipeHelper { */ boolean isDisplayVisible(RecipeDisplay display); - > void registerRecipes(ResourceLocation category, Predicate recipeFilter, Function mappingFunction); - /** * Registers a live recipe generator. * @@ -290,9 +288,11 @@ public interface RecipeHelper { */ void registerClickArea(Class screenClass, ClickAreaHandler handler); - > void registerRecipes(ResourceLocation category, Class recipeClass, Function mappingFunction); + default > void registerRecipes(ResourceLocation category, Class recipeClass, Function mappingFunction) { + registerRecipes(category, recipe -> recipeClass.isAssignableFrom(recipe.getClass()), mappingFunction); + } - > void registerRecipes(ResourceLocation category, Function recipeFilter, Function mappingFunction); + > void registerRecipes(ResourceLocation category, Predicate> recipeFilter, Function mappingFunction); @ApiStatus.Internal boolean arePluginsLoading(); diff --git a/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/Renderer.java b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/Renderer.java new file mode 100644 index 000000000..f6a9c39ba --- /dev/null +++ b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/Renderer.java @@ -0,0 +1,20 @@ +package me.shedaniel.rei.api; + +import com.mojang.blaze3d.vertex.PoseStack; +import me.shedaniel.math.Point; +import me.shedaniel.math.Rectangle; +import me.shedaniel.rei.api.widgets.Tooltip; +import org.jetbrains.annotations.Nullable; + +public interface Renderer { + void render(PoseStack matrices, Rectangle bounds, int mouseX, int mouseY, float delta); + + @Nullable + default Tooltip getTooltip(Point mouse) { + return null; + } + + int getZ(); + + void setZ(int z); +} diff --git a/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/TextRepresentable.java b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/TextRepresentable.java index b346ab822..f245d629e 100644 --- a/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/TextRepresentable.java +++ b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/TextRepresentable.java @@ -23,8 +23,6 @@ package me.shedaniel.rei.api; -import me.shedaniel.math.impl.PointHelper; -import me.shedaniel.rei.api.widgets.Tooltip; import me.shedaniel.rei.utils.FormattingUtils; import me.shedaniel.rei.utils.ImmutableLiteralText; import net.fabricmc.api.EnvType; @@ -36,11 +34,6 @@ import org.jetbrains.annotations.NotNull; public interface TextRepresentable { @NotNull default Component asFormattedText() { - if (this instanceof EntryStack) { - Tooltip tooltip = ((EntryStack) this).getTooltip(PointHelper.ofMouse()); - if (tooltip != null && !tooltip.getText().isEmpty()) - return tooltip.getText().get(0); - } return ImmutableLiteralText.EMPTY; } diff --git a/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/TransferRecipeDisplay.java b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/TransferRecipeDisplay.java index d3f937410..0fe6374f9 100644 --- a/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/TransferRecipeDisplay.java +++ b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/TransferRecipeDisplay.java @@ -40,6 +40,5 @@ public interface TransferRecipeDisplay extends RecipeDisplay { */ int getHeight(); - List> getOrganisedInputEntries(ContainerInfo containerInfo, AbstractContainerMenu container); - + List>> getOrganisedInputEntries(ContainerInfo containerInfo, AbstractContainerMenu container); } diff --git a/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/entry/AbstractEntryRenderer.java b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/entry/AbstractEntryRenderer.java new file mode 100644 index 000000000..0fad3333a --- /dev/null +++ b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/entry/AbstractEntryRenderer.java @@ -0,0 +1,6 @@ +package me.shedaniel.rei.api.entry; + +import net.minecraft.client.gui.GuiComponent; + +public abstract class AbstractEntryRenderer extends GuiComponent implements EntryRenderer { +} diff --git a/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/entry/AbstractRenderer.java b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/entry/AbstractRenderer.java new file mode 100644 index 000000000..23b90db65 --- /dev/null +++ b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/entry/AbstractRenderer.java @@ -0,0 +1,16 @@ +package me.shedaniel.rei.api.entry; + +import me.shedaniel.rei.api.Renderer; +import net.minecraft.client.gui.GuiComponent; + +public abstract class AbstractRenderer extends GuiComponent implements Renderer { + @Override + public int getZ() { + return getBlitOffset(); + } + + @Override + public void setZ(int z) { + setBlitOffset(z); + } +} diff --git a/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/entry/BatchEntryRenderer.java b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/entry/BatchEntryRenderer.java new file mode 100644 index 000000000..2384c2099 --- /dev/null +++ b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/entry/BatchEntryRenderer.java @@ -0,0 +1,38 @@ +package me.shedaniel.rei.api.entry; + +import com.mojang.blaze3d.vertex.PoseStack; +import me.shedaniel.math.Rectangle; +import me.shedaniel.rei.api.EntryStack; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.MultiBufferSource; + +public interface BatchEntryRenderer extends EntryRenderer { + static int getBatchIdFrom(EntryStack entry) { + EntryRenderer renderer = entry.getRenderer(); + if (renderer instanceof BatchEntryRenderer) return ((BatchEntryRenderer) renderer).getBatchId(entry); + return renderer.getClass().hashCode(); + } + + default int getBatchId(EntryStack entry) { + return getClass().hashCode(); + } + + void startBatch(EntryStack entry, PoseStack matrices, float delta); + + void renderBase(EntryStack entry, PoseStack matrices, MultiBufferSource.BufferSource immediate, Rectangle bounds, int mouseX, int mouseY, float delta); + + void renderOverlay(EntryStack entry, PoseStack matrices, Rectangle bounds, int mouseX, int mouseY, float delta); + + void endBatch(EntryStack entry, PoseStack matrices, float delta); + + @Deprecated + @Override + default void render(EntryStack entry, PoseStack matrices, Rectangle bounds, int mouseX, int mouseY, float delta) { + startBatch(entry, matrices, delta); + MultiBufferSource.BufferSource immediate = Minecraft.getInstance().renderBuffers().bufferSource(); + renderBase(entry, matrices, immediate, bounds, mouseX, mouseY, delta); + immediate.endBatch(); + renderOverlay(entry, matrices, bounds, mouseX, mouseY, delta); + endBatch(entry, matrices, delta); + } +} \ No newline at end of file diff --git a/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/entry/BuiltinEntryTypes.java b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/entry/BuiltinEntryTypes.java new file mode 100644 index 000000000..a588bfa9f --- /dev/null +++ b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/entry/BuiltinEntryTypes.java @@ -0,0 +1,14 @@ +package me.shedaniel.rei.api.entry; + +import me.shedaniel.rei.impl.Internals; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.Unit; +import org.jetbrains.annotations.ApiStatus; + +@ApiStatus.NonExtendable +public interface BuiltinEntryTypes { + ResourceLocation EMPTY_ID = new ResourceLocation("empty"); + ResourceLocation RENDERING_ID = new ResourceLocation("rendering"); + EntryType EMPTY = Internals.getEntryStackProvider().emptyType(EMPTY_ID); + EntryType RENDERING = Internals.getEntryStackProvider().renderingType(RENDERING_ID); +} diff --git a/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/entry/ComparisonContext.java b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/entry/ComparisonContext.java new file mode 100644 index 000000000..3afebbcba --- /dev/null +++ b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/entry/ComparisonContext.java @@ -0,0 +1,36 @@ +package me.shedaniel.rei.api.entry; + +public enum ComparisonContext { + /** + * Should only compare the type of the object + */ + FUZZY(true, true), + /** + * Should compare the nbt and the type of the object + */ + IGNORE_COUNT(true, false), + /** + * Should compare the amount and the type of the object + */ + IGNORE_NBT(true, false), + /** + * Should compare the amount, the nbt and the type of the object + */ + EXACT(false, false); + + boolean ignoresCount; + boolean ignoresNbt; + + ComparisonContext(boolean ignoresCount, boolean ignoresNbt) { + this.ignoresCount = ignoresCount; + this.ignoresNbt = ignoresNbt; + } + + public boolean isIgnoresCount() { + return ignoresCount; + } + + public boolean isIgnoresNbt() { + return ignoresNbt; + } +} \ No newline at end of file diff --git a/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/entry/EntryDefinition.java b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/entry/EntryDefinition.java new file mode 100644 index 000000000..fcc6085dc --- /dev/null +++ b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/entry/EntryDefinition.java @@ -0,0 +1,55 @@ +package me.shedaniel.rei.api.entry; + +import me.shedaniel.architectury.utils.Fraction; +import me.shedaniel.rei.api.EntryStack; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; + +import java.util.Optional; + +public interface EntryDefinition { + @NotNull + Class getValueType(); + + @NotNull + EntryType getType(); + + @NotNull + EntryRenderer getRenderer(); + + @NotNull + Optional getIdentifier(EntryStack entry, T value); + + @NotNull + Fraction getAmount(EntryStack entry, T value); + + void setAmount(EntryStack entry, T value, Fraction amount); + + boolean isEmpty(EntryStack entry, T value); + + @NotNull + T copy(EntryStack entry, T value); + + int hash(EntryStack entry, T value, ComparisonContext context); + + boolean equals(T o1, T o2, ComparisonContext context); + + @NotNull + CompoundTag toTag(EntryStack entry, T value); + + @NotNull + T fromTag(@NotNull CompoundTag tag); + + @NotNull + Component asFormattedText(EntryStack entry, T value); + + @ApiStatus.NonExtendable + @NotNull + default EntryDefinition cast() { + return (EntryDefinition) this; + } +} + diff --git a/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/entry/EntryRenderer.java b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/entry/EntryRenderer.java new file mode 100644 index 000000000..2606f1b8f --- /dev/null +++ b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/entry/EntryRenderer.java @@ -0,0 +1,15 @@ +package me.shedaniel.rei.api.entry; + +import com.mojang.blaze3d.vertex.PoseStack; +import me.shedaniel.math.Point; +import me.shedaniel.math.Rectangle; +import me.shedaniel.rei.api.EntryStack; +import me.shedaniel.rei.api.widgets.Tooltip; +import org.jetbrains.annotations.Nullable; + +public interface EntryRenderer { + void render(EntryStack entry, PoseStack matrices, Rectangle bounds, int mouseX, int mouseY, float delta); + + @Nullable + Tooltip getTooltip(EntryStack entry, Point mouse); +} \ No newline at end of file diff --git a/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/entry/EntryStacks.java b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/entry/EntryStacks.java new file mode 100644 index 000000000..f2123aa6e --- /dev/null +++ b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/entry/EntryStacks.java @@ -0,0 +1,164 @@ +package me.shedaniel.rei.api.entry; + +import com.google.common.collect.ImmutableList; +import me.shedaniel.architectury.fluid.FluidStack; +import me.shedaniel.architectury.utils.Fraction; +import me.shedaniel.rei.api.EntryStack; +import net.minecraft.world.InteractionResultHolder; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.level.ItemLike; +import net.minecraft.world.level.material.Fluid; + +import java.util.*; +import java.util.stream.Stream; + +public final class EntryStacks { + private EntryStacks() {} + + public static EntryStack of(Fluid fluid) { + return of(fluid, FluidStack.bucketAmount()); + } + + public static EntryStack of(Fluid fluid, int amount) { + return of(fluid, Fraction.ofWhole(amount)); + } + + public static EntryStack of(Fluid fluid, double amount) { + return of(fluid, Fraction.from(amount)); + } + + public static EntryStack of(Fluid fluid, Fraction amount) { + return EntryStack.of(VanillaEntryTypes.FLUID, FluidStack.create(fluid, amount)); + } + + public static EntryStack of(ItemStack stack) { + return EntryStack.of(VanillaEntryTypes.ITEM, stack); + } + + public static EntryStack of(ItemLike item) { + return of(new ItemStack(item)); + } + + public static List> ofItems(Collection stacks) { + if (stacks.size() == 0) return Collections.emptyList(); + if (stacks.size() == 1) return Collections.singletonList(of(stacks.iterator().next())); + EntryStack[] result = new EntryStack[stacks.size()]; + int i = 0; + for (ItemLike stack : stacks) { + result[i] = of(stack); + i++; + } + return Arrays.asList(result); + } + + public static List> ofItemStacks(Collection stacks) { + if (stacks.size() == 0) return Collections.emptyList(); + if (stacks.size() == 1) { + ItemStack stack = stacks.iterator().next(); + if (stack.isEmpty()) return Collections.emptyList(); + return Collections.singletonList(of(stack)); + } + List> result = new ArrayList<>(stacks.size()); + for (ItemStack stack : stacks) { + result.add(of(stack)); + } + return ImmutableList.copyOf(result); + } + + public static List> ofIngredient(Ingredient ingredient) { + if (ingredient.isEmpty()) return Collections.emptyList(); + ItemStack[] matchingStacks = ingredient.getItems(); + if (matchingStacks.length == 0) return Collections.emptyList(); + if (matchingStacks.length == 1) return Collections.singletonList(of(matchingStacks[0])); + List> result = new ArrayList<>(matchingStacks.length); + for (ItemStack matchingStack : matchingStacks) { + if (!matchingStack.isEmpty()) + result.add(of(matchingStack)); + } + return ImmutableList.copyOf(result); + } + + public static List>> ofIngredients(List ingredients) { + if (ingredients.size() == 0) return Collections.emptyList(); + if (ingredients.size() == 1) { + Ingredient ingredient = ingredients.get(0); + if (ingredient.isEmpty()) return Collections.emptyList(); + return Collections.singletonList(ofIngredient(ingredient)); + } + boolean emptyFlag = true; + List>> result = new ArrayList<>(ingredients.size()); + for (int i = ingredients.size() - 1; i >= 0; i--) { + Ingredient ingredient = ingredients.get(i); + if (emptyFlag && ingredient.isEmpty()) continue; + result.add(0, ofIngredient(ingredient)); + emptyFlag = false; + } + return ImmutableList.copyOf(result); + } + + public static boolean equals(EntryStack left, EntryStack right, ComparisonContext context) { + if (left == null) return right == null; + if (right == null) return left == null; + if (left == right) return true; + EntryType leftType = left.getType(); + EntryType rightType = right.getType(); + if (leftType == rightType) + return left.equals((EntryStack) right, context); + for (EntryTypeBridge bridge : EntryTypeRegistry.getInstance().getBridgesFor(leftType, rightType)) { + InteractionResultHolder>> holder = bridge.bridge(left); + if (holder.getResult().shouldSwing()) { + Iterator> iterator = holder.getObject().iterator(); + while (iterator.hasNext()) { + EntryStack bridged = iterator.next(); + if (bridged.equals(right, context)) + return true; + } + } + } + for (EntryTypeBridge bridge : EntryTypeRegistry.getInstance().getBridgesFor(rightType, leftType)) { + InteractionResultHolder>> holder = bridge.bridge(right); + if (holder.getResult().shouldSwing()) { + Iterator> iterator = holder.getObject().iterator(); + while (iterator.hasNext()) { + EntryStack bridged = iterator.next(); + if (bridged.equals(left, context)) + return true; + } + } + } + return false; + } + + public static boolean equalsExact(EntryStack left, EntryStack right) { + return equals(left, right, ComparisonContext.EXACT); + } + + public static boolean equalsFuzzy(EntryStack left, EntryStack right) { + return equals(left, right, ComparisonContext.FUZZY); + } + + public static boolean equalsIgnoreCount(EntryStack left, EntryStack right) { + return equals(left, right, ComparisonContext.IGNORE_COUNT); + } + + public static boolean equalsIgnoreNbt(EntryStack left, EntryStack right) { + return equals(left, right, ComparisonContext.IGNORE_NBT); + } + + public static int hashExact(EntryStack stack) { + return stack.hash(ComparisonContext.EXACT); + } + + public static int hashFuzzy(EntryStack stack) { + return stack.hash(ComparisonContext.FUZZY); + } + + public static int hashIgnoreCount(EntryStack stack) { + return stack.hash(ComparisonContext.IGNORE_COUNT); + } + + public static int hashIgnoreNbt(EntryStack stack) { + return stack.hash(ComparisonContext.IGNORE_NBT); + } +} diff --git a/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/entry/EntryType.java b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/entry/EntryType.java new file mode 100644 index 000000000..1bbd98071 --- /dev/null +++ b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/entry/EntryType.java @@ -0,0 +1,25 @@ +package me.shedaniel.rei.api.entry; + +import me.shedaniel.rei.impl.Internals; +import net.minecraft.resources.ResourceLocation; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; + +@ApiStatus.NonExtendable +public interface EntryType { + static EntryType deferred(ResourceLocation id) { + return Internals.deferEntryType(id).cast(); + } + + @NotNull + ResourceLocation getId(); + + @NotNull + EntryDefinition getDefinition(); + + @ApiStatus.NonExtendable + @NotNull + default EntryType cast() { + return (EntryType) this; + } +} diff --git a/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/entry/EntryTypeBridge.java b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/entry/EntryTypeBridge.java new file mode 100644 index 000000000..2d9ac1e1e --- /dev/null +++ b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/entry/EntryTypeBridge.java @@ -0,0 +1,11 @@ +package me.shedaniel.rei.api.entry; + +import me.shedaniel.rei.api.EntryStack; +import net.minecraft.world.InteractionResultHolder; + +import java.util.stream.Stream; + +@FunctionalInterface +public interface EntryTypeBridge { + InteractionResultHolder>> bridge(EntryStack object); +} diff --git a/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/entry/EntryTypeRegistry.java b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/entry/EntryTypeRegistry.java new file mode 100644 index 000000000..689c6f99c --- /dev/null +++ b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/entry/EntryTypeRegistry.java @@ -0,0 +1,24 @@ +package me.shedaniel.rei.api.entry; + +import me.shedaniel.rei.impl.Internals; +import net.minecraft.resources.ResourceLocation; +import org.jetbrains.annotations.NotNull; + +public interface EntryTypeRegistry { + @NotNull + static EntryTypeRegistry getInstance() { + return Internals.getEntryTypeRegistry(); + } + + default void register(EntryType id, EntryDefinition definition) { + register(id.getId(), definition); + } + + void register(ResourceLocation id, EntryDefinition definition); + + void registerBridge(EntryType original, EntryType destination, EntryTypeBridge bridge); + + EntryDefinition get(ResourceLocation id); + + Iterable> getBridgesFor(EntryType original, EntryType destination); +} \ No newline at end of file diff --git a/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/entry/VanillaEntryTypes.java b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/entry/VanillaEntryTypes.java new file mode 100644 index 000000000..553698da4 --- /dev/null +++ b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/entry/VanillaEntryTypes.java @@ -0,0 +1,12 @@ +package me.shedaniel.rei.api.entry; + +import me.shedaniel.architectury.fluid.FluidStack; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.ItemStack; +import org.jetbrains.annotations.ApiStatus; + +@ApiStatus.NonExtendable +public interface VanillaEntryTypes { + EntryType ITEM = EntryType.deferred(new ResourceLocation("item")); + EntryType FLUID = EntryType.deferred(new ResourceLocation("fluid")); +} diff --git a/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/favorites/FavoriteEntry.java b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/favorites/FavoriteEntry.java index 211dbc915..c9df7b6c1 100644 --- a/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/favorites/FavoriteEntry.java +++ b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/favorites/FavoriteEntry.java @@ -25,6 +25,7 @@ package me.shedaniel.rei.api.favorites; import com.google.gson.JsonObject; import me.shedaniel.rei.api.EntryStack; +import me.shedaniel.rei.api.Renderer; import me.shedaniel.rei.impl.Internals; import net.minecraft.resources.ResourceLocation; import org.jetbrains.annotations.NotNull; @@ -71,7 +72,7 @@ public abstract class FavoriteEntry { public abstract boolean isInvalid(); - public abstract EntryStack getWidget(boolean showcase); + public abstract Renderer getRenderer(boolean showcase); public abstract boolean doAction(int button); diff --git a/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/fluid/FluidSupportProvider.java b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/fluid/FluidSupportProvider.java index a4ffe23e4..0769bde5c 100644 --- a/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/fluid/FluidSupportProvider.java +++ b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/fluid/FluidSupportProvider.java @@ -23,15 +23,18 @@ package me.shedaniel.rei.api.fluid; +import me.shedaniel.architectury.fluid.FluidStack; import me.shedaniel.rei.api.EntryStack; import me.shedaniel.rei.impl.Internals; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.world.InteractionResultHolder; +import net.minecraft.world.item.ItemStack; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Optional; import java.util.stream.Stream; /** @@ -47,11 +50,11 @@ public interface FluidSupportProvider { void registerProvider(@NotNull Provider provider); @NotNull - Stream itemToFluids(@NotNull EntryStack itemStack); + Optional>> itemToFluids(@NotNull EntryStack itemStack); @FunctionalInterface interface Provider { @NotNull - InteractionResultHolder<@Nullable Stream<@NotNull EntryStack>> itemToFluid(@NotNull EntryStack itemStack); + InteractionResultHolder<@Nullable Stream<@NotNull EntryStack>> itemToFluid(@NotNull EntryStack itemStack); } } diff --git a/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/fractions/Fraction.java b/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/fractions/Fraction.java deleted file mode 100644 index 1e25577ce..000000000 --- a/RoughlyEnoughItems-api/src/main/java/me/shedaniel/rei/api/fractions/Fraction.java +++ /dev/null @@ -1,186 +0,0 @@ -/* - * This file is licensed under the MIT License, part of Roughly Enough Items. - * Copyright (c) 2018, 2019, 2020 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.api.fractions; - -import com.google.common.math.LongMath; -import org.jetbrains.annotations.NotNull; - -import java.text.DecimalFormat; - -public fina