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