aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin/util/data/IDataHolder.kt
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/kotlin/util/data/IDataHolder.kt')
-rw-r--r--src/main/kotlin/util/data/IDataHolder.kt154
1 files changed, 100 insertions, 54 deletions
diff --git a/src/main/kotlin/util/data/IDataHolder.kt b/src/main/kotlin/util/data/IDataHolder.kt
index 1e9ba98..3229011 100644
--- a/src/main/kotlin/util/data/IDataHolder.kt
+++ b/src/main/kotlin/util/data/IDataHolder.kt
@@ -1,71 +1,117 @@
package moe.nea.firmament.util.data
-import java.util.concurrent.CopyOnWriteArrayList
-import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents
-import kotlin.reflect.KClass
-import net.minecraft.text.Text
+import java.util.UUID
+import java.util.concurrent.CompletableFuture
+import kotlinx.serialization.KSerializer
+import kotlinx.serialization.json.JsonObject
+import kotlinx.serialization.json.buildJsonObject
import moe.nea.firmament.Firmament
-import moe.nea.firmament.events.ScreenChangeEvent
-import moe.nea.firmament.util.MC
+import moe.nea.firmament.gui.config.storage.ConfigStorageClass
+import moe.nea.firmament.gui.config.storage.FirmamentConfigLoader
+import moe.nea.firmament.util.SBData
-interface IDataHolder<T> {
- companion object {
- internal var badLoads: MutableList<String> = CopyOnWriteArrayList()
- private val allConfigs: MutableMap<KClass<out IDataHolder<*>>, IDataHolder<*>> = mutableMapOf()
- private val dirty: MutableSet<KClass<out IDataHolder<*>>> = mutableSetOf()
+sealed class IDataHolder<T> {
+ fun markDirty(future: CompletableFuture<Void?>? = null) {
+ FirmamentConfigLoader.markDirty(this, future)
+ }
- internal fun <T : IDataHolder<K>, K> putDataHolder(kClass: KClass<T>, inst: IDataHolder<K>) {
- allConfigs[kClass] = inst
- }
+ init {
+ require(this.javaClass.getAnnotation(Config::class.java) != null)
+ }
+
+ abstract fun keys(): Collection<T>
+ abstract fun saveTo(key: T): JsonObject
+ abstract fun loadFrom(key: T, jsonObject: JsonObject)
+ abstract fun explicitDefaultLoad()
+ abstract fun clear()
+ abstract val storageClass: ConfigStorageClass
+}
+
+open class ProfileKeyedConfig<T>(
+ val prefix: String,
+ val serializer: KSerializer<T>,
+ val default: () -> T & Any,
+) : IDataHolder<UUID>() {
+
+ override val storageClass: ConfigStorageClass
+ get() = ConfigStorageClass.PROFILE
+ private var _data: MutableMap<UUID, T>? = null
- fun <T : IDataHolder<K>, K> markDirty(kClass: KClass<T>) {
- if (kClass !in allConfigs) {
- Firmament.logger.error("Tried to markDirty '${kClass.qualifiedName}', which isn't registered as 'IConfigHolder'")
- return
- }
- dirty.add(kClass)
+ val data: T & Any
+ get() {
+ val map = _data ?: error("Config $this not loaded — forgot to register?")
+ map[SBData.profileIdOrNil]?.let { return it }
+ val newValue = default()
+ map[SBData.profileIdOrNil] = newValue
+ return newValue
}
- private fun performSaves() {
- val toSave = dirty.toList().also {
- dirty.clear()
- }
- for (it in toSave) {
- val obj = allConfigs[it]
- if (obj == null) {
- Firmament.logger.error("Tried to save '${it}', which isn't registered as 'ConfigHolder'")
- continue
- }
- obj.save()
- }
+ override fun keys(): Collection<UUID> {
+ return _data!!.keys
+ }
+
+ override fun saveTo(key: UUID): JsonObject {
+ val d = _data!!
+ return buildJsonObject {
+ put(prefix, Firmament.json.encodeToJsonElement(serializer, d[key] ?: return@buildJsonObject))
}
+ }
- private fun warnForResetConfigs() {
- if (badLoads.isNotEmpty()) {
- MC.sendChat(
- Text.literal(
- "The following configs have been reset: ${badLoads.joinToString(", ")}. " +
- "This can be intentional, but probably isn't."
- )
- )
- badLoads.clear()
- }
+ override fun loadFrom(key: UUID, jsonObject: JsonObject) {
+ var map = _data
+ if (map == null) {
+ map = mutableMapOf()
+ _data = map
}
+ map[key] =
+ jsonObject[prefix]
+ ?.let {
+ Firmament.json.decodeFromJsonElement(serializer, it)
+ } ?: default()
+ }
- fun registerEvents() {
- ScreenChangeEvent.subscribe("IDataHolder:saveOnScreenChange") { event ->
- performSaves()
- warnForResetConfigs()
- }
- ClientLifecycleEvents.CLIENT_STOPPING.register(ClientLifecycleEvents.ClientStopping {
- performSaves()
- })
+ override fun explicitDefaultLoad() {
+ _data = mutableMapOf()
+ }
+
+ override fun clear() {
+ _data = null
+ }
+}
+
+abstract class GenericConfig<T>(
+ val prefix: String,
+ val serializer: KSerializer<T>,
+ val default: () -> T,
+) : IDataHolder<Unit>() {
+
+ private var _data: T? = null
+
+ val data get() = _data ?: error("Config $this not loaded — forgot to register?")
+
+ override fun keys(): Collection<Unit> {
+ return listOf(Unit)
+ }
+
+ override fun explicitDefaultLoad() {
+ _data = default()
+ }
+
+ open fun onLoad() {
+ }
+
+ override fun saveTo(key: Unit): JsonObject {
+ return buildJsonObject {
+ put(prefix, Firmament.json.encodeToJsonElement(serializer, data))
}
+ }
+ override fun loadFrom(key: Unit, jsonObject: JsonObject) {
+ _data = jsonObject[prefix]?.let { Firmament.json.decodeFromJsonElement(serializer, it) } ?: default()
+ onLoad()
}
- val data: T
- fun save()
- fun markDirty()
- fun load()
+ override fun clear() {
+ _data = null
+ }
}