aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/src/main/java/me/shedaniel/rei/api/client/registry/screen/DisplayBoundsProvider.java2
-rw-r--r--api/src/main/java/me/shedaniel/rei/api/client/registry/screen/OverlayDecider.java7
-rw-r--r--default-plugin/src/main/java/me/shedaniel/rei/plugin/client/DefaultClientPlugin.java14
-rw-r--r--forge/build.gradle4
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java7
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/ScreenOverlayImpl.java27
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryListWidget.java56
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/registry/display/DisplayRegistryImpl.java93
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/registry/screen/ScreenRegistryImpl.java41
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/plugin/client/runtime/DefaultClientRuntimePlugin.java19
10 files changed, 199 insertions, 71 deletions
diff --git a/api/src/main/java/me/shedaniel/rei/api/client/registry/screen/DisplayBoundsProvider.java b/api/src/main/java/me/shedaniel/rei/api/client/registry/screen/DisplayBoundsProvider.java
index 4e32def9e..fcda7a01d 100644
--- a/api/src/main/java/me/shedaniel/rei/api/client/registry/screen/DisplayBoundsProvider.java
+++ b/api/src/main/java/me/shedaniel/rei/api/client/registry/screen/DisplayBoundsProvider.java
@@ -26,6 +26,7 @@ package me.shedaniel.rei.api.client.registry.screen;
import me.shedaniel.math.Rectangle;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
+import org.jetbrains.annotations.Nullable;
@Environment(EnvType.CLIENT)
public interface DisplayBoundsProvider<T> extends OverlayDecider {
@@ -33,5 +34,6 @@ public interface DisplayBoundsProvider<T> extends OverlayDecider {
* @param screen the screen
* @return the boundary of the base container panel.
*/
+ @Nullable
Rectangle getScreenBounds(T screen);
} \ No newline at end of file
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 d8f31b627..8fcb2c456 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
@@ -29,6 +29,7 @@ import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.world.InteractionResult;
+import org.jetbrains.annotations.ApiStatus;
import static net.minecraft.world.InteractionResult.PASS;
@@ -39,10 +40,16 @@ import static net.minecraft.world.InteractionResult.PASS;
public interface OverlayDecider extends Comparable<OverlayDecider> {
<R extends Screen> boolean isHandingScreen(Class<R> screen);
+ @ApiStatus.ScheduledForRemoval
+ @Deprecated
default InteractionResult shouldScreenBeOverlaid(Class<?> screen) {
return InteractionResult.PASS;
}
+ default <R extends Screen> InteractionResult shouldScreenBeOverlaid(R screen) {
+ return shouldScreenBeOverlaid(screen.getClass());
+ }
+
/**
* Gets the priority of the handler, the higher it is, the earlier it is called.
*
diff --git a/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/DefaultClientPlugin.java b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/DefaultClientPlugin.java
index 15c55430d..87d7af248 100644
--- a/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/DefaultClientPlugin.java
+++ b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/DefaultClientPlugin.java
@@ -39,7 +39,6 @@ import me.shedaniel.rei.api.client.plugins.REIClientPlugin;
import me.shedaniel.rei.api.client.registry.category.CategoryRegistry;
import me.shedaniel.rei.api.client.registry.display.DisplayRegistry;
import me.shedaniel.rei.api.client.registry.entry.EntryRegistry;
-import me.shedaniel.rei.api.client.registry.screen.DisplayBoundsProvider;
import me.shedaniel.rei.api.client.registry.screen.ExclusionZones;
import me.shedaniel.rei.api.client.registry.screen.ScreenRegistry;
import me.shedaniel.rei.api.client.registry.transfer.TransferHandlerRegistry;
@@ -74,7 +73,6 @@ import me.shedaniel.rei.plugin.common.displays.crafting.DefaultCustomDisplay;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.Minecraft;
-import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.gui.screens.inventory.*;
import net.minecraft.client.gui.screens.recipebook.RecipeUpdateListener;
import net.minecraft.core.Registry;
@@ -343,18 +341,6 @@ public class DefaultClientPlugin implements REIClientPlugin, BuiltinClientPlugin
@Override
public void registerScreens(ScreenRegistry registry) {
- registry.registerDecider(new DisplayBoundsProvider<AbstractContainerScreen<?>>() {
- @Override
- public Rectangle getScreenBounds(AbstractContainerScreen<?> screen) {
- return new Rectangle(screen.leftPos, screen.topPos, screen.imageWidth, screen.imageHeight);
- }
-
- @Override
- public <R extends Screen> boolean isHandingScreen(Class<R> screen) {
- return AbstractContainerScreen.class.isAssignableFrom(screen);
- }
- });
-
registry.registerContainerClickArea(new Rectangle(88, 32, 28, 23), CraftingScreen.class, CRAFTING);
registry.registerContainerClickArea(new Rectangle(137, 29, 10, 13), InventoryScreen.class, CRAFTING);
registry.registerContainerClickArea(new Rectangle(97, 16, 14, 30), BrewingStandScreen.class, BREWING);
diff --git a/forge/build.gradle b/forge/build.gradle
index 008abfcdc..a5c2c75ee 100644
--- a/forge/build.gradle
+++ b/forge/build.gradle
@@ -88,8 +88,8 @@ dependencies {
// modRuntime("curse.maven:titanium-287342:3346366")
// modRuntime("curse.maven:extended-crafting-268387:3470453")
// modRuntime("curse.maven:cucumber-272335:3349690")
- // modRuntime("curse.maven:crafttweaker-239197:3494644")
- // modRuntime("curse.maven:jeitweaker-368718:3468722")
+ modRuntime("curse.maven:crafttweaker-239197:3602440")
+ modRuntime("curse.maven:jeitweaker-368718:3602846")
// modRuntime("curse.maven:eidolon-429625:3157832")
// modRuntime("curse.maven:token-enchanter-444421:3449483")
// modRuntime("curse.maven:silent-lib-242998:3400030")
diff --git a/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java b/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java
index 4c493fa39..ff32b1753 100644
--- a/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java
+++ b/runtime/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCoreClient.java
@@ -255,11 +255,8 @@ public class RoughlyEnoughItemsCoreClient {
private static boolean _shouldReturn(Screen screen) {
try {
- Class<? extends Screen> screenClass = screen.getClass();
- for (OverlayDecider decider : ScreenRegistry.getInstance().getDeciders()) {
- if (!decider.isHandingScreen(screen.getClass()))
- continue;
- InteractionResult result = decider.shouldScreenBeOverlaid(screenClass);
+ for (OverlayDecider decider : ScreenRegistry.getInstance().getDeciders(screen)) {
+ InteractionResult result = decider.shouldScreenBeOverlaid(screen);
if (result != InteractionResult.PASS) {
return result == InteractionResult.FAIL || REIRuntime.getInstance().getPreviousScreen() == null;
}
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/ScreenOverlayImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/ScreenOverlayImpl.java
index 0c71a7cbd..d9c57ea73 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/ScreenOverlayImpl.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/ScreenOverlayImpl.java
@@ -108,6 +108,7 @@ public class ScreenOverlayImpl extends ScreenOverlay {
private final List<Widget> widgets = Lists.newLinkedList();
public boolean shouldReload = false;
public boolean shouldReloadSearch = false;
+ private Rectangle screenBounds;
private Rectangle bounds;
private Window window;
private Button leftButton, rightButton;
@@ -220,6 +221,10 @@ public class ScreenOverlayImpl extends ScreenOverlay {
return draggingStack;
}
+ protected boolean hasSpace() {
+ return !this.bounds.isEmpty();
+ }
+
public void init(boolean useless) {
init();
}
@@ -234,8 +239,8 @@ public class ScreenOverlayImpl extends ScreenOverlay {
this.children().clear();
this.closeOverlayMenu();
this.window = Minecraft.getInstance().getWindow();
+ this.screenBounds = ScreenRegistry.getInstance().getScreenBounds(Minecraft.getInstance().screen);
this.bounds = calculateOverlayBounds();
- widgets.add(ENTRY_LIST_WIDGET);
if (ConfigObject.getInstance().isFavoritesEnabled()) {
if (favoritesListWidget == null) {
favoritesListWidget = new FavoritesListWidget();
@@ -244,6 +249,7 @@ public class ScreenOverlayImpl extends ScreenOverlay {
widgets.add(favoritesListWidget);
}
ENTRY_LIST_WIDGET.updateArea(this.bounds, REIRuntimeImpl.getSearchField() == null ? "" : REIRuntimeImpl.getSearchField().getText());
+ widgets.add(ENTRY_LIST_WIDGET);
REIRuntimeImpl.getSearchField().getBounds().setBounds(getSearchFieldArea());
this.widgets.add(REIRuntimeImpl.getSearchField());
REIRuntimeImpl.getSearchField().setResponder(s -> ENTRY_LIST_WIDGET.updateSearch(s, false));
@@ -472,6 +478,10 @@ public class ScreenOverlayImpl extends ScreenOverlay {
return bounds;
}
+ public Rectangle getScreenBounds() {
+ return screenBounds;
+ }
+
@Override
public void render(PoseStack matrices, int mouseX, int mouseY, float delta) {
if (shouldReload || !calculateOverlayBounds().equals(bounds)) {
@@ -502,6 +512,7 @@ public class ScreenOverlayImpl extends ScreenOverlay {
}
matrices.popPose();
}
+ if (!hasSpace()) return;
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
this.renderWidgets(matrices, mouseX, mouseY, delta);
if (ConfigObject.getInstance().areClickableRecipeArrowsEnabled()) {
@@ -543,7 +554,7 @@ public class ScreenOverlayImpl extends ScreenOverlay {
}
public void lateRender(PoseStack matrices, int mouseX, int mouseY, float delta) {
- if (REIRuntime.getInstance().isOverlayVisible()) {
+ if (REIRuntime.getInstance().isOverlayVisible() && hasSpace()) {
REIRuntimeImpl.getSearchField().laterRender(matrices, mouseX, mouseY, delta);
for (Widget widget : widgets) {
if (widget instanceof LateRenderable && (overlayMenu == null || overlayMenu.wrappedMenu != widget))
@@ -643,6 +654,7 @@ public class ScreenOverlayImpl extends ScreenOverlay {
@Override
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
+ if (!hasSpace()) return false;
if (REIRuntime.getInstance().isOverlayVisible()) {
if (keyCode == 256 && choosePageWidget != null) {
choosePageWidget = null;
@@ -691,16 +703,17 @@ public class ScreenOverlayImpl extends ScreenOverlay {
}
@Override
- public boolean charTyped(char char_1, int int_1) {
+ public boolean charTyped(char character, int modifiers) {
if (!REIRuntime.getInstance().isOverlayVisible())
return false;
+ if (!hasSpace()) return false;
if (choosePageWidget != null) {
- return choosePageWidget.charTyped(char_1, int_1);
+ return choosePageWidget.charTyped(character, modifiers);
}
- if (REIRuntimeImpl.getSearchField().charTyped(char_1, int_1))
+ if (REIRuntimeImpl.getSearchField().charTyped(character, modifiers))
return true;
for (GuiEventListener listener : widgets)
- if (listener != REIRuntimeImpl.getSearchField() && listener.charTyped(char_1, int_1))
+ if (listener != REIRuntimeImpl.getSearchField() && listener.charTyped(character, modifiers))
return true;
return false;
}
@@ -722,6 +735,7 @@ public class ScreenOverlayImpl extends ScreenOverlay {
return false;
}
}
+ if (!hasSpace()) return false;
if (visible && configButton.mouseClicked(mouseX, mouseY, button)) {
this.setFocused(configButton);
if (button == 0)
@@ -807,6 +821,7 @@ public class ScreenOverlayImpl extends ScreenOverlay {
public boolean mouseDragged(double double_1, double double_2, int int_1, double double_3, double double_4) {
if (!REIRuntime.getInstance().isOverlayVisible())
return false;
+ if (!hasSpace()) return false;
if (choosePageWidget != null) {
return choosePageWidget.mouseDragged(double_1, double_2, int_1, double_3, double_4);
}
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryListWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryListWidget.java
index 4796da9d5..71e6983fb 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryListWidget.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryListWidget.java
@@ -72,7 +72,6 @@ import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.util.Mth;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.item.CreativeModeTab;
-import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import org.apache.commons.lang3.mutable.MutableInt;
import org.apache.commons.lang3.mutable.MutableLong;
@@ -148,12 +147,25 @@ public class EntryListWidget extends WidgetWithBounds implements OverlayListWidg
return fit;
}
- private boolean containsChecked(Point point) {
- return containsChecked(point.x, point.y);
+ private boolean containsChecked(Point point, boolean inner) {
+ return containsChecked(point.x, point.y, inner);
}
- private boolean containsChecked(double x, double y) {
- if (!containsMouse(x, y)) return false;
+ @Override
+ public boolean containsMouse(double mouseX, double mouseY) {
+ return hasSpace() && super.containsMouse(mouseX, mouseY);
+ }
+
+ public boolean innerContainsMouse(double mouseX, double mouseY) {
+ return hasSpace() && innerBounds.contains(mouseX, mouseY);
+ }
+
+ private boolean containsChecked(double x, double y, boolean inner) {
+ if (inner) {
+ if (!innerContainsMouse(x, y)) return false;
+ } else {
+ if (!containsMouse(x, y)) return false;
+ }
Minecraft instance = Minecraft.getInstance();
for (OverlayDecider decider : ScreenRegistry.getInstance().getDeciders(instance.screen)) {
InteractionResult result = decider.isInZone(x, y);
@@ -199,7 +211,7 @@ public class EntryListWidget extends WidgetWithBounds implements OverlayListWidg
@Override
public boolean mouseScrolled(double mouseX, double mouseY, double amount) {
- if (bounds.contains(mouseX, mouseY)) {
+ if (containsChecked(mouseX, mouseY, false)) {
if (Screen.hasControlDown()) {
ConfigObjectImpl config = ConfigManagerImpl.getInstance().getConfig();
if (config.setEntrySize(config.getEntrySize() + amount * 0.075)) {
@@ -244,6 +256,8 @@ public class EntryListWidget extends WidgetWithBounds implements OverlayListWidg
@Override
public void render(PoseStack matrices, int mouseX, int mouseY, float delta) {
+ if (!hasSpace()) return;
+
MutableInt size = new MutableInt();
MutableLong time = new MutableLong();
long totalTimeStart = debugTime ? System.nanoTime() : 0;
@@ -320,7 +334,7 @@ public class EntryListWidget extends WidgetWithBounds implements OverlayListWidg
matrices.popPose();
}
- if (containsChecked(mouseX, mouseY) && ClientHelper.getInstance().isCheating() && !(Minecraft.getInstance().screen instanceof DisplayScreen) && !minecraft.player.containerMenu.getCarried().isEmpty() && ClientHelperImpl.getInstance().canDeleteItems()) {
+ if (containsChecked(mouseX, mouseY, false) && ClientHelper.getInstance().isCheating() && !(Minecraft.getInstance().screen instanceof DisplayScreen) && !minecraft.player.containerMenu.getCarried().isEmpty() && ClientHelperImpl.getInstance().canDeleteItems()) {
EntryStack<?> stack = EntryStacks.of(minecraft.player.containerMenu.getCarried().copy());
if (stack.getType() != VanillaEntryTypes.ITEM) {
EntryStack<ItemStack> cheatsAs = stack.cheatsAs();
@@ -345,7 +359,7 @@ public class EntryListWidget extends WidgetWithBounds implements OverlayListWidg
@Override
public boolean mouseDragged(double mouseX, double mouseY, int button, double dx, double dy) {
- if (scrolling.mouseDragged(mouseX, mouseY, button, dx, dy, ConfigObject.getInstance().doesSnapToRows(), entrySize()))
+ if (hasSpace() && scrolling.mouseDragged(mouseX, mouseY, button, dx, dy, ConfigObject.getInstance().doesSnapToRows(), entrySize()))
return true;
return super.mouseDragged(mouseX, mouseY, button, dx, dy);
}
@@ -362,10 +376,10 @@ public class EntryListWidget extends WidgetWithBounds implements OverlayListWidg
}
@Override
- public boolean keyPressed(int int_1, int int_2, int int_3) {
- if (containsChecked(PointHelper.ofMouse()))
+ public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
+ if (containsChecked(PointHelper.ofMouse(), false))
for (Widget widget : widgets)
- if (widget.keyPressed(int_1, int_2, int_3))
+ if (widget.keyPressed(keyCode, scanCode, modifiers))
return true;
return false;
}
@@ -383,6 +397,13 @@ public class EntryListWidget extends WidgetWithBounds implements OverlayListWidg
}
}
+ public boolean hasSpace() {
+ int entrySize = entrySize();
+ int width = innerBounds.width / entrySize;
+ int height = innerBounds.height / entrySize;
+ return width * height > 0;
+ }
+
public void updateEntriesPosition() {
int entrySize = entrySize();
this.innerBounds = updateInnerBounds(bounds);
@@ -481,20 +502,21 @@ public class EntryListWidget extends WidgetWithBounds implements OverlayListWidg
}
@Override
- public boolean mouseClicked(double double_1, double double_2, int int_1) {
+ public boolean mouseClicked(double mouseX, double mouseY, int button) {
+ if (!hasSpace()) return false;
if (ConfigObject.getInstance().isEntryListWidgetScrolled()) {
- if (scrolling.updateDraggingState(double_1, double_2, int_1))
+ if (scrolling.updateDraggingState(mouseX, mouseY, button))
return true;
}
for (Widget widget : children())
- if (widget.mouseClicked(double_1, double_2, int_1))
+ if (widget.mouseClicked(mouseX, mouseY, button))
return true;
return false;
}
@Override
public boolean mouseReleased(double mouseX, double mouseY, int button) {
- if (containsChecked(mouseX, mouseY)) {
+ if (containsChecked(mouseX, mouseY, false)) {
LocalPlayer player = minecraft.player;
if (ClientHelper.getInstance().isCheating() && !(Minecraft.getInstance().screen instanceof DisplayScreen) && player != null && player.containerMenu != null && !player.containerMenu.getCarried().isEmpty() && ClientHelperImpl.getInstance().canDeleteItems()) {
ClientHelper.getInstance().sendDeletePacket();
@@ -510,7 +532,7 @@ public class EntryListWidget extends WidgetWithBounds implements OverlayListWidg
@Override
public EntryStack<?> getFocusedStack() {
Point mouse = PointHelper.ofMouse();
- if (containsMouse(mouse)) {
+ if (containsChecked(mouse, false)) {
for (EntryListEntry entry : entries) {
EntryStack<?> currentEntry = entry.getCurrentEntry();
if (!currentEntry.isEmpty() && entry.containsMouse(mouse)) {
@@ -543,7 +565,7 @@ public class EntryListWidget extends WidgetWithBounds implements OverlayListWidg
@Override
public boolean containsMouse(double mouseX, double mouseY) {
- return super.containsMouse(mouseX, mouseY) && containsChecked(mouseX, mouseY);
+ return super.containsMouse(mouseX, mouseY) && containsChecked(mouseX, mouseY, true);
}
}
}
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/display/DisplayRegistryImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/display/DisplayRegistryImpl.java
index bfc975188..4976d9fb2 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/display/DisplayRegistryImpl.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/display/DisplayRegistryImpl.java
@@ -24,6 +24,9 @@
package me.shedaniel.rei.impl.client.registry.display;
import com.google.common.base.Preconditions;
+import com.google.common.collect.ForwardingMap;
+import com.google.common.collect.ForwardingMapEntry;
+import com.google.common.collect.Iterators;
import dev.architectury.event.EventResult;
import me.shedaniel.rei.RoughlyEnoughItemsCore;
import me.shedaniel.rei.api.client.plugins.REIClientPlugin;
@@ -36,9 +39,12 @@ import me.shedaniel.rei.api.client.registry.display.reason.DisplayAdditionReason
import me.shedaniel.rei.api.client.registry.display.visibility.DisplayVisibilityPredicate;
import me.shedaniel.rei.api.common.category.CategoryIdentifier;
import me.shedaniel.rei.api.common.display.Display;
+import me.shedaniel.rei.api.common.plugins.PluginManager;
import me.shedaniel.rei.impl.common.registry.RecipeManagerContextImpl;
import net.minecraft.world.item.crafting.Recipe;
import org.apache.commons.lang3.mutable.MutableInt;
+import org.apache.commons.lang3.mutable.MutableLong;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
@@ -46,10 +52,12 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiPredicate;
import java.util.function.Function;
import java.util.function.Predicate;
+import java.util.function.UnaryOperator;
public class DisplayRegistryImpl extends RecipeManagerContextImpl<REIClientPlugin> implements DisplayRegistry {
private final WeakHashMap<Display, Object> displaysBase = new WeakHashMap<>();
- private final Map<CategoryIdentifier<?>, List<Display>> displays = new ConcurrentHashMap<>();
+ private final Map<CategoryIdentifier<?>, DisplaysList> displays = new ConcurrentHashMap<>();
+ private final Map<CategoryIdentifier<?>, List<Display>> unmodifiableDisplays;
private final Map<CategoryIdentifier<?>, List<DynamicDisplayGenerator<?>>> displayGenerators = new ConcurrentHashMap<>();
private final List<DynamicDisplayGenerator<?>> globalDisplayGenerators = new ArrayList<>();
private final List<DisplayVisibilityPredicate> visibilityPredicates = new ArrayList<>();
@@ -58,6 +66,74 @@ public class DisplayRegistryImpl extends RecipeManagerContextImpl<REIClientPlugi
public DisplayRegistryImpl() {
super(RecipeManagerContextImpl.supplier());
+
+ this.unmodifiableDisplays = new RemappingMap<>(Collections.unmodifiableMap(displays), list -> {
+ if (list == null) {
+ return null;
+ } else {
+ return ((DisplaysList) list).unmodifiableList;
+ }
+ });
+ }
+
+ private static class RemappingMap<K, V> extends ForwardingMap<K, V> {
+ protected final Map<K, V> map;
+ protected final UnaryOperator<V> remapper;
+
+ public RemappingMap(Map<K, V> map, UnaryOperator<V> remapper) {
+ this.map = map;
+ this.remapper = remapper;
+ }
+
+ @Override
+ @NotNull
+ protected Map<K, V> delegate() {
+ return map;
+ }
+
+ @Override
+ public V get(Object key) {
+ return remapper.apply(super.get(key));
+ }
+
+ @SuppressWarnings("UnstableApiUsage")
+ @Override
+ @NotNull
+ public Set<Entry<K, V>> entrySet() {
+ return this.new StandardEntrySet() {
+ @Override
+ public Iterator<Entry<K, V>> iterator() {
+ return mapIterator(map.entrySet().iterator());
+ }
+ };
+ }
+
+ private Iterator<Entry<K, V>> mapIterator(Iterator<Entry<K, V>> iterator) {
+ return Iterators.transform(iterator, this::mapEntry);
+ }
+
+ private Entry<K, V> mapEntry(Entry<K, V> entry) {
+ return new ForwardingMapEntry<>() {
+ @Override
+ @NotNull
+ protected Entry<K, V> delegate() {
+ return entry;
+ }
+
+ @Override
+ public V getValue() {
+ return remapper.apply(entry.getValue());
+ }
+ };
+ }
+ }
+
+ private static class DisplaysList extends ArrayList<Display> {
+ private final List<Display> unmodifiableList;
+
+ public DisplaysList() {
+ this.unmodifiableList = Collections.unmodifiableList(this);
+ }
}
@Override
@@ -70,9 +146,20 @@ public class DisplayRegistryImpl extends RecipeManagerContextImpl<REIClientPlugi
return displayCount.getValue();
}
+ private MutableLong lastAddWarning = new MutableLong(-1);
+
@Override
public void add(Display display, @Nullable Object origin) {
- displays.computeIfAbsent(display.getCategoryIdentifier(), location -> new ArrayList<>())
+ if (!PluginManager.areAnyReloading()) {
+ if (lastAddWarning != null) {
+ if (lastAddWarning.getValue() > 0 && System.currentTimeMillis() - lastAddWarning.getValue() > 5000) {
+ RoughlyEnoughItemsCore.LOGGER.warn("Detected runtime DisplayRegistry modification, this can be extremely dangerous!");
+ }
+ lastAddWarning.setValue(System.currentTimeMillis());
+ }
+ }
+
+ displays.computeIfAbsent(display.getCategoryIdentifier(), location -> new DisplaysList())
.add(display);
displayCount.increment();
if (origin != null) {
@@ -84,7 +171,7 @@ public class DisplayRegistryImpl extends RecipeManagerContextImpl<REIClientPlugi
@Override
public Map<CategoryIdentifier<?>, List<Display>> getAll() {
- return Collections.unmodifiableMap(displays);
+ return unmodifiableDisplays;
}
@Override
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/screen/ScreenRegistryImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/screen/ScreenRegistryImpl.java
index 6f6dcf338..e25434c8b 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/screen/ScreenRegistryImpl.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/registry/screen/ScreenRegistryImpl.java
@@ -42,6 +42,7 @@ import me.shedaniel.rei.api.common.entry.EntryStack;
import me.shedaniel.rei.api.common.registry.ReloadStage;
import me.shedaniel.rei.api.common.util.CollectionUtils;
import me.shedaniel.rei.api.common.util.EntryStacks;
+import me.shedaniel.rei.impl.client.gui.screen.AbstractDisplayViewingScreen;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.Minecraft;
@@ -109,7 +110,11 @@ public class ScreenRegistryImpl implements ScreenRegistry {
public <T extends Screen> Rectangle getScreenBounds(T screen) {
for (OverlayDecider decider : getDeciders(screen)) {
if (decider instanceof DisplayBoundsProvider) {
- return ((DisplayBoundsProvider<T>) decider).getScreenBounds(screen);
+ Rectangle bounds = ((DisplayBoundsProvider<T>) decider).getScreenBounds(screen);
+
+ if (bounds != null) {
+ return bounds;
+ }
}
}
return new Rectangle();
@@ -238,15 +243,41 @@ public class ScreenRegistryImpl implements ScreenRegistry {
private void registerDefault() {
registerDecider(this.exclusionZones = new ExclusionZonesImpl());
- registerDecider(new OverlayDecider() {
+ registerDecider(new DisplayBoundsProvider<AbstractContainerScreen<?>>() {
+ @Override
+ public Rectangle getScreenBounds(AbstractContainerScreen<?> screen) {
+ return new Rectangle(screen.leftPos, screen.topPos, screen.imageWidth, screen.imageHeight);
+ }
+
+ @Override
+ public <R extends Screen> boolean isHandingScreen(Class<R> screen) {
+ return AbstractContainerScreen.class.isAssignableFrom(screen);
+ }
+
+ @Override
+ public <R extends Screen> InteractionResult shouldScreenBeOverlaid(R screen) {
+ return screen instanceof AbstractContainerScreen<?> ? InteractionResult.SUCCESS : InteractionResult.PASS;
+ }
+
+ @Override
+ public double getPriority() {
+ return -10.0;
+ }
+ });
+ registerDecider(new DisplayBoundsProvider<AbstractDisplayViewingScreen>() {
+ @Override
+ public Rectangle getScreenBounds(AbstractDisplayViewingScreen screen) {
+ return screen.getBounds();
+ }
+
@Override
public <R extends Screen> boolean isHandingScreen(Class<R> screen) {
- return true;
+ return AbstractDisplayViewingScreen.class.isAssignableFrom(screen);
}
@Override
- public InteractionResult shouldScreenBeOverlaid(Class<?> screen) {
- return AbstractContainerScreen.class.isAssignableFrom(screen) ? InteractionResult.SUCCESS : InteractionResult.PASS;
+ public <R extends Screen> InteractionResult shouldScreenBeOverlaid(R screen) {
+ return InteractionResult.SUCCESS;
}
@Override
diff --git a/runtime/src/main/java/me/shedaniel/rei/plugin/client/runtime/DefaultClientRuntimePlugin.java b/runtime/src/main/java/me/shedaniel/rei/plugin/client/runtime/DefaultClientRuntimePlugin.java
index d67d8e99e..7c70c6928 100644
--- a/runtime/src/main/java/me/shedaniel/rei/plugin/client/runtime/DefaultClientRuntimePlugin.java
+++ b/runtime/src/main/java/me/shedaniel/rei/plugin/client/runtime/DefaultClientRuntimePlugin.java
@@ -45,7 +45,6 @@ import me.shedaniel.rei.api.client.gui.widgets.Widgets;
import me.shedaniel.rei.api.client.plugins.REIClientPlugin;
import me.shedaniel.rei.api.client.registry.display.DisplayRegistry;
import me.shedaniel.rei.api.client.registry.entry.EntryRegistry;
-import me.shedaniel.rei.api.client.registry.screen.DisplayBoundsProvider;
import me.shedaniel.rei.api.client.registry.screen.ExclusionZones;
import me.shedaniel.rei.api.client.registry.screen.ScreenRegistry;
import me.shedaniel.rei.api.client.registry.transfer.TransferHandlerRegistry;
@@ -59,7 +58,6 @@ import me.shedaniel.rei.api.common.util.EntryStacks;
import me.shedaniel.rei.impl.client.ClientHelperImpl;
import me.shedaniel.rei.impl.client.REIRuntimeImpl;
import me.shedaniel.rei.impl.client.gui.ScreenOverlayImpl;
-import me.shedaniel.rei.impl.client.gui.screen.AbstractDisplayViewingScreen;
import me.shedaniel.rei.impl.client.gui.screen.DefaultDisplayViewingScreen;
import me.shedaniel.rei.impl.client.gui.widget.FavoritesListWidget;
import me.shedaniel.rei.impl.common.entry.type.EntryRegistryImpl;
@@ -71,7 +69,6 @@ import net.minecraft.client.gui.screens.Screen;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.TextComponent;
import net.minecraft.resources.ResourceLocation;
-import net.minecraft.world.InteractionResult;
import net.minecraft.world.item.ItemStack;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
@@ -141,22 +138,6 @@ public class DefaultClientRuntimePlugin implements REIClientPlugin {
}
return Collections.emptyList();
});
- registry.registerDecider(new DisplayBoundsProvider<AbstractDisplayViewingScreen>() {
- @Override
- public Rectangle getScreenBounds(AbstractDisplayViewingScreen screen) {
- return screen.getBounds();
- }
-
- @Override
- public <R extends Screen> boolean isHandingScreen(Class<R> screen) {
- return AbstractDisplayViewingScreen.class.isAssignableFrom(screen);
- }
-
- @Override
- public InteractionResult shouldScreenBeOverlaid(Class<?> screen) {
- return InteractionResult.SUCCESS;
- }
- });
registry.registerDraggableStackProvider(DraggableStackProviderWidget.from(context -> {
if (RoughlyEnoughItemsCoreClient.shouldReturn(context.getScreen()) || !REIRuntime.getInstance().isOverlayVisible()) return Collections.emptyList();
return Widgets.walk(REIRuntime.getInstance().getOverlay().get().children(), DraggableStackProviderWidget.class::isInstance);