aboutsummaryrefslogtreecommitdiff
path: root/runtime/src/main/java/me/shedaniel/rei/impl/ScreenRegistryImpl.java
diff options
context:
space:
mode:
authorshedaniel <daniel@shedaniel.me>2021-02-27 17:14:08 +0800
committershedaniel <daniel@shedaniel.me>2021-02-27 17:15:02 +0800
commit542eb5154ebce387312ca3691f743b89e4aef99e (patch)
tree48583bad05514d9a1a8d0ab3499af0d39f3fd1e5 /runtime/src/main/java/me/shedaniel/rei/impl/ScreenRegistryImpl.java
parent9c570a0e71a6e209e0d234a99f35bd24efc18d7d (diff)
downloadRoughlyEnoughItems-542eb5154ebce387312ca3691f743b89e4aef99e.tar.gz
RoughlyEnoughItems-542eb5154ebce387312ca3691f743b89e4aef99e.tar.bz2
RoughlyEnoughItems-542eb5154ebce387312ca3691f743b89e4aef99e.zip
Remove depending on Cloth API, switching to architectury
Signed-off-by: shedaniel <daniel@shedaniel.me>
Diffstat (limited to 'runtime/src/main/java/me/shedaniel/rei/impl/ScreenRegistryImpl.java')
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/ScreenRegistryImpl.java184
1 files changed, 145 insertions, 39 deletions
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/ScreenRegistryImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/ScreenRegistryImpl.java
index 7432de512..a2f933723 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/ScreenRegistryImpl.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/ScreenRegistryImpl.java
@@ -23,58 +23,81 @@
package me.shedaniel.rei.impl;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.Multimap;
import com.mojang.blaze3d.platform.Window;
import me.shedaniel.math.Rectangle;
-import me.shedaniel.rei.api.registry.screens.ExclusionZones;
-import me.shedaniel.rei.api.registry.screens.DisplayBoundsProvider;
-import me.shedaniel.rei.api.registry.screens.OverlayDecider;
-import me.shedaniel.rei.api.registry.screens.ScreenRegistry;
+import me.shedaniel.rei.api.FocusedStackProvider;
+import me.shedaniel.rei.api.ScreenClickAreaProvider;
import me.shedaniel.rei.api.gui.config.DisplayPanelLocation;
+import me.shedaniel.rei.api.ingredient.EntryStack;
+import me.shedaniel.rei.api.ingredient.util.EntryStacks;
+import me.shedaniel.rei.api.plugins.REIPlugin;
+import me.shedaniel.rei.api.registry.screen.*;
import me.shedaniel.rei.api.util.CollectionUtils;
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.AbstractContainerScreen;
+import net.minecraft.resources.ResourceLocation;
+import net.minecraft.world.InteractionResult;
+import net.minecraft.world.InteractionResultHolder;
+import net.minecraft.world.inventory.AbstractContainerMenu;
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
+import java.util.stream.Collectors;
@ApiStatus.Internal
@Environment(EnvType.CLIENT)
public class ScreenRegistryImpl implements ScreenRegistry {
- private List<OverlayDecider> screenDisplayBoundsHandlers = Lists.newArrayList();
- private Map<Class<?>, List<OverlayDecider>> deciderSortedCache = Maps.newHashMap();
+ private Multimap<Class<? extends Screen>, ClickArea<?>> clickAreas = HashMultimap.create();
+ private List<FocusedStackProvider> focusedStackProviders = new ArrayList<>();
+ private List<OverlayDecider> deciders = new ArrayList<>();
+ private Map<Class<?>, List<OverlayDecider>> cache = new HashMap<>();
private ExclusionZones exclusionZones;
- private Class<?> tempScreen;
+ private Class<? extends Screen> tmpScreen;
@Override
- public List<OverlayDecider> getSortedOverlayDeciders(Class<?> screenClass) {
- List<OverlayDecider> possibleCached = deciderSortedCache.get(screenClass);
+ public void acceptPlugin(REIPlugin plugin) {
+ plugin.registerScreens(this);
+ plugin.registerExclusionZones(exclusionZones());
+ }
+
+ @Override
+ public <R extends Screen> List<OverlayDecider> getDeciders(Class<R> screenClass) {
+ List<OverlayDecider> possibleCached = cache.get(screenClass);
if (possibleCached != null) {
return possibleCached;
}
- tempScreen = screenClass;
- List<OverlayDecider> deciders = CollectionUtils.filter(screenDisplayBoundsHandlers, this::filterResponsible);
- deciderSortedCache.put(screenClass, deciders);
+ tmpScreen = screenClass;
+ List<OverlayDecider> deciders = CollectionUtils.filterToList(this.deciders, this::filterResponsible);
+ cache.put(screenClass, deciders);
+ tmpScreen = null;
return deciders;
}
+ private boolean filterResponsible(OverlayDecider handler) {
+ return handler.isHandingScreen(tmpScreen);
+ }
+
@Override
- public List<OverlayDecider> getAllOverlayDeciders() {
- return Collections.unmodifiableList(screenDisplayBoundsHandlers);
+ public List<OverlayDecider> getDeciders() {
+ return Collections.unmodifiableList(deciders);
}
@Override
- public <T> Rectangle getOverlayBounds(DisplayPanelLocation location, T screen) {
+ public <T extends Screen> Rectangle getOverlayBounds(DisplayPanelLocation location, T screen) {
Window window = Minecraft.getInstance().getWindow();
int scaledWidth = window.getGuiScaledWidth();
int scaledHeight = window.getGuiScaledHeight();
- for (OverlayDecider decider : getSortedOverlayDeciders(screen.getClass())) {
+ for (OverlayDecider decider : getDeciders(screen.getClass())) {
if (decider instanceof DisplayBoundsProvider) {
Rectangle containerBounds = ((DisplayBoundsProvider<T>) decider).getScreenBounds(screen);
if (location == DisplayPanelLocation.LEFT) {
@@ -89,16 +112,35 @@ public class ScreenRegistryImpl implements ScreenRegistry {
return new Rectangle();
}
- private boolean filterResponsible(OverlayDecider handler) {
- return handler.isHandingScreen(tempScreen);
+ @Nullable
+ @Override
+ public <T extends Screen> EntryStack<?> getFocusedStack(T screen) {
+ for (FocusedStackProvider provider : focusedStackProviders) {
+ InteractionResultHolder<EntryStack<?>> result = Objects.requireNonNull(provider.provide(screen));
+ if (result.getResult() == InteractionResult.SUCCESS) {
+ if (result != null && !result.getObject().isEmpty())
+ return result.getObject();
+ return null;
+ } else if (result.getResult() == InteractionResult.FAIL)
+ return null;
+ }
+
+ return null;
+ }
+
+ @Override
+ public void registerDecider(OverlayDecider decider) {
+ deciders.add(decider);
+ deciders.sort(Comparator.reverseOrder());
+ clickAreas.clear();
+ cache.clear();
+ tmpScreen = null;
}
@Override
- public void registerHandler(OverlayDecider decider) {
- screenDisplayBoundsHandlers.add(decider);
- screenDisplayBoundsHandlers.sort(Comparator.reverseOrder());
- deciderSortedCache.clear();
- tempScreen = null;
+ public void registerFocusedStack(FocusedStackProvider provider) {
+ focusedStackProviders.add(provider);
+ focusedStackProviders.sort(Comparator.reverseOrder());
}
@Override
@@ -106,18 +148,82 @@ public class ScreenRegistryImpl implements ScreenRegistry {
return exclusionZones;
}
- @ApiStatus.Internal
- public void setExclusionZones(ExclusionZones exclusionZones) {
- registerHandler(exclusionZones);
- this.exclusionZones = exclusionZones;
+ @Override
+ public <C extends AbstractContainerMenu, T extends AbstractContainerScreen<C>> void registerContainerClickArea(ScreenClickAreaProvider<T> provider, Class<T> screenClass, ResourceLocation... categories) {
+ registerClickArea(screen -> {
+ Rectangle rectangle = provider.provide(screen).clone();
+ rectangle.translate(screen.leftPos, screen.topPos);
+ return rectangle;
+ }, screenClass, categories);
+ }
+
+ @Override
+ public <T extends Screen> void registerClickArea(Class<T> screenClass, ClickArea<T> area) {
+ clickAreas.put(screenClass, area);
+ }
+
+ @Override
+ @Nullable
+ public <T extends Screen> Set<ResourceLocation> handleClickArea(Class<T> screenClass, ClickArea.ClickAreaContext<T> context) {
+ Mutable<Set<ResourceLocation>> categories = new MutableObject<>(null);
+ for (ClickArea<?> area : this.clickAreas.get(screenClass)) {
+ ClickArea.Result result = ((ClickArea<T>) area).handle(context);
+
+ if (result.isSuccessful()) {
+ if (categories.getValue() == null) {
+ categories.setValue(new LinkedHashSet<>());
+ }
+ result.getCategories().collect(Collectors.toCollection(categories::getValue));
+ }
+ }
+ return categories.getValue();
}
- @ApiStatus.Internal
@Override
- public void resetData() {
- screenDisplayBoundsHandlers.clear();
- deciderSortedCache.clear();
- tempScreen = null;
- setExclusionZones(new ExclusionZonesImpl());
+ public void startReload() {
+ clickAreas.clear();
+ deciders.clear();
+ cache.clear();
+ focusedStackProviders.clear();
+ tmpScreen = null;
+
+ registerDefault();
+ }
+
+ private void registerDefault() {
+ registerDecider(this.exclusionZones = new ExclusionZonesImpl());
+ registerDecider(new OverlayDecider() {
+ @Override
+ public <R extends Screen> boolean isHandingScreen(Class<R> screen) {
+ return true;
+ }
+
+ @Override
+ public InteractionResult shouldScreenBeOverlaid(Class<?> screen) {
+ return AbstractContainerScreen.class.isAssignableFrom(screen) ? InteractionResult.SUCCESS : InteractionResult.PASS;
+ }
+
+ @Override
+ public float getPriority() {
+ return -10;
+ }
+ });
+ registerFocusedStack(new FocusedStackProvider() {
+ @Override
+ @NotNull
+ public InteractionResultHolder<EntryStack<?>> provide(Screen screen) {
+ if (screen instanceof AbstractContainerScreen) {
+ AbstractContainerScreen<?> containerScreen = (AbstractContainerScreen<?>) screen;
+ if (containerScreen.hoveredSlot != null && !containerScreen.hoveredSlot.getItem().isEmpty())
+ return InteractionResultHolder.success(EntryStacks.of(containerScreen.hoveredSlot.getItem()));
+ }
+ return InteractionResultHolder.pass(EntryStack.empty());
+ }
+
+ @Override
+ public double getPriority() {
+ return -10.0;
+ }
+ });
}
}