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