aboutsummaryrefslogtreecommitdiff
path: root/api/src/main
diff options
context:
space:
mode:
authorshedaniel <daniel@shedaniel.me>2021-06-27 16:38:33 +0800
committershedaniel <daniel@shedaniel.me>2021-06-27 16:38:33 +0800
commitc0c2bd8d259b9ccc55d2111d806220753b9d89bd (patch)
tree52059a5dd2bcc6320e750a48e1b1e4c22adebbca /api/src/main
parentf6b10e75179c8237cab172d757238d1404273187 (diff)
downloadRoughlyEnoughItems-c0c2bd8d259b9ccc55d2111d806220753b9d89bd.tar.gz
RoughlyEnoughItems-c0c2bd8d259b9ccc55d2111d806220753b9d89bd.tar.bz2
RoughlyEnoughItems-c0c2bd8d259b9ccc55d2111d806220753b9d89bd.zip
Fix #572 & add getDraggableAcceptingBounds
Diffstat (limited to 'api/src/main')
-rw-r--r--api/src/main/java/me/shedaniel/rei/api/client/favorites/FavoriteEntry.java28
-rw-r--r--api/src/main/java/me/shedaniel/rei/api/client/favorites/FavoriteEntryType.java22
-rw-r--r--api/src/main/java/me/shedaniel/rei/api/client/gui/drag/DraggableStackVisitor.java97
-rw-r--r--api/src/main/java/me/shedaniel/rei/api/client/gui/drag/DraggableStackVisitorWidget.java67
-rw-r--r--api/src/main/java/me/shedaniel/rei/api/common/entry/EntryStack.java10
-rw-r--r--api/src/main/java/me/shedaniel/rei/impl/ClientInternals.java9
6 files changed, 205 insertions, 28 deletions
diff --git a/api/src/main/java/me/shedaniel/rei/api/client/favorites/FavoriteEntry.java b/api/src/main/java/me/shedaniel/rei/api/client/favorites/FavoriteEntry.java
index 336a80088..856cea841 100644
--- a/api/src/main/java/me/shedaniel/rei/api/client/favorites/FavoriteEntry.java
+++ b/api/src/main/java/me/shedaniel/rei/api/client/favorites/FavoriteEntry.java
@@ -23,6 +23,8 @@
package me.shedaniel.rei.api.client.favorites;
+import com.mojang.serialization.DataResult;
+import com.mojang.serialization.Lifecycle;
import me.shedaniel.rei.api.client.gui.Renderer;
import me.shedaniel.rei.api.common.entry.EntryStack;
import me.shedaniel.rei.impl.ClientInternals;
@@ -44,16 +46,29 @@ public abstract class FavoriteEntry {
private final UUID uuid = UUID.randomUUID();
public static FavoriteEntry delegate(Supplier<FavoriteEntry> supplier, @Nullable Supplier<CompoundTag> toJson) {
+ return delegateResult(() -> DataResult.success(supplier.get(), Lifecycle.stable()), toJson);
+ }
+
+ public static FavoriteEntry delegateResult(Supplier<DataResult<FavoriteEntry>> supplier, @Nullable Supplier<CompoundTag> toJson) {
return ClientInternals.delegateFavoriteEntry(supplier, toJson);
}
@Nullable
public static FavoriteEntry read(CompoundTag object) {
+ return readResult(object).result().orElse(null);
+ }
+
+ public static DataResult<FavoriteEntry> readResult(CompoundTag object) {
return ClientInternals.favoriteEntryFromJson(object);
}
+ public static FavoriteEntry readDelegated(CompoundTag object) {
+ CompoundTag copy = object.copy();
+ return delegateResult(() -> readResult(object), () -> copy);
+ }
+
public static FavoriteEntry fromEntryStack(EntryStack<?> stack) {
- return delegate(() -> FavoriteEntryType.registry().get(FavoriteEntryType.ENTRY_STACK).fromArgs(stack), null);
+ return delegateResult(() -> FavoriteEntryType.registry().get(FavoriteEntryType.ENTRY_STACK).fromArgsResult(stack), null);
}
public static boolean isEntryInvalid(@Nullable FavoriteEntry entry) {
@@ -89,9 +104,14 @@ public abstract class FavoriteEntry {
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof FavoriteEntry that)) return false;
- FavoriteEntry unwrapped = getUnwrapped();
- FavoriteEntry thatUnwrapped = that.getUnwrapped();
- return unwrapped == thatUnwrapped || unwrapped.isSame(thatUnwrapped);
+ try {
+ FavoriteEntry unwrapped = getUnwrapped();
+ FavoriteEntry thatUnwrapped = that.getUnwrapped();
+ return unwrapped == thatUnwrapped || unwrapped.isSame(thatUnwrapped);
+ } catch (Throwable throwable) {
+ throwable.printStackTrace();
+ return false;
+ }
}
@Override
diff --git a/api/src/main/java/me/shedaniel/rei/api/client/favorites/FavoriteEntryType.java b/api/src/main/java/me/shedaniel/rei/api/client/favorites/FavoriteEntryType.java
index fd05c2bbd..7c60253b9 100644
--- a/api/src/main/java/me/shedaniel/rei/api/client/favorites/FavoriteEntryType.java
+++ b/api/src/main/java/me/shedaniel/rei/api/client/favorites/FavoriteEntryType.java
@@ -23,6 +23,8 @@
package me.shedaniel.rei.api.client.favorites;
+import com.mojang.serialization.DataResult;
+import com.mojang.serialization.Lifecycle;
import me.shedaniel.rei.api.client.plugins.REIClientPlugin;
import me.shedaniel.rei.api.common.entry.EntryStack;
import me.shedaniel.rei.api.common.plugins.PluginManager;
@@ -48,9 +50,25 @@ public interface FavoriteEntryType<T extends FavoriteEntry> {
return PluginManager.getClientInstance().get(FavoriteEntryType.Registry.class);
}
- T read(CompoundTag object);
+ @ApiStatus.ScheduledForRemoval
+ @Deprecated
+ default T read(CompoundTag object) {
+ throw new UnsupportedOperationException("Implementation of FavoriteEntryType must override #read or #readResult");
+ }
+
+ default DataResult<T> readResult(CompoundTag object) {
+ return DataResult.success(read(object), Lifecycle.stable());
+ }
- T fromArgs(Object... args);
+ @ApiStatus.ScheduledForRemoval
+ @Deprecated
+ default T fromArgs(Object... args) {
+ throw new UnsupportedOperationException("Implementation of FavoriteEntryType must override #fromArgs or #fromArgsResult");
+ }
+
+ default DataResult<T> fromArgsResult(Object... args) {
+ return DataResult.success(fromArgs(args), Lifecycle.stable());
+ }
CompoundTag save(T entry, CompoundTag tag);
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 a3eeebdbf..ae973be16 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,10 +23,16 @@
package me.shedaniel.rei.api.client.gui.drag;
+import me.shedaniel.math.Rectangle;
import net.minecraft.client.gui.screens.Screen;
+import net.minecraft.world.phys.shapes.Shapes;
+import net.minecraft.world.phys.shapes.VoxelShape;
+import org.jetbrains.annotations.ApiStatus;
import java.util.Optional;
import java.util.function.Supplier;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
/**
* A visitor for accepting {@link DraggableStack} to the screen.
@@ -45,19 +51,60 @@ public interface DraggableStackVisitor<T extends Screen> extends Comparable<Drag
}
@Override
- public Optional<Acceptor> visitDraggedStack(DraggingContext<T> context, DraggableStack stack) {
+ public boolean acceptDraggedStack(DraggingContext<T> context, DraggableStack stack) {
for (DraggableStackVisitor<T> visitor : visitors.get()) {
if (visitor.isHandingScreen(context.getScreen())) {
- Optional<Acceptor> acceptor = visitor.visitDraggedStack(context, stack);
- if (acceptor.isPresent()) return acceptor;
+ boolean visited = visitor.acceptDraggedStack(context, stack);
+ if (visited) return true;
}
}
- return Optional.empty();
+ return false;
+ }
+
+ @Override
+ public Stream<BoundsProvider> getDraggableAcceptingBounds(DraggingContext<T> context, DraggableStack stack) {
+ return StreamSupport.stream(visitors.get().spliterator(), false)
+ .filter(visitor -> visitor.isHandingScreen(context.getScreen()))
+ .flatMap(visitor -> visitor.getDraggableAcceptingBounds(context, stack));
}
};
}
- Optional<Acceptor> visitDraggedStack(DraggingContext<T> context, DraggableStack stack);
+ @Deprecated(forRemoval = true)
+ @ApiStatus.ScheduledForRemoval
+ default Optional<Acceptor> visitDraggedStack(DraggingContext<T> context, DraggableStack stack) {
+ return Optional.empty();
+ }
+
+ /**
+ * Accepts a dragged stack, implementations of this function should check if the {@code context} is within
+ * boundaries of the accepting boundaries.
+ *
+ * @param context the context of the current dragged stack on the overlay
+ * @param stack the stack being dragged
+ * @return whether the stack is accepted by the visitor
+ */
+ default boolean acceptDraggedStack(DraggingContext<T> context, DraggableStack stack) {
+ Optional<Acceptor> acceptor = visitDraggedStack(context, stack);
+ if (acceptor.isPresent()) {
+ acceptor.get().accept(stack);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Returns the accepting bounds for the dragging stack, this should only be called once on drag.
+ * The bounds are used to overlay to indicate to the users that the area is accepting entries.
+ *
+ * @param context the context of the current dragged stack on the overlay
+ * @param stack the stack being dragged
+ * @return the accepting bounds for the dragging stack in a stream
+ */
+ default Stream<BoundsProvider> getDraggableAcceptingBounds(DraggingContext<T> context, DraggableStack stack) {
+ return Stream.empty();
+ }
<R extends Screen> boolean isHandingScreen(R screen);
@@ -83,4 +130,44 @@ public interface DraggableStackVisitor<T extends Screen> extends Comparable<Drag
interface Acceptor {
void accept(DraggableStack stack);
}
+
+ @FunctionalInterface
+ interface BoundsProvider {
+ static VoxelShape fromRectangle(Rectangle bounds) {
+ return Shapes.box(bounds.x, bounds.y, 0, bounds.getMaxX(), bounds.getMaxY(), 0.1);
+ }
+
+ static BoundsProvider ofRectangle(Rectangle bounds) {
+ return ofShape(fromRectangle(bounds));
+ }
+
+ static BoundsProvider ofRectangles(Iterable<Rectangle> bounds) {
+ VoxelShape shape = StreamSupport.stream(bounds.spliterator(), false)
+ .map(BoundsProvider::fromRectangle)
+ .reduce(Shapes.empty(), Shapes::or);
+ return ofShape(shape);
+ }
+
+ static BoundsProvider ofShape(VoxelShape shape) {
+ return () -> shape;
+ }
+
+ static BoundsProvider ofShapes(Iterable<VoxelShape> shapes) {
+ VoxelShape shape = StreamSupport.stream(shapes.spliterator(), false)
+ .reduce(Shapes.empty(), Shapes::or);
+ return ofShape(shape);
+ }
+
+ static BoundsProvider empty() {
+ return Shapes::empty;
+ }
+
+ static BoundsProvider concat(Iterable<BoundsProvider> providers) {
+ return () -> StreamSupport.stream(providers.spliterator(), false)
+ .map(BoundsProvider::bounds)
+ .reduce(Shapes.empty(), Shapes::or);
+ }
+
+ VoxelShape bounds();
+ }
}
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
index e1cd311d4..7bb813d4d 100644
--- 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
@@ -24,37 +24,79 @@
package me.shedaniel.rei.api.client.gui.drag;
import net.minecraft.client.gui.screens.Screen;
+import org.jetbrains.annotations.ApiStatus;
import java.util.Optional;
import java.util.function.Function;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
/**
* 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<DraggingContext<Screen>, Iterable<DraggableStackVisitorWidget>> providers) {
- return (context, stack) -> {
- for (DraggableStackVisitorWidget visitor : providers.apply(context)) {
- Optional<DraggableStackVisitor.Acceptor> acceptor = visitor.visitDraggedStack(context, stack);
- if (acceptor.isPresent()) return acceptor;
+ return new DraggableStackVisitorWidget() {
+ @Override
+ public boolean acceptDraggedStack(DraggingContext<Screen> context, DraggableStack stack) {
+ return StreamSupport.stream(providers.apply(context).spliterator(), false)
+ .anyMatch(visitor -> visitor.acceptDraggedStack(context, stack));
+ }
+
+ @Override
+ public Stream<DraggableStackVisitor.BoundsProvider> getDraggableAcceptingBounds(DraggingContext<Screen> context, DraggableStack stack) {
+ return StreamSupport.stream(providers.apply(context).spliterator(), false)
+ .flatMap(visitor -> visitor.getDraggableAcceptingBounds(context, stack));
}
- return Optional.empty();
};
}
- Optional<DraggableStackVisitor.Acceptor> visitDraggedStack(DraggingContext<Screen> context, DraggableStack stack);
+ @ApiStatus.ScheduledForRemoval
+ @Deprecated(forRemoval = true)
+ default Optional<DraggableStackVisitor.Acceptor> visitDraggedStack(DraggingContext<Screen> context, DraggableStack stack) {
+ return Optional.empty();
+ }
+
+ /**
+ * Accepts a dragged stack, implementations of this function should check if the {@code context} is within
+ * boundaries of the widget.
+ *
+ * @param context the context of the current dragged stack on the overlay
+ * @param stack the stack being dragged
+ * @return whether the stack is accepted by the widget
+ */
+ default boolean acceptDraggedStack(DraggingContext<Screen> context, DraggableStack stack) {
+ Optional<DraggableStackVisitor.Acceptor> acceptor = visitDraggedStack(context, stack);
+ if (acceptor.isPresent()) {
+ acceptor.get().accept(stack);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Returns the accepting bounds for the dragging stack, this should only be called once on drag.
+ * The bounds are used to overlay to indicate to the users that the widget is accepting entries.
+ *
+ * @param context the context of the current dragged stack on the overlay
+ * @param stack the stack being dragged
+ * @return the accepting bounds for the dragging stack in a stream
+ */
+ default Stream<DraggableStackVisitor.BoundsProvider> getDraggableAcceptingBounds(DraggingContext<Screen> context, DraggableStack stack) {
+ return Stream.empty();
+ }
static DraggableStackVisitor<Screen> toVisitor(DraggableStackVisitorWidget widget) {
return toVisitor(widget, 0.0);
}
static DraggableStackVisitor<Screen> toVisitor(DraggableStackVisitorWidget widget, double priority) {
- return new DraggableStackVisitor<Screen>() {
+ return new DraggableStackVisitor<>() {
@Override
- public Optional<Acceptor> visitDraggedStack(DraggingContext<Screen> context, DraggableStack stack) {
- return widget.visitDraggedStack(context, stack);
+ public boolean acceptDraggedStack(DraggingContext<Screen> context, DraggableStack stack) {
+ return widget.acceptDraggedStack(context, stack);
}
@Override
@@ -63,6 +105,11 @@ public interface DraggableStackVisitorWidget {
}
@Override
+ public Stream<BoundsProvider> getDraggableAcceptingBounds(DraggingContext<Screen> context, DraggableStack stack) {
+ return widget.getDraggableAcceptingBounds(context, stack);
+ }
+
+ @Override
public double getPriority() {
return priority;
}
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 9ac571bdb..76ff50f98 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
@@ -77,15 +77,19 @@ public interface EntryStack<T> extends TextRepresentable, Renderer {
@Nullable
default CompoundTag save() {
- EntrySerializer<T> serializer = getDefinition().getSerializer();
- if (serializer != null && serializer.supportSaving()) {
- CompoundTag tag = serializer.save(this, getValue());
+ if (supportSaving()) {
+ CompoundTag tag = getDefinition().getSerializer().save(this, getValue());
tag.putString("type", getType().getId().toString());
return tag;
}
throw new UnsupportedOperationException(getType().getId() + " does not support serialization!");
}
+ default boolean supportSaving() {
+ EntrySerializer<T> serializer = getDefinition().getSerializer();
+ return serializer != null && serializer.supportSaving();
+ }
+
@Nullable
@Environment(EnvType.CLIENT)
Tooltip getTooltip(Point mouse, boolean appendModName);
diff --git a/api/src/main/java/me/shedaniel/rei/impl/ClientInternals.java b/api/src/main/java/me/shedaniel/rei/impl/ClientInternals.java
index daccb744d..d9cb5eaa8 100644
--- a/api/src/main/java/me/shedaniel/rei/impl/ClientInternals.java
+++ b/api/src/main/java/me/shedaniel/rei/impl/ClientInternals.java
@@ -23,6 +23,7 @@
package me.shedaniel.rei.impl;
+import com.mojang.serialization.DataResult;
import me.shedaniel.math.Point;
import me.shedaniel.math.Rectangle;
import me.shedaniel.rei.api.client.ClientHelper;
@@ -60,8 +61,8 @@ public final class ClientInternals {
private static Supplier<ViewSearchBuilder> viewSearchBuilder = ClientInternals::throwNotSetup;
private static Supplier<PluginManager<REIClientPlugin>> clientPluginManager = ClientInternals::throwNotSetup;
private static Supplier<EntryRenderer<?>> emptyEntryRenderer = ClientInternals::throwNotSetup;
- private static BiFunction<Supplier<FavoriteEntry>, Supplier<CompoundTag>, FavoriteEntry> delegateFavoriteEntry = (supplier, toJson) -> throwNotSetup();
- private static Function<CompoundTag, FavoriteEntry> favoriteEntryFromJson = (object) -> throwNotSetup();
+ private static BiFunction<Supplier<DataResult<FavoriteEntry>>, Supplier<CompoundTag>, FavoriteEntry> delegateFavoriteEntry = (supplier, toJson) -> throwNotSetup();
+ private static Function<CompoundTag, DataResult<FavoriteEntry>> favoriteEntryFromJson = (object) -> throwNotSetup();
private static Function<Boolean, ClickArea.Result> clickAreaHandlerResult = (result) -> throwNotSetup();
private static BiConsumer<List<ClientTooltipComponent>, TooltipComponent> clientTooltipComponentProvider = (tooltip, result) -> throwNotSetup();
private static BiFunction<@Nullable Point, Collection<Tooltip.Entry>, Tooltip> tooltipProvider = (point, texts) -> throwNotSetup();
@@ -130,11 +131,11 @@ public final class ClientInternals {
return tooltipEntryProvider.apply(component);
}
- public static FavoriteEntry delegateFavoriteEntry(Supplier<FavoriteEntry> supplier, Supplier<CompoundTag> toJoin) {
+ public static FavoriteEntry delegateFavoriteEntry(Supplier<DataResult<FavoriteEntry>> supplier, Supplier<CompoundTag> toJoin) {
return delegateFavoriteEntry.apply(supplier, toJoin);
}
- public static FavoriteEntry favoriteEntryFromJson(CompoundTag tag) {
+ public static DataResult<FavoriteEntry> favoriteEntryFromJson(CompoundTag tag) {
return favoriteEntryFromJson.apply(tag);
}