aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorshedaniel <daniel@shedaniel.me>2020-07-16 23:30:07 +0800
committershedaniel <daniel@shedaniel.me>2020-07-16 23:30:07 +0800
commit687e6503f44b504db141ed777588c2bdfa2184ca (patch)
tree2337de861656d600ad713527868a066844fb364c /src/main/java
parentbe6a2ca9f20059d19907230425ca258f908d5644 (diff)
downloadRoughlyEnoughItems-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')
-rw-r--r--src/main/java/me/shedaniel/rei/api/FocusedStackProvider.java40
-rw-r--r--src/main/java/me/shedaniel/rei/api/OptimalEntryStack.java12
-rw-r--r--src/main/java/me/shedaniel/rei/api/RecipeHelper.java8
-rw-r--r--src/main/java/me/shedaniel/rei/gui/ContainerScreenOverlay.java11
-rw-r--r--src/main/java/me/shedaniel/rei/gui/widget/EntryListWidget.java63
-rw-r--r--src/main/java/me/shedaniel/rei/impl/ItemEntryStack.java59
-rw-r--r--src/main/java/me/shedaniel/rei/impl/RecipeHelperImpl.java66
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());
}