Fix accidental LIFO order on tick list when queueing ticks (when it always should be FIFO)

This commit is contained in:
DBotThePony 2023-12-30 19:57:21 +07:00
parent 7c9657c6d2
commit 023081eaaa
Signed by: DBot
GPG Key ID: DCC23B5715498507

View File

@ -1,21 +1,24 @@
package ru.dbotthepony.mc.otm.core.util package ru.dbotthepony.mc.otm.core.util
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap
import it.unimi.dsi.fastutil.objects.ObjectAVLTreeSet
import org.apache.logging.log4j.LogManager import org.apache.logging.log4j.LogManager
import ru.dbotthepony.mc.otm.core.addSorted import ru.dbotthepony.mc.otm.core.addSorted
import java.util.concurrent.atomic.AtomicInteger
class TickList : ITickable { class TickList : ITickable {
private val conditional = ArrayDeque<IConditionalTickable>() private val conditional = ArrayList<IConditionalTickable>()
private val conditionalQueued = ArrayList<IConditionalTickable>() private val conditionalQueued = ArrayList<IConditionalTickable>()
private val once = ArrayDeque<ITickable>() private val once = ArrayList<ITickable>()
private val onceQueued = ArrayList<ITickable>() private val onceQueued = ArrayList<ITickable>()
private val always = ArrayList<ITickable>() private val always = ArrayList<ITickable>()
private val alwaysQueued = ArrayList<ITickable>() private val alwaysQueued = ArrayList<ITickable>()
private val toRemoveFromAlways = ArrayList<ITickable>() private val toRemoveFromAlways = ArrayList<ITickable>()
private val timers = ArrayDeque<Timer>() private val timers = ObjectAVLTreeSet<Timer>()
private val nextTimerID = AtomicInteger()
private val namedTimers = Object2ObjectOpenHashMap<Any, Timer>(0) private val namedTimers = Object2ObjectOpenHashMap<Any, Timer>(0)
private var shouldTick = false private var shouldTick = false
@ -24,21 +27,26 @@ class TickList : ITickable {
private set private set
var ticks = 0 var ticks = 0
private set private set
private var nextSometime = 0 private var nextSometime = 0
inner class Timer(val timerTicks: Int, val runnable: Runnable) : Comparable<Timer> { inner class Timer(val timerTicks: Int, val runnable: Runnable) : Comparable<Timer> {
val ringAt = ticks + timerTicks val ringAt = ticks + timerTicks
val timerID = nextTimerID.incrementAndGet()
var finished = false var finished = false
private set private set
init { init {
shouldTick = true shouldTick = true
timers.addSorted(this) timers.add(this)
} }
override fun compareTo(other: Timer): Int { 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() { fun execute() {
@ -174,22 +182,13 @@ class TickList : ITickable {
try { try {
if (conditional.isNotEmpty()) { if (conditional.isNotEmpty()) {
shouldTick = true shouldTick = true
val iterator = conditional.iterator() conditional.removeIf { !it.tick() }
for (ticker in iterator) {
if (!ticker.tick()) {
iterator.remove()
}
}
} }
if (once.isNotEmpty()) { if (once.isNotEmpty()) {
shouldTick = true shouldTick = true
for (ticker in once) { for (ticker in once) ticker.tick()
ticker.tick()
}
once.clear() once.clear()
} }
@ -219,20 +218,14 @@ class TickList : ITickable {
if (conditionalQueued.isNotEmpty()) { if (conditionalQueued.isNotEmpty()) {
shouldTick = true shouldTick = true
for (ticker in conditionalQueued) { for (ticker in conditionalQueued) conditional.add(ticker)
conditional.addFirst(ticker)
}
conditionalQueued.clear() conditionalQueued.clear()
} }
if (onceQueued.isNotEmpty()) { if (onceQueued.isNotEmpty()) {
shouldTick = true shouldTick = true
for (ticker in onceQueued) { for (ticker in onceQueued) once.add(ticker)
once.addFirst(ticker)
}
onceQueued.clear() onceQueued.clear()
} }
@ -241,7 +234,7 @@ class TickList : ITickable {
if (head.ringAt <= ticks) { if (head.ringAt <= ticks) {
head.execute() head.execute()
timers.removeFirst() timers.remove(head)
} else { } else {
break break
} }