diff options
| author | shedaniel <daniel@shedaniel.me> | 2021-11-20 17:50:10 +0800 |
|---|---|---|
| committer | shedaniel <daniel@shedaniel.me> | 2021-11-20 18:30:52 +0800 |
| commit | 69e26e78b69f7eeb745b604b2347ac30fe32666f (patch) | |
| tree | 8fec70dc56f335817702ac20429ab32f2301d136 /api/src/main/java/me | |
| parent | b92284180f3c58361180f9e5fb1062ba5560466e (diff) | |
| download | RoughlyEnoughItems-69e26e78b69f7eeb745b604b2347ac30fe32666f.tar.gz RoughlyEnoughItems-69e26e78b69f7eeb745b604b2347ac30fe32666f.tar.bz2 RoughlyEnoughItems-69e26e78b69f7eeb745b604b2347ac30fe32666f.zip | |
Rewrite on how TransferHandler render errors, and fix #580
Diffstat (limited to 'api/src/main/java/me')
6 files changed, 162 insertions, 18 deletions
diff --git a/api/src/main/java/me/shedaniel/rei/api/client/registry/display/TransferDisplayCategory.java b/api/src/main/java/me/shedaniel/rei/api/client/registry/display/TransferDisplayCategory.java index 5cc0fc459..00843f57a 100644 --- a/api/src/main/java/me/shedaniel/rei/api/client/registry/display/TransferDisplayCategory.java +++ b/api/src/main/java/me/shedaniel/rei/api/client/registry/display/TransferDisplayCategory.java @@ -35,6 +35,8 @@ import org.jetbrains.annotations.ApiStatus; import java.util.List; @Environment(EnvType.CLIENT) +@Deprecated +@ApiStatus.ScheduledForRemoval public interface TransferDisplayCategory<T extends Display> extends DisplayCategory<T> { @ApiStatus.OverrideOnly @ApiStatus.ScheduledForRemoval diff --git a/api/src/main/java/me/shedaniel/rei/api/client/registry/transfer/TransferHandler.java b/api/src/main/java/me/shedaniel/rei/api/client/registry/transfer/TransferHandler.java index 9ec3a3a15..2d8a8ef83 100644 --- a/api/src/main/java/me/shedaniel/rei/api/client/registry/transfer/TransferHandler.java +++ b/api/src/main/java/me/shedaniel/rei/api/client/registry/transfer/TransferHandler.java @@ -23,7 +23,6 @@ package me.shedaniel.rei.api.client.registry.transfer; -import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntList; import me.shedaniel.rei.api.client.registry.display.TransferDisplayCategory; import me.shedaniel.rei.api.common.display.Display; @@ -36,6 +35,7 @@ import net.minecraft.world.inventory.AbstractContainerMenu; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; +import java.util.List; import java.util.function.Supplier; /** @@ -63,6 +63,16 @@ public interface TransferHandler extends Comparable<TransferHandler> { return Double.compare(getPriority(), o.getPriority()); } + @Environment(EnvType.CLIENT) + @Nullable + default TransferHandlerErrorRenderer provideErrorRenderer(Context context, Object data) { + if (data instanceof IntList) { + return TransferHandlerErrorRenderer.forRedSlots((IntList) data); + } + + return null; + } + @ApiStatus.NonExtendable interface Result { /** @@ -86,7 +96,7 @@ public interface TransferHandler extends Comparable<TransferHandler> { * @param error The error itself */ static Result createFailed(Component error) { - return new ResultImpl(error, new IntArrayList(), 0x67ff0000); + return new ResultImpl(error, 0x67ff0000); } /** @@ -97,7 +107,7 @@ public interface TransferHandler extends Comparable<TransferHandler> { * @param color A special color for the button */ static Result createFailedCustomButtonColor(Component error, int color) { - return new ResultImpl(error, new IntArrayList(), color); + return createFailed(error).color(color); } /** @@ -107,7 +117,7 @@ public interface TransferHandler extends Comparable<TransferHandler> { * @param redSlots A list of slots to be marked as red. Will be passed to {@link TransferDisplayCategory}. */ static Result createFailed(Component error, IntList redSlots) { - return new ResultImpl(error, redSlots, 0x67ff0000); + return createFailed(error).errorRenderer(redSlots); } /** @@ -119,7 +129,7 @@ public interface TransferHandler extends Comparable<TransferHandler> { * @param redSlots A list of slots to be marked as red. Will be passed to {@link TransferDisplayCategory}. */ static Result createFailedCustomButtonColor(Component error, IntList redSlots, int color) { - return new ResultImpl(error, redSlots, color); + return createFailed(error).errorRenderer(redSlots).color(color); } /** @@ -138,13 +148,18 @@ public interface TransferHandler extends Comparable<TransferHandler> { * @return the color in which the button should be displayed in. */ int getColor(); - + /** * Sets the color in which the button should be displayed in. */ Result color(int color); /** + * Sets the error data, to be passed to {@link TransferHandler#provideErrorRenderer(Context, Object)}. + */ + Result errorRenderer(Object data); + + /** * @return whether this handler has successfully handled the transfer. */ boolean isSuccessful(); @@ -173,10 +188,12 @@ public interface TransferHandler extends Comparable<TransferHandler> { */ Component getError(); - /** - * @return a list of slots to be marked as red. Will be passed to {@link TransferDisplayCategory}. - */ - IntList getIntegers(); + @Environment(EnvType.CLIENT) + @ApiStatus.Internal + TransferHandlerErrorRenderer getErrorRenderer(TransferHandler handler, Context context); + + @ApiStatus.Internal + void fillTooltip(List<Component> components); } @ApiStatus.NonExtendable @@ -211,7 +228,7 @@ public interface TransferHandler extends Comparable<TransferHandler> { final class ResultImpl implements Result { private boolean successful, applicable, returningToScreen, blocking; private Component error; - private IntList integers = new IntArrayList(); + private Object errorRenderer; private int color; private ResultImpl() { @@ -227,12 +244,10 @@ public interface TransferHandler extends Comparable<TransferHandler> { this.applicable = applicable; } - public ResultImpl(Component error, IntList integers, int color) { + public ResultImpl(Component error, int color) { this.successful = false; this.applicable = true; this.error = error; - if (integers != null) - this.integers = integers; this.color = color; } @@ -255,6 +270,12 @@ public interface TransferHandler extends Comparable<TransferHandler> { } @Override + public Result errorRenderer(Object data) { + this.errorRenderer = data; + return this; + } + + @Override public boolean isSuccessful() { return successful; } @@ -280,8 +301,17 @@ public interface TransferHandler extends Comparable<TransferHandler> { } @Override - public IntList getIntegers() { - return integers; + @Environment(EnvType.CLIENT) + public TransferHandlerErrorRenderer getErrorRenderer(TransferHandler handler, Context context) { + if (errorRenderer == null) return null; + return handler.provideErrorRenderer(context, errorRenderer); + } + + @Override + public void fillTooltip(List<Component> components) { + if (!isSuccessful() && isApplicable()) { + components.add(getError()); + } } } diff --git a/api/src/main/java/me/shedaniel/rei/api/client/registry/transfer/TransferHandlerErrorRenderer.java b/api/src/main/java/me/shedaniel/rei/api/client/registry/transfer/TransferHandlerErrorRenderer.java new file mode 100644 index 000000000..1d683ba41 --- /dev/null +++ b/api/src/main/java/me/shedaniel/rei/api/client/registry/transfer/TransferHandlerErrorRenderer.java @@ -0,0 +1,31 @@ +package me.shedaniel.rei.api.client.registry.transfer; + +import com.mojang.blaze3d.vertex.PoseStack; +import it.unimi.dsi.fastutil.ints.IntList; +import me.shedaniel.math.Rectangle; +import me.shedaniel.rei.api.client.gui.widgets.Widget; +import me.shedaniel.rei.api.client.registry.category.CategoryRegistry; +import me.shedaniel.rei.api.client.registry.display.DisplayCategory; +import me.shedaniel.rei.api.client.registry.display.TransferDisplayCategory; +import me.shedaniel.rei.api.common.display.Display; +import org.jetbrains.annotations.ApiStatus; + +import java.util.List; +import java.util.Objects; + +@ApiStatus.Experimental +@FunctionalInterface +public interface TransferHandlerErrorRenderer { + void render(PoseStack matrices, int mouseX, int mouseY, float delta, List<Widget> widgets, Rectangle bounds, Display display); + + @ApiStatus.Internal + static TransferHandlerErrorRenderer forRedSlots(IntList redSlots) { + return (matrices, mouseX, mouseY, delta, widgets, bounds, display) -> { + DisplayCategory<?> category = Objects.requireNonNull(CategoryRegistry.getInstance().get(display.getCategoryIdentifier())) + .getCategory(); + if (category instanceof TransferDisplayCategory) { + ((TransferDisplayCategory<Display>) category).renderRedSlots(matrices, widgets, bounds, display, redSlots); + } + }; + } +} diff --git a/api/src/main/java/me/shedaniel/rei/api/common/display/Display.java b/api/src/main/java/me/shedaniel/rei/api/common/display/Display.java index 1ee2515e3..8b2b2ee22 100644 --- a/api/src/main/java/me/shedaniel/rei/api/common/display/Display.java +++ b/api/src/main/java/me/shedaniel/rei/api/common/display/Display.java @@ -25,6 +25,8 @@ package me.shedaniel.rei.api.common.display; import me.shedaniel.rei.api.common.category.CategoryIdentifier; import me.shedaniel.rei.api.common.entry.EntryIngredient; +import me.shedaniel.rei.api.common.transfer.info.MenuInfo; +import me.shedaniel.rei.api.common.transfer.info.MenuSerializationContext; import me.shedaniel.rei.impl.display.DisplaySpec; import net.minecraft.resources.ResourceLocation; import org.jetbrains.annotations.ApiStatus; @@ -47,6 +49,10 @@ public interface Display extends DisplaySpec { */ List<EntryIngredient> getInputEntries(); + default List<EntryIngredient> getInputEntries(MenuSerializationContext<?, ?, ?> context, MenuInfo<?, ?> info, boolean fill) { + return getInputEntries(); + } + /** * @return a list of outputs */ diff --git a/api/src/main/java/me/shedaniel/rei/api/common/transfer/info/MenuInfo.java b/api/src/main/java/me/shedaniel/rei/api/common/transfer/info/MenuInfo.java index b5ed1de67..4fa19f4b2 100644 --- a/api/src/main/java/me/shedaniel/rei/api/common/transfer/info/MenuInfo.java +++ b/api/src/main/java/me/shedaniel/rei/api/common/transfer/info/MenuInfo.java @@ -23,6 +23,11 @@ package me.shedaniel.rei.api.common.transfer.info; +import com.mojang.blaze3d.vertex.PoseStack; +import it.unimi.dsi.fastutil.ints.IntList; +import me.shedaniel.math.Rectangle; +import me.shedaniel.rei.api.client.gui.widgets.Slot; +import me.shedaniel.rei.api.client.gui.widgets.Widget; import me.shedaniel.rei.api.common.category.CategoryIdentifier; import me.shedaniel.rei.api.common.display.Display; import me.shedaniel.rei.api.common.display.DisplaySerializerRegistry; @@ -36,10 +41,12 @@ import me.shedaniel.rei.api.common.transfer.info.stack.SlotAccessor; import me.shedaniel.rei.api.common.util.CollectionUtils; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; +import net.minecraft.client.gui.GuiComponent; import net.minecraft.nbt.CompoundTag; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.item.ItemStack; +import org.jetbrains.annotations.ApiStatus; import java.util.Collections; import java.util.List; @@ -119,16 +126,30 @@ public interface MenuInfo<T extends AbstractContainerMenu, D extends Display> ex * Returns the inputs of the {@link Display}. The nested lists are possible stacks for that specific slot. * * @param context the context of the transfer + * @param fill whether this call is for a fill or not, if it is for a fill, the returned list should be aligned for the menu, + * otherwise it should be aligned for the display category * @return the list of lists of items */ - default List<List<ItemStack>> getInputs(MenuInfoContext<T, ?, D> context) { + default List<List<ItemStack>> getInputs(MenuInfoContext<T, ?, D> context, boolean fill) { if (context.getDisplay() == null) return Collections.emptyList(); - return CollectionUtils.map(context.getDisplay().getInputEntries(), inputEntry -> + return CollectionUtils.map(context.getDisplay().getInputEntries(context, this, fill), inputEntry -> CollectionUtils.<EntryStack<?>, ItemStack>filterAndMap(inputEntry, stack -> stack.getType() == VanillaEntryTypes.ITEM, EntryStack::castValue)); } /** + * Returns the inputs of the {@link Display}. The nested lists are possible stacks for that specific slot. + * + * @param context the context of the transfer + * @return the list of lists of items + */ + @Deprecated + @ApiStatus.ScheduledForRemoval + default List<List<ItemStack>> getInputs(MenuInfoContext<T, ?, D> context) { + return getInputs(context, false); + } + + /** * Serializes the {@link Display} as {@link CompoundTag}, sent to the server for further info for the transfer. * * @param context the context of the transfer @@ -150,4 +171,35 @@ public interface MenuInfo<T extends AbstractContainerMenu, D extends Display> ex default D read(MenuSerializationContext<T, ?, D> context, CompoundTag tag) { return DisplaySerializerRegistry.getInstance().read(context.getCategoryIdentifier(), tag); } + + /** + * Renders the missing ingredients of the transfer. + * The indices of the missing stacks are provided, this aligns with the list returned by {@link #getInputs(MenuInfoContext, boolean)}. + * + * @param context the context of the transfer + * @param inputs the list of inputs + * @param missingIndices the indices of the missing stacks + * @param matrices the rendering transforming matrices + * @param mouseX the mouse x position + * @param mouseY the mouse y position + * @param delta the delta frame time + * @param widgets the widgets set-up by the category + * @param bounds the bounds of the display + */ + @Environment(EnvType.CLIENT) + default void renderMissingInput(MenuInfoContext<T, ?, D> context, List<List<ItemStack>> inputs, IntList missingIndices, PoseStack matrices, int mouseX, int mouseY, + float delta, List<Widget> widgets, Rectangle bounds) { + int i = 0; + for (Widget widget : widgets) { + if (widget instanceof Slot && ((Slot) widget).getNoticeMark() == Slot.INPUT) { + if (missingIndices.contains(i++)) { + matrices.pushPose(); + matrices.translate(0, 0, 400); + Rectangle innerBounds = ((Slot) widget).getInnerBounds(); + GuiComponent.fill(matrices, innerBounds.x, innerBounds.y, innerBounds.getMaxX(), innerBounds.getMaxY(), 0x40ff0000); + matrices.popPose(); + } + } + } + } } 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 aa4ac5037..0d20cf7f9 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 @@ -323,6 +323,29 @@ public class CollectionUtils { public int size() { return realSize; } + + @Override + public Iterator<T> iterator() { + Iterator<T> iterator = super.iterator(); + return new Iterator<T>() { + boolean endReached = false; + + @Override + public boolean hasNext() { + return iterator.hasNext() && !endReached; + } + + @Override + public T next() { + try { + return iterator.next(); + } catch (NoSuchElementException e) { + endReached = true; + return null; + } + } + }; + } }; } }; |
