Skip to content

Commit

Permalink
Fix improper handling of non-extracted configs
Browse files Browse the repository at this point in the history
- Config reloading now detects file deletion
- Configs can now also be loaded through Configs.get instead of just through extraction / reloading
  • Loading branch information
NichtStudioCode committed Oct 26, 2024
1 parent 8901a48 commit c65125f
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 7 deletions.
14 changes: 13 additions & 1 deletion nova/src/main/kotlin/xyz/xenondevs/nova/config/ConfigProvider.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import java.lang.ref.WeakReference
import java.lang.reflect.Type
import java.nio.file.Path
import java.util.concurrent.locks.ReentrantLock
import kotlin.io.path.exists
import kotlin.reflect.KType
import kotlin.reflect.jvm.javaType
import kotlin.reflect.typeOf
Expand Down Expand Up @@ -355,8 +356,19 @@ internal class RootConfigProvider internal constructor(
var loaded = false
private set

@Volatile
var fileExisted = false
private set

init {
subscribe { loaded = true }
subscribe {
loaded = true
fileExisted = path.exists()
}
}

fun reload() {
set(Configs.createLoader(path).load())
}

override fun pull(): CommentedConfigurationNode {
Expand Down
14 changes: 8 additions & 6 deletions nova/src/main/kotlin/xyz/xenondevs/nova/config/Configs.kt
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,11 @@ object Configs {
private fun extractConfig(from: Path, to: Path, configId: ResourceLocation) {
extractor.extract(configId, from, to)
val provider = configProviders.getOrPut(configId) { RootConfigProvider(to, configId) }
provider.set(createLoader(to).load())
provider.reload()
}

private fun resolveConfigPath(configId: ResourceLocation): Path {
val dataFolder = when(configId.namespace) {
val dataFolder = when (configId.namespace) {
"nova" -> Nova.dataFolder
else -> AddonBootstrapper.addons.firstOrNull { it.id == configId.namespace }?.dataFolder
?: throw IllegalArgumentException("No addon with id ${configId.namespace} found")
Expand All @@ -93,9 +93,11 @@ object Configs {

internal fun reload(): List<ResourceLocation> {
val reloadedConfigs = configProviders.asSequence()
.filter { (_, provider) -> provider.path.exists() }
.filter { (_, provider) -> provider.path.getLastModifiedTime().toMillis() > lastReload } // only reload updated configs
.onEach { (_, provider) -> provider.set(createLoader(provider.path).load()) }
.filter { (_, provider) ->
!provider.path.exists() && provider.fileExisted
|| provider.path.exists() && provider.path.getLastModifiedTime().toMillis() > lastReload
} // only reload updated configs
.onEach { (_, provider) -> provider.reload() }
.mapTo(ArrayList()) { (id, _) -> id }
lastReload = System.currentTimeMillis()

Expand All @@ -111,7 +113,7 @@ object Configs {
get(ResourceLocation(addon, path))

operator fun get(id: ResourceLocation): Provider<CommentedConfigurationNode> =
configProviders.getOrPut(id) { RootConfigProvider(resolveConfigPath(id), id) }
configProviders.getOrPut(id) { RootConfigProvider(resolveConfigPath(id), id).also { if (lastReload > -1) it.reload() } }

fun getOrNull(id: String): CommentedConfigurationNode? =
getOrNull(ResourceLocation.parse(id))
Expand Down

0 comments on commit c65125f

Please sign in to comment.