KStarbound/src/main/kotlin/ru/dbotthepony/kstarbound/util/AssetPathStack.kt

49 lines
1.1 KiB
Kotlin

package ru.dbotthepony.kstarbound.util
import com.google.common.collect.Interner
import kotlin.concurrent.getOrSet
class AssetPathStack(private val interner: Interner<String>? = null) {
private val _stack = ThreadLocal<ArrayDeque<String>>()
private val stack: ArrayDeque<String> get() = _stack.getOrSet { ArrayDeque() }
fun push(value: String) {
stack.addLast(value)
}
fun pushFilename(value: String) {
push(value.substringBefore(':').substringBeforeLast('/'))
}
fun last() = stack.lastOrNull()
fun pop() = stack.removeLast()
inline fun <T> block(path: String, block: (String) -> T): T {
try {
push(path)
return block.invoke(path)
} finally {
pop()
}
}
inline operator fun <T> invoke(path: String, block: (String) -> T) = block(path, block)
private fun remap(a: String, b: String): String {
if (b.isEmpty())
return a
if (b[0] == '/')
return b
return interner?.intern("$a/$b") ?: "$a/$b"
}
fun remap(path: String): String {
return remap(checkNotNull(last()) { "Not reading an asset on current thread" }, path)
}
fun remapSafe(path: String): String? {
return remap(last() ?: return null, path)
}
}