aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin/features/texturepack/TintOverrides.kt
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/kotlin/features/texturepack/TintOverrides.kt')
-rw-r--r--src/main/kotlin/features/texturepack/TintOverrides.kt75
1 files changed, 75 insertions, 0 deletions
diff --git a/src/main/kotlin/features/texturepack/TintOverrides.kt b/src/main/kotlin/features/texturepack/TintOverrides.kt
new file mode 100644
index 0000000..8006db8
--- /dev/null
+++ b/src/main/kotlin/features/texturepack/TintOverrides.kt
@@ -0,0 +1,75 @@
+package moe.nea.firmament.features.texturepack
+
+import com.google.gson.JsonObject
+import com.google.gson.JsonPrimitive
+import moe.nea.firmament.util.ErrorUtil
+import moe.nea.firmament.util.assertNotNullOr
+
+data class TintOverrides(
+ val layerMap: Map<Int, TintOverride> = mapOf()
+) {
+ val hasOverrides by lazy { layerMap.values.any { it !is Reset } }
+
+ companion object {
+ val EMPTY = TintOverrides()
+ private val threadLocal = object : ThreadLocal<TintOverrides>() {}
+ fun enter(overrides: TintOverrides?) {
+ ErrorUtil.softCheck("Double entered tintOverrides") {
+ threadLocal.get() == null
+ }
+ threadLocal.set(overrides ?: EMPTY)
+ }
+
+ fun exit(overrides: TintOverrides?) {
+ ErrorUtil.softCheck("Exited with non matching enter tintOverrides") {
+ threadLocal.get() == (overrides ?: EMPTY)
+ }
+ threadLocal.remove()
+ }
+
+ fun getCurrentOverrides() =
+ assertNotNullOr(threadLocal.get(), "Got current tintOverrides without entering") { EMPTY }
+
+ fun parse(jsonObject: JsonObject): TintOverrides {
+ val map = mutableMapOf<Int, TintOverride>()
+ for ((key, value) in jsonObject.entrySet()) {
+ val layerIndex =
+ ErrorUtil.notNullOr(key.toIntOrNull(),
+ "Unknown layer index $value. Should be integer") { continue }
+ if (value.isJsonNull) {
+ map[layerIndex] = Reset
+ continue
+ }
+ val override = (value as? JsonPrimitive)
+ ?.takeIf(JsonPrimitive::isNumber)
+ ?.asInt
+ ?.let(::Fixed)
+ if (override == null) {
+ ErrorUtil.softError("Invalid tint override for a layer: $value")
+ continue
+ }
+ map[layerIndex] = override
+ }
+ return TintOverrides(map)
+ }
+ }
+
+ fun mergeWithParent(parent: TintOverrides): TintOverrides {
+ val mergedMap = parent.layerMap.toMutableMap()
+ mergedMap.putAll(this.layerMap)
+ return TintOverrides(mergedMap)
+ }
+
+ fun hasOverrides(): Boolean = hasOverrides
+ fun getOverride(tintIndex: Int): Int? {
+ return when (val tint = layerMap[tintIndex]) {
+ is Reset -> null
+ is Fixed -> tint.color
+ null -> null
+ }
+ }
+
+ sealed interface TintOverride
+ data object Reset : TintOverride
+ data class Fixed(val color: Int) : TintOverride
+}