diff options
| author | Unknown <shekwancheung0528@gmail.com> | 2019-08-13 01:36:18 +0800 |
|---|---|---|
| committer | Unknown <shekwancheung0528@gmail.com> | 2019-08-13 01:36:18 +0800 |
| commit | f3c5a830dc55ef44db2cc73cad0abed5a952ae7d (patch) | |
| tree | 74858de87fdfe7d5a8ec69068426b4f12c71c610 /src/main/java | |
| parent | 47c7c18456493bc584835dcc3dd19d5dc444cc23 (diff) | |
| download | RoughlyEnoughItems-f3c5a830dc55ef44db2cc73cad0abed5a952ae7d.tar.gz RoughlyEnoughItems-f3c5a830dc55ef44db2cc73cad0abed5a952ae7d.tar.bz2 RoughlyEnoughItems-f3c5a830dc55ef44db2cc73cad0abed5a952ae7d.zip | |
Cache handlers so it won't leak ram
Diffstat (limited to 'src/main/java')
3 files changed, 47 insertions, 35 deletions
diff --git a/src/main/java/me/shedaniel/rei/api/BaseBoundsHandler.java b/src/main/java/me/shedaniel/rei/api/BaseBoundsHandler.java index 3dea674fe..b93730a51 100644 --- a/src/main/java/me/shedaniel/rei/api/BaseBoundsHandler.java +++ b/src/main/java/me/shedaniel/rei/api/BaseBoundsHandler.java @@ -18,7 +18,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<? extends Screen> currentScreenClass, boolean isOnRightSide); + default List<Rectangle> getCurrentExclusionZones(Class<? extends Screen> currentScreenClass, boolean isOnRightSide) { + return getCurrentExclusionZones(currentScreenClass, isOnRightSide, true); + } + + List<Rectangle> getCurrentExclusionZones(Class<? extends Screen> currentScreenClass, boolean isOnRightSide, boolean sort); /** * Register an exclusion zone diff --git a/src/main/java/me/shedaniel/rei/client/BaseBoundsHandlerImpl.java b/src/main/java/me/shedaniel/rei/client/BaseBoundsHandlerImpl.java index 972fba8b3..e6b807696 100644 --- a/src/main/java/me/shedaniel/rei/client/BaseBoundsHandlerImpl.java +++ b/src/main/java/me/shedaniel/rei/client/BaseBoundsHandlerImpl.java @@ -18,23 +18,20 @@ 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, String> RECTANGLE_STRING_FUNCTION = rectangle -> rectangle.x + "," + rectangle.y + "," + rectangle.width + "," + rectangle.height; - private static final Comparator<Rectangle> RECTANGLE_COMPARATOR = BaseBoundsHandlerImpl::compare; - private static final Comparator<Pair<Pair<Class<? extends Screen>, Float>, ExclusionZoneSupplier>> LIST_PAIR_COMPARATOR; + private static final Function<? super 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>, ExclusionZoneSupplier>> LIST_PAIR_COMPARATOR; + private static final Comparator<? super Rectangle> RECTANGLE_COMPARER = Comparator.comparingLong(RECTANGLE_LONG_FUNCTION::apply); static { - Comparator<Pair<Pair<Class<? extends Screen>, Float>, ExclusionZoneSupplier>> comparator = Comparator.comparingDouble(value -> value.getLeft().getRight()); + Comparator<Pair<Pair<Class<?>, Float>, ExclusionZoneSupplier>> comparator = Comparator.comparingDouble(value -> value.getLeft().getRight()); LIST_PAIR_COMPARATOR = comparator.reversed(); } - private String lastArea = null; - private List<Pair<Pair<Class<? extends Screen>, Float>, ExclusionZoneSupplier>> list = Lists.newArrayList(); - - private static int compare(Rectangle o1, Rectangle o2) {return RECTANGLE_STRING_FUNCTION.apply(o1).compareTo(RECTANGLE_STRING_FUNCTION.apply(o2));} + private long lastArea = -1; + private List<Pair<Pair<Class<?>, Float>, ExclusionZoneSupplier>> list = Lists.newArrayList(); @Override public Class getBaseSupportedClass() { @@ -58,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; @@ -66,13 +63,10 @@ public class BaseBoundsHandlerImpl implements BaseBoundsHandler { @Override public boolean shouldRecalculateArea(boolean isOnRightSide, Rectangle rectangle) { - if (lastArea == null) { - lastArea = getStringFromCurrent(isOnRightSide); - return false; - } - if (lastArea.contentEquals(getStringFromCurrent(isOnRightSide))) + long current = getStringFromCurrent(isOnRightSide); + if (lastArea == current) return false; - lastArea = getStringFromCurrent(isOnRightSide); + lastArea = current; return true; } @@ -80,24 +74,27 @@ public class BaseBoundsHandlerImpl implements BaseBoundsHandler { return RoughlyEnoughItemsCore.getDisplayHelper().getResponsibleBoundsHandler(MinecraftClient.getInstance().currentScreen.getClass()); } - private String getStringFromCurrent(boolean isOnRightSide) { - return getStringFromAreas(isOnRightSide ? getHandler().getRightBounds(MinecraftClient.getInstance().currentScreen) : getHandler().getLeftBounds(MinecraftClient.getInstance().currentScreen), getCurrentExclusionZones(MinecraftClient.getInstance().currentScreen.getClass(), isOnRightSide)); + private long getStringFromCurrent(boolean 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<? extends Screen> currentScreenClass, boolean isOnRightSide) { - List<Pair<Pair<Class<? extends Screen>, Float>, ExclusionZoneSupplier>> only = list.stream().filter(pair -> pair.getLeft().getLeft().isAssignableFrom(currentScreenClass)).collect(Collectors.toList()); - only.sort(LIST_PAIR_COMPARATOR); + @Override + public List<Rectangle> getCurrentExclusionZones(Class<? extends Screen> currentScreenClass, boolean isOnRightSide, boolean sort) { List<Rectangle> rectangles = Lists.newArrayList(); - only.forEach(pair -> rectangles.addAll(pair.getRight().apply(isOnRightSide))); + for (Pair<Pair<Class<?>, Float>, ExclusionZoneSupplier> pair : list) { + if (pair.getLeft().getLeft().isAssignableFrom(currentScreenClass)) + rectangles.addAll(pair.getRight().apply(isOnRightSide)); + } + if (sort) + rectangles.sort(RECTANGLE_COMPARER); return rectangles; } @@ -106,10 +103,11 @@ public class BaseBoundsHandlerImpl implements BaseBoundsHandler { list.add(new Pair<>(new Pair<>(screenClass, 0f), supplier)); } - public String getStringFromAreas(Rectangle rectangle, List<Rectangle> exclusionZones) { - List<Rectangle> sorted = Lists.newArrayList(exclusionZones); - sorted.sort(RECTANGLE_COMPARATOR); - return RECTANGLE_STRING_FUNCTION.apply(rectangle) + ":" + sorted.stream().map(RECTANGLE_STRING_FUNCTION::apply).collect(Collectors.joining("|")); + public long getLongFromAreas(Rectangle rectangle, List<Rectangle> exclusionZones) { + long a = RECTANGLE_LONG_FUNCTION.apply(rectangle); + for (Rectangle exclusionZone : exclusionZones) + a -= RECTANGLE_LONG_FUNCTION.apply(exclusionZone); + return a; } } diff --git a/src/main/java/me/shedaniel/rei/client/DisplayHelperImpl.java b/src/main/java/me/shedaniel/rei/client/DisplayHelperImpl.java index 4cac6a11f..84d665c3e 100644 --- a/src/main/java/me/shedaniel/rei/client/DisplayHelperImpl.java +++ b/src/main/java/me/shedaniel/rei/client/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<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(); } } |
