Skip to content

Commit 18cdeef

Browse files
Merge pull request #16 from simplecloudapp/feat/config-factory
Feat/config factory
2 parents e7b12c9 + e2d6ec3 commit 18cdeef

File tree

2 files changed

+102
-2
lines changed

2 files changed

+102
-2
lines changed

gradle/libs.versions.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ kotlinJvm = { module = "org.jetbrains.kotlin:kotlin-stdlib-jdk8", version.ref =
1010
simpleCloudControllerApi = { module = "app.simplecloud.controller:controller-api", version.ref = "simpleCloudController" }
1111
simpleCloudControllerShared = { module = "app.simplecloud.controller:controller-shared", version.ref = "simpleCloudController" }
1212

13-
adventureApi = { module = "net.kyori:adventure-api", version.ref = "adventure" }
13+
adventure = { module = "net.kyori:adventure-api", version.ref = "adventure" }
1414
adventureMiniMessage = { module = "net.kyori:adventure-text-minimessage", version.ref = "adventure" }
1515

1616
[bundles]
1717
simpleCloudController = ["simpleCloudControllerApi", "simpleCloudControllerShared"]
18-
adventure = ["adventureApi", "adventureMiniMessage"]
18+
adventure = ["adventure", "adventureMiniMessage"]
1919

2020
[plugins]
2121
kotlin = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
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)