diff options
author | Kevin <92656833+kevinthegreat1@users.noreply.github.com> | 2023-09-12 21:15:45 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-09-12 21:15:45 -0400 |
commit | eaca5ec7dc631e4c56ec3cbf2655e54d90ae2358 (patch) | |
tree | d73344e341b17f28c499f9ec7f468736efa1672c /src/main/java/me/xmrvizzy/skyblocker/utils | |
parent | cddd32a81916bffa67a3de0e5754c8068fc2d56e (diff) | |
parent | 059385f9dd070beae77a77bebae34f0ca06b664a (diff) | |
download | Skyblocker-eaca5ec7dc631e4c56ec3cbf2655e54d90ae2358.tar.gz Skyblocker-eaca5ec7dc631e4c56ec3cbf2655e54d90ae2358.tar.bz2 Skyblocker-eaca5ec7dc631e4c56ec3cbf2655e54d90ae2358.zip |
Merge pull request #295 from kevinthegreat1/scheduler
Optimize Scheduler
Diffstat (limited to 'src/main/java/me/xmrvizzy/skyblocker/utils')
4 files changed, 59 insertions, 40 deletions
diff --git a/src/main/java/me/xmrvizzy/skyblocker/utils/Utils.java b/src/main/java/me/xmrvizzy/skyblocker/utils/Utils.java index 1e8e7ffa..149004c4 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/utils/Utils.java +++ b/src/main/java/me/xmrvizzy/skyblocker/utils/Utils.java @@ -2,9 +2,9 @@ package me.xmrvizzy.skyblocker.utils; import com.google.gson.JsonObject; import com.google.gson.JsonParser; -import me.xmrvizzy.skyblocker.SkyblockerMod; import me.xmrvizzy.skyblocker.skyblock.item.PriceInfoTooltip; import me.xmrvizzy.skyblocker.skyblock.rift.TheRift; +import me.xmrvizzy.skyblocker.utils.scheduler.MessageScheduler; import net.fabricmc.fabric.api.client.item.v1.ItemTooltipCallback; import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents; @@ -294,7 +294,7 @@ public class Utils { if (isOnSkyblock) { long currentTime = System.currentTimeMillis(); if (!sentLocRaw && currentTime > clientWorldJoinTime + 1000 && currentTime > lastLocRaw + 15000) { - SkyblockerMod.getInstance().messageScheduler.sendMessageAfterCooldown("/locraw"); + MessageScheduler.INSTANCE.sendMessageAfterCooldown("/locraw"); sentLocRaw = true; lastLocRaw = currentTime; } diff --git a/src/main/java/me/xmrvizzy/skyblocker/utils/render/title/TitleContainer.java b/src/main/java/me/xmrvizzy/skyblocker/utils/render/title/TitleContainer.java index 6e15c871..2555572c 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/utils/render/title/TitleContainer.java +++ b/src/main/java/me/xmrvizzy/skyblocker/utils/render/title/TitleContainer.java @@ -1,6 +1,5 @@ package me.xmrvizzy.skyblocker.utils.render.title; -import me.xmrvizzy.skyblocker.SkyblockerMod; import me.xmrvizzy.skyblocker.config.SkyblockerConfig; import me.xmrvizzy.skyblocker.utils.scheduler.Scheduler; import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager; @@ -66,7 +65,7 @@ public class TitleContainer { */ public static boolean addTitle(Title title, int ticks) { if (addTitle(title)) { - SkyblockerMod.getInstance().scheduler.schedule(() -> TitleContainer.removeTitle(title), ticks); + Scheduler.INSTANCE.schedule(() -> TitleContainer.removeTitle(title), ticks); return true; } return false; diff --git a/src/main/java/me/xmrvizzy/skyblocker/utils/scheduler/MessageScheduler.java b/src/main/java/me/xmrvizzy/skyblocker/utils/scheduler/MessageScheduler.java index bde29c13..b8ffa548 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/utils/scheduler/MessageScheduler.java +++ b/src/main/java/me/xmrvizzy/skyblocker/utils/scheduler/MessageScheduler.java @@ -3,19 +3,22 @@ package me.xmrvizzy.skyblocker.utils.scheduler; import net.minecraft.client.MinecraftClient; /** - * A scheduler for sending chat messages or commands. Use the instance in {@link me.xmrvizzy.skyblocker.SkyblockerMod#messageScheduler SkyblockerMod.messageScheduler}. Do not instantiate this class. + * A scheduler for sending chat messages or commands. Use the instance in {@link #INSTANCE}. Do not instantiate this class. */ -@SuppressWarnings("deprecation") public class MessageScheduler extends Scheduler { /** * The minimum delay that the server will accept between chat messages. */ private static final int MIN_DELAY = 200; + public static final MessageScheduler INSTANCE = new MessageScheduler(); /** * The timestamp of the last message send, */ private long lastMessage = 0; + protected MessageScheduler() { + } + /** * Sends a chat message or command after the minimum cooldown. Prefer this method to send messages or commands to the server. * diff --git a/src/main/java/me/xmrvizzy/skyblocker/utils/scheduler/Scheduler.java b/src/main/java/me/xmrvizzy/skyblocker/utils/scheduler/Scheduler.java index 76112e0d..700bdce3 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/utils/scheduler/Scheduler.java +++ b/src/main/java/me/xmrvizzy/skyblocker/utils/scheduler/Scheduler.java @@ -1,30 +1,28 @@ package me.xmrvizzy.skyblocker.utils.scheduler; import com.mojang.brigadier.Command; -import me.xmrvizzy.skyblocker.SkyblockerMod; +import it.unimi.dsi.fastutil.ints.AbstractInt2ObjectMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.screen.Screen; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.PriorityQueue; +import java.util.ArrayList; +import java.util.List; import java.util.function.Supplier; /** - * A scheduler for running tasks at a later time. Tasks will be run synchronously on the main client thread. Use the instance stored in {@link SkyblockerMod#scheduler}. Do not instantiate this class. + * A scheduler for running tasks at a later time. Tasks will be run synchronously on the main client thread. Use the instance stored in {@link #INSTANCE}. Do not instantiate this class. */ public class Scheduler { private static final Logger LOGGER = LoggerFactory.getLogger(Scheduler.class); + public static final Scheduler INSTANCE = new Scheduler(); private int currentTick = 0; - private final PriorityQueue<ScheduledTask> tasks = new PriorityQueue<>(); + private final AbstractInt2ObjectMap<List<ScheduledTask>> tasks = new Int2ObjectOpenHashMap<>(); - /** - * Do not instantiate this class. Use {@link SkyblockerMod#scheduler} instead. - */ - @SuppressWarnings("DeprecatedIsStillUsed") - @Deprecated - public Scheduler() { + protected Scheduler() { } /** @@ -34,11 +32,11 @@ public class Scheduler { * @param delay the delay in ticks */ public void schedule(Runnable task, int delay) { - if (delay < 0) { + if (delay >= 0) { + addTask(new ScheduledTask(task), currentTick + delay); + } else { LOGGER.warn("Scheduled a task with negative delay"); } - ScheduledTask tmp = new ScheduledTask(task, currentTick + delay); - tasks.add(tmp); } /** @@ -48,15 +46,15 @@ public class Scheduler { * @param period the period in ticks */ public void scheduleCyclic(Runnable task, int period) { - if (period <= 0) { - LOGGER.error("Attempted to schedule a cyclic task with period lower than 1"); + if (period > 0) { + addTask(new CyclicTask(task, period), currentTick); } else { - new CyclicTask(task, period).run(); + LOGGER.error("Attempted to schedule a cyclic task with period lower than 1"); } } public static Command<FabricClientCommandSource> queueOpenScreenCommand(Supplier<Screen> screenSupplier) { - return context -> SkyblockerMod.getInstance().scheduler.queueOpenScreen(screenSupplier); + return context -> INSTANCE.queueOpenScreen(screenSupplier); } /** @@ -71,11 +69,18 @@ public class Scheduler { } public void tick() { - currentTick += 1; - ScheduledTask task; - while ((task = tasks.peek()) != null && task.schedule <= currentTick && runTask(task)) { - tasks.poll(); + if (tasks.containsKey(currentTick)) { + List<ScheduledTask> currentTickTasks = tasks.get(currentTick); + //noinspection ForLoopReplaceableByForEach (or else we get a ConcurrentModificationException) + for (int i = 0; i < currentTickTasks.size(); i++) { + ScheduledTask task = currentTickTasks.get(i); + if (!runTask(task)) { + tasks.computeIfAbsent(currentTick + 1, key -> new ArrayList<>()).add(task); + } + } + tasks.remove(currentTick); } + currentTick += 1; } /** @@ -89,30 +94,42 @@ public class Scheduler { return true; } + private void addTask(ScheduledTask scheduledTask, int schedule) { + if (tasks.containsKey(schedule)) { + tasks.get(schedule).add(scheduledTask); + } else { + List<ScheduledTask> list = new ArrayList<>(); + list.add(scheduledTask); + tasks.put(schedule, list); + } + } + /** * A task that runs every period ticks. More specifically, this task reschedules itself to run again after period ticks every time it runs. - * - * @param inner the task to run - * @param period the period in ticks */ - protected record CyclicTask(Runnable inner, int period) implements Runnable { + protected class CyclicTask extends ScheduledTask { + private final int period; + + CyclicTask(Runnable inner, int period) { + super(inner); + this.period = period; + } + @Override public void run() { - SkyblockerMod.getInstance().scheduler.schedule(this, period); - inner.run(); + super.run(); + addTask(this, currentTick + period); } } /** * A task that runs at a specific tick, relative to {@link #currentTick}. - * - * @param inner the task to run - * @param schedule the tick to run at */ - protected record ScheduledTask(Runnable inner, int schedule) implements Comparable<ScheduledTask>, Runnable { - @Override - public int compareTo(ScheduledTask o) { - return schedule - o.schedule; + protected static class ScheduledTask implements Runnable { + private final Runnable inner; + + public ScheduledTask(Runnable inner) { + this.inner = inner; } @Override |