KStarbound/src/main/kotlin/ru/dbotthepony/kstarbound/LoadingLog.kt

88 lines
1.8 KiB
Kotlin

package ru.dbotthepony.kstarbound
import it.unimi.dsi.fastutil.ints.IntIterators
import it.unimi.dsi.fastutil.objects.ObjectIterators
interface ILoadingLog : Iterable<ILoadingLog.ILine> {
interface ILine {
var text: String
val progress: Float
get() = if (maxElements > 0) elements.toFloat() / maxElements.toFloat() else 0f
var elements: Int
var maxElements: Int
}
fun line(text: String): ILine
companion object : ILoadingLog, ILine {
override var text: String
get() = ""
set(value) {}
override var elements: Int
get() = 0
set(value) {}
override var maxElements: Int
get() = 0
set(value) {}
override fun line(text: String): ILine {
return this
}
override fun iterator(): Iterator<ILine> {
return ObjectIterators.emptyIterator()
}
}
}
class LoadingLog : ILoadingLog {
private val lines = arrayOfNulls<Line>(128)
private var index = 0
private val lock = Any()
private var size = 0
var lastActivity: Long = System.nanoTime()
private set
override fun line(text: String): ILoadingLog.ILine {
return Line(text)
}
inner class Line(text: String) : ILoadingLog.ILine {
override var text: String = text
set(value) {
field = value
lastActivity = System.nanoTime()
}
@Volatile
override var elements: Int = 0
override var maxElements: Int = 0
init {
lastActivity = System.nanoTime()
synchronized(lock) {
lines[index++ and 127] = this
size = (size + 1).coerceAtMost(127)
}
}
}
override fun iterator(): Iterator<ILoadingLog.ILine> {
return object : Iterator<ILoadingLog.ILine> {
private val index = (this@LoadingLog.index - 1) and 127
private val parent = IntIterators.fromTo(0, size)
override fun hasNext(): Boolean {
return parent.hasNext()
}
override fun next(): ILoadingLog.ILine {
return lines[(index - parent.nextInt()) and 127]!!
}
}
}
}