Skip to content

Commit a9f8dd2

Browse files
feat: add ConfigFactory
1 parent e7b12c9 commit a9f8dd2

File tree

1 file changed

+100
-0
lines changed
  • plugin-shared/src/main/kotlin/app/simplecloud/plugin/api/shared/config

1 file changed

+100
-0
lines changed
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
package app.simplecloud.plugin.api.shared.config
2+
3+
import app.simplecloud.plugin.api.shared.repository.GenericEnumSerializer
4+
import kotlinx.coroutines.CoroutineScope
5+
import kotlinx.coroutines.Dispatchers
6+
import kotlinx.coroutines.Job
7+
import kotlinx.coroutines.delay
8+
import kotlinx.coroutines.isActive
9+
import kotlinx.coroutines.launch
10+
import org.spongepowered.configurate.ConfigurationOptions
11+
import org.spongepowered.configurate.kotlin.objectMapperFactory
12+
import org.spongepowered.configurate.kotlin.toNode
13+
import org.spongepowered.configurate.yaml.NodeStyle
14+
import org.spongepowered.configurate.yaml.YamlConfigurationLoader
15+
import java.io.File
16+
import java.nio.file.FileSystems
17+
import java.nio.file.Files
18+
import java.nio.file.Path
19+
import java.nio.file.StandardWatchEventKinds
20+
21+
/**
22+
* @author Niklas Nieberler
23+
*/
24+
25+
class ConfigFactory<E>(
26+
private val file: File,
27+
private val defaultConfig: E
28+
) {
29+
30+
private var config = defaultConfig
31+
private val path = file.toPath()
32+
33+
private val configurationLoader = YamlConfigurationLoader.builder()
34+
.path(this.path)
35+
.nodeStyle(NodeStyle.BLOCK)
36+
.defaultOptions { options ->
37+
options.serializers { builder ->
38+
builder.registerAnnotatedObjects(objectMapperFactory())
39+
builder.register(Enum::class.java, GenericEnumSerializer)
40+
}
41+
}
42+
.build()
43+
44+
fun loadOrCreate() {
45+
registerWatcher()
46+
if (this.file.exists()) {
47+
loadConfig()
48+
return
49+
}
50+
createDefaultConfig()
51+
}
52+
53+
private fun createDefaultConfig() {
54+
this.path.parent?.let { Files.createDirectories(it) }
55+
Files.createFile(this.path)
56+
57+
val configurationNode = this.configurationLoader.load(ConfigurationOptions.defaults())
58+
this.defaultConfig!!.toNode(configurationNode)
59+
this.configurationLoader.save(configurationNode)
60+
}
61+
62+
fun getConfig(): E = this.config
63+
64+
private fun loadConfig() {
65+
val configurationNode = this.configurationLoader.load(ConfigurationOptions.defaults())
66+
this.config = configurationNode.get(this.defaultConfig!!::class.java)
67+
?: throw IllegalStateException("Config could not be loaded")
68+
}
69+
70+
private fun registerWatcher(): Job {
71+
val watchService = FileSystems.getDefault().newWatchService()
72+
this.path.register(
73+
watchService,
74+
StandardWatchEventKinds.ENTRY_CREATE,
75+
StandardWatchEventKinds.ENTRY_MODIFY
76+
)
77+
78+
return CoroutineScope(Dispatchers.IO).launch {
79+
while (isActive) {
80+
val key = watchService.take()
81+
82+
key.pollEvents().forEach { event ->
83+
val path = event.context() as? Path ?: return@forEach
84+
if (!file.name.contains(path.toString())) return@launch
85+
86+
when (event.kind()) {
87+
StandardWatchEventKinds.ENTRY_CREATE,
88+
StandardWatchEventKinds.ENTRY_MODIFY -> {
89+
delay(100)
90+
loadConfig()
91+
}
92+
}
93+
}
94+
95+
key.reset()
96+
}
97+
}
98+
}
99+
100+
}

0 commit comments

Comments
 (0)