浏览代码

4.0.4

Signed-off-by: shedaniel <daniel@shedaniel.me>
shedaniel 5 年之前
父节点
当前提交
6b8ee77bb1

+ 1 - 1
gradle.properties

@@ -1,4 +1,4 @@
-mod_version=4.0.3-unstable
+mod_version=4.0.4-unstable
 minecraft_version=20w07a
 yarn_version=20w07a+build.1
 fabricloader_version=0.7.8+build.184

+ 51 - 34
src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java

@@ -52,7 +52,6 @@ import java.util.Optional;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
-import java.util.concurrent.atomic.AtomicLong;
 
 @ApiStatus.Internal
 public class RoughlyEnoughItemsCore implements ClientModInitializer {
@@ -131,13 +130,13 @@ public class RoughlyEnoughItemsCore implements ClientModInitializer {
     }
     
     @ApiStatus.Internal
-    public static void syncRecipes(AtomicLong lastSync) {
+    public static void syncRecipes(long[] lastSync) {
         if (lastSync != null) {
-            if (lastSync.get() > 0 && System.currentTimeMillis() - lastSync.get() <= 5000) {
+            if (lastSync[0] > 0 && System.currentTimeMillis() - lastSync[0] <= 5000) {
                 RoughlyEnoughItemsCore.LOGGER.warn("[REI] Suppressing Sync Recipes!");
                 return;
             }
-            lastSync.set(System.currentTimeMillis());
+            lastSync[0] = System.currentTimeMillis();
         }
         RecipeManager recipeManager = MinecraftClient.getInstance().getNetworkHandler().getRecipeManager();
         if (ConfigObject.getInstance().doesRegisterRecipesInAnotherThread()) {
@@ -230,9 +229,20 @@ public class RoughlyEnoughItemsCore implements ClientModInitializer {
         }
     }
     
+    private boolean shouldReturn(Class<?> screen) {
+        for (OverlayDecider decider : DisplayHelper.getInstance().getAllOverlayDeciders()) {
+            if (!decider.isHandingScreen(screen))
+                continue;
+            ActionResult result = decider.shouldScreenBeOverlayed(screen);
+            if (result != ActionResult.PASS)
+                return result == ActionResult.FAIL || ScreenHelper.getLastContainerScreenHooks() == null;
+        }
+        return true;
+    }
+    
     private void registerClothEvents() {
         final Identifier recipeButtonTex = new Identifier("textures/gui/recipe_button.png");
-        AtomicLong lastSync = new AtomicLong(-1);
+        long[] lastSync = {-1};
         ClothClientHooks.SYNC_RECIPES.register((minecraftClient, recipeManager, synchronizeRecipesS2CPacket) -> syncRecipes(lastSync));
         ClothClientHooks.SCREEN_ADD_BUTTON.register((minecraftClient, screen, abstractButtonWidget) -> {
             if (ConfigObject.getInstance().doesDisableRecipeBook() && screen instanceof ContainerScreen && abstractButtonWidget instanceof TexturedButtonWidget)
@@ -241,29 +251,32 @@ public class RoughlyEnoughItemsCore implements ClientModInitializer {
             return ActionResult.PASS;
         });
         ClothClientHooks.SCREEN_INIT_POST.register((minecraftClient, screen, screenHooks) -> {
-            if (screen instanceof ContainerScreen) {
-                if (screen instanceof InventoryScreen && minecraftClient.interactionManager.hasCreativeInventory())
-                    return;
+            if (screen instanceof InventoryScreen && minecraftClient.interactionManager.hasCreativeInventory())
+                return;
+            if (shouldReturn(screen.getClass()))
+                return;
+            if (screen instanceof ContainerScreen)
                 ScreenHelper.setLastContainerScreen((ContainerScreen<?>) screen);
-                boolean alreadyAdded = false;
-                for (Element element : Lists.newArrayList(screenHooks.cloth_getInputListeners()))
-                    if (ContainerScreenOverlay.class.isAssignableFrom(element.getClass()))
-                        if (alreadyAdded)
-                            screenHooks.cloth_getInputListeners().remove(element);
-                        else
-                            alreadyAdded = true;
-                if (!alreadyAdded)
-                    screenHooks.cloth_getInputListeners().add(ScreenHelper.getLastOverlay(true, false));
-            }
+            boolean alreadyAdded = false;
+            for (Element element : Lists.newArrayList(screenHooks.cloth_getInputListeners()))
+                if (ContainerScreenOverlay.class.isAssignableFrom(element.getClass()))
+                    if (alreadyAdded)
+                        screenHooks.cloth_getInputListeners().remove(element);
+                    else
+                        alreadyAdded = true;
+            if (!alreadyAdded)
+                screenHooks.cloth_getInputListeners().add(ScreenHelper.getLastOverlay(true, false));
         });
         ClothClientHooks.SCREEN_RENDER_POST.register((minecraftClient, screen, i, i1, v) -> {
-            if (screen instanceof ContainerScreen)
-                ScreenHelper.getLastOverlay().render(i, i1, v);
+            if (shouldReturn(screen.getClass()))
+                return;
+            ScreenHelper.getLastOverlay().render(i, i1, v);
         });
         ClothClientHooks.SCREEN_MOUSE_DRAGGED.register((minecraftClient, screen, v, v1, i, v2, v3) -> {
-            if (screen instanceof ContainerScreen)
-                if (ScreenHelper.isOverlayVisible() && ScreenHelper.getLastOverlay().mouseDragged(v, v1, i, v2, v3))
-                    return ActionResult.SUCCESS;
+            if (shouldReturn(screen.getClass()))
+                return ActionResult.PASS;
+            if (ScreenHelper.isOverlayVisible() && ScreenHelper.getLastOverlay().mouseDragged(v, v1, i, v2, v3))
+                return ActionResult.SUCCESS;
             return ActionResult.PASS;
         });
         ClothClientHooks.SCREEN_MOUSE_CLICKED.register((minecraftClient, screen, v, v1, i) -> {
@@ -277,29 +290,33 @@ public class RoughlyEnoughItemsCore implements ClientModInitializer {
             return ActionResult.PASS;
         });
         ClothClientHooks.SCREEN_MOUSE_SCROLLED.register((minecraftClient, screen, v, v1, v2) -> {
-            if (screen instanceof ContainerScreen)
-                if (ScreenHelper.isOverlayVisible() && ScreenHelper.getLastOverlay().mouseScrolled(v, v1, v2))
-                    return ActionResult.SUCCESS;
+            if (shouldReturn(screen.getClass()))
+                return ActionResult.PASS;
+            if (ScreenHelper.isOverlayVisible() && ScreenHelper.getLastOverlay().mouseScrolled(v, v1, v2))
+                return ActionResult.SUCCESS;
             return ActionResult.PASS;
         });
         ClothClientHooks.SCREEN_CHAR_TYPED.register((minecraftClient, screen, character, keyCode) -> {
-            if (screen instanceof ContainerScreen)
-                if (ScreenHelper.getLastOverlay().charTyped(character, keyCode))
-                    return ActionResult.SUCCESS;
+            if (shouldReturn(screen.getClass()))
+                return ActionResult.PASS;
+            if (ScreenHelper.getLastOverlay().charTyped(character, keyCode))
+                return ActionResult.SUCCESS;
             return ActionResult.PASS;
         });
         ClothClientHooks.SCREEN_LATE_RENDER.register((minecraftClient, screen, i, i1, v) -> {
             if (!ScreenHelper.isOverlayVisible())
                 return;
-            if (screen instanceof ContainerScreen)
-                ScreenHelper.getLastOverlay().lateRender(i, i1, v);
+            if (shouldReturn(screen.getClass()))
+                return;
+            ScreenHelper.getLastOverlay().lateRender(i, i1, v);
         });
         ClothClientHooks.SCREEN_KEY_PRESSED.register((minecraftClient, screen, i, i1, i2) -> {
             if (screen.getFocused() != null && screen.getFocused() instanceof TextFieldWidget || (screen.getFocused() instanceof RecipeBookWidget && ((RecipeBookGuiHooks) screen.getFocused()).rei_getSearchField() != null && ((RecipeBookGuiHooks) screen.getFocused()).rei_getSearchField().isFocused()))
                 return ActionResult.PASS;
-            if (screen instanceof ContainerScreen)
-                if (ScreenHelper.getLastOverlay().keyPressed(i, i1, i2))
-                    return ActionResult.SUCCESS;
+            if (shouldReturn(screen.getClass()))
+                return ActionResult.PASS;
+            if (ScreenHelper.getLastOverlay().keyPressed(i, i1, i2))
+                return ActionResult.SUCCESS;
             if (screen instanceof ContainerScreen && ConfigObject.getInstance().doesDisableRecipeBook() && ConfigObject.getInstance().doesFixTabCloseContainer())
                 if (i == 258 && minecraftClient.options.keyInventory.matchesKey(i, i1)) {
                     minecraftClient.player.closeContainer();

+ 5 - 0
src/main/java/me/shedaniel/rei/api/BaseBoundsHandler.java

@@ -12,6 +12,11 @@ import java.util.List;
 import java.util.function.Supplier;
 
 public interface BaseBoundsHandler extends DisplayHelper.DisplayBoundsHandler<Screen> {
+    
+    static BaseBoundsHandler getInstance() {
+        return DisplayHelper.getInstance().getBaseBoundsHandler();
+    }
+    
     /**
      * Gets the exclusion zones by the screen class
      *

+ 37 - 3
src/main/java/me/shedaniel/rei/api/DisplayHelper.java

@@ -8,7 +8,9 @@ package me.shedaniel.rei.api;
 import me.shedaniel.math.api.Rectangle;
 import me.shedaniel.rei.RoughlyEnoughItemsCore;
 import me.shedaniel.rei.gui.config.SearchFieldLocation;
+import me.shedaniel.rei.utils.CollectionUtils;
 import net.minecraft.util.ActionResult;
+import org.jetbrains.annotations.ApiStatus;
 
 import java.util.List;
 import java.util.function.Supplier;
@@ -34,8 +36,20 @@ public interface DisplayHelper {
      * Gets all registered bounds handlers
      *
      * @return the list of registered bounds handlers
+     * @deprecated see {@link #getAllOverlayDeciders()}
      */
-    List<DisplayBoundsHandler<?>> getAllBoundsHandlers();
+    @Deprecated
+    @ApiStatus.ScheduledForRemoval
+    default List<DisplayBoundsHandler<?>> getAllBoundsHandlers() {
+        return (List) CollectionUtils.castAndMap(getAllOverlayDeciders(), DisplayBoundsHandler.class);
+    }
+    
+    /**
+     * Gets all registered overlay deciders
+     *
+     * @return the list of registered overlay deciders
+     */
+    List<OverlayDecider> getAllOverlayDeciders();
     
     /**
      * Gets all responsible bounds handlers
@@ -50,17 +64,31 @@ public interface DisplayHelper {
      * Registers a bounds handler
      *
      * @param handler the handler to register
+     * @deprecated see {@link #registerHandler(OverlayDecider)}
+     */
+    @Deprecated
+    @ApiStatus.ScheduledForRemoval
+    default void registerBoundsHandler(DisplayBoundsHandler<?> handler) {
+        registerHandler(handler);
+    }
+    
+    /**
+     * Registers a bounds decider
+     *
+     * @param decider the decider to register
      */
-    void registerBoundsHandler(DisplayBoundsHandler<?> handler);
+    void registerHandler(OverlayDecider decider);
     
     /**
      * Gets the base bounds handler api for exclusion zones
      *
      * @return the base bounds handler
+     * @see BaseBoundsHandler#getInstance()
      */
+    @ApiStatus.Internal
     BaseBoundsHandler getBaseBoundsHandler();
     
-    interface DisplayBoundsHandler<T> {
+    interface DisplayBoundsHandler<T> extends OverlayDecider {
         /**
          * Gets the base supported class for the bounds handler
          *
@@ -68,6 +96,11 @@ public interface DisplayHelper {
          */
         Class<?> getBaseSupportedClass();
         
+        @Override
+        default boolean isHandingScreen(Class<?> screen) {
+            return getBaseSupportedClass().isAssignableFrom(screen);
+        }
+        
         /**
          * Gets the left bounds of the overlay
          *
@@ -140,6 +173,7 @@ public interface DisplayHelper {
          *
          * @return the priority in float
          */
+        @Override
         default float getPriority() {
             return 0f;
         }

+ 25 - 0
src/main/java/me/shedaniel/rei/api/OverlayDecider.java

@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2018, 2019, 2020 shedaniel
+ * Licensed under the MIT License (the "License").
+ */
+
+package me.shedaniel.rei.api;
+
+import net.minecraft.util.ActionResult;
+
+public interface OverlayDecider {
+    boolean isHandingScreen(Class<?> screen);
+    
+    default ActionResult shouldScreenBeOverlayed(Class<?> screen) {
+        return ActionResult.PASS;
+    }
+    
+    /**
+     * Gets the priority of the handler, the higher it is, the earlier it is called.
+     *
+     * @return the priority in float
+     */
+    default float getPriority() {
+        return 0f;
+    }
+}

+ 15 - 10
src/main/java/me/shedaniel/rei/impl/DisplayHelperImpl.java

@@ -10,8 +10,11 @@ import com.google.common.collect.Maps;
 import me.shedaniel.math.api.Rectangle;
 import me.shedaniel.rei.api.BaseBoundsHandler;
 import me.shedaniel.rei.api.DisplayHelper;
+import me.shedaniel.rei.api.OverlayDecider;
+import me.shedaniel.rei.utils.CollectionUtils;
 import org.jetbrains.annotations.ApiStatus;
 
+import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
 import java.util.Map;
@@ -20,7 +23,7 @@ import java.util.stream.Collectors;
 @ApiStatus.Internal
 public class DisplayHelperImpl implements DisplayHelper {
     
-    private static final Comparator<DisplayBoundsHandler<?>> BOUNDS_HANDLER_COMPARATOR;
+    private static final Comparator<OverlayDecider> BOUNDS_HANDLER_COMPARATOR;
     private static final DisplayBoundsHandler<Object> EMPTY = new DisplayBoundsHandler<Object>() {
         @Override
         public Class<Object> getBaseSupportedClass() {
@@ -44,29 +47,30 @@ public class DisplayHelperImpl implements DisplayHelper {
     };
     
     static {
-        Comparator<DisplayBoundsHandler<?>> comparator = Comparator.comparingDouble(DisplayBoundsHandler::getPriority);
+        Comparator<OverlayDecider> comparator = Comparator.comparingDouble(OverlayDecider::getPriority);
         BOUNDS_HANDLER_COMPARATOR = comparator.reversed();
     }
     
-    private List<DisplayBoundsHandler<?>> screenDisplayBoundsHandlers = Lists.newArrayList();
+    private List<OverlayDecider> screenDisplayBoundsHandlers = Lists.newArrayList();
     private Map<Class<?>, DisplayBoundsHandler<?>> handlerCache = Maps.newHashMap();
     private Map<Class<?>, List<DisplayBoundsHandler<?>>> handlerSortedCache = Maps.newHashMap();
     private BaseBoundsHandler baseBoundsHandler;
     private Class<?> tempScreen;
     
+    @SuppressWarnings("rawtypes")
     @Override
     public List<DisplayBoundsHandler<?>> getSortedBoundsHandlers(Class<?> screenClass) {
         List<DisplayBoundsHandler<?>> possibleCached = handlerSortedCache.get(screenClass);
         if (possibleCached != null)
             return possibleCached;
         tempScreen = screenClass;
-        handlerSortedCache.put(screenClass, screenDisplayBoundsHandlers.stream().filter(this::filterResponsible).sorted(BOUNDS_HANDLER_COMPARATOR).collect(Collectors.toList()));
+        handlerSortedCache.put(screenClass, (List) CollectionUtils.castAndMap(CollectionUtils.filter(screenDisplayBoundsHandlers, this::filterResponsible), DisplayBoundsHandler.class));
         return handlerSortedCache.get(screenClass);
     }
     
     @Override
-    public List<DisplayBoundsHandler<?>> getAllBoundsHandlers() {
-        return screenDisplayBoundsHandlers;
+    public List<OverlayDecider> getAllOverlayDeciders() {
+        return Collections.unmodifiableList(screenDisplayBoundsHandlers);
     }
     
     @Override
@@ -79,13 +83,14 @@ public class DisplayHelperImpl implements DisplayHelper {
         return handlerCache.get(screenClass);
     }
     
-    private boolean filterResponsible(DisplayBoundsHandler<?> handler) {
-        return handler.getBaseSupportedClass().isAssignableFrom(tempScreen);
+    private boolean filterResponsible(OverlayDecider handler) {
+        return handler.isHandingScreen(tempScreen);
     }
     
     @Override
-    public void registerBoundsHandler(DisplayBoundsHandler<?> handler) {
-        screenDisplayBoundsHandlers.add(handler);
+    public void registerHandler(OverlayDecider decider) {
+        screenDisplayBoundsHandlers.add(decider);
+        screenDisplayBoundsHandlers.sort(BOUNDS_HANDLER_COMPARATOR);
     }
     
     @Override

+ 18 - 2
src/main/java/me/shedaniel/rei/impl/RecipeHelperImpl.java

@@ -264,7 +264,7 @@ public class RecipeHelperImpl implements RecipeHelper {
         ((DisplayHelperImpl) DisplayHelper.getInstance()).resetData();
         ((DisplayHelperImpl) DisplayHelper.getInstance()).resetCache();
         BaseBoundsHandler baseBoundsHandler = new BaseBoundsHandlerImpl();
-        DisplayHelper.getInstance().registerBoundsHandler(baseBoundsHandler);
+        DisplayHelper.getInstance().registerHandler(baseBoundsHandler);
         ((DisplayHelperImpl) DisplayHelper.getInstance()).setBaseBoundsHandler(baseBoundsHandler);
         List<REIPluginEntry> plugins = RoughlyEnoughItemsCore.getPlugins();
         plugins.sort(Comparator.comparingInt(REIPluginEntry::getPriority).reversed());
@@ -328,6 +328,22 @@ public class RecipeHelperImpl implements RecipeHelper {
                     return -1f;
                 }
             });
+        DisplayHelper.getInstance().registerHandler(new OverlayDecider() {
+            @Override
+            public boolean isHandingScreen(Class<?> screen) {
+                return true;
+            }
+    
+            @Override
+            public ActionResult shouldScreenBeOverlayed(Class<?> screen) {
+                return ContainerScreen.class.isAssignableFrom(screen) ? ActionResult.SUCCESS : ActionResult.PASS;
+            }
+    
+            @Override
+            public float getPriority() {
+                return -10;
+            }
+        });
         
         // Clear Cache
         ((DisplayHelperImpl) DisplayHelper.getInstance()).resetCache();
@@ -344,7 +360,7 @@ public class RecipeHelperImpl implements RecipeHelper {
         
         displayVisibilityHandlers.sort(VISIBILITY_HANDLER_COMPARATOR);
         long usedTime = System.currentTimeMillis() - startTime;
-        RoughlyEnoughItemsCore.LOGGER.info("[REI] Registered %d stack entries, %d recipes displays, %d exclusion zones suppliers, %d bounds handler, %d visibility handlers and %d categories (%s) in %d ms.", EntryRegistry.getInstance().getStacksList().size(), recipeCount[0], DisplayHelper.getInstance().getBaseBoundsHandler().supplierSize(), DisplayHelper.getInstance().getAllBoundsHandlers().size(), getDisplayVisibilityHandlers().size(), categories.size(), categories.keySet().stream().map(RecipeCategory::getCategoryName).collect(Collectors.joining(", ")), usedTime);
+        RoughlyEnoughItemsCore.LOGGER.info("[REI] Registered %d stack entries, %d recipes displays, %d exclusion zones suppliers, %d overlay decider, %d visibility handlers and %d categories (%s) in %d ms.", EntryRegistry.getInstance().getStacksList().size(), recipeCount[0], BaseBoundsHandler.getInstance().supplierSize(), DisplayHelper.getInstance().getAllOverlayDeciders().size(), getDisplayVisibilityHandlers().size(), categories.size(), categories.keySet().stream().map(RecipeCategory::getCategoryName).collect(Collectors.joining(", ")), usedTime);
     }
     
     @Override

+ 24 - 6
src/main/java/me/shedaniel/rei/plugin/DefaultPlugin.java

@@ -57,6 +57,7 @@ import net.minecraft.item.*;
 import net.minecraft.potion.PotionUtil;
 import net.minecraft.recipe.*;
 import net.minecraft.tag.BlockTags;
+import net.minecraft.util.ActionResult;
 import net.minecraft.util.Identifier;
 import net.minecraft.util.math.MathHelper;
 import net.minecraft.util.registry.Registry;
@@ -267,15 +268,32 @@ public class DefaultPlugin implements REIPluginV0 {
         if (!ConfigObject.getInstance().isLoadingDefaultPlugin()) {
             return;
         }
-        displayHelper.getBaseBoundsHandler().registerExclusionZones(AbstractInventoryScreen.class, new DefaultPotionEffectExclusionZones());
-        displayHelper.getBaseBoundsHandler().registerExclusionZones(RecipeBookProvider.class, new DefaultRecipeBookExclusionZones());
-        displayHelper.getBaseBoundsHandler().registerExclusionZones(RecipeViewingScreen.class, () -> {
+        BaseBoundsHandler baseBoundsHandler = BaseBoundsHandler.getInstance();
+        baseBoundsHandler.registerExclusionZones(AbstractInventoryScreen.class, new DefaultPotionEffectExclusionZones());
+        baseBoundsHandler.registerExclusionZones(RecipeBookProvider.class, new DefaultRecipeBookExclusionZones());
+        baseBoundsHandler.registerExclusionZones(RecipeViewingScreen.class, () -> {
             CategoryBaseWidget widget = ((RecipeViewingScreen) MinecraftClient.getInstance().currentScreen).getWorkingStationsBaseWidget();
             if (widget == null)
                 return Collections.emptyList();
             return Collections.singletonList(widget.getBounds().clone());
         });
-        displayHelper.registerBoundsHandler(new DisplayHelper.DisplayBoundsHandler<ContainerScreen<?>>() {
+        displayHelper.registerHandler(new OverlayDecider() {
+            @Override
+            public boolean isHandingScreen(Class<?> screen) {
+                return InventoryScreen.class.isAssignableFrom(screen);
+            }
+            
+            @Override
+            public ActionResult shouldScreenBeOverlayed(Class<?> screen) {
+                return isHandingScreen(screen) ? ActionResult.FAIL : ActionResult.PASS;
+            }
+    
+            @Override
+            public float getPriority() {
+                return 10f;
+            }
+        });
+        displayHelper.registerHandler(new DisplayHelper.DisplayBoundsHandler<ContainerScreen<?>>() {
             @Override
             public Class<?> getBaseSupportedClass() {
                 return ContainerScreen.class;
@@ -297,7 +315,7 @@ public class DefaultPlugin implements REIPluginV0 {
                 return -1.0f;
             }
         });
-        displayHelper.registerBoundsHandler(new DisplayHelper.DisplayBoundsHandler<RecipeViewingScreen>() {
+        displayHelper.registerHandler(new DisplayHelper.DisplayBoundsHandler<RecipeViewingScreen>() {
             @Override
             public Class<?> getBaseSupportedClass() {
                 return RecipeViewingScreen.class;
@@ -319,7 +337,7 @@ public class DefaultPlugin implements REIPluginV0 {
                 return -1.0f;
             }
         });
-        displayHelper.registerBoundsHandler(new DisplayHelper.DisplayBoundsHandler<VillagerRecipeViewingScreen>() {
+        displayHelper.registerHandler(new DisplayHelper.DisplayBoundsHandler<VillagerRecipeViewingScreen>() {
             @Override
             public Class<?> getBaseSupportedClass() {
                 return VillagerRecipeViewingScreen.class;

+ 9 - 0
src/main/java/me/shedaniel/rei/utils/CollectionUtils.java

@@ -32,6 +32,15 @@ public class CollectionUtils {
         return null;
     }
     
+    public static <T,R> List<R> castAndMap(List<T> list, Class<R> castClass) {
+        List<R> l = new ArrayList<>();
+        for (T t : list) {
+            if (castClass.isAssignableFrom(t.getClass()))
+                l.add((R) t);
+        }
+        return l;
+    }
+    
     public static <T> T findFirstOrNull(List<T> list, Predicate<T> predicate) {
         for (T t : list) {
             if (predicate.test(t))