diff options
| author | shedaniel <daniel@shedaniel.me> | 2020-07-16 23:30:07 +0800 |
|---|---|---|
| committer | shedaniel <daniel@shedaniel.me> | 2020-07-16 23:30:07 +0800 |
| commit | 687e6503f44b504db141ed777588c2bdfa2184ca (patch) | |
| tree | 2337de861656d600ad713527868a066844fb364c /src/main/java | |
| parent | be6a2ca9f20059d19907230425ca258f908d5644 (diff) | |
| download | RoughlyEnoughItems-687e6503f44b504db141ed777588c2bdfa2184ca.tar.gz RoughlyEnoughItems-687e6503f44b504db141ed777588c2bdfa2184ca.tar.bz2 RoughlyEnoughItems-687e6503f44b504db141ed777588c2bdfa2184ca.zip | |
Added FocusedStackProvider api.
Optimised item rendering.
Signed-off-by: shedaniel <daniel@shedaniel.me>
Diffstat (limited to 'src/main/java')
7 files changed, 191 insertions, 68 deletions
diff --git a/src/main/java/me/shedaniel/rei/api/FocusedStackProvider.java b/src/main/java/me/shedaniel/rei/api/FocusedStackProvider.java new file mode 100644 index 000000000..ec13a37cc --- /dev/null +++ b/src/main/java/me/shedaniel/rei/api/FocusedStackProvider.java @@ -0,0 +1,40 @@ +/* + * 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; + +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.util.TypedActionResult; +import org.jetbrains.annotations.NotNull; + +public interface FocusedStackProvider { + /** + * @return the priority of this handler, higher priorities will be called first. + */ + default double getPriority() { + return 0d; + } + + @NotNull + TypedActionResult<EntryStack> provide(Screen screen); +} diff --git a/src/main/java/me/shedaniel/rei/api/OptimalEntryStack.java b/src/main/java/me/shedaniel/rei/api/OptimalEntryStack.java index a7a4a4f04..8f7c2bf39 100644 --- a/src/main/java/me/shedaniel/rei/api/OptimalEntryStack.java +++ b/src/main/java/me/shedaniel/rei/api/OptimalEntryStack.java @@ -24,15 +24,25 @@ package me.shedaniel.rei.api; import me.shedaniel.math.Rectangle; +import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.util.math.MatrixStack; import org.jetbrains.annotations.ApiStatus; @ApiStatus.Internal public interface OptimalEntryStack { + static int groupingHashFrom(EntryStack stack) { + if (stack instanceof OptimalEntryStack) return ((OptimalEntryStack) stack).groupingHash(); + return stack.getClass().hashCode(); + } + + default int groupingHash() { + return getClass().hashCode(); + } + default void optimisedRenderStart(MatrixStack matrices, float delta) { } - default void optimisedRenderBase(MatrixStack matrices, Rectangle bounds, int mouseX, int mouseY, float delta) { + default void optimisedRenderBase(MatrixStack matrices, VertexConsumerProvider.Immediate immediate, Rectangle bounds, int mouseX, int mouseY, float delta) { } default void optimisedRenderOverlay(MatrixStack matrices, Rectangle bounds, int mouseX, int mouseY, float delta) { diff --git a/src/main/java/me/shedaniel/rei/api/RecipeHelper.java b/src/main/java/me/shedaniel/rei/api/RecipeHelper.java index 04b699b5a..b46280a63 100644 --- a/src/main/java/me/shedaniel/rei/api/RecipeHelper.java +++ b/src/main/java/me/shedaniel/rei/api/RecipeHelper.java @@ -27,12 +27,14 @@ import me.shedaniel.math.Rectangle; import me.shedaniel.rei.RoughlyEnoughItemsCore; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; +import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.ingame.ContainerScreen; import net.minecraft.recipe.Recipe; import net.minecraft.recipe.RecipeManager; import net.minecraft.util.Identifier; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.List; import java.util.Map; @@ -53,6 +55,12 @@ public interface RecipeHelper { AutoTransferHandler registerAutoCraftingHandler(AutoTransferHandler handler); + void registerFocusedStackProvider(FocusedStackProvider provider); + + @Nullable + @ApiStatus.Internal + EntryStack getScreenFocusedStack(Screen screen); + List<AutoTransferHandler> getSortedAutoCraftingHandler(); /** diff --git a/src/main/java/me/shedaniel/rei/gui/ContainerScreenOverlay.java b/src/main/java/me/shedaniel/rei/gui/ContainerScreenOverlay.java index 7b4b9ead7..4bf587829 100644 --- a/src/main/java/me/shedaniel/rei/gui/ContainerScreenOverlay.java +++ b/src/main/java/me/shedaniel/rei/gui/ContainerScreenOverlay.java @@ -642,14 +642,9 @@ public class ContainerScreenOverlay extends WidgetWithBounds implements REIOverl ScreenHelper.toggleOverlayVisible(); return true; } - ItemStack itemStack = null; - if (MinecraftClient.getInstance().currentScreen instanceof ContainerScreen) { - ContainerScreen<?> containerScreen = (ContainerScreen<?>) MinecraftClient.getInstance().currentScreen; - if (containerScreen.focusedSlot != null && !containerScreen.focusedSlot.getStack().isEmpty()) - itemStack = containerScreen.focusedSlot.getStack(); - } - if (itemStack != null && !itemStack.isEmpty()) { - EntryStack stack = EntryStack.create(itemStack.copy()); + EntryStack stack = RecipeHelper.getInstance().getScreenFocusedStack(MinecraftClient.getInstance().currentScreen); + if (stack != null && !stack.isEmpty()) { + stack = stack.copy(); if (ConfigObject.getInstance().getRecipeKeybind().matchesKey(keyCode, scanCode)) { return ClientHelper.getInstance().openView(ClientHelper.ViewSearchBuilder.builder().addRecipesFor(stack).setOutputNotice(stack).fillPreferredOpenedCategory()); } else if (ConfigObject.getInstance().getUsageKeybind().matchesKey(keyCode, scanCode)) { diff --git a/src/main/java/me/shedaniel/rei/gui/widget/EntryListWidget.java b/src/main/java/me/shedaniel/rei/gui/widget/EntryListWidget.java index 40c972581..f2e5a6f31 100644 --- a/src/main/java/me/shedaniel/rei/gui/widget/EntryListWidget.java +++ b/src/main/java/me/shedaniel/rei/gui/widget/EntryListWidget.java @@ -57,7 +57,10 @@ import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.*; +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; @@ -244,32 +247,32 @@ public class EntryListWidget extends WidgetWithBounds { scrolling.renderScrollBar(0, 1, REIHelper.getInstance().isDarkThemeEnabled() ? 0.8f : 1f); } else { if (debugTime) { - int size = 0; - long time = 0; + int[] size = {0}; + long[] time = {0}; for (Widget widget : renders) { widget.render(matrices, mouseX, mouseY, delta); } long totalTimeStart = System.nanoTime(); if (ConfigObject.getInstance().doesFastEntryRendering()) { - for (Map.Entry<? extends Class<? extends EntryStack>, List<EntryListEntry>> entry : entries.stream().collect(Collectors.groupingBy(entryListEntry -> entryListEntry.getCurrentEntry().getClass())).entrySet()) { - List<EntryListEntry> list = entry.getValue(); - if (list.isEmpty()) - continue; - EntryListEntry firstWidget = list.get(0); + entries.stream().collect(Collectors.groupingBy(entryListEntry -> OptimalEntryStack.groupingHashFrom(entryListEntry.getCurrentEntry()))).forEach((integer, entries) -> { + if (entries.isEmpty()) return; + EntryListEntry firstWidget = entries.get(0); EntryStack first = firstWidget.getCurrentEntry(); if (first instanceof OptimalEntryStack) { OptimalEntryStack firstStack = (OptimalEntryStack) first; firstStack.optimisedRenderStart(matrices, delta); long l = System.nanoTime(); - for (EntryListEntry listEntry : list) { + VertexConsumerProvider.Immediate immediate = MinecraftClient.getInstance().getBufferBuilders().getEntityVertexConsumers(); + for (EntryListEntry listEntry : entries) { EntryStack currentEntry = listEntry.getCurrentEntry(); currentEntry.setZ(100); listEntry.drawBackground(matrices, mouseX, mouseY, delta); - ((OptimalEntryStack) currentEntry).optimisedRenderBase(matrices, listEntry.getInnerBounds(), mouseX, mouseY, delta); + ((OptimalEntryStack) currentEntry).optimisedRenderBase(matrices, immediate, listEntry.getInnerBounds(), mouseX, mouseY, delta); if (!currentEntry.isEmpty()) - size++; + size[0]++; } - for (EntryListEntry listEntry : list) { + immediate.draw(); + for (EntryListEntry listEntry : entries) { EntryStack currentEntry = listEntry.getCurrentEntry(); ((OptimalEntryStack) currentEntry).optimisedRenderOverlay(matrices, listEntry.getInnerBounds(), mouseX, mouseY, delta); if (listEntry.containsMouse(mouseX, mouseY)) { @@ -277,33 +280,33 @@ public class EntryListWidget extends WidgetWithBounds { listEntry.drawHighlighted(matrices, mouseX, mouseY, delta); } } - time += (System.nanoTime() - l); + time[0] += (System.nanoTime() - l); firstStack.optimisedRenderEnd(matrices, delta); } else { - for (EntryListEntry listEntry : list) { + for (EntryListEntry listEntry : entries) { if (listEntry.getCurrentEntry().isEmpty()) continue; - size++; + size[0]++; long l = System.nanoTime(); listEntry.render(matrices, mouseX, mouseY, delta); - time += (System.nanoTime() - l); + time[0] += (System.nanoTime() - l); } } - } + }); } else { for (EntryListEntry entry : entries) { if (entry.getCurrentEntry().isEmpty()) continue; - size++; + size[0]++; long l = System.nanoTime(); entry.render(matrices, mouseX, mouseY, delta); - time += (System.nanoTime() - l); + time[0] += (System.nanoTime() - l); } } long totalTime = System.nanoTime() - totalTimeStart; int z = getZ(); setZ(500); - Text debugText = new LiteralText(String.format("%d entries, avg. %.0fns, ttl. %.0fms, %s fps", size, time / (double) size, totalTime / 1000000d, minecraft.fpsDebugString.split(" ")[0])); + Text debugText = new LiteralText(String.format("%d entries, avg. %.0fns, ttl. %.0fms, %s fps", size[0], time[0] / (double) size[0], totalTime / 1000000d, minecraft.fpsDebugString.split(" ")[0])); int stringWidth = font.getWidth(debugText); fillGradient(matrices, Math.min(bounds.x, minecraft.currentScreen.width - stringWidth - 2), bounds.y, bounds.x + stringWidth + 2, bounds.y + font.fontHeight + 2, -16777216, -16777216); VertexConsumerProvider.Immediate immediate = VertexConsumerProvider.immediate(Tessellator.getInstance().getBuffer()); @@ -319,22 +322,22 @@ public class EntryListWidget extends WidgetWithBounds { widget.render(matrices, mouseX, mouseY, delta); } if (ConfigObject.getInstance().doesFastEntryRendering()) { - for (Map.Entry<? extends Class<? extends EntryStack>, List<EntryListEntry>> entry : entries.stream().collect(Collectors.groupingBy(entryListEntry -> entryListEntry.getCurrentEntry().getClass())).entrySet()) { - List<EntryListEntry> list = entry.getValue(); - if (list.isEmpty()) - continue; - EntryListEntry firstWidget = list.get(0); + entries.stream().collect(Collectors.groupingBy(entryListEntry -> OptimalEntryStack.groupingHashFrom(entryListEntry.getCurrentEntry()))).forEach((integer, entries) -> { + if (entries.isEmpty()) return; + EntryListEntry firstWidget = entries.get(0); EntryStack first = firstWidget.getCurrentEntry(); if (first instanceof OptimalEntryStack) { OptimalEntryStack firstStack = (OptimalEntryStack) first; firstStack.optimisedRenderStart(matrices, delta); - for (EntryListEntry listEntry : list) { + VertexConsumerProvider.Immediate immediate = MinecraftClient.getInstance().getBufferBuilders().getEntityVertexConsumers(); + for (EntryListEntry listEntry : entries) { EntryStack currentEntry = listEntry.getCurrentEntry(); currentEntry.setZ(100); listEntry.drawBackground(matrices, mouseX, mouseY, delta); - ((OptimalEntryStack) currentEntry).optimisedRenderBase(matrices, listEntry.getInnerBounds(), mouseX, mouseY, delta); + ((OptimalEntryStack) currentEntry).optimisedRenderBase(matrices, immediate, listEntry.getInnerBounds(), mouseX, mouseY, delta); } - for (EntryListEntry listEntry : list) { + immediate.draw(); + for (EntryListEntry listEntry : entries) { EntryStack currentEntry = listEntry.getCurrentEntry(); ((OptimalEntryStack) currentEntry).optimisedRenderOverlay(matrices, listEntry.getInnerBounds(), mouseX, mouseY, delta); if (listEntry.containsMouse(mouseX, mouseY)) { @@ -344,13 +347,13 @@ public class EntryListWidget extends WidgetWithBounds { } firstStack.optimisedRenderEnd(matrices, delta); } else { - for (EntryListEntry listEntry : list) { + for (EntryListEntry listEntry : entries) { if (listEntry.getCurrentEntry().isEmpty()) continue; listEntry.render(matrices, mouseX, mouseY, delta); } } - } + }); } else { for (EntryListEntry listEntry : entries) { if (listEntry.getCurrentEntry().isEmpty()) diff --git a/src/main/java/me/shedaniel/rei/impl/ItemEntryStack.java b/src/main/java/me/shedaniel/rei/impl/ItemEntryStack.java index af2ac018d..fdd7155ec 100644 --- a/src/main/java/me/shedaniel/rei/impl/ItemEntryStack.java +++ b/src/main/java/me/shedaniel/rei/impl/ItemEntryStack.java @@ -25,6 +25,7 @@ package me.shedaniel.rei.impl; import com.google.common.collect.Lists; import com.mojang.blaze3d.platform.GlStateManager; +import com.mojang.blaze3d.systems.RenderSystem; import me.shedaniel.math.Point; import me.shedaniel.math.Rectangle; import me.shedaniel.rei.api.*; @@ -53,7 +54,6 @@ import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Optional; @@ -293,22 +293,52 @@ public class ItemEntryStack extends AbstractEntryStack implements OptimalEntrySt @Override public void render(MatrixStack matrices, Rectangle bounds, int mouseX, int mouseY, float delta) { optimisedRenderStart(matrices, delta); - optimisedRenderBase(matrices, bounds, mouseX, mouseY, delta); + VertexConsumerProvider.Immediate immediate = MinecraftClient.getInstance().getBufferBuilders().getEntityVertexConsumers(); + optimisedRenderBase(matrices, immediate, bounds, mouseX, mouseY, delta); + immediate.draw(); optimisedRenderOverlay(matrices, bounds, mouseX, mouseY, delta); optimisedRenderEnd(matrices, delta); } - @SuppressWarnings("deprecation") @Override public void optimisedRenderStart(MatrixStack matrices, float delta) { - MinecraftClient.getInstance().getTextureManager().bindTexture(SpriteAtlasTexture.BLOCK_ATLAS_TEX); - GlStateManager.enableRescaleNormal(); + optimisedRenderStart(matrices, delta, true); } @SuppressWarnings("deprecation") + public void optimisedRenderStart(MatrixStack matrices, float delta, boolean isOptimised) { + MinecraftClient.getInstance().getTextureManager().bindTexture(SpriteAtlasTexture.BLOCK_ATLAS_TEX); + MinecraftClient.getInstance().getTextureManager().getTexture(SpriteAtlasTexture.BLOCK_ATLAS_TEX).setFilter(false, false); + RenderSystem.pushMatrix(); + RenderSystem.enableRescaleNormal(); + RenderSystem.enableAlphaTest(); + RenderSystem.defaultAlphaFunc(); + RenderSystem.enableBlend(); + RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE_MINUS_SRC_ALPHA); + RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F); + if (isOptimised) { + boolean sideLit = getModelFromStack(itemStack).isSideLit(); + if (!sideLit) + DiffuseLighting.disableGuiDepthLighting(); + } + } + @Override public void optimisedRenderEnd(MatrixStack matrices, float delta) { - GlStateManager.disableRescaleNormal(); + optimisedRenderEnd(matrices, delta, true); + } + + @SuppressWarnings("deprecation") + public void optimisedRenderEnd(MatrixStack matrices, float delta, boolean isOptimised) { + RenderSystem.enableDepthTest(); + RenderSystem.disableAlphaTest(); + RenderSystem.disableRescaleNormal(); + if (isOptimised) { + boolean sideLit = getModelFromStack(itemStack).isSideLit(); + if (!sideLit) + DiffuseLighting.enableGuiDepthLighting(); + } + RenderSystem.popMatrix(); } private BakedModel getModelFromStack(ItemStack stack) { @@ -316,22 +346,19 @@ public class ItemEntryStack extends AbstractEntryStack implements OptimalEntrySt } @Override - public void optimisedRenderBase(MatrixStack matrices, Rectangle bounds, int mouseX, int mouseY, float delta) { + public int groupingHash() { + return 1738923 + (getModelFromStack(itemStack).isSideLit() ? 1 : 0); + } + + @Override + public void optimisedRenderBase(MatrixStack matrices, VertexConsumerProvider.Immediate 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.push(); matrices.translate(bounds.getCenterX(), bounds.getCenterY(), 100.0F + getZ()); matrices.scale(bounds.getWidth(), (bounds.getWidth() + bounds.getHeight()) / -2f, bounds.getHeight()); - VertexConsumerProvider.Immediate immediate = MinecraftClient.getInstance().getBufferBuilders().getEntityVertexConsumers(); - BakedModel model = getModelFromStack(stack); - boolean sideLit = !model.isSideLit(); - if (sideLit) - DiffuseLighting.disableGuiDepthLighting(); - MinecraftClient.getInstance().getItemRenderer().renderItem(stack, ModelTransformation.Mode.GUI, false, matrices, immediate, 15728880, OverlayTexture.DEFAULT_UV, model); - immediate.draw(); - if (sideLit) - DiffuseLighting.enableGuiDepthLighting(); + MinecraftClient.getInstance().getItemRenderer().renderItem(stack, ModelTransformation.Mode.GUI, false, matrices, immediate, 15728880, OverlayTexture.DEFAULT_UV, getModelFromStack(stack)); matrices.pop(); ((ItemStackHook) (Object) stack).rei_setRenderEnchantmentGlint(false); } diff --git a/src/main/java/me/shedaniel/rei/impl/RecipeHelperImpl.java b/src/main/java/me/shedaniel/rei/impl/RecipeHelperImpl.java index b9d23b679..66e9e33ef 100644 --- a/src/main/java/me/shedaniel/rei/impl/RecipeHelperImpl.java +++ b/src/main/java/me/shedaniel/rei/impl/RecipeHelperImpl.java @@ -36,13 +36,17 @@ import me.shedaniel.rei.impl.subsets.SubsetsRegistryImpl; import me.shedaniel.rei.utils.CollectionUtils; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; +import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.ingame.ContainerScreen; import net.minecraft.recipe.Recipe; import net.minecraft.recipe.RecipeManager; import net.minecraft.util.ActionResult; import net.minecraft.util.Identifier; +import net.minecraft.util.TypedActionResult; import net.minecraft.util.Util; import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.*; import java.util.function.Consumer; @@ -54,26 +58,23 @@ import java.util.stream.Collectors; @Environment(EnvType.CLIENT) public class RecipeHelperImpl implements RecipeHelper { - private static final Comparator<DisplayVisibilityHandler> VISIBILITY_HANDLER_COMPARATOR; + private static final Comparator<FocusedStackProvider> FOCUSED_STACK_PROVIDER_COMPARATOR = Comparator.comparingDouble(FocusedStackProvider::getPriority).reversed(); + private static final Comparator<DisplayVisibilityHandler> VISIBILITY_HANDLER_COMPARATOR = Comparator.comparingDouble(DisplayVisibilityHandler::getPriority).reversed(); @SuppressWarnings("rawtypes") private static final Comparator<Recipe> RECIPE_COMPARATOR = Comparator.comparing((Recipe o) -> o.getId().getNamespace()).thenComparing(o -> o.getId().getPath()); - static { - Comparator<DisplayVisibilityHandler> comparator = Comparator.comparingDouble(DisplayVisibilityHandler::getPriority); - VISIBILITY_HANDLER_COMPARATOR = comparator.reversed(); - } - - private final List<AutoTransferHandler> autoTransferHandlers = Lists.newLinkedList(); - private final List<RecipeFunction> recipeFunctions = Lists.newLinkedList(); - private final List<ScreenClickArea> screenClickAreas = Lists.newLinkedList(); + private final List<FocusedStackProvider> focusedStackProviders = Lists.newArrayList(); + private final List<AutoTransferHandler> autoTransferHandlers = Lists.newArrayList(); + private final List<RecipeFunction> recipeFunctions = Lists.newArrayList(); + private final List<ScreenClickArea> screenClickAreas = Lists.newArrayList(); private final int[] recipeCount = {0}; private final Map<Identifier, List<RecipeDisplay>> recipeCategoryListMap = Maps.newLinkedHashMap(); private final Map<RecipeCategory<?>, Identifier> categories = Maps.newLinkedHashMap(); private final Map<Identifier, RecipeCategory<?>> reversedCategories = Maps.newHashMap(); - private final Map<Identifier, ButtonAreaSupplier> autoCraftAreaSupplierMap = Maps.newLinkedHashMap(); - private final Map<Identifier, List<List<EntryStack>>> categoryWorkingStations = Maps.newLinkedHashMap(); - private final List<DisplayVisibilityHandler> displayVisibilityHandlers = Lists.newLinkedList(); - private final List<LiveRecipeGenerator<RecipeDisplay>> liveRecipeGenerators = Lists.newLinkedList(); + private final Map<Identifier, ButtonAreaSupplier> autoCraftAreaSupplierMap = Maps.newHashMap(); + private final Map<Identifier, List<List<EntryStack>>> categoryWorkingStations = Maps.newHashMap(); + private final List<DisplayVisibilityHandler> displayVisibilityHandlers = Lists.newArrayList(); + private final List<LiveRecipeGenerator<RecipeDisplay>> liveRecipeGenerators = Lists.newArrayList(); private RecipeManager recipeManager; private boolean arePluginsLoading = false; @@ -362,6 +363,7 @@ public class RecipeHelperImpl implements RecipeHelper { this.displayVisibilityHandlers.clear(); this.liveRecipeGenerators.clear(); this.autoTransferHandlers.clear(); + this.focusedStackProviders.clear(); ((SubsetsRegistryImpl) SubsetsRegistry.INSTANCE).reset(); ((FluidSupportProviderImpl) FluidSupportProvider.INSTANCE).reset(); ((DisplayHelperImpl) DisplayHelper.getInstance()).resetData(); @@ -424,6 +426,23 @@ public class RecipeHelperImpl implements RecipeHelper { return -1f; } }); + registerFocusedStackProvider(new FocusedStackProvider() { + @Override + @NotNull + public TypedActionResult<EntryStack> provide(Screen screen) { + if (screen instanceof ContainerScreen) { + ContainerScreen<?> containerScreen = (ContainerScreen<?>) screen; + if (containerScreen.focusedSlot != null && !containerScreen.focusedSlot.getStack().isEmpty()) + return TypedActionResult.success(EntryStack.create(containerScreen.focusedSlot.getStack())); + } + return TypedActionResult.pass(EntryStack.empty()); + } + + @Override + public double getPriority() { + return -1.0; + } + }); DisplayHelper.getInstance().registerHandler(new OverlayDecider() { @Override public boolean isHandingScreen(Class<?> screen) { @@ -479,6 +498,27 @@ public class RecipeHelperImpl implements RecipeHelper { } @Override + public void registerFocusedStackProvider(FocusedStackProvider provider) { + focusedStackProviders.add(provider); + focusedStackProviders.sort(FOCUSED_STACK_PROVIDER_COMPARATOR); + } + + @Override + @Nullable + public EntryStack getScreenFocusedStack(Screen screen) { + for (FocusedStackProvider provider : focusedStackProviders) { + TypedActionResult<EntryStack> result = Objects.requireNonNull(provider.provide(screen)); + if (result.getResult() == ActionResult.SUCCESS) { + if (!result.getValue().isEmpty()) + return result.getValue(); + return null; + } else if (result.getResult() == ActionResult.FAIL) + return null; + } + return null; + } + + @Override public List<AutoTransferHandler> getSortedAutoCraftingHandler() { return autoTransferHandlers.stream().sorted(Comparator.comparingDouble(AutoTransferHandler::getPriority).reversed()).collect(Collectors.toList()); } |
