From 966bbd7fe43237f9b1aa6cfd94cf5e34a9bcfddf Mon Sep 17 00:00:00 2001 From: shedaniel Date: Tue, 6 Apr 2021 15:47:20 +0800 Subject: Expose draggable stacks Signed-off-by: shedaniel --- .../me/shedaniel/rei/api/client/REIOverlay.java | 2 +- .../rei/api/client/gui/SimpleDisplayRenderer.java | 38 ++++++----- .../api/client/gui/config/DisplayScreenType.java | 2 - .../client/gui/drag/DraggableStackProvider.java | 57 ++++++++++++++--- .../gui/drag/DraggableStackProviderWidget.java | 73 ++++++++++++++++++++++ .../api/client/gui/drag/DraggableStackVisitor.java | 58 ++++++++++++++--- .../gui/drag/DraggableStackVisitorWidget.java | 71 +++++++++++++++++++++ .../rei/api/client/gui/drag/DraggingContext.java | 23 +++++-- .../client/registry/display/DisplayCategory.java | 2 +- .../client/registry/display/DisplayRegistry.java | 43 +++++++++++-- .../visibility/DisplayVisibilityPredicate.java | 5 +- .../api/client/registry/entry/EntryRegistry.java | 59 ++++++++++------- .../api/client/registry/screen/ExclusionZones.java | 8 ++- .../api/client/registry/screen/OverlayDecider.java | 6 +- .../api/client/registry/screen/ScreenRegistry.java | 31 ++++++++- .../rei/api/client/util/ClientEntryStacks.java | 2 +- .../shedaniel/rei/api/common/entry/EntryStack.java | 1 - .../common/entry/comparison/ComparisonContext.java | 2 +- .../common/entry/comparison/ItemComparator.java | 21 +++++-- .../entry/comparison/ItemComparatorRegistry.java | 6 +- .../rei/api/common/fluid/FluidSupportProvider.java | 3 +- .../rei/api/common/plugins/PluginView.java | 3 +- .../rei/api/common/plugins/REIPlugin.java | 2 +- .../rei/api/common/transfer/RecipeFinder.java | 2 - .../api/common/transfer/info/MenuInfoRegistry.java | 2 + .../me/shedaniel/rei/api/common/util/Animator.java | 2 - .../rei/api/common/util/CollectionUtils.java | 8 +++ 27 files changed, 432 insertions(+), 100 deletions(-) create mode 100644 api/src/main/java/me/shedaniel/rei/api/client/gui/drag/DraggableStackProviderWidget.java create mode 100644 api/src/main/java/me/shedaniel/rei/api/client/gui/drag/DraggableStackVisitorWidget.java (limited to 'api') diff --git a/api/src/main/java/me/shedaniel/rei/api/client/REIOverlay.java b/api/src/main/java/me/shedaniel/rei/api/client/REIOverlay.java index b585c2642..5ef067f6a 100644 --- a/api/src/main/java/me/shedaniel/rei/api/client/REIOverlay.java +++ b/api/src/main/java/me/shedaniel/rei/api/client/REIOverlay.java @@ -33,7 +33,7 @@ public abstract class REIOverlay extends WidgetWithBounds { public abstract void queueReloadOverlay(); - public abstract DraggingContext getDraggingContext(); + public abstract DraggingContext getDraggingContext(); public abstract boolean isNotInExclusionZones(double mouseX, double mouseY); } diff --git a/api/src/main/java/me/shedaniel/rei/api/client/gui/SimpleDisplayRenderer.java b/api/src/main/java/me/shedaniel/rei/api/client/gui/SimpleDisplayRenderer.java index c4b2205ae..917a88b75 100644 --- a/api/src/main/java/me/shedaniel/rei/api/client/gui/SimpleDisplayRenderer.java +++ b/api/src/main/java/me/shedaniel/rei/api/client/gui/SimpleDisplayRenderer.java @@ -23,6 +23,7 @@ package me.shedaniel.rei.api.client.gui; +import com.google.common.base.Predicates; import com.mojang.blaze3d.vertex.PoseStack; import it.unimi.dsi.fastutil.longs.LongOpenHashSet; import it.unimi.dsi.fastutil.longs.LongSet; @@ -46,39 +47,42 @@ import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Comparator; import java.util.List; -import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; public class SimpleDisplayRenderer extends DisplayRenderer implements WidgetHolder { - private static final Comparator> ENTRY_COMPARATOR = Comparator.comparingLong(EntryStacks::hashExact); - private static final ResourceLocation CHEST_GUI_TEXTURE = new ResourceLocation("roughlyenoughitems", "textures/gui/recipecontainer.png"); - private List inputWidgets; - private List outputWidgets; - private List widgets; + protected static final Comparator> ENTRY_COMPARATOR = Comparator.comparingLong(EntryStacks::hashExact); + protected static final ResourceLocation CHEST_GUI_TEXTURE = new ResourceLocation("roughlyenoughitems", "textures/gui/recipecontainer.png"); + protected List inputWidgets; + protected List outputWidgets; + protected List widgets; @ApiStatus.Internal - private SimpleDisplayRenderer(List input, List output) { - this.inputWidgets = simplify(input).stream().filter(stacks -> !stacks.isEmpty()).map(stacks -> Widgets.createSlot(new Point(0, 0)).entries(stacks).disableBackground().disableHighlight().disableTooltips()).collect(Collectors.toList()); - this.outputWidgets = CollectionUtils.map(simplify(output), outputStacks -> - Widgets.createSlot(new Point(0, 0)).entries(CollectionUtils.filterToList(outputStacks, stack -> !stack.isEmpty())).disableBackground().disableHighlight().disableTooltips()); + protected SimpleDisplayRenderer(List input, List output) { + this.inputWidgets = CollectionUtils.map(simplify(input), this::createSlot); + this.outputWidgets = CollectionUtils.map(simplify(output), this::createSlot); this.widgets = Stream.concat(inputWidgets.stream(), outputWidgets.stream()).collect(Collectors.toList()); } + private Slot createSlot(EntryIngredient ingredient) { + return Widgets.createSlot(new Point(0, 0)) + .entries(CollectionUtils.filterToList(ingredient, stack -> !stack.isEmpty())) + .disableBackground() + .disableHighlight() + .disableTooltips(); + } + private static List simplify(List original) { List out = new ArrayList<>(); for (EntryIngredient ingredient : original) { - if (out.stream().noneMatch(s -> equalsList(ingredient, s))) { - out.add(ingredient); + EntryIngredient filter = ingredient.filter(Predicates.not(EntryStack::isEmpty)); + if (!filter.isEmpty() && out.stream().noneMatch(s -> equalsList(filter, s))) { + out.add(filter); } } return out; } - public static DisplayRenderer from(Supplier> input, Supplier> output) { - return from(input.get(), output.get()); - } - public static DisplayRenderer from(List input, List output) { return new SimpleDisplayRenderer(input, output); } @@ -148,7 +152,7 @@ public class SimpleDisplayRenderer extends DisplayRenderer implements WidgetHold } public int getItemsHeight() { - return Mth.ceil(((float) inputWidgets.size()) / (getItemsPerLine() - 2)); + return Math.max(Mth.ceil(((float) inputWidgets.size()) / (getItemsPerLine() - 2)), outputWidgets.size()); } public int getItemsPerLine() { diff --git a/api/src/main/java/me/shedaniel/rei/api/client/gui/config/DisplayScreenType.java b/api/src/main/java/me/shedaniel/rei/api/client/gui/config/DisplayScreenType.java index 7500f5375..8e2fcc726 100644 --- a/api/src/main/java/me/shedaniel/rei/api/client/gui/config/DisplayScreenType.java +++ b/api/src/main/java/me/shedaniel/rei/api/client/gui/config/DisplayScreenType.java @@ -26,11 +26,9 @@ package me.shedaniel.rei.api.client.gui.config; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.resources.language.I18n; -import org.jetbrains.annotations.ApiStatus; import java.util.Locale; -@ApiStatus.Internal @Environment(EnvType.CLIENT) public enum DisplayScreenType { UNSET, diff --git a/api/src/main/java/me/shedaniel/rei/api/client/gui/drag/DraggableStackProvider.java b/api/src/main/java/me/shedaniel/rei/api/client/gui/drag/DraggableStackProvider.java index 4fc3e892c..fe5ccffe2 100644 --- a/api/src/main/java/me/shedaniel/rei/api/client/gui/drag/DraggableStackProvider.java +++ b/api/src/main/java/me/shedaniel/rei/api/client/gui/drag/DraggableStackProvider.java @@ -23,22 +23,61 @@ package me.shedaniel.rei.api.client.gui.drag; +import net.minecraft.client.gui.screens.Screen; import org.jetbrains.annotations.Nullable; import java.util.function.Supplier; -@FunctionalInterface -public interface DraggableStackProvider { - static DraggableStackProvider from(Supplier> providers) { - return (context, mouseX, mouseY) -> { - for (DraggableStackProvider provider : providers.get()) { - DraggableStack stack = provider.getHoveredStack(context, mouseX, mouseY); - if (stack != null) return stack; +/** + * A provider for supplying {@link DraggableStack} to the screen. + */ +public interface DraggableStackProvider extends Comparable> { + static DraggableStackProvider from(Supplier>> providers) { + return new DraggableStackProvider() { + @Override + public boolean isHandingScreen(R screen) { + for (DraggableStackProvider provider : providers.get()) { + if (provider.isHandingScreen(screen)) { + return true; + } + } + return false; + } + + @Override + @Nullable + public DraggableStack getHoveredStack(DraggingContext context, double mouseX, double mouseY) { + for (DraggableStackProvider provider : providers.get()) { + if (provider.isHandingScreen(context.getScreen())) { + DraggableStack stack = provider.getHoveredStack(context, mouseX, mouseY); + if (stack != null) return stack; + } + } + return null; } - return null; }; } @Nullable - DraggableStack getHoveredStack(DraggingContext context, double mouseX, double mouseY); + DraggableStack getHoveredStack(DraggingContext context, double mouseX, double mouseY); + + boolean isHandingScreen(R screen); + + default DraggingContext getContext() { + return DraggingContext.getInstance().cast(); + } + + /** + * Gets the priority of the handler, the higher the priority, the earlier this is called. + * + * @return the priority + */ + default double getPriority() { + return 0f; + } + + @Override + default int compareTo(DraggableStackProvider o) { + return Double.compare(getPriority(), o.getPriority()); + } } \ No newline at end of file diff --git a/api/src/main/java/me/shedaniel/rei/api/client/gui/drag/DraggableStackProviderWidget.java b/api/src/main/java/me/shedaniel/rei/api/client/gui/drag/DraggableStackProviderWidget.java new file mode 100644 index 000000000..8efb79311 --- /dev/null +++ b/api/src/main/java/me/shedaniel/rei/api/client/gui/drag/DraggableStackProviderWidget.java @@ -0,0 +1,73 @@ +/* + * 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.client.gui.drag; + +import net.minecraft.client.gui.screens.Screen; +import org.jetbrains.annotations.Nullable; + +import java.util.function.Function; + +/** + * An interface to be implemented on {@link me.shedaniel.rei.api.client.gui.widgets.Widget} to provide + * {@link DraggableStack}. + */ +@FunctionalInterface +public interface DraggableStackProviderWidget { + static DraggableStackProviderWidget from(Function, Iterable> providers) { + return (context, mouseX, mouseY) -> { + for (DraggableStackProviderWidget provider : providers.apply(context)) { + DraggableStack stack = provider.getHoveredStack(context, mouseX, mouseY); + if (stack != null) return stack; + } + return null; + }; + } + + @Nullable + DraggableStack getHoveredStack(DraggingContext context, double mouseX, double mouseY); + + static DraggableStackProvider toProvider(DraggableStackProviderWidget widget) { + return toProvider(widget, 0D); + } + + static DraggableStackProvider toProvider(DraggableStackProviderWidget widget, double priority) { + return new DraggableStackProvider() { + @Override + @Nullable + public DraggableStack getHoveredStack(DraggingContext context, double mouseX, double mouseY) { + return widget.getHoveredStack(context, mouseX, mouseY); + } + + @Override + public boolean isHandingScreen(R screen) { + return true; + } + + @Override + public double getPriority() { + return priority; + } + }; + } +} diff --git a/api/src/main/java/me/shedaniel/rei/api/client/gui/drag/DraggableStackVisitor.java b/api/src/main/java/me/shedaniel/rei/api/client/gui/drag/DraggableStackVisitor.java index 8ebdf9c57..6959d912a 100644 --- a/api/src/main/java/me/shedaniel/rei/api/client/gui/drag/DraggableStackVisitor.java +++ b/api/src/main/java/me/shedaniel/rei/api/client/gui/drag/DraggableStackVisitor.java @@ -23,23 +23,63 @@ package me.shedaniel.rei.api.client.gui.drag; +import net.minecraft.client.gui.screens.Screen; + import java.util.Optional; import java.util.function.Supplier; -@FunctionalInterface -public interface DraggableStackVisitor { - static DraggableStackVisitor from(Supplier> visitors) { - return (stack) -> { - for (DraggableStackVisitor visitor : visitors.get()) { - Optional acceptor = visitor.visitDraggedStack(stack); - if (acceptor.isPresent()) return acceptor; +/** + * A visitor for accepting {@link DraggableStack} to the screen. + */ +public interface DraggableStackVisitor extends Comparable> { + static DraggableStackVisitor from(Supplier>> visitors) { + return new DraggableStackVisitor() { + @Override + public boolean isHandingScreen(R screen) { + for (DraggableStackVisitor visitor : visitors.get()) { + if (visitor.isHandingScreen(screen)) { + return true; + } + } + return false; + } + + @Override + public Optional visitDraggedStack(DraggingContext context, DraggableStack stack) { + for (DraggableStackVisitor visitor : visitors.get()) { + if (visitor.isHandingScreen(context.getScreen())) { + Optional acceptor = visitor.visitDraggedStack(context, stack); + if (acceptor.isPresent()) return acceptor; + } + } + return Optional.empty(); } - return Optional.empty(); }; } - Optional visitDraggedStack(DraggableStack stack); + Optional visitDraggedStack(DraggingContext context, DraggableStack stack); + + boolean isHandingScreen(R screen); + + default DraggingContext getContext() { + return DraggingContext.getInstance().cast(); + } + + /** + * Gets the priority of the handler, the higher the priority, the earlier this is called. + * + * @return the priority + */ + default double getPriority() { + return 0.0; + } + + @Override + default int compareTo(DraggableStackVisitor o) { + return Double.compare(getPriority(), o.getPriority()); + } + @FunctionalInterface interface Acceptor { void accept(DraggableStack stack); } diff --git a/api/src/main/java/me/shedaniel/rei/api/client/gui/drag/DraggableStackVisitorWidget.java b/api/src/main/java/me/shedaniel/rei/api/client/gui/drag/DraggableStackVisitorWidget.java new file mode 100644 index 000000000..0af21ddc5 --- /dev/null +++ b/api/src/main/java/me/shedaniel/rei/api/client/gui/drag/DraggableStackVisitorWidget.java @@ -0,0 +1,71 @@ +/* + * 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.client.gui.drag; + +import net.minecraft.client.gui.screens.Screen; + +import java.util.Optional; +import java.util.function.Function; + +/** + * An interface to be implemented on {@link me.shedaniel.rei.api.client.gui.widgets.Widget} to accept + * incoming {@link DraggableStack}. + */ +@FunctionalInterface +public interface DraggableStackVisitorWidget { + static DraggableStackVisitorWidget from(Function, Iterable> providers) { + return (context, stack) -> { + for (DraggableStackVisitorWidget visitor : providers.apply(context)) { + Optional acceptor = visitor.visitDraggedStack(context, stack); + if (acceptor.isPresent()) return acceptor; + } + return Optional.empty(); + }; + } + + Optional visitDraggedStack(DraggingContext context, DraggableStack stack); + + static DraggableStackVisitor toVisitor(DraggableStackVisitorWidget widget) { + return toVisitor(widget, 0.0); + } + + static DraggableStackVisitor toVisitor(DraggableStackVisitorWidget widget, double priority) { + return new DraggableStackVisitor() { + @Override + public Optional visitDraggedStack(DraggingContext context, DraggableStack stack) { + return widget.visitDraggedStack(context, stack); + } + + @Override + public boolean isHandingScreen(R screen) { + return true; + } + + @Override + public double getPriority() { + return priority; + } + }; + } +} diff --git a/api/src/main/java/me/shedaniel/rei/api/client/gui/drag/DraggingContext.java b/api/src/main/java/me/shedaniel/rei/api/client/gui/drag/DraggingContext.java index 9ea02d146..628408dce 100644 --- a/api/src/main/java/me/shedaniel/rei/api/client/gui/drag/DraggingContext.java +++ b/api/src/main/java/me/shedaniel/rei/api/client/gui/drag/DraggingContext.java @@ -25,6 +25,7 @@ package me.shedaniel.rei.api.client.gui.drag; import me.shedaniel.math.Point; import me.shedaniel.rei.api.client.REIHelper; +import net.minecraft.client.gui.screens.Screen; import org.jetbrains.annotations.Nullable; import java.util.function.Supplier; @@ -32,18 +33,28 @@ import java.util.function.Supplier; /** * The context of the current dragged stack on the overlay. *

- * Widgets should implement {@link DraggableStackProvider} to submit applicable stacks to drag. - * Widgets should implement {@link DraggableStackVisitor} to accept incoming dragged stacks. + * Widgets should implement {@link DraggableStackProviderWidget} to submit applicable stacks to drag. + * Widgets should implement {@link DraggableStackVisitorWidget} to accept incoming dragged stacks. + *

+ * External providers should use {@link me.shedaniel.rei.api.client.registry.screen.ScreenRegistry#registerDraggableStackProvider(DraggableStackProvider)}, + * and {@link me.shedaniel.rei.api.client.registry.screen.ScreenRegistry#registerDraggableStackVisitor(DraggableStackVisitor)}. */ -public interface DraggingContext { - static DraggingContext getInstance() { +public interface DraggingContext { + static DraggingContext getInstance() { return REIHelper.getInstance().getOverlay().get().getDraggingContext(); } + /** + * Returns whether a draggable stack is present. + * + * @return whether a draggable stack is present + */ default boolean isDraggingStack() { return getCurrentStack() != null; } + S getScreen(); + /** * Returns the current dragged stack, may be null. * @@ -70,4 +81,8 @@ public interface DraggingContext { * @param position the position supplier of the destination */ void renderBackToPosition(DraggableStack stack, Point initialPosition, Supplier position); + + default DraggingContext cast() { + return (DraggingContext) this; + } } diff --git a/api/src/main/java/me/shedaniel/rei/api/client/registry/display/DisplayCategory.java b/api/src/main/java/me/shedaniel/rei/api/client/registry/display/DisplayCategory.java index f209ac35c..5c9a697c6 100644 --- a/api/src/main/java/me/shedaniel/rei/api/client/registry/display/DisplayCategory.java +++ b/api/src/main/java/me/shedaniel/rei/api/client/registry/display/DisplayCategory.java @@ -65,7 +65,7 @@ public interface DisplayCategory extends Identifiable { */ @ApiStatus.OverrideOnly default DisplayRenderer getDisplayRenderer(T display) { - return SimpleDisplayRenderer.from(display::getInputEntries, display::getOutputEntries); + return SimpleDisplayRenderer.from(display.getInputEntries(), display.getOutputEntries()); } /** diff --git a/api/src/main/java/me/shedaniel/rei/api/client/registry/display/DisplayRegistry.java b/api/src/main/java/me/shedaniel/rei/api/client/registry/display/DisplayRegistry.java index fc4ecd094..65bdb9460 100644 --- a/api/src/main/java/me/shedaniel/rei/api/client/registry/display/DisplayRegistry.java +++ b/api/src/main/java/me/shedaniel/rei/api/client/registry/display/DisplayRegistry.java @@ -23,6 +23,7 @@ package me.shedaniel.rei.api.client.registry.display; +import com.google.common.base.Predicates; import me.shedaniel.rei.api.client.plugins.REIClientPlugin; import me.shedaniel.rei.api.client.registry.display.visibility.DisplayVisibilityPredicate; import me.shedaniel.rei.api.common.category.CategoryIdentifier; @@ -31,8 +32,8 @@ import me.shedaniel.rei.api.common.plugins.PluginManager; import me.shedaniel.rei.api.common.registry.RecipeManagerContext; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; -import org.jetbrains.annotations.Nullable; +import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; @@ -54,7 +55,7 @@ public interface DisplayRegistry extends RecipeManagerContext { * * @return the recipe count */ - int getDisplayCount(); + int displaySize(); /** * Registers a recipe display @@ -149,11 +150,41 @@ public interface DisplayRegistry extends RecipeManagerContext { */ List getVisibilityPredicates(); - default void registerFiller(Class typeClass, Function mappingFunction) { - registerFiller(typeClass, typeClass::isInstance, mappingFunction); + /** + * Registers a display filler, to be filled during {@link #tryFillDisplay(Object)}. + *

+ * Vanilla {@link net.minecraft.world.item.crafting.Recipe} are by default filled, display filters + * can be used to automatically generate displaies for vanilla {@link net.minecraft.world.item.crafting.Recipe}. + * + * @param typeClass the type of {@code T} + * @param filler the filler, taking a {@code T} and returning a {@code D} + * @param the type of object + * @param the type of display + */ + default void registerFiller(Class typeClass, Function filler) { + registerFiller(typeClass, Predicates.alwaysTrue(), filler); } - void registerFiller(Class typeClass, Predicate predicate, Function mappingFunction); + /** + * Registers a display filler, to be filled during {@link #tryFillDisplay(Object)}. + *

+ * Vanilla {@link net.minecraft.world.item.crafting.Recipe} are by default filled, display filters + * can be used to automatically generate displaies for vanilla {@link net.minecraft.world.item.crafting.Recipe}. + * + * @param typeClass the type of {@code T} + * @param predicate the predicate of {@code T} + * @param filler the filler, taking a {@code T} and returning a {@code D} + * @param the type of object + * @param the type of display + */ + void registerFiller(Class typeClass, Predicate predicate, Function filler); - @Nullable Display tryFillDisplay(T value); + /** + * Tries to fill displays from {@code T}. + * + * @param value the object + * @param the type of object + * @return the collection of displays + */ + Collection tryFillDisplay(T value); } diff --git a/api/src/main/java/me/shedaniel/rei/api/client/registry/display/visibility/DisplayVisibilityPredicate.java b/api/src/main/java/me/shedaniel/rei/api/client/registry/display/visibility/DisplayVisibilityPredicate.java index d3e993e1e..4f09c5c53 100644 --- a/api/src/main/java/me/shedaniel/rei/api/client/registry/display/visibility/DisplayVisibilityPredicate.java +++ b/api/src/main/java/me/shedaniel/rei/api/client/registry/display/visibility/DisplayVisibilityPredicate.java @@ -28,14 +28,13 @@ import me.shedaniel.rei.api.common.display.Display; import net.minecraft.world.InteractionResult; public interface DisplayVisibilityPredicate extends Comparable { - /** * Gets the priority of the handler, the higher the priority, the earlier this is called. * * @return the priority */ - default float getPriority() { - return 0f; + default double getPriority() { + return 0.0; } /** diff --git a/api/src/main/java/me/shedaniel/rei/api/client/registry/entry/EntryRegistry.java b/api/src/main/java/me/shedaniel/rei/api/client/registry/entry/EntryRegistry.java index 141799a8a..3d32684de 100644 --- a/api/src/main/java/me/shedaniel/rei/api/client/registry/entry/EntryRegistry.java +++ b/api/src/main/java/me/shedaniel/rei/api/client/registry/entry/EntryRegistry.java @@ -36,6 +36,7 @@ import org.jetbrains.annotations.Nullable; import java.util.Arrays; import java.util.Collection; import java.util.List; +import java.util.function.LongPredicate; import java.util.function.Predicate; import java.util.stream.Stream; @@ -79,56 +80,56 @@ public interface EntryRegistry extends Reloadable { List appendStacksForItem(Item item); /** - * Registers an new stack to the entry list. + * Adds an new stack to the entry list. * - * @param stack the stack to register + * @param stack the stack to add */ - default void registerEntry(EntryStack stack) { - registerEntryAfter(null, stack); + default void addEntry(EntryStack stack) { + addEntryAfter(null, stack); } /** - * Registers an new stack to the entry list, after a certain stack. + * Adds an new stack to the entry list, after a certain stack. * * @param afterEntry the stack to put after - * @param stack the stack to register + * @param stack the stack to add */ - void registerEntryAfter(@Nullable EntryStack afterEntry, EntryStack stack); + void addEntryAfter(@Nullable EntryStack afterEntry, EntryStack stack); /** - * Registers multiple stacks to the item list, after a certain stack. + * Adds multiple stacks to the item list, after a certain stack. * * @param afterStack the stack to put after - * @param stacks the stacks to register + * @param stacks the stacks to add */ - default void registerEntriesAfter(@Nullable EntryStack afterStack, EntryStack... stacks) { - registerEntriesAfter(afterStack, Arrays.asList(stacks)); + default void addEntriesAfter(@Nullable EntryStack afterStack, EntryStack... stacks) { + addEntriesAfter(afterStack, Arrays.asList(stacks)); } /** - * Registers multiple stacks to the item list, after a certain stack. + * Adds multiple stacks to the item list, after a certain stack. * * @param afterStack the stack to put after - * @param stacks the stacks to register + * @param stacks the stacks to add */ - void registerEntriesAfter(@Nullable EntryStack afterStack, Collection> stacks); + void addEntriesAfter(@Nullable EntryStack afterStack, Collection> stacks); /** - * Registers multiple stacks to the item list. + * Adds multiple stacks to the item list. * - * @param stacks the stacks to register + * @param stacks the stacks to add */ - default void registerEntries(EntryStack... stacks) { - registerEntries(Arrays.asList(stacks)); + default void addEntries(EntryStack... stacks) { + addEntries(Arrays.asList(stacks)); } /** - * Registers multiple stacks to the item list. + * Adds multiple stacks to the item list. * - * @param stacks the stacks to register + * @param stacks the stacks to add */ - default void registerEntries(Collection> stacks) { - registerEntriesAfter(null, stacks); + default void addEntries(Collection> stacks) { + addEntriesAfter(null, stacks); } /** @@ -150,8 +151,18 @@ public interface EntryRegistry extends Reloadable { /** * Removes entries from the entry list, if it matches the predicate. * - * @param filter a predicate which returns {@code true} for the entries to be removed + * @param predicate a predicate which returns {@code true} for the entries to be removed * @return whether it was successful to remove any entry */ - boolean removeEntryIf(Predicate> filter); + boolean removeEntryIf(Predicate> predicate); + + /** + * Removes entries from the entry list, if it matches the predicate. + * This method is usually faster than {@link #removeEntryIf(Predicate)} + * due to its fast comparison. + * + * @param predicate a predicate which returns {@code true} for the entries to be removed + * @return whether it was successful to remove any entry + */ + boolean removeEntryExactHashIf(LongPredicate predicate); } diff --git a/api/src/main/java/me/shedaniel/rei/api/client/registry/screen/ExclusionZones.java b/api/src/main/java/me/shedaniel/rei/api/client/registry/screen/ExclusionZones.java index 0ea2567eb..cfd1f859a 100644 --- a/api/src/main/java/me/shedaniel/rei/api/client/registry/screen/ExclusionZones.java +++ b/api/src/main/java/me/shedaniel/rei/api/client/registry/screen/ExclusionZones.java @@ -32,7 +32,7 @@ import java.util.List; @Environment(EnvType.CLIENT) public interface ExclusionZones extends OverlayDecider { /** - * Gets the exclusion zones by the screen class + * Returns the exclusion zones by the screen class * * @param currentScreenClass the current screen class * @return the list of exclusion zones @@ -41,6 +41,12 @@ public interface ExclusionZones extends OverlayDecider { return getExclusionZones(currentScreenClass, false); } + /** + * Returns the exclusion zones by the screen class + * + * @param currentScreenClass the current screen class + * @return the list of exclusion zones + */ List getExclusionZones(Class currentScreenClass, boolean sort); int getZonesCount(); diff --git a/api/src/main/java/me/shedaniel/rei/api/client/registry/screen/OverlayDecider.java b/api/src/main/java/me/shedaniel/rei/api/client/registry/screen/OverlayDecider.java index 71180a841..8f8bf7112 100644 --- a/api/src/main/java/me/shedaniel/rei/api/client/registry/screen/OverlayDecider.java +++ b/api/src/main/java/me/shedaniel/rei/api/client/registry/screen/OverlayDecider.java @@ -40,10 +40,10 @@ public interface OverlayDecider extends Comparable { /** * Gets the priority of the handler, the higher it is, the earlier it is called. * - * @return the priority in float + * @return the priority */ - default float getPriority() { - return 0f; + default double getPriority() { + return 0.0; } /** diff --git a/api/src/main/java/me/shedaniel/rei/api/client/registry/screen/ScreenRegistry.java b/api/src/main/java/me/shedaniel/rei/api/client/registry/screen/ScreenRegistry.java index 916168aa3..0d7ef43ca 100644 --- a/api/src/main/java/me/shedaniel/rei/api/client/registry/screen/ScreenRegistry.java +++ b/api/src/main/java/me/shedaniel/rei/api/client/registry/screen/ScreenRegistry.java @@ -26,6 +26,10 @@ package me.shedaniel.rei.api.client.registry.screen; import me.shedaniel.math.Point; import me.shedaniel.math.Rectangle; import me.shedaniel.rei.api.client.gui.config.DisplayPanelLocation; +import me.shedaniel.rei.api.client.gui.drag.DraggableStackProvider; +import me.shedaniel.rei.api.client.gui.drag.DraggableStackProviderWidget; +import me.shedaniel.rei.api.client.gui.drag.DraggableStackVisitor; +import me.shedaniel.rei.api.client.gui.drag.DraggableStackVisitorWidget; import me.shedaniel.rei.api.client.plugins.REIClientPlugin; import me.shedaniel.rei.api.common.category.CategoryIdentifier; import me.shedaniel.rei.api.common.entry.EntryStack; @@ -35,7 +39,6 @@ import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; -import net.minecraft.resources.ResourceLocation; import net.minecraft.world.inventory.AbstractContainerMenu; import org.jetbrains.annotations.Nullable; @@ -80,6 +83,30 @@ public interface ScreenRegistry extends Reloadable { */ void registerFocusedStack(FocusedStackProvider provider); + void registerDraggableStackVisitor(DraggableStackVisitor visitor); + + void registerDraggableStackProvider(DraggableStackProvider provider); + + default void registerDraggableStackVisitor(DraggableStackVisitorWidget visitor) { + registerDraggableStackVisitor(DraggableStackVisitorWidget.toVisitor(visitor)); + } + + default void registerDraggableStackProvider(DraggableStackProviderWidget provider) { + registerDraggableStackProvider(DraggableStackProviderWidget.toProvider(provider)); + } + + default void registerDraggableStackVisitor(double priority, DraggableStackVisitorWidget visitor) { + registerDraggableStackVisitor(DraggableStackVisitorWidget.toVisitor(visitor, priority)); + } + + default void registerDraggableStackProvider(double priority, DraggableStackProviderWidget provider) { + registerDraggableStackProvider(DraggableStackProviderWidget.toProvider(provider, priority)); + } + + Iterable> getDraggableProviders(); + + Iterable> getDraggableVisitors(); + /** * Returns the main center screen bounds returned, provided by deciders. * @@ -143,7 +170,7 @@ public interface ScreenRegistry extends Reloadable { * @param screenClass The class of the screen. * @param area The click area that is offset to the window's top left corner. * @param The screen type to be registered to. - * @see #registerClickArea(SimpleClickArea, Class, ResourceLocation...) for a simpler way to handle areas without custom categories. + * @see #registerClickArea(SimpleClickArea, Class, CategoryIdentifier...) for a simpler way to handle areas without custom categories. */ void registerClickArea(Class screenClass, ClickArea area); diff --git a/api/src/main/java/me/shedaniel/rei/api/client/util/ClientEntryStacks.java b/api/src/main/java/me/shedaniel/rei/api/client/util/ClientEntryStacks.java index 85d3d4a84..537a658f2 100644 --- a/api/src/main/java/me/shedaniel/rei/api/client/util/ClientEntryStacks.java +++ b/api/src/main/java/me/shedaniel/rei/api/client/util/ClientEntryStacks.java @@ -23,8 +23,8 @@ package me.shedaniel.rei.api.client.util; -import me.shedaniel.rei.api.client.gui.Renderer; import me.shedaniel.rei.api.client.entry.type.BuiltinClientEntryTypes; +import me.shedaniel.rei.api.client.gui.Renderer; import me.shedaniel.rei.api.common.entry.EntryStack; public final class ClientEntryStacks { diff --git a/api/src/main/java/me/shedaniel/rei/api/common/entry/EntryStack.java b/api/src/main/java/me/shedaniel/rei/api/common/entry/EntryStack.java index b75624da0..0f3279f3b 100644 --- a/api/src/main/java/me/shedaniel/rei/api/common/entry/EntryStack.java +++ b/api/src/main/java/me/shedaniel/rei/api/common/entry/EntryStack.java @@ -28,7 +28,6 @@ import me.shedaniel.rei.api.client.config.ConfigObject; import me.shedaniel.rei.api.client.entry.renderer.EntryRenderer; import me.shedaniel.rei.api.client.gui.Renderer; import me.shedaniel.rei.api.client.gui.widgets.Tooltip; -import me.shedaniel.rei.api.common.entry.comparison.ComparisonContext; import me.shedaniel.rei.api.common.entry.type.EntryDefinition; import me.shedaniel.rei.api.common.entry.type.EntryType; import me.shedaniel.rei.api.common.entry.type.EntryTypeRegistry; diff --git a/api/src/main/java/me/shedaniel/rei/api/common/entry/comparison/ComparisonContext.java b/api/src/main/java/me/shedaniel/rei/api/common/entry/comparison/ComparisonContext.java index 6dd350bfd..88f3a78e3 100644 --- a/api/src/main/java/me/shedaniel/rei/api/common/entry/comparison/ComparisonContext.java +++ b/api/src/main/java/me/shedaniel/rei/api/common/entry/comparison/ComparisonContext.java @@ -33,7 +33,7 @@ public enum ComparisonContext { */ EXACT(true); - boolean exact; + private final boolean exact; ComparisonContext(boolean exact) { this.exact = exact; diff --git a/api/src/main/java/me/shedaniel/rei/api/common/entry/comparison/ItemComparator.java b/api/src/main/java/me/shedaniel/rei/api/common/entry/comparison/ItemComparator.java index 21cc7bfe7..8a6de69d9 100644 --- a/api/src/main/java/me/shedaniel/rei/api/common/entry/comparison/ItemComparator.java +++ b/api/src/main/java/me/shedaniel/rei/api/common/entry/comparison/ItemComparator.java @@ -37,12 +37,12 @@ import java.util.function.ToLongFunction; @FunctionalInterface public interface ItemComparator { static ItemComparator noop() { - return stack -> 1; + return (context, stack) -> 1; } static ItemComparator itemNbt() { ToLongFunction nbtHasher = nbtHasher("Count"); - return stack -> { + return (context, stack) -> { CompoundTag tag = stack.getTag(); return tag == null ? 0L : nbtHasher.applyAsLong(tag); }; @@ -52,15 +52,24 @@ public interface ItemComparator { return Internals.getNbtHasher(ignoredKeys); } - long hash(ItemStack stack); + long hash(ComparisonContext context, ItemStack stack); + + default ItemComparator onlyExact() { + ItemComparator self = this; + + return (context, stack) -> { + return context.isExact() ? self.hash(context, stack) : 1; + }; + } default ItemComparator then(ItemComparator other) { Objects.requireNonNull(other); + ItemComparator self = this; - return stack -> { + return (context, stack) -> { long hash = 1L; - hash = hash * 31 + hash(stack); - hash = hash * 31 + other.hash(stack); + hash = hash * 31 + self.hash(context, stack); + hash = hash * 31 + other.hash(context, stack); return hash; }; } diff --git a/api/src/main/java/me/shedaniel/rei/api/common/entry/comparison/ItemComparatorRegistry.java b/api/src/main/java/me/shedaniel/rei/api/common/entry/comparison/ItemComparatorRegistry.java index 6a3140bc3..f7be05132 100644 --- a/api/src/main/java/me/shedaniel/rei/api/common/entry/comparison/ItemComparatorRegistry.java +++ b/api/src/main/java/me/shedaniel/rei/api/common/entry/comparison/ItemComparatorRegistry.java @@ -59,5 +59,9 @@ public interface ItemComparatorRegistry extends Reloadable> { register(ItemComparator.itemNbt(), items); } - long hashOf(ItemStack stack); + long hashOf(ComparisonContext context, ItemStack stack); + + boolean containsComparator(Item item); + + int comparatorSize(); } diff --git a/api/src/main/java/me/shedaniel/rei/api/common/fluid/FluidSupportProvider.java b/api/src/main/java/me/shedaniel/rei/api/common/fluid/FluidSupportProvider.java index 34191b947..f6260a4fc 100644 --- a/api/src/main/java/me/shedaniel/rei/api/common/fluid/FluidSupportProvider.java +++ b/api/src/main/java/me/shedaniel/rei/api/common/fluid/FluidSupportProvider.java @@ -32,13 +32,14 @@ import net.minecraft.world.InteractionResultHolder; import net.minecraft.world.item.ItemStack; import org.jetbrains.annotations.Nullable; +import java.util.List; import java.util.Optional; import java.util.stream.Stream; /** * A registry to provide support for getting fluids from items. */ -public interface FluidSupportProvider extends Reloadable> { +public interface FluidSupportProvider extends Reloadable>, List { static FluidSupportProvider getInstance() { return PluginManager.getInstance().get(FluidSupportProvider.class); } diff --git a/api/src/main/java/me/shedaniel/rei/api/common/plugins/PluginView.java b/api/src/main/java/me/shedaniel/rei/api/common/plugins/PluginView.java index 7e88967fa..d922dff38 100644 --- a/api/src/main/java/me/shedaniel/rei/api/common/plugins/PluginView.java +++ b/api/src/main/java/me/shedaniel/rei/api/common/plugins/PluginView.java @@ -30,6 +30,7 @@ import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import org.jetbrains.annotations.ApiStatus; +@ApiStatus.Internal @FunctionalInterface public interface PluginView

> { @Environment(EnvType.CLIENT) @@ -49,9 +50,7 @@ public interface PluginView

> { * Registers a REI plugin * * @param plugin the plugin instance - * @return the plugin instance */ - @ApiStatus.Internal void registerPlugin(REIPluginProvider plugin); default PluginView

then(PluginView view) { diff --git a/api/src/main/java/me/shedaniel/rei/api/common/plugins/REIPlugin.java b/api/src/main/java/me/shedaniel/rei/api/common/plugins/REIPlugin.java index d56e04dc2..5605e1862 100644 --- a/api/src/main/java/me/shedaniel/rei/api/common/plugins/REIPlugin.java +++ b/api/src/main/java/me/shedaniel/rei/api/common/plugins/REIPlugin.java @@ -24,9 +24,9 @@ package me.shedaniel.rei.api.common.plugins; import me.shedaniel.rei.api.common.display.DisplaySerializerRegistry; -import me.shedaniel.rei.api.common.fluid.FluidSupportProvider; import me.shedaniel.rei.api.common.entry.comparison.ItemComparatorRegistry; import me.shedaniel.rei.api.common.entry.type.EntryTypeRegistry; +import me.shedaniel.rei.api.common.fluid.FluidSupportProvider; import org.jetbrains.annotations.ApiStatus; import java.util.Collection; diff --git a/api/src/main/java/me/shedaniel/rei/api/common/transfer/RecipeFinder.java b/api/src/main/java/me/shedaniel/rei/api/common/transfer/RecipeFinder.java index 6ff11a6e5..5a4ae3bf3 100644 --- a/api/src/main/java/me/shedaniel/rei/api/common/transfer/RecipeFinder.java +++ b/api/src/main/java/me/shedaniel/rei/api/common/transfer/RecipeFinder.java @@ -30,14 +30,12 @@ import net.minecraft.core.Registry; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.Ingredient; -import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.BitSet; import java.util.List; -@ApiStatus.Internal public class RecipeFinder { public final Int2IntMap idToAmountMap = new Int2IntOpenHashMap(); diff --git a/api/src/main/java/me/shedaniel/rei/api/common/transfer/info/MenuInfoRegistry.java b/api/src/main/java/me/shedaniel/rei/api/common/transfer/info/MenuInfoRegistry.java index 4248a198f..a6e7b665b 100644 --- a/api/src/main/java/me/shedaniel/rei/api/common/transfer/info/MenuInfoRegistry.java +++ b/api/src/main/java/me/shedaniel/rei/api/common/transfer/info/MenuInfoRegistry.java @@ -45,4 +45,6 @@ public interface MenuInfoRegistry extends Reloadable { void registerGeneric(Predicate> categoryPredicate, MenuInfo menuInfo); MenuInfo get(CategoryIdentifier category, Class menuClass); + + int infoSize(); } diff --git a/api/src/main/java/me/shedaniel/rei/api/common/util/Animator.java b/api/src/main/java/me/shedaniel/rei/api/common/util/Animator.java index e0e313c16..05d5deea4 100644 --- a/api/src/main/java/me/shedaniel/rei/api/common/util/Animator.java +++ b/api/src/main/java/me/shedaniel/rei/api/common/util/Animator.java @@ -25,9 +25,7 @@ package me.shedaniel.rei.api.common.util; import me.shedaniel.clothconfig2.impl.EasingMethod; import net.minecraft.Util; -import org.jetbrains.annotations.ApiStatus; -@ApiStatus.Internal public final class Animator extends Number { private double amount; private double target; diff --git a/api/src/main/java/me/shedaniel/rei/api/common/util/CollectionUtils.java b/api/src/main/java/me/shedaniel/rei/api/common/util/CollectionUtils.java index a191d85ce..3c6dd857f 100644 --- a/api/src/main/java/me/shedaniel/rei/api/common/util/CollectionUtils.java +++ b/api/src/main/java/me/shedaniel/rei/api/common/util/CollectionUtils.java @@ -130,6 +130,14 @@ public class CollectionUtils { return l; } + public static List flatMap(Iterable list, Function> function) { + List l = new ArrayList<>(); + for (T t : list) { + l.addAll(function.apply(t)); + } + return l; + } + public static IntList mapToInt(Collection list, ToIntFunction function) { IntList l = new IntArrayList(list.size() + 1); for (T t : list) { -- cgit