Execution spinner for unified and improved spinning
This commit is contained in:
parent
2f47aa0652
commit
3e2872ea5e
@ -0,0 +1,74 @@
|
||||
package ru.dbotthepony.kstarbound.util
|
||||
|
||||
import ru.dbotthepony.kommons.util.MailboxExecutorService
|
||||
import ru.dbotthepony.kstarbound.Starbound
|
||||
import java.util.concurrent.locks.LockSupport
|
||||
import java.util.function.BooleanSupplier
|
||||
|
||||
class ExecutionSpinner(private val executor: MailboxExecutorService, private val spinner: BooleanSupplier, private val timeBetweenFrames: Long) : Runnable {
|
||||
private var lastRender = System.nanoTime()
|
||||
private var frameRenderTime = 0L
|
||||
private val frameRenderTimes = LongArray(60) { 1L }
|
||||
private var frameRenderIndex = 0
|
||||
private val renderWaitTimes = LongArray(60) { 1L }
|
||||
private var renderWaitIndex = 0
|
||||
|
||||
val averageRenderWait: Double get() {
|
||||
var sum = 0.0
|
||||
|
||||
for (value in renderWaitTimes)
|
||||
sum += value
|
||||
|
||||
if (sum == 0.0)
|
||||
return 0.0
|
||||
|
||||
sum /= 1_000_000_000.0
|
||||
return sum / renderWaitTimes.size
|
||||
}
|
||||
|
||||
val averageRenderTime: Double get() {
|
||||
var sum = 0.0
|
||||
|
||||
for (value in frameRenderTimes)
|
||||
sum += value
|
||||
|
||||
if (sum == 0.0)
|
||||
return 0.0
|
||||
|
||||
sum /= 1_000_000_000.0
|
||||
return sum / frameRenderTimes.size
|
||||
}
|
||||
|
||||
private fun timeUntilNextFrame(): Long {
|
||||
return Starbound.TICK_TIME_ADVANCE_NANOS - (System.nanoTime() - lastRender) - frameRenderTime
|
||||
}
|
||||
|
||||
fun spin(): Boolean {
|
||||
var diff = timeUntilNextFrame()
|
||||
|
||||
while (diff > 1_000_000L) {
|
||||
executor.executeQueuedTasks()
|
||||
diff = timeUntilNextFrame()
|
||||
if (diff > 1_000_000L) LockSupport.parkNanos(diff - 400_000L)
|
||||
}
|
||||
|
||||
while (diff > 0L) {
|
||||
executor.executeQueuedTasks()
|
||||
diff = timeUntilNextFrame()
|
||||
if (diff > 0L) Thread.yield()
|
||||
}
|
||||
|
||||
val mark = System.nanoTime()
|
||||
val result = spinner.asBoolean
|
||||
frameRenderTime = System.nanoTime() - mark
|
||||
frameRenderTimes[++frameRenderIndex % frameRenderTimes.size] = frameRenderTime
|
||||
renderWaitTimes[++renderWaitIndex % renderWaitTimes.size] = System.nanoTime() - lastRender
|
||||
lastRender = System.nanoTime()
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
override fun run() {
|
||||
while (spin()) {}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user