Browse Source

Cache handlers so it won't leak ram

Unknown 5 năm trước cách đây
mục cha
commit
b7998aa5ca

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

@@ -19,7 +19,11 @@ public interface BaseBoundsHandler extends DisplayHelper.DisplayBoundsHandler<Sc
      * @param isOnRightSide      whether the user has set the overlay to the right
      * @return the list of exclusion zones
      */
-    List<Rectangle> getCurrentExclusionZones(Class<?> currentScreenClass, boolean isOnRightSide);
+    default List<Rectangle> getCurrentExclusionZones(Class<?> currentScreenClass, boolean isOnRightSide) {
+        return getCurrentExclusionZones(currentScreenClass, isOnRightSide, false);
+    }
+    
+    List<Rectangle> getCurrentExclusionZones(Class<?> currentScreenClass, boolean isOnRightSide, boolean sort);
     
     /**
      * Register an exclusion zone

+ 12 - 9
src/main/java/me/shedaniel/rei/impl/BaseBoundsHandlerImpl.java

@@ -18,12 +18,12 @@ import java.awt.*;
 import java.util.Comparator;
 import java.util.List;
 import java.util.function.Function;
-import java.util.stream.Collectors;
 
 public class BaseBoundsHandlerImpl implements BaseBoundsHandler {
     
     private static final Function<Rectangle, Long> RECTANGLE_LONG_FUNCTION = r -> r.x + 1000l * r.y + 1000000l * r.width + 1000000000l * r.height;
     private static final Comparator<Pair<Pair<Class<?>, Float>, Function<Boolean, List<Rectangle>>>> LIST_PAIR_COMPARATOR;
+    private static final Comparator<? super Rectangle> RECTANGLE_COMPARER = Comparator.comparingLong(RECTANGLE_LONG_FUNCTION::apply);
     
     static {
         Comparator<Pair<Pair<Class<?>, Float>, Function<Boolean, List<Rectangle>>>> comparator = Comparator.comparingDouble(value -> value.getLeft().getRight());
@@ -55,7 +55,7 @@ public class BaseBoundsHandlerImpl implements BaseBoundsHandler {
     
     @Override
     public ActionResult isInZone(boolean isOnRightSide, double mouseX, double mouseY) {
-        for (Rectangle zone : getCurrentExclusionZones(MinecraftClient.getInstance().currentScreen.getClass(), isOnRightSide))
+        for (Rectangle zone : getCurrentExclusionZones(MinecraftClient.getInstance().currentScreen.getClass(), isOnRightSide, false))
             if (zone.contains(mouseX, mouseY))
                 return ActionResult.FAIL;
         return ActionResult.PASS;
@@ -75,23 +75,26 @@ public class BaseBoundsHandlerImpl implements BaseBoundsHandler {
     }
     
     private long getStringFromCurrent(boolean isOnRightSide) {
-        return getLongFromAreas(isOnRightSide ? getHandler().getRightBounds(MinecraftClient.getInstance().currentScreen) : getHandler().getLeftBounds(MinecraftClient.getInstance().currentScreen), getCurrentExclusionZones(MinecraftClient.getInstance().currentScreen.getClass(), isOnRightSide));
+        return getLongFromAreas(isOnRightSide ? getHandler().getRightBounds(MinecraftClient.getInstance().currentScreen) : getHandler().getLeftBounds(MinecraftClient.getInstance().currentScreen), getCurrentExclusionZones(MinecraftClient.getInstance().currentScreen.getClass(), isOnRightSide, false));
     }
     
     @Override
     public ActionResult canItemSlotWidgetFit(boolean isOnRightSide, int left, int top, Screen screen, Rectangle fullBounds) {
-        List<Rectangle> currentExclusionZones = getCurrentExclusionZones(MinecraftClient.getInstance().currentScreen.getClass(), isOnRightSide);
-        for (Rectangle currentExclusionZone : currentExclusionZones)
+        for (Rectangle currentExclusionZone : getCurrentExclusionZones(MinecraftClient.getInstance().currentScreen.getClass(), isOnRightSide, false))
             if (left + 18 >= currentExclusionZone.x && top + 18 >= currentExclusionZone.y && left <= currentExclusionZone.x + currentExclusionZone.width && top <= currentExclusionZone.y + currentExclusionZone.height)
                 return ActionResult.FAIL;
         return ActionResult.PASS;
     }
     
-    public List<Rectangle> getCurrentExclusionZones(Class<?> currentScreenClass, boolean isOnRightSide) {
-        List<Pair<Pair<Class<?>, Float>, Function<Boolean, List<Rectangle>>>> only = list.stream().filter(pair -> pair.getLeft().getLeft().isAssignableFrom(currentScreenClass)).collect(Collectors.toList());
-        only.sort(LIST_PAIR_COMPARATOR);
+    @Override
+    public List<Rectangle> getCurrentExclusionZones(Class<?> currentScreenClass, boolean isOnRightSide, boolean sort) {
         List<Rectangle> rectangles = Lists.newArrayList();
-        only.forEach(pair -> rectangles.addAll(pair.getRight().apply(isOnRightSide)));
+        for (Pair<Pair<Class<?>, Float>, Function<Boolean, List<Rectangle>>> pair : list) {
+            if (pair.getLeft().getLeft().isAssignableFrom(currentScreenClass))
+                rectangles.addAll(pair.getRight().apply(isOnRightSide));
+        }
+        if (sort)
+            rectangles.sort(RECTANGLE_COMPARER);
         return rectangles;
     }
     

+ 16 - 6
src/main/java/me/shedaniel/rei/impl/DisplayHelperImpl.java

@@ -14,7 +14,6 @@ import java.awt.*;
 import java.util.Comparator;
 import java.util.List;
 import java.util.Map;
-import java.util.Optional;
 import java.util.stream.Collectors;
 
 public class DisplayHelperImpl implements DisplayHelper {
@@ -49,11 +48,17 @@ public class DisplayHelperImpl implements DisplayHelper {
     
     private List<DisplayBoundsHandler<?>> screenDisplayBoundsHandlers = Lists.newArrayList();
     private Map<Class<?>, DisplayBoundsHandler<?>> handlerCache = Maps.newHashMap();
+    private Map<Class, List<DisplayBoundsHandler<?>>> handlerSortedCache = Maps.newHashMap();
     private BaseBoundsHandler baseBoundsHandler;
+    private Class tempScreen;
     
     @Override
     public List<DisplayBoundsHandler<?>> getSortedBoundsHandlers(Class<?> screenClass) {
-        return screenDisplayBoundsHandlers.stream().filter(handler -> handler.getBaseSupportedClass().isAssignableFrom(screenClass)).sorted(BOUNDS_HANDLER_COMPARATOR).collect(Collectors.toList());
+        if (handlerSortedCache.containsKey(screenClass))
+            return handlerSortedCache.get(screenClass);
+        tempScreen = screenClass;
+        handlerSortedCache.put(screenClass, screenDisplayBoundsHandlers.stream().filter(this::filterResponsible).sorted(BOUNDS_HANDLER_COMPARATOR).collect(Collectors.toList()));
+        return handlerSortedCache.get(screenClass);
     }
     
     @Override
@@ -63,13 +68,17 @@ public class DisplayHelperImpl implements DisplayHelper {
     
     @Override
     public DisplayBoundsHandler<?> getResponsibleBoundsHandler(Class<?> screenClass) {
-        Optional<? extends DisplayBoundsHandler<?>> any = handlerCache.entrySet().stream().filter(entry -> entry.getKey().equals(screenClass)).map(Map.Entry::getValue).findAny();
-        if (any.isPresent())
-            return any.get();
-        handlerCache.put(screenClass, screenDisplayBoundsHandlers.stream().filter(handler -> handler.getBaseSupportedClass().isAssignableFrom(screenClass)).sorted(BOUNDS_HANDLER_COMPARATOR).findAny().orElse(EMPTY));
+        if (handlerCache.containsKey(screenClass))
+            return handlerCache.get(screenClass);
+        tempScreen = screenClass;
+        handlerCache.put(screenClass, screenDisplayBoundsHandlers.stream().filter(this::filterResponsible).sorted(BOUNDS_HANDLER_COMPARATOR).findAny().orElse(EMPTY));
         return handlerCache.get(screenClass);
     }
     
+    public boolean filterResponsible(DisplayBoundsHandler handler) {
+        return handler.getBaseSupportedClass().isAssignableFrom(tempScreen);
+    }
+    
     @Override
     public void registerBoundsHandler(DisplayBoundsHandler<?> handler) {
         screenDisplayBoundsHandlers.add(handler);
@@ -86,6 +95,7 @@ public class DisplayHelperImpl implements DisplayHelper {
     
     public void resetCache() {
         handlerCache.clear();
+        handlerSortedCache.clear();
     }
     
 }