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

54 lines
1.2 KiB
Kotlin

package ru.dbotthepony.kstarbound.util
import com.github.benmanes.caffeine.cache.Interner
import kotlin.concurrent.getOrSet
class PathStack(private val interner: Interner<String> = Interner { it }) {
private val _stack = object : ThreadLocal<ArrayDeque<String>>() {
override fun initialValue(): ArrayDeque<String> {
return ArrayDeque()
}
}
private val stack: ArrayDeque<String> get() = _stack.get()
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")
}
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)
}
}