From 023081eaaaa9ba15c3f202bcf385aa31f467eed3 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Sat, 30 Dec 2023 19:57:21 +0700 Subject: [PATCH] Fix accidental LIFO order on tick list when queueing ticks (when it always should be FIFO) --- .../dbotthepony/mc/otm/core/util/TickList.kt | 43 ++++++++----------- 1 file changed, 18 insertions(+), 25 deletions(-) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/TickList.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/TickList.kt index a02a49ca8..d3d006ba2 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/TickList.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/util/TickList.kt @@ -1,21 +1,24 @@ package ru.dbotthepony.mc.otm.core.util import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap +import it.unimi.dsi.fastutil.objects.ObjectAVLTreeSet import org.apache.logging.log4j.LogManager import ru.dbotthepony.mc.otm.core.addSorted +import java.util.concurrent.atomic.AtomicInteger class TickList : ITickable { - private val conditional = ArrayDeque() + private val conditional = ArrayList() private val conditionalQueued = ArrayList() - private val once = ArrayDeque() + private val once = ArrayList() private val onceQueued = ArrayList() private val always = ArrayList() private val alwaysQueued = ArrayList() private val toRemoveFromAlways = ArrayList() - private val timers = ArrayDeque() + private val timers = ObjectAVLTreeSet() + private val nextTimerID = AtomicInteger() private val namedTimers = Object2ObjectOpenHashMap(0) private var shouldTick = false @@ -24,21 +27,26 @@ class TickList : ITickable { private set var ticks = 0 private set + private var nextSometime = 0 inner class Timer(val timerTicks: Int, val runnable: Runnable) : Comparable { val ringAt = ticks + timerTicks + val timerID = nextTimerID.incrementAndGet() var finished = false private set init { shouldTick = true - timers.addSorted(this) + timers.add(this) } override fun compareTo(other: Timer): Int { - return ringAt.compareTo(other.ringAt) + var c = ringAt.compareTo(other.ringAt) + if (c != 0) return c + c = timerID.compareTo(other.timerID) + return c } fun execute() { @@ -174,22 +182,13 @@ class TickList : ITickable { try { if (conditional.isNotEmpty()) { shouldTick = true - val iterator = conditional.iterator() - - for (ticker in iterator) { - if (!ticker.tick()) { - iterator.remove() - } - } + conditional.removeIf { !it.tick() } } if (once.isNotEmpty()) { shouldTick = true - for (ticker in once) { - ticker.tick() - } - + for (ticker in once) ticker.tick() once.clear() } @@ -219,20 +218,14 @@ class TickList : ITickable { if (conditionalQueued.isNotEmpty()) { shouldTick = true - for (ticker in conditionalQueued) { - conditional.addFirst(ticker) - } - + for (ticker in conditionalQueued) conditional.add(ticker) conditionalQueued.clear() } if (onceQueued.isNotEmpty()) { shouldTick = true - for (ticker in onceQueued) { - once.addFirst(ticker) - } - + for (ticker in onceQueued) once.add(ticker) onceQueued.clear() } @@ -241,7 +234,7 @@ class TickList : ITickable { if (head.ringAt <= ticks) { head.execute() - timers.removeFirst() + timers.remove(head) } else { break }