diff options
| author | shedaniel <daniel@shedaniel.me> | 2021-02-27 17:14:08 +0800 |
|---|---|---|
| committer | shedaniel <daniel@shedaniel.me> | 2021-02-27 17:15:02 +0800 |
| commit | 542eb5154ebce387312ca3691f743b89e4aef99e (patch) | |
| tree | 48583bad05514d9a1a8d0ab3499af0d39f3fd1e5 /runtime/src/main/java/me/shedaniel/rei/impl/ScreenRegistryImpl.java | |
| parent | 9c570a0e71a6e209e0d234a99f35bd24efc18d7d (diff) | |
| download | RoughlyEnoughItems-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.java | 184 |
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; + } + }); } } |
