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 c6532ba4e..d76dd95e1 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 @@ -4,24 +4,16 @@ 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.LinkedList import java.util.PriorityQueue import java.util.concurrent.atomic.AtomicInteger class TickList : ITickable { - private val conditional = ArrayList() - private val conditionalQueued = ArrayList() - - private val once = ArrayList() - private val onceQueued = ArrayList() - - private val always = ArrayList() - private val alwaysQueued = ArrayList() - private val toRemoveFromAlways = ArrayList() + private val tickers = LinkedList() + private val queuedTickers = ArrayList() private val timers = PriorityQueue() - private val namedTimers = Object2ObjectOpenHashMap(0) - - private var shouldTick = false + private val namedTimers = HashMap() var inTicker = false private set @@ -37,7 +29,6 @@ class TickList : ITickable { private set init { - shouldTick = true timers.add(this) } @@ -66,9 +57,9 @@ class TickList : ITickable { return timer } - inner class Ticker(parent: ITickable) : ITickable by parent { + inner class Ticker(private val parent: ITickable) : IConditionalTickable { init { - add(this, always, alwaysQueued) + add(this) } var isEnabled = true @@ -77,19 +68,21 @@ class TickList : ITickable { field = value if (value) { - add(this, always, alwaysQueued) + add(this) } else { - alwaysQueued.remove(this) - - if (inTicker) { - toRemoveFromAlways.add(this) - } else { - always.remove(this) - } + queuedTickers.remove(this) } } } + override fun tick(): Boolean { + if (!isEnabled) + return false + + parent.tick() + return true + } + fun disable() { isEnabled = false } @@ -99,20 +92,14 @@ class TickList : ITickable { } } - private fun add(value: T, regular: MutableList, queue: MutableList) { - shouldTick = true - + fun add(value: IConditionalTickable) { if (inTicker) { - queue.add(value) + queuedTickers.add(value) } else { - regular.add(value) + tickers.add(value) } } - fun add(ticker: IConditionalTickable) { - add(ticker, conditional, conditionalQueued) - } - fun add(ticker: IConditionalTickable, condition: Boolean, reason: String) { if (!condition) { LOGGER.error("Refusing to add tickable $ticker because we $reason", IllegalStateException(reason)) @@ -123,7 +110,7 @@ class TickList : ITickable { } fun once(ticker: ITickable) { - add(ticker, once, onceQueued) + add(IConditionalTickable { ticker.tick(); false }) } fun once(ticker: ITickable, condition: Boolean, reason: String) { @@ -136,7 +123,7 @@ class TickList : ITickable { } fun always(ticker: ITickable) { - add(ticker, always, alwaysQueued) + add(IConditionalTickable { ticker.tick(); true }) } fun timer(timerTicks: Int, action: Runnable, condition: Boolean, reason: String): Timer? { @@ -170,59 +157,15 @@ class TickList : ITickable { } ticks++ - if (!shouldTick) return inTicker = true - shouldTick = timers.isNotEmpty() try { - if (conditional.isNotEmpty()) { - shouldTick = true - conditional.removeIf { !it.tick() } - } + tickers.removeIf { !it.tick() } - if (once.isNotEmpty()) { - shouldTick = true - - for (ticker in once) ticker.tick() - once.clear() - } - - if (toRemoveFromAlways.isNotEmpty()) { - shouldTick = true - - for (v in toRemoveFromAlways) always.remove(v) - toRemoveFromAlways.clear() - } - - if (always.isNotEmpty()) { - shouldTick = true - - for (ticker in always) { - ticker.tick() - } - } - - if (alwaysQueued.isNotEmpty()) { - shouldTick = true - - always.ensureCapacity(always.size + alwaysQueued.size) - for (v in alwaysQueued) always.add(v) // avoid toArray() - alwaysQueued.clear() - } - - if (conditionalQueued.isNotEmpty()) { - shouldTick = true - - for (ticker in conditionalQueued) conditional.add(ticker) - conditionalQueued.clear() - } - - if (onceQueued.isNotEmpty()) { - shouldTick = true - - for (ticker in onceQueued) once.add(ticker) - onceQueued.clear() + if (queuedTickers.isNotEmpty()) { + tickers.addAll(queuedTickers) + queuedTickers.clear() } while (timers.isNotEmpty()) { @@ -243,14 +186,8 @@ class TickList : ITickable { fun clear() { if (inTicker) throw ConcurrentModificationException() - conditional.clear() - conditionalQueued.clear() - - once.clear() - onceQueued.clear() - - always.clear() - alwaysQueued.clear() + tickers.clear() + queuedTickers.clear() timers.clear() }