49 lines
1.1 KiB
Kotlin
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)
|
|
}
|
|
}
|