Files
BetterFoliage/src/main/kotlin/mods/betterfoliage/util/Misc.kt
octarine-noise 81d3a2eba4 [WIP] beginning port to 1.16.5
+most of the stuff is working
2021-05-14 22:40:04 +02:00

74 lines
2.9 KiB
Kotlin

@file:Suppress("NOTHING_TO_INLINE")
package mods.betterfoliage.util
import mods.betterfoliage.BetterFoliage
import net.minecraft.text.LiteralText
import net.minecraft.text.Style
import net.minecraft.util.Formatting
import net.minecraft.util.Identifier
import net.minecraft.util.math.BlockPos
import net.minecraft.world.World
import java.lang.Math.*
import kotlin.reflect.KProperty
const val PI2 = 2.0 * PI
/** Strip the given prefix off the start of the string, if present */
inline fun String.stripStart(str: String, ignoreCase: Boolean = true) = if (startsWith(str, ignoreCase)) substring(str.length) else this
inline fun String.stripEnd(str: String, ignoreCase: Boolean = true) = if (endsWith(str, ignoreCase)) substring(0, length - str.length) else this
/** Strip the given prefix off the start of the resource path, if present */
inline fun Identifier.stripStart(str: String) = Identifier(namespace, path.stripStart(str))
inline fun Identifier.stripEnd(str: String) = Identifier(namespace, path.stripEnd(str))
/**
* Property-level delegate backed by a [ThreadLocal].
*
* @param[init] Lambda to get initial value
*/
class ThreadLocalDelegate<T>(init: () -> T) {
var tlVal = ThreadLocal.withInitial(init)
operator fun getValue(thisRef: Any?, property: KProperty<*>): T = tlVal.get()
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) { tlVal.set(value) }
}
/** Call the supplied lambda and return its result, or the given default value if an exception is thrown. */
fun <T> tryDefault(default: T, work: ()->T) = try { work() } catch (e: Throwable) { default }
/**
* Return this [Double] value if it lies between the two limits. If outside, return the
* minimum/maximum value correspondingly.
*/
fun Double.minmax(minVal: Double, maxVal: Double) = min(max(this, minVal), maxVal)
/**
* Return this [Int] value if it lies between the two limits. If outside, return the
* minimum/maximum value correspondingly.
*/
fun Int.minmax(minVal: Int, maxVal: Int) = min(max(this, minVal), maxVal)
fun nextPowerOf2(x: Int): Int {
return 1 shl (if (x == 0) 0 else 32 - Integer.numberOfLeadingZeros(x - 1))
}
/**
* Check if the Chunk containing the given [BlockPos] is loaded.
* Works for both [World] and [ChunkCache] (vanilla and OptiFine) instances.
*/
//fun IWorldReader.isBlockLoaded(pos: BlockPos) = when {
// this is World -> isBlockLoaded(pos, false)
// this is RenderChunkCache -> isworld.isBlockLoaded(pos, false)
// Refs.OptifineChunkCache.isInstance(this) -> (Refs.CCOFChunkCache.get(this) as ChunkCache).world.isBlockLoaded(pos, false)
// else -> false
//}
@Suppress("LeakingThis")
abstract class HasLogger {
val logger = BetterFoliage.logger(this)
val detailLogger = BetterFoliage.detailLogger(this)
}
fun textComponent(msg: String, color: Formatting = Formatting.GRAY): LiteralText {
val style = Style.EMPTY.withColor(color)
return LiteralText(msg).apply { this.style = style }
}