From e3bbafaad49d15c7459ec0b38dd4268b4fd7e5ef Mon Sep 17 00:00:00 2001 From: shedaniel Date: Wed, 9 Sep 2020 17:08:36 +0800 Subject: Get rid of mixins, turn EntryStack methods turn an ImmutableList instead of ArrayList Signed-off-by: shedaniel --- .../java/me/shedaniel/rei/api/BuiltinPlugin.java | 6 +- .../java/me/shedaniel/rei/api/ConfigObject.java | 2 + .../main/java/me/shedaniel/rei/api/EntryStack.java | 65 +++++- .../me/shedaniel/rei/plugin/DefaultPlugin.java | 103 +++++---- .../rei/plugin/brewing/DefaultBrewingDisplay.java | 16 +- .../plugin/brewing/RegisteredBrewingRecipe.java | 4 +- .../composting/DefaultCompostingCategory.java | 14 +- .../composting/DefaultCompostingDisplay.java | 34 +-- .../rei/plugin/crafting/DefaultCustomDisplay.java | 19 +- .../rei/plugin/mixin/MixinPotionBrewing.java | 88 -------- .../src/main/resources/fabric.mod.json | 3 - .../mixin.roughlyenoughitems-default-plugin.json | 13 -- ...roughlyenoughitems-default-plugin.accessWidener | 7 + .../shedaniel/rei/gui/widget/EntryListWidget.java | 12 +- .../rei/gui/widget/FavoritesListWidget.java | 12 +- .../me/shedaniel/rei/impl/AbstractEntryStack.java | 43 ++-- .../me/shedaniel/rei/impl/ConfigObjectImpl.java | 3 +- .../me/shedaniel/rei/impl/EntryRegistryImpl.java | 2 +- .../me/shedaniel/rei/impl/FluidEntryStack.java | 6 +- .../java/me/shedaniel/rei/impl/ItemEntryStack.java | 19 +- .../java/me/shedaniel/rei/impl/ItemStackHook.java | 31 --- .../me/shedaniel/rei/impl/RecipeHelperImpl.java | 10 +- .../me/shedaniel/rei/mixin/MixinItemStack.java | 48 ----- .../src/main/resources/fabric.mod.json | 3 - .../mixin.roughlyenoughitems-runtime.json | 13 -- build.gradle | 239 ++++++++++++++++++++- gradle.properties | 2 +- 27 files changed, 486 insertions(+), 331 deletions(-) delete mode 100644 RoughlyEnoughItems-default-plugin/src/main/java/me/shedaniel/rei/plugin/mixin/MixinPotionBrewing.java delete mode 100644 RoughlyEnoughItems-default-plugin/src/main/resources/mixin.roughlyenoughitems-default-plugin.json delete mode 100644 RoughlyEnoughItems-runtime/src/main/java/me/shedaniel/rei/impl/ItemStackHook.java delete mode 100644 RoughlyEnoughItems-runtime/src/main/java/me/shedaniel/rei/mixin/MixinItemStack.java delete mode 100644 RoughlyEnoughItems-runtime/src/main/resources/mixin.roughlyenoughitems-runtime.json 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 ca9c60085..057ac2613 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 @@ -56,7 +56,11 @@ public interface BuiltinPlugin { return Internals.getBuiltinPlugin(); } - void registerBrewingRecipe(ItemStack input, Ingredient ingredient, ItemStack output); + default void registerBrewingRecipe(ItemStack input, Ingredient ingredient, ItemStack output) { + registerBrewingRecipe(Ingredient.of(input), ingredient, output); + } + + void registerBrewingRecipe(Ingredient input, Ingredient ingredient, ItemStack output); void registerInformation(List entryStacks, Component name, UnaryOperator> textBuilder); 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 044b5e659..e7b2bf1a5 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 @@ -59,6 +59,8 @@ public interface ConfigObject { boolean isToastDisplayedOnCopyIdentifier(); + @Deprecated + @ApiStatus.ScheduledForRemoval boolean doesRenderEntryEnchantmentGlint(); boolean isEntryListWidgetScrolled(); 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 e1ff44c24..98ef1533e 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,9 +23,12 @@ 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 it.unimi.dsi.fastutil.shorts.Short2ObjectMap; +import it.unimi.dsi.fastutil.shorts.Short2ObjectOpenHashMap; import me.shedaniel.math.Point; import me.shedaniel.math.Rectangle; import me.shedaniel.rei.api.fluid.FluidSupportProvider; @@ -85,36 +88,57 @@ public interface EntryStack extends TextRepresentable { } static List ofItems(Collection stacks) { - List result = new ArrayList<>(stacks.size()); + 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.add(create(stack)); + result[i] = create(stack); + i++; } - return result; + 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 result; + 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) { - result.add(create(matchingStack)); + if (!matchingStack.isEmpty()) + result.add(create(matchingStack)); } - return result; + return ImmutableList.copyOf(result); } 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)); + } List> result = new ArrayList<>(ingredients.size()); for (Ingredient ingredient : ingredients) { - result.add(ofIngredient(ingredient)); + if (!ingredient.isEmpty()) + result.add(ofIngredient(ingredient)); } - return result; + return ImmutableList.copyOf(result); } @Deprecated @@ -246,6 +270,11 @@ public interface EntryStack extends TextRepresentable { EntryStack copy(); + @ApiStatus.Internal + default EntryStack rewrap() { + return copy(); + } + Object getObject(); boolean equals(EntryStack stack, boolean ignoreTags, boolean ignoreAmount); @@ -335,6 +364,9 @@ public interface EntryStack extends TextRepresentable { } class Settings { + @ApiStatus.Internal + private static final Short2ObjectMap> ID_TO_SETTINGS = new Short2ObjectOpenHashMap<>(); + public static final Supplier TRUE = () -> true; public static final Supplier FALSE = () -> false; public static final Settings> RENDER = new Settings<>(TRUE); @@ -346,17 +378,34 @@ public interface EntryStack extends TextRepresentable { public static final Settings>> TOOLTIP_APPEND_EXTRA = new Settings<>(stack -> Collections.emptyList()); public static final Settings> COUNTS = new Settings<>(stack -> null); + private static short nextId; private T defaultValue; + private short id; + @ApiStatus.Internal public Settings(T defaultValue) { this.defaultValue = defaultValue; + this.id = nextId++; + ID_TO_SETTINGS.put(this.id, this); + } + + @ApiStatus.Internal + public static Settings getById(short id) { + return (Settings) ID_TO_SETTINGS.get(id); } public T getDefaultValue() { return defaultValue; } + @ApiStatus.Internal + public short getId() { + return id; + } + public static class Item { + @Deprecated + @ApiStatus.ScheduledForRemoval public static final Settings> RENDER_ENCHANTMENT_GLINT = new Settings<>(TRUE); private Item() { diff --git a/RoughlyEnoughItems-default-plugin/src/main/java/me/shedaniel/rei/plugin/DefaultPlugin.java b/RoughlyEnoughItems-default-plugin/src/main/java/me/shedaniel/rei/plugin/DefaultPlugin.java index 3c1ef8c46..c5198bce1 100644 --- a/RoughlyEnoughItems-default-plugin/src/main/java/me/shedaniel/rei/plugin/DefaultPlugin.java +++ b/RoughlyEnoughItems-default-plugin/src/main/java/me/shedaniel/rei/plugin/DefaultPlugin.java @@ -23,9 +23,12 @@ package me.shedaniel.rei.plugin; +import com.google.common.collect.Iterators; import com.google.common.collect.Lists; -import com.google.common.collect.Maps; +import com.google.common.collect.Sets; 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; import me.shedaniel.rei.api.*; import me.shedaniel.rei.api.fluid.FluidSupportProvider; @@ -79,10 +82,10 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.tags.BlockTags; import net.minecraft.tags.ItemTags; import net.minecraft.tags.Tag; -import net.minecraft.util.LazyLoadedValue; -import net.minecraft.util.Mth; import net.minecraft.world.InteractionResultHolder; import net.minecraft.world.item.*; +import net.minecraft.world.item.alchemy.Potion; +import net.minecraft.world.item.alchemy.PotionBrewing; import net.minecraft.world.item.alchemy.PotionUtils; import net.minecraft.world.item.crafting.*; import net.minecraft.world.item.enchantment.Enchantment; @@ -123,8 +126,6 @@ public class DefaultPlugin implements REIPluginV0, BuiltinPlugin { public static final ResourceLocation INFO = BuiltinPlugin.INFO; private static final ResourceLocation DISPLAY_TEXTURE = new ResourceLocation("roughlyenoughitems", "textures/gui/display.png"); private static final ResourceLocation DISPLAY_TEXTURE_DARK = new ResourceLocation("roughlyenoughitems", "textures/gui/display_dark.png"); - private static final List> BREWING_DISPLAYS = Lists.newArrayList(); - private static final List INFO_DISPLAYS = Lists.newArrayList(); public static ResourceLocation getDisplayTexture() { return REIHelper.getInstance().getDefaultDisplayTexture(); @@ -137,19 +138,19 @@ public class DefaultPlugin implements REIPluginV0, BuiltinPlugin { @Deprecated @ApiStatus.ScheduledForRemoval public static void registerBrewingDisplay(DefaultBrewingDisplay recipe) { - BREWING_DISPLAYS.add(new LazyLoadedValue<>(() -> recipe)); + RecipeHelper.getInstance().registerDisplay(recipe); } public static void registerBrewingRecipe(RegisteredBrewingRecipe recipe) { - BREWING_DISPLAYS.add(new LazyLoadedValue<>(() -> new DefaultBrewingDisplay(recipe.input, recipe.ingredient, recipe.output))); + RecipeHelper.getInstance().registerDisplay(new DefaultBrewingDisplay(recipe.input, recipe.ingredient, recipe.output)); } public static void registerInfoDisplay(DefaultInformationDisplay display) { - INFO_DISPLAYS.add(display); + RecipeHelper.getInstance().registerDisplay(display); } @Override - public void registerBrewingRecipe(ItemStack input, Ingredient ingredient, ItemStack output) { + public void registerBrewingRecipe(Ingredient input, Ingredient ingredient, ItemStack output) { registerBrewingRecipe(new RegisteredBrewingRecipe(input, ingredient, output)); } @@ -163,11 +164,6 @@ public class DefaultPlugin implements REIPluginV0, BuiltinPlugin { return PLUGIN; } - @Override - public void preRegister() { - INFO_DISPLAYS.clear(); - } - @Override public void registerEntries(EntryRegistry entryRegistry) { for (Item item : Registry.ITEM) { @@ -232,41 +228,36 @@ public class DefaultPlugin implements REIPluginV0, BuiltinPlugin { recipeHelper.registerRecipes(CAMPFIRE, CampfireCookingRecipe.class, DefaultCampfireDisplay::new); recipeHelper.registerRecipes(STONE_CUTTING, StonecutterRecipe.class, DefaultStoneCuttingDisplay::new); recipeHelper.registerRecipes(SMITHING, UpgradeRecipe.class, DefaultSmithingDisplay::new); - for (LazyLoadedValue display : BREWING_DISPLAYS) { - recipeHelper.registerDisplay(display.get()); - } for (Map.Entry entry : AbstractFurnaceBlockEntity.getFuel().entrySet()) { recipeHelper.registerDisplay(new DefaultFuelDisplay(EntryStack.create(entry.getKey()), entry.getValue())); } List arrowStack = Collections.singletonList(EntryStack.create(Items.ARROW)); + ReferenceSet registeredPotions = new ReferenceOpenHashSet<>(); EntryRegistry.getInstance().getEntryStacks().filter(entry -> entry.getItem() == Items.LINGERING_POTION).forEach(entry -> { - List> input = new ArrayList<>(); - for (int i = 0; i < 4; i++) - input.add(arrowStack); - input.add(Collections.singletonList(EntryStack.create(entry.getItemStack()))); - for (int i = 0; i < 4; i++) - input.add(arrowStack); - ItemStack outputStack = new ItemStack(Items.TIPPED_ARROW, 8); - PotionUtils.setPotion(outputStack, PotionUtils.getPotion(entry.getItemStack())); - PotionUtils.setCustomEffects(outputStack, PotionUtils.getCustomEffects(entry.getItemStack())); - List output = Collections.singletonList(EntryStack.create(outputStack).addSetting(EntryStack.Settings.CHECK_TAGS, EntryStack.Settings.TRUE)); - recipeHelper.registerDisplay(new DefaultCustomDisplay(null, input, output)); + Potion potion = PotionUtils.getPotion(entry.getItemStack()); + if (registeredPotions.add(potion)) { + List> input = new ArrayList<>(); + for (int i = 0; i < 4; i++) + input.add(arrowStack); + input.add(Collections.singletonList(EntryStack.create(entry.getItemStack()))); + 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(entry.getItemStack())); + List output = Collections.singletonList(EntryStack.create(outputStack).addSetting(EntryStack.Settings.CHECK_TAGS, EntryStack.Settings.TRUE)); + recipeHelper.registerDisplay(new DefaultCustomDisplay(null, input, output)); + } }); - Map map = Maps.newLinkedHashMap(); if (ComposterBlock.COMPOSTABLES.isEmpty()) ComposterBlock.bootStrap(); - for (Object2FloatMap.Entry entry : ComposterBlock.COMPOSTABLES.object2FloatEntrySet()) { - if (entry.getFloatValue() > 0) - map.put(entry.getKey(), entry.getFloatValue()); - } - List stacks = Lists.newArrayList(map.keySet()); - stacks.sort(Comparator.comparing(map::get)); - for (int i = 0; i < stacks.size(); i += Mth.clamp(48, 1, stacks.size() - i)) { - List thisStacks = Lists.newArrayList(); - for (int j = i; j < i + 48; j++) - if (j < stacks.size()) - thisStacks.add(stacks.get(j)); - recipeHelper.registerDisplay(new DefaultCompostingDisplay(Mth.floor(i / 48f), thisStacks, map, new ItemStack(Items.BONE_MEAL))); + Object2FloatMap compostables = ComposterBlock.COMPOSTABLES; + int i = 0; + Iterator>> iterator = Iterators.partition(compostables.object2FloatEntrySet().stream().sorted(Map.Entry.comparingByValue()).iterator(), 48); + while (iterator.hasNext()) { + List> entries = iterator.next(); + recipeHelper.registerDisplay(new DefaultCompostingDisplay(i, entries, compostables, new ItemStack(Items.BONE_MEAL))); + i++; } DummyAxeItem.getStrippedBlocksMap().entrySet().stream().sorted(Comparator.comparing(b -> Registry.BLOCK.getKey(b.getKey()))).forEach(set -> { recipeHelper.registerDisplay(new DefaultStrippingDisplay(EntryStack.create(set.getKey()), EntryStack.create(set.getValue()))); @@ -279,12 +270,38 @@ public class DefaultPlugin implements REIPluginV0, BuiltinPlugin { }); recipeHelper.registerDisplay(new DefaultBeaconBaseDisplay(CollectionUtils.map(Lists.newArrayList(BlockTags.BEACON_BASE_BLOCKS.getValues()), ItemStack::new))); recipeHelper.registerDisplay(new DefaultBeaconPaymentDisplay(CollectionUtils.map(Lists.newArrayList(ItemTags.BEACON_PAYMENT_ITEMS.getValues()), ItemStack::new))); + Set potions = Sets.newLinkedHashSet(); + for (Ingredient container : PotionBrewing.ALLOWED_CONTAINERS) { + for (PotionBrewing.Mix mix : PotionBrewing.POTION_MIXES) { + Potion from = mix.from; + Ingredient ingredient = mix.ingredient; + Potion to = mix.to; + Ingredient base = Ingredient.of(Arrays.stream(container.getItems()) + .map(ItemStack::copy) + .map(stack -> PotionUtils.setPotion(stack, from))); + ItemStack output = Arrays.stream(container.getItems()) + .map(ItemStack::copy) + .map(stack -> PotionUtils.setPotion(stack, to)) + .findFirst().orElse(ItemStack.EMPTY); + registerBrewingRecipe(base, ingredient, output); + potions.add(from); + potions.add(to); + } + } + for (Potion potion : potions) { + for (PotionBrewing.Mix mix : PotionBrewing.CONTAINER_MIXES) { + Item from = mix.from; + Ingredient ingredient = mix.ingredient; + Item to = mix.to; + Ingredient base = Ingredient.of(PotionUtils.setPotion(new ItemStack(from), potion)); + ItemStack output = PotionUtils.setPotion(new ItemStack(to), potion); + registerBrewingRecipe(base, ingredient, output); + } + } } @Override public void postRegister() { - for (DefaultInformationDisplay display : INFO_DISPLAYS) - RecipeHelper.getInstance().registerDisplay(display); // TODO Turn this into an API // Sit tight! This will be a fast journey! long time = System.currentTimeMillis(); diff --git a/RoughlyEnoughItems-default-plugin/src/main/java/me/shedaniel/rei/plugin/brewing/DefaultBrewingDisplay.java b/RoughlyEnoughItems-default-plugin/src/main/java/me/shedaniel/rei/plugin/brewing/DefaultBrewingDisplay.java index 69537a9b6..a297ddfab 100644 --- a/RoughlyEnoughItems-default-plugin/src/main/java/me/shedaniel/rei/plugin/brewing/DefaultBrewingDisplay.java +++ b/RoughlyEnoughItems-default-plugin/src/main/java/me/shedaniel/rei/plugin/brewing/DefaultBrewingDisplay.java @@ -44,12 +44,18 @@ import java.util.List; @Environment(EnvType.CLIENT) public class DefaultBrewingDisplay implements RecipeDisplay { - private EntryStack input, output; - private List reactant; + private EntryStack output; + private List reactant, input; @ApiStatus.Internal - public DefaultBrewingDisplay(ItemStack input, Ingredient reactant, ItemStack output) { - this.input = EntryStack.create(input).setting(EntryStack.Settings.TOOLTIP_APPEND_EXTRA, stack -> Collections.singletonList(new TranslatableComponent("category.rei.brewing.input").withStyle(ChatFormatting.YELLOW))); + public DefaultBrewingDisplay(Ingredient input, Ingredient reactant, ItemStack output) { + ItemStack[] inputItems = input.getItems(); + this.input = new ArrayList<>(inputItems.length); + for (ItemStack inputItem : inputItems) { + EntryStack entryStack = EntryStack.create(inputItem); + entryStack.setting(EntryStack.Settings.TOOLTIP_APPEND_EXTRA, s -> Collections.singletonList(new TranslatableComponent("category.rei.brewing.input").withStyle(ChatFormatting.YELLOW))); + this.input.add(entryStack); + } ItemStack[] reactantStacks = reactant.getItems(); this.reactant = new ArrayList<>(reactantStacks.length); for (ItemStack stack : reactantStacks) { @@ -62,7 +68,7 @@ public class DefaultBrewingDisplay implements RecipeDisplay { @Override public @NotNull List> getInputEntries() { - return Lists.newArrayList(Collections.singletonList(input), reactant); + return Lists.newArrayList(input, reactant); } @Override diff --git a/RoughlyEnoughItems-default-plugin/src/main/java/me/shedaniel/rei/plugin/brewing/RegisteredBrewingRecipe.java b/RoughlyEnoughItems-default-plugin/src/main/java/me/shedaniel/rei/plugin/brewing/RegisteredBrewingRecipe.java index 51c6e054b..e331a9253 100644 --- a/RoughlyEnoughItems-default-plugin/src/main/java/me/shedaniel/rei/plugin/brewing/RegisteredBrewingRecipe.java +++ b/RoughlyEnoughItems-default-plugin/src/main/java/me/shedaniel/rei/plugin/brewing/RegisteredBrewingRecipe.java @@ -28,11 +28,11 @@ import net.minecraft.world.item.crafting.Ingredient; public class RegisteredBrewingRecipe { - public final ItemStack input; + public final Ingredient input; public final Ingredient ingredient; public final ItemStack output; - public RegisteredBrewingRecipe(ItemStack input, Ingredient ingredient, ItemStack output) { + public RegisteredBrewingRecipe(Ingredient input, Ingredient ingredient, ItemStack output) { this.input = input; this.ingredient = ingredient; this.output = output; diff --git a/RoughlyEnoughItems-default-plugin/src/main/java/me/shedaniel/rei/plugin/composting/DefaultCompostingCategory.java b/RoughlyEnoughItems-default-plugin/src/main/java/me/shedaniel/rei/plugin/composting/DefaultCompostingCategory.java index 56447b60f..0b529a026 100644 --- a/RoughlyEnoughItems-default-plugin/src/main/java/me/shedaniel/rei/plugin/composting/DefaultCompostingCategory.java +++ b/RoughlyEnoughItems-default-plugin/src/main/java/me/shedaniel/rei/plugin/composting/DefaultCompostingCategory.java @@ -86,17 +86,19 @@ public class DefaultCompostingCategory implements RecipeCategory setupDisplay(DefaultCompostingDisplay display, Rectangle bounds) { List widgets = Lists.newArrayList(); Point startingPoint = new Point(bounds.x + bounds.width - 55, bounds.y + 110); - List stacks = new ArrayList<>(display.getRequiredEntries().get(0)); + List> stacks = new ArrayList<>(display.getInputEntries()); int i = 0; for (int y = 0; y < 6; y++) for (int x = 0; x < 8; x++) { - EntryStack[] entryStack = {stacks.size() > i ? stacks.get(i) : EntryStack.empty()}; - if (!entryStack[0].isEmpty()) { - display.getInputMap().entrySet().parallelStream().filter(entry -> entry.getKey() != null && Objects.equals(entry.getKey().asItem(), entryStack[0].getItem())).findAny().map(Map.Entry::getValue).ifPresent(chance -> { - entryStack[0] = entryStack[0].setting(EntryStack.Settings.TOOLTIP_APPEND_EXTRA, s -> Collections.singletonList(new TranslatableComponent("text.rei.composting.chance", Mth.fastFloor(chance * 100)).withStyle(ChatFormatting.YELLOW))); + List entryStack = stacks.size() > i ? stacks.get(i) : Collections.emptyList(); + if (!entryStack.isEmpty()) { + display.getInputMap().object2FloatEntrySet().stream().filter(entry -> entry.getKey() != null && Objects.equals(entry.getKey().asItem(), entryStack.get(0).getItem())).findAny().map(Map.Entry::getValue).ifPresent(chance -> { + for (EntryStack stack : entryStack) { + stack.setting(EntryStack.Settings.TOOLTIP_APPEND_EXTRA, s -> Collections.singletonList(new TranslatableComponent("text.rei.composting.chance", Mth.fastFloor(chance * 100)).withStyle(ChatFormatting.YELLOW))); + } }); } - widgets.add(Widgets.createSlot(new Point(bounds.getCenterX() - 72 + x * 18, bounds.y + 3 + y * 18)).entry(entryStack[0]).markInput()); + widgets.add(Widgets.createSlot(new Point(bounds.getCenterX() - 72 + x * 18, bounds.y + 3 + y * 18)).entries(entryStack).markInput()); i++; } widgets.add(Widgets.createArrow(new Point(startingPoint.x - 1, startingPoint.y + 7))); diff --git a/RoughlyEnoughItems-default-plugin/src/main/java/me/shedaniel/rei/plugin/composting/DefaultCompostingDisplay.java b/RoughlyEnoughItems-default-plugin/src/main/java/me/shedaniel/rei/plugin/composting/DefaultCompostingDisplay.java index f5f1df2f6..b764a00e5 100644 --- a/RoughlyEnoughItems-default-plugin/src/main/java/me/shedaniel/rei/plugin/composting/DefaultCompostingDisplay.java +++ b/RoughlyEnoughItems-default-plugin/src/main/java/me/shedaniel/rei/plugin/composting/DefaultCompostingDisplay.java @@ -23,10 +23,10 @@ package me.shedaniel.rei.plugin.composting; +import it.unimi.dsi.fastutil.objects.Object2FloatMap; import me.shedaniel.rei.api.EntryStack; import me.shedaniel.rei.api.RecipeDisplay; import me.shedaniel.rei.plugin.DefaultPlugin; -import me.shedaniel.rei.utils.CollectionUtils; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.resources.ResourceLocation; @@ -34,22 +34,30 @@ import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.ItemLike; import org.jetbrains.annotations.NotNull; +import java.util.Arrays; import java.util.Collections; import java.util.List; -import java.util.Map; @Environment(EnvType.CLIENT) public class DefaultCompostingDisplay implements RecipeDisplay { - private List order; - private Map inputMap; - private List output; + private List> inputs; + private Object2FloatMap inputMap; + private List> output; private int page; - public DefaultCompostingDisplay(int page, List order, Map inputMap, ItemStack output) { + public DefaultCompostingDisplay(int page, List> inputs, Object2FloatMap map, ItemStack output) { this.page = page; - this.order = EntryStack.ofItems(order); - this.inputMap = inputMap; - this.output = EntryStack.ofItemStacks(Collections.singletonList(output)); + { + List[] result = new List[inputs.size()]; + int i = 0; + for (Object2FloatMap.Entry entry : inputs) { + result[i] = Collections.singletonList(EntryStack.create(entry.getKey())); + i++; + } + this.inputs = Arrays.asList(result); + } + this.inputMap = map; + this.output = Collections.singletonList(Collections.singletonList(EntryStack.create(output))); } public int getPage() { @@ -58,16 +66,16 @@ public class DefaultCompostingDisplay implements RecipeDisplay { @Override public @NotNull List> getInputEntries() { - return CollectionUtils.map(order, Collections::singletonList); + return inputs; } - public Map getInputMap() { + public Object2FloatMap getInputMap() { return inputMap; } @Override public @NotNull List> getResultingEntries() { - return Collections.singletonList(output); + return output; } @Override @@ -77,6 +85,6 @@ public class DefaultCompostingDisplay implements RecipeDisplay { @Override public @NotNull List> getRequiredEntries() { - return Collections.singletonList(order); + return inputs; } } diff --git a/RoughlyEnoughItems-default-plugin/src/main/java/me/shedaniel/rei/plugin/crafting/DefaultCustomDisplay.java b/RoughlyEnoughItems-default-plugin/src/main/java/me/shedaniel/rei/plugin/crafting/DefaultCustomDisplay.java index e8f650cdd..5bab62e7a 100644 --- a/RoughlyEnoughItems-default-plugin/src/main/java/me/shedaniel/rei/plugin/crafting/DefaultCustomDisplay.java +++ b/RoughlyEnoughItems-default-plugin/src/main/java/me/shedaniel/rei/plugin/crafting/DefaultCustomDisplay.java @@ -23,7 +23,7 @@ package me.shedaniel.rei.plugin.crafting; -import com.google.common.collect.Lists; +import com.google.common.collect.ImmutableList; import me.shedaniel.rei.api.EntryStack; import me.shedaniel.rei.utils.CollectionUtils; import net.fabricmc.api.EnvType; @@ -33,6 +33,7 @@ import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.Recipe; import org.jetbrains.annotations.NotNull; +import java.util.BitSet; import java.util.Collections; import java.util.List; import java.util.Optional; @@ -50,21 +51,21 @@ public class DefaultCustomDisplay implements DefaultCraftingDisplay { } public DefaultCustomDisplay(Recipe possibleRecipe, List> input, List output) { - this.input = input; - this.output = output; + this.input = ImmutableList.copyOf(input); + this.output = ImmutableList.copyOf(output); this.possibleRecipe = possibleRecipe; - List row = Lists.newArrayList(false, false, false); - List column = Lists.newArrayList(false, false, false); + BitSet row = new BitSet(3); + BitSet column = new BitSet(3); for (int i = 0; i < 9; i++) if (i < this.input.size()) { List stacks = this.input.get(i); if (stacks.stream().anyMatch(stack -> !stack.isEmpty())) { - row.set((i - (i % 3)) / 3, true); - column.set(i % 3, true); + row.set((i - (i % 3)) / 3); + column.set(i % 3); } } - this.width = (int) column.stream().filter(Boolean::booleanValue).count(); - this.height = (int) row.stream().filter(Boolean::booleanValue).count(); + this.width = row.cardinality(); + this.height = column.cardinality(); } public DefaultCustomDisplay(List> input, List output) { diff --git a/RoughlyEnoughItems-default-plugin/src/main/java/me/shedaniel/rei/plugin/mixin/MixinPotionBrewing.java b/RoughlyEnoughItems-default-plugin/src/main/java/me/shedaniel/rei/plugin/mixin/MixinPotionBrewing.java deleted file mode 100644 index 1c5250833..000000000 --- a/RoughlyEnoughItems-default-plugin/src/main/java/me/shedaniel/rei/plugin/mixin/MixinPotionBrewing.java +++ /dev/null @@ -1,88 +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.plugin.mixin; - -import com.google.common.collect.Lists; -import me.shedaniel.rei.plugin.DefaultPlugin; -import me.shedaniel.rei.plugin.brewing.BrewingRecipe; -import me.shedaniel.rei.plugin.brewing.RegisteredBrewingRecipe; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.PotionItem; -import net.minecraft.world.item.alchemy.Potion; -import net.minecraft.world.item.alchemy.PotionBrewing; -import net.minecraft.world.item.alchemy.PotionUtils; -import net.minecraft.world.item.crafting.Ingredient; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import java.util.List; - -@Mixin(PotionBrewing.class) -@Environment(EnvType.CLIENT) -public class MixinPotionBrewing { - - @Unique private static final List SELF_ITEM_RECIPES = Lists.newArrayList(); - @Unique private static final List REGISTERED_POTION_TYPES = Lists.newArrayList(); - @Unique private static final List SELF_POTION_TYPES = Lists.newArrayList(); - - @Inject(method = "addContainer", at = @At("RETURN")) - private static void addContainer(Item item_1, CallbackInfo ci) { - if (item_1 instanceof PotionItem) - SELF_POTION_TYPES.add(Ingredient.of(item_1)); - } - - @Inject(method = "addContainerRecipe", at = @At("RETURN")) - private static void addContainerRecipe(Item item_1, Item item_2, Item item_3, CallbackInfo ci) { - if (item_1 instanceof PotionItem && item_3 instanceof PotionItem) - SELF_ITEM_RECIPES.add(new BrewingRecipe(item_1, Ingredient.of(item_2), item_3)); - } - - @Inject(method = "addMix", at = @At("RETURN")) - private static void addMix(Potion potion_1, Item item_1, Potion potion_2, CallbackInfo ci) { - if (!REGISTERED_POTION_TYPES.contains(potion_1)) - rei_registerPotionType(potion_1); - if (!REGISTERED_POTION_TYPES.contains(potion_2)) - rei_registerPotionType(potion_2); - for (Ingredient type : SELF_POTION_TYPES) { - for (ItemStack stack : type.getItems()) { - DefaultPlugin.registerBrewingRecipe(new RegisteredBrewingRecipe(PotionUtils.setPotion(stack.copy(), potion_1), Ingredient.of(item_1), PotionUtils.setPotion(stack.copy(), potion_2))); - } - } - } - - @Unique - private static void rei_registerPotionType(Potion potion) { - REGISTERED_POTION_TYPES.add(potion); - for (BrewingRecipe recipe : SELF_ITEM_RECIPES) { - DefaultPlugin.registerBrewingRecipe(new RegisteredBrewingRecipe(PotionUtils.setPotion(recipe.input.getDefaultInstance(), potion), recipe.ingredient, PotionUtils.setPotion(recipe.output.getDefaultInstance(), potion))); - } - } - -} diff --git a/RoughlyEnoughItems-default-plugin/src/main/resources/fabric.mod.json b/RoughlyEnoughItems-default-plugin/src/main/resources/fabric.mod.json index 985864498..c6b67960d 100644 --- a/RoughlyEnoughItems-default-plugin/src/main/resources/fabric.mod.json +++ b/RoughlyEnoughItems-default-plugin/src/main/resources/fabric.mod.json @@ -23,9 +23,6 @@ ] }, "accessWidener": "roughlyenoughitems-default-plugin.accessWidener", - "mixins": [ - "mixin.roughlyenoughitems-default-plugin.json" - ], "custom": { "modmenu:parent": "roughlyenoughitems" } diff --git a/RoughlyEnoughItems-default-plugin/src/main/resources/mixin.roughlyenoughitems-default-plugin.json b/RoughlyEnoughItems-default-plugin/src/main/resources/mixin.roughlyenoughitems-default-plugin.json deleted file mode 100644 index 5c4a2e574..000000000 --- a/RoughlyEnoughItems-default-plugin/src/main/resources/mixin.roughlyenoughitems-default-plugin.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "required": true, - "package": "me.shedaniel.rei.plugin.mixin", - "minVersion": "0.7.11", - "compatibilityLevel": "JAVA_8", - "mixins": [], - "client": [ - "MixinPotionBrewing" - ], - "injectors": { - "defaultRequire": 1 - } -} diff --git a/RoughlyEnoughItems-default-plugin/src/main/resources/roughlyenoughitems-default-plugin.accessWidener b/RoughlyEnoughItems-default-plugin/src/main/resources/roughlyenoughitems-default-plugin.accessWidener index b85ba6826..7a3f5ba99 100644 --- a/RoughlyEnoughItems-default-plugin/src/main/resources/roughlyenoughitems-default-plugin.accessWidener +++ b/RoughlyEnoughItems-default-plugin/src/main/resources/roughlyenoughitems-default-plugin.accessWidener @@ -12,3 +12,10 @@ accessible field net/minecraft/client/gui/screens/inventory/AbstractContainerScr accessible method net/minecraft/client/gui/GuiComponent innerBlit (Lcom/mojang/math/Matrix4f;IIIIIFFFF)V accessible field net/minecraft/world/item/crafting/UpgradeRecipe base Lnet/minecraft/world/item/crafting/Ingredient; accessible field net/minecraft/world/item/crafting/UpgradeRecipe addition Lnet/minecraft/world/item/crafting/Ingredient; +accessible field net/minecraft/world/item/alchemy/PotionBrewing ALLOWED_CONTAINERS Ljava/util/List; +accessible field net/minecraft/world/item/alchemy/PotionBrewing POTION_MIXES Ljava/util/List; +accessible field net/minecraft/world/item/alchemy/PotionBrewing CONTAINER_MIXES Ljava/util/List; +accessible class net/minecraft/world/item/alchemy/PotionBrewing$Mix +accessible field net/minecraft/world/item/alchemy/PotionBrewing$Mix from Ljava/lang/Object; +accessible field net/minecraft/world/item/alchemy/PotionBrewing$Mix to Ljava/lang/Object; +accessible field net/minecraft/world/item/alchemy/PotionBrewing$Mix ingredient Lnet/minecraft/world/item/crafting/Ingredient; diff --git a/RoughlyEnoughItems-runtime/src/main/java/me/shedaniel/rei/gui/widget/EntryListWidget.java b/RoughlyEnoughItems-runtime/src/main/java/me/shedaniel/rei/gui/widget/EntryListWidget.java index abad5ef0c..eea8a5e30 100644 --- a/RoughlyEnoughItems-runtime/src/main/java/me/shedaniel/rei/gui/widget/EntryListWidget.java +++ b/RoughlyEnoughItems-runtime/src/main/java/me/shedaniel/rei/gui/widget/EntryListWidget.java @@ -25,10 +25,11 @@ package me.shedaniel.rei.gui.widget; import com.google.common.base.Stopwatch; import com.google.common.collect.Lists; -import com.google.common.collect.Sets; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.Tesselator; import com.mojang.math.Matrix4f; +import it.unimi.dsi.fastutil.ints.IntOpenHashSet; +import it.unimi.dsi.fastutil.ints.IntSet; import me.shedaniel.clothconfig2.ClothConfigInitializer; import me.shedaniel.clothconfig2.api.ScissorsHandler; import me.shedaniel.clothconfig2.api.ScrollingContainer; @@ -62,16 +63,13 @@ import org.jetbrains.annotations.Nullable; import java.util.Collections; import java.util.Comparator; import java.util.List; -import java.util.Set; import java.util.concurrent.*; -import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; @ApiStatus.Internal public class EntryListWidget extends WidgetWithBounds { - static final Supplier RENDER_ENCHANTMENT_GLINT = ConfigObject.getInstance()::doesRenderEntryEnchantmentGlint; static final Comparator ENTRY_NAME_COMPARER = Comparator.comparing(stack -> stack.asFormatStrippedText().getString()); static final Comparator ENTRY_GROUP_COMPARER = Comparator.comparingInt(stack -> { if (stack.getType() == EntryStack.Type.ITEM) { @@ -436,7 +434,7 @@ public class EntryListWidget extends WidgetWithBounds { this.lastSearchArguments = SearchArgument.processSearchTerm(searchTerm); List list = Lists.newArrayList(); boolean checkCraftable = ConfigManager.getInstance().isCraftableOnlyEnabled() && !ScreenHelper.inventoryStacks.isEmpty(); - Set workingItems = checkCraftable ? Sets.newHashSet() : null; + IntSet workingItems = checkCraftable ? new IntOpenHashSet() : null; if (checkCraftable) workingItems.addAll(CollectionUtils.map(RecipeHelper.getInstance().findCraftableEntriesByItems(ScreenHelper.inventoryStacks), EntryStack::hashIgnoreAmount)); List stacks = EntryRegistry.getInstance().getPreFilteredList(); @@ -450,7 +448,7 @@ public class EntryListWidget extends WidgetWithBounds { if (canLastSearchTermsBeAppliedTo(stack)) { if (workingItems != null && !workingItems.contains(stack.hashIgnoreAmount())) continue; - filtered.add(stack.copy().setting(EntryStack.Settings.RENDER_COUNTS, EntryStack.Settings.FALSE).setting(EntryStack.Settings.Item.RENDER_ENCHANTMENT_GLINT, RENDER_ENCHANTMENT_GLINT)); + filtered.add(stack.rewrap().setting(EntryStack.Settings.RENDER_COUNTS, EntryStack.Settings.FALSE)); } } return filtered; @@ -471,7 +469,7 @@ public class EntryListWidget extends WidgetWithBounds { if (canLastSearchTermsBeAppliedTo(stack)) { if (workingItems != null && !workingItems.contains(stack.hashIgnoreAmount())) continue; - list.add(stack.copy().setting(EntryStack.Settings.RENDER_COUNTS, EntryStack.Settings.FALSE).setting(EntryStack.Settings.Item.RENDER_ENCHANTMENT_GLINT, RENDER_ENCHANTMENT_GLINT)); + list.add(stack.rewrap().setting(EntryStack.Settings.RENDER_COUNTS, EntryStack.Settings.FALSE)); } } } diff --git a/RoughlyEnoughItems-runtime/src/main/java/me/shedaniel/rei/gui/widget/FavoritesListWidget.java b/RoughlyEnoughItems-runtime/src/main/java/me/shedaniel/rei/gui/widget/FavoritesListWidget.java index a09d01e96..cb9171296 100644 --- a/RoughlyEnoughItems-runtime/src/main/java/me/shedaniel/rei/gui/widget/FavoritesListWidget.java +++ b/RoughlyEnoughItems-runtime/src/main/java/me/shedaniel/rei/gui/widget/FavoritesListWidget.java @@ -24,8 +24,9 @@ package me.shedaniel.rei.gui.widget; import com.google.common.collect.Lists; -import com.google.common.collect.Sets; import com.mojang.blaze3d.vertex.PoseStack; +import it.unimi.dsi.fastutil.ints.IntOpenHashSet; +import it.unimi.dsi.fastutil.ints.IntSet; import me.shedaniel.clothconfig2.ClothConfigInitializer; import me.shedaniel.clothconfig2.api.ScissorsHandler; import me.shedaniel.clothconfig2.api.ScrollingContainer; @@ -51,7 +52,6 @@ import org.jetbrains.annotations.Nullable; import java.util.Collections; import java.util.List; -import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -199,14 +199,14 @@ public class FavoritesListWidget extends WidgetWithBounds { if (ConfigObject.getInstance().doSearchFavorites()) { List list = Lists.newArrayList(); boolean checkCraftable = ConfigManager.getInstance().isCraftableOnlyEnabled() && !ScreenHelper.inventoryStacks.isEmpty(); - Set workingItems = checkCraftable ? Sets.newHashSet() : null; + IntSet workingItems = checkCraftable ? new IntOpenHashSet() : null; if (checkCraftable) workingItems.addAll(CollectionUtils.map(RecipeHelper.getInstance().findCraftableEntriesByItems(ScreenHelper.inventoryStacks), EntryStack::hashIgnoreAmount)); for (EntryStack stack : ConfigObject.getInstance().getFavorites()) { if (listWidget.canLastSearchTermsBeAppliedTo(stack)) { if (checkCraftable && !workingItems.contains(stack.hashIgnoreAmount())) continue; - list.add(stack.copy().setting(EntryStack.Settings.RENDER_COUNTS, EntryStack.Settings.FALSE).setting(EntryStack.Settings.Item.RENDER_ENCHANTMENT_GLINT, RENDER_ENCHANTMENT_GLINT)); + list.add(stack.copy().setting(EntryStack.Settings.RENDER_COUNTS, EntryStack.Settings.FALSE)); } } EntryPanelOrdering ordering = ConfigObject.getInstance().getItemListOrdering(); @@ -220,13 +220,13 @@ public class FavoritesListWidget extends WidgetWithBounds { } else { List list = Lists.newArrayList(); boolean checkCraftable = ConfigManager.getInstance().isCraftableOnlyEnabled() && !ScreenHelper.inventoryStacks.isEmpty(); - Set workingItems = checkCraftable ? Sets.newHashSet() : null; + IntSet workingItems = checkCraftable ? new IntOpenHashSet() : null; if (checkCraftable) workingItems.addAll(CollectionUtils.map(RecipeHelper.getInstance().findCraftableEntriesByItems(ScreenHelper.inventoryStacks), EntryStack::hashIgnoreAmount)); for (EntryStack stack : ConfigObject.getInstance().getFavorites()) { if (checkCraftable && !workingItems.contains(stack.hashIgnoreAmount())) continue; - list.add(stack.copy().setting(EntryStack.Settings.RENDER_COUNTS, EntryStack.Settings.FALSE).setting(EntryStack.Settings.Item.RENDER_ENCHANTMENT_GLINT, RENDER_ENCHANTMENT_GLINT)); + list.add(stack.copy().setting(EntryStack.Settings.RENDER_COUNTS, EntryStack.Settings.FALSE)); } EntryPanelOrdering ordering = ConfigObject.getInstance().getItemListOrdering(); if (ordering == EntryPanelOrdering.NAME) diff --git a/RoughlyEnoughItems-runtime/src/main/java/me/shedaniel/rei/impl/AbstractEntryStack.java b/RoughlyEnoughItems-runtime/src/main/java/me/shedaniel/rei/impl/AbstractEntryStack.java index 91907294d..2f182ab35 100644 --- a/RoughlyEnoughItems-runtime/src/main/java/me/shedaniel/rei/impl/AbstractEntryStack.java +++ b/RoughlyEnoughItems-runtime/src/main/java/me/shedaniel/rei/impl/AbstractEntryStack.java @@ -23,31 +23,50 @@ package me.shedaniel.rei.impl; -import it.unimi.dsi.fastutil.objects.Reference2ObjectMaps; -import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap; +import it.unimi.dsi.fastutil.shorts.Short2ObjectMap; +import it.unimi.dsi.fastutil.shorts.Short2ObjectMaps; +import it.unimi.dsi.fastutil.shorts.Short2ObjectOpenHashMap; import me.shedaniel.rei.api.EntryStack; import net.minecraft.client.gui.GuiComponent; import org.jetbrains.annotations.ApiStatus; -import java.util.Map; - @ApiStatus.Internal public abstract class AbstractEntryStack extends GuiComponent implements EntryStack { - private static final Map, Object> EMPTY_SETTINGS = Reference2ObjectMaps.emptyMap(); - private Map, Object> settings = null; + private static final Short2ObjectMap EMPTY_SETTINGS = Short2ObjectMaps.emptyMap(); + private Short2ObjectMap settings = null; @Override public EntryStack setting(Settings settings, T value) { + short settingsId = settings.getId(); if (this.settings == null) - this.settings = new Reference2ObjectOpenHashMap<>(4); - this.settings.put(settings, value); + this.settings = Short2ObjectMaps.singleton(settingsId, value); + else { + if (this.settings.size() == 1) { + if (this.settings.containsKey(settingsId)) { + this.settings = Short2ObjectMaps.singleton(settingsId, value); + return this; + } else { + Short2ObjectMap singletonSettings = this.settings; + this.settings = new Short2ObjectOpenHashMap<>(4, 1); + this.settings.putAll(singletonSettings); + } + } + this.settings.put(settingsId, value); + } return this; } @Override public EntryStack removeSetting(Settings settings) { - if (this.settings != null && this.settings.remove(settings) != null && this.settings.isEmpty()) { - this.settings = null; + if (this.settings != null) { + short settingsId = settings.getId(); + if (this.settings.size() == 1) { + if (this.settings.containsKey(settingsId)) { + this.settings = null; + } + } else if (this.settings.remove(settingsId) != null && this.settings.isEmpty()) { + this.settings = null; + } } return this; } @@ -58,13 +77,13 @@ public abstract class AbstractEntryStack extends GuiComponent implements EntrySt return this; } - protected Map, Object> getSettings() { + protected Short2ObjectMap getSettings() { return this.settings == null ? EMPTY_SETTINGS : this.settings; } @Override public T get(Settings settings) { - Object o = this.settings == null ? null : this.settings.get(settings); + Object o = this.settings == null ? null : this.settings.get(settings.getId()); if (o == null) return settings.getDefaultValue(); return (T) o; diff --git a/RoughlyEnoughItems-runtime/src/main/java/me/shedaniel/rei/impl/ConfigObjectImpl.java b/RoughlyEnoughItems-runtime/src/main/java/me/shedaniel/rei/impl/ConfigObjectImpl.java index b9dff2dae..1037f6ac4 100644 --- a/RoughlyEnoughItems-runtime/src/main/java/me/shedaniel/rei/impl/ConfigObjectImpl.java +++ b/RoughlyEnoughItems-runtime/src/main/java/me/shedaniel/rei/impl/ConfigObjectImpl.java @@ -106,7 +106,7 @@ public class ConfigObjectImpl implements ConfigObject, ConfigData { @Override public boolean doesRenderEntryEnchantmentGlint() { - return advanced.miscellaneous.renderEntryEnchantmentGlint; + return true; } @Override @@ -464,7 +464,6 @@ public class ConfigObjectImpl implements ConfigObject, ConfigData { public static class Miscellaneous { @Comment("Declares whether arrows in containers should be clickable.") private boolean clickableRecipeArrows = true; private boolean registerRecipesInAnotherThread = true; - @Comment("Whether REI should render entry's enchantment glint") private boolean renderEntryEnchantmentGlint = true; private boolean newFastEntryRendering = true; } diff --git a/RoughlyEnoughItems-runtime/src/main/java/me/shedaniel/rei/impl/EntryRegistryImpl.java b/RoughlyEnoughItems-runtime/src/main/java/me/shedaniel/rei/impl/EntryRegistryImpl.java index a96f7ead8..0ccb380b3 100644 --- a/RoughlyEnoughItems-runtime/src/main/java/me/shedaniel/rei/impl/EntryRegistryImpl.java +++ b/RoughlyEnoughItems-runtime/src/main/java/me/shedaniel/rei/impl/EntryRegistryImpl.java @@ -78,7 +78,7 @@ public class EntryRegistryImpl implements EntryRegistry { @Override @NotNull public Stream getEntryStacks() { - return entries.stream(); + return reloading ? reloadingRegistry.stream().map(AmountIgnoredEntryStackWrapper::unwrap) : entries.stream(); } @Override diff --git a/RoughlyEnoughItems-runtime/src/main/java/me/shedaniel/rei/impl/FluidEntryStack.java b/RoughlyEnoughItems-runtime/src/main/java/me/shedaniel/rei/impl/FluidEntryStack.java index 65019ba8b..2d777869e 100644 --- a/RoughlyEnoughItems-runtime/src/main/java/me/shedaniel/rei/impl/FluidEntryStack.java +++ b/RoughlyEnoughItems-runtime/src/main/java/me/shedaniel/rei/impl/FluidEntryStack.java @@ -29,6 +29,7 @@ import com.mojang.blaze3d.vertex.DefaultVertexFormat; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.Tesselator; import com.mojang.math.Matrix4f; +import it.unimi.dsi.fastutil.shorts.Short2ObjectMap; import me.shedaniel.math.Point; import me.shedaniel.math.Rectangle; import me.shedaniel.rei.api.ClientHelper; @@ -55,7 +56,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.List; -import java.util.Map; import java.util.Optional; import java.util.concurrent.ThreadLocalRandom; import java.util.stream.Collectors; @@ -124,8 +124,8 @@ public class FluidEntryStack extends AbstractEntryStack { @Override public EntryStack copy() { EntryStack stack = EntryStack.create(fluid, amount); - for (Map.Entry, Object> entry : getSettings().entrySet()) { - stack.setting((Settings) entry.getKey(), entry.getValue()); + for (Short2ObjectMap.Entry entry : getSettings().short2ObjectEntrySet()) { + stack.setting(EntryStack.Settings.getById(entry.getShortKey()), entry.getValue()); } return stack; } diff --git a/RoughlyEnoughItems-runtime/src/main/java/me/shedaniel/rei/impl/ItemEntryStack.java b/RoughlyEnoughItems-runtime/src/main/java/me/shedaniel/rei/impl/ItemEntryStack.java index 0e3e17d89..f59746214 100644 --- a/RoughlyEnoughItems-runtime/src/main/java/me/shedaniel/rei/impl/ItemEntryStack.java +++ b/RoughlyEnoughItems-runtime/src/main/java/me/shedaniel/rei/impl/ItemEntryStack.java @@ -30,6 +30,7 @@ import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.PoseStack; import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; import it.unimi.dsi.fastutil.objects.ReferenceSet; +import it.unimi.dsi.fastutil.shorts.Short2ObjectMap; import me.shedaniel.math.Point; import me.shedaniel.math.Rectangle; import me.shedaniel.rei.api.ClientHelper; @@ -61,7 +62,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.List; -import java.util.Map; import java.util.Optional; import java.util.stream.Stream; @@ -110,9 +110,18 @@ public class ItemEntryStack extends AbstractEntryStack implements OptimalEntrySt @Override public EntryStack copy() { - EntryStack stack = EntryStack.create(getItemStack().copy()); - for (Map.Entry, Object> entry : getSettings().entrySet()) { - stack.setting((Settings) entry.getKey(), entry.getValue()); + EntryStack stack = EntryStack.create(itemStack.copy()); + for (Short2ObjectMap.Entry entry : getSettings().short2ObjectEntrySet()) { + stack.setting(EntryStack.Settings.getById(entry.getShortKey()), entry.getValue()); + } + return stack; + } + + @Override + public EntryStack rewrap() { + EntryStack stack = EntryStack.create(itemStack); + for (Short2ObjectMap.Entry entry : getSettings().short2ObjectEntrySet()) { + stack.setting(EntryStack.Settings.getById(entry.getShortKey()), entry.getValue()); } return stack; } @@ -358,13 +367,11 @@ public class ItemEntryStack extends AbstractEntryStack implements OptimalEntrySt public void optimisedRenderBase(PoseStack matrices, MultiBufferSource.BufferSource immediate, Rectangle bounds, int mouseX, int mouseY, float delta) { if (!isEmpty() && get(Settings.RENDER).get()) { ItemStack stack = getItemStack(); - ((ItemStackHook) (Object) stack).rei_setRenderEnchantmentGlint(get(Settings.Item.RENDER_ENCHANTMENT_GLINT).get()); matrices.pushPose(); matrices.translate(bounds.getCenterX(), bounds.getCenterY(), 100.0F + getZ()); matrices.scale(bounds.getWidth(), (bounds.getWidth() + bounds.getHeight()) / -2f, bounds.getHeight()); Minecraft.getInstance().getItemRenderer().render(stack, ItemTransforms.TransformType.GUI, false, matrices, immediate, 15728880, OverlayTexture.NO_OVERLAY, getModelFromStack(stack)); matrices.popPose(); - ((ItemStackHook) (Object) stack).rei_setRenderEnchantmentGlint(false); } } diff --git a/RoughlyEnoughItems-runtime/src/main/java/me/shedaniel/rei/impl/ItemStackHook.java b/RoughlyEnoughItems-runtime/src/main/java/me/shedaniel/rei/impl/ItemStackHook.java deleted file mode 100644 index bbcc4bb12..000000000 --- a/RoughlyEnoughItems-runtime/src/main/java/me/shedaniel/rei/impl/ItemStackHook.java +++ /dev/null @@ -1,31 +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.impl; - -import org.jetbrains.annotations.ApiStatus; - -@ApiStatus.Internal -public interface ItemStackHook { - void rei_setRenderEnchantmentGlint(boolean b); -} diff --git a/RoughlyEnoughItems-runtime/src/main/java/me/shedaniel/rei/impl/RecipeHelperImpl.java b/RoughlyEnoughItems-runtime/src/main/java/me/shedaniel/rei/impl/RecipeHelperImpl.java index 4d78312ed..5dd8ade09 100644 --- a/RoughlyEnoughItems-runtime/src/main/java/me/shedaniel/rei/impl/RecipeHelperImpl.java +++ b/RoughlyEnoughItems-runtime/src/main/java/me/shedaniel/rei/impl/RecipeHelperImpl.java @@ -309,7 +309,7 @@ public class RecipeHelperImpl implements RecipeHelper { private void startSection(MutablePair sectionData, String section) { sectionData.setRight(section); RoughlyEnoughItemsCore.LOGGER.debug("Reloading Section: \"%s\"", section); - sectionData.getLeft().start(); + sectionData.getLeft().reset().start(); } private void endSection(MutablePair sectionData) { @@ -321,13 +321,13 @@ public class RecipeHelperImpl implements RecipeHelper { private void pluginSection(MutablePair sectionData, String sectionName, List list, Consumer consumer) { for (REIPluginV0 plugin : list) { + startSection(sectionData, sectionName + " for " + plugin.getPluginIdentifier().toString()); try { - startSection(sectionData, sectionName + " for " + plugin.getPluginIdentifier().toString()); consumer.accept(plugin); - endSection(sectionData); } catch (Throwable e) { RoughlyEnoughItemsCore.LOGGER.error(plugin.getPluginIdentifier().toString() + " plugin failed to " + sectionName + "!", e); } + endSection(sectionData); } } @@ -378,16 +378,16 @@ public class RecipeHelperImpl implements RecipeHelper { List reiPluginV0s = new ArrayList<>(); endSection(sectionData); for (REIPluginEntry plugin : plugins) { + startSection(sectionData, "pre-register for " + plugin.getPluginIdentifier().toString()); try { if (plugin instanceof REIPluginV0) { - startSection(sectionData, "pre-register for " + plugin.getPluginIdentifier().toString()); ((REIPluginV0) plugin).preRegister(); reiPluginV0s.add((REIPluginV0) plugin); - endSection(sectionData); } } catch (Throwable e) { RoughlyEnoughItemsCore.LOGGER.error(plugin.getPluginIdentifier().toString() + " plugin failed to pre register!", e); } + endSection(sectionData); } pluginSection(sectionData, "register-bounds", reiPluginV0s, plugin -> plugin.registerBounds(displayHelper)); pluginSection(sectionData, "register-entries", reiPluginV0s, plugin -> plugin.registerEntries(entryRegistry)); diff --git a/RoughlyEnoughItems-runtime/src/main/java/me/shedaniel/rei/mixin/MixinItemStack.java b/RoughlyEnoughItems-runtime/src/main/java/me/shedaniel/rei/mixin/MixinItemStack.java deleted file mode 100644 index 33d015883..000000000 --- a/RoughlyEnoughItems-runtime/src/main/java/me/shedaniel/rei/mixin/MixinItemStack.java +++ /dev/null @@ -1,48 +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