aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin/util/data/IDataHolder.kt
blob: de6dff86b879efdbc2f6d47fd070f2fc70fd4266 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package moe.nea.firmament.util.data

import java.util.UUID
import kotlinx.serialization.KSerializer
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.buildJsonObject
import moe.nea.firmament.Firmament
import moe.nea.firmament.gui.config.storage.ConfigStorageClass
import moe.nea.firmament.gui.config.storage.FirmamentConfigLoader
import moe.nea.firmament.util.SBData

sealed class IDataHolder<T> {
	fun markDirty() {
		FirmamentConfigLoader.markDirty(this)
	}

	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

	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
		}

	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))
		}
	}

	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()
	}

	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()
	}

	override fun clear() {
		_data = null
	}
}