Eliminate most of TickList's internal logic, greatly speeding it up
This commit is contained in:
parent
884caba048
commit
f416cd69e5
@ -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<IConditionalTickable>()
|
||||
private val conditionalQueued = ArrayList<IConditionalTickable>()
|
||||
|
||||
private val once = ArrayList<ITickable>()
|
||||
private val onceQueued = ArrayList<ITickable>()
|
||||
|
||||
private val always = ArrayList<ITickable>()
|
||||
private val alwaysQueued = ArrayList<ITickable>()
|
||||
private val toRemoveFromAlways = ArrayList<ITickable>()
|
||||
private val tickers = LinkedList<IConditionalTickable>()
|
||||
private val queuedTickers = ArrayList<IConditionalTickable>()
|
||||
|
||||
private val timers = PriorityQueue<Timer>()
|
||||
private val namedTimers = Object2ObjectOpenHashMap<Any, Timer>(0)
|
||||
|
||||
private var shouldTick = false
|
||||
private val namedTimers = HashMap<Any?, Timer>()
|
||||
|
||||
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 <T : Any> add(value: T, regular: MutableList<T>, queue: MutableList<T>) {
|
||||
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()
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user