From ad940f51ee86c9c3367e1374e32946e1e35499d8 Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 21 Aug 2020 18:46:03 -0400 Subject: [PATCH] xp globes: fix timing out xp globes after no xp is gained The overlay was clobbering the plugins sorted xpglobe list when it re-sorted it by skill instead, preventing the expire routine from correctly expiring xpglobes. Instead keep the list in render order (by skill) and just check the full list for expired orbs, since there are not usually many to check. --- .../plugins/xpglobes/XpGlobesOverlay.java | 8 ++-- .../plugins/xpglobes/XpGlobesPlugin.java | 44 ++++++++----------- 2 files changed, 22 insertions(+), 30 deletions(-) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xpglobes/XpGlobesOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/xpglobes/XpGlobesOverlay.java index 4b2654948c..4beb3f6347 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/xpglobes/XpGlobesOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/xpglobes/XpGlobesOverlay.java @@ -96,17 +96,15 @@ public class XpGlobesOverlay extends Overlay @Override public Dimension render(Graphics2D graphics) { - final int queueSize = plugin.getXpGlobesSize(); + final List xpGlobes = plugin.getXpGlobes(); + final int queueSize = xpGlobes.size(); if (queueSize == 0) { return null; } - final List sortedXpGlobes = plugin.getXpGlobes(); - sortedXpGlobes.sort((a, b) -> a.getSkill().compareTo(b.getSkill())); - int curDrawX = 0; - for (final XpGlobe xpGlobe : sortedXpGlobes) + for (final XpGlobe xpGlobe : xpGlobes) { int startXp = xpTrackerService.getStartGoalXp(xpGlobe.getSkill()); int goalXp = xpTrackerService.getEndGoalXp(xpGlobe.getSkill()); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/xpglobes/XpGlobesPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/xpglobes/XpGlobesPlugin.java index 9a19e6a0fd..a09d817276 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/xpglobes/XpGlobesPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/xpglobes/XpGlobesPlugin.java @@ -28,7 +28,8 @@ import com.google.inject.Provides; import java.time.Instant; import java.time.temporal.ChronoUnit; import java.util.ArrayList; -import java.util.Iterator; +import java.util.Collections; +import java.util.Comparator; import java.util.List; import javax.inject.Inject; import lombok.Getter; @@ -118,7 +119,7 @@ public class XpGlobesPlugin extends Plugin cachedGlobe.setCurrentXp(currentXp); cachedGlobe.setCurrentLevel(currentLevel); cachedGlobe.setTime(Instant.now()); - this.addXpGlobe(globeCache[skillIdx], MAXIMUM_SHOWN_GLOBES); + addXpGlobe(globeCache[skillIdx]); } else { @@ -127,20 +128,22 @@ public class XpGlobesPlugin extends Plugin } } - private void addXpGlobe(XpGlobe xpGlobe, int maxLength) + private void addXpGlobe(XpGlobe xpGlobe) { - //remove the old globe, allowing it to be readded as the most recent (right) side when drawn - xpGlobes.remove(xpGlobe); - if (getXpGlobesSize() >= maxLength) + // insert the globe, ordered by skill, if it isn't already in the list to be drawn + int idx = Collections.binarySearch(xpGlobes, xpGlobe, Comparator.comparing(XpGlobe::getSkill)); + if (idx < 0) { - xpGlobes.remove(0); - } - xpGlobes.add(xpGlobe); - } + xpGlobes.add(-idx - 1, xpGlobe); - int getXpGlobesSize() - { - return xpGlobes.size(); + // remove the oldest globe if there are too many + if (xpGlobes.size() > MAXIMUM_SHOWN_GLOBES) + { + xpGlobes.stream() + .min(Comparator.comparing(XpGlobe::getTime)) + .ifPresent(xpGlobes::remove); + } + } } @Schedule( @@ -151,18 +154,9 @@ public class XpGlobesPlugin extends Plugin { if (!xpGlobes.isEmpty()) { - Instant currentTime = Instant.now(); - for (Iterator it = xpGlobes.iterator(); it.hasNext();) - { - XpGlobe globe = it.next(); - Instant globeCreationTime = globe.getTime(); - if (currentTime.isBefore(globeCreationTime.plusSeconds(config.xpOrbDuration()))) - { - //if a globe is not expired, stop checking newer globes - return; - } - it.remove(); - } + Instant expireTime = Instant.now() + .minusSeconds(config.xpOrbDuration()); + xpGlobes.removeIf(globe -> globe.getTime().isBefore(expireTime)); } }