mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-17 19:35:00 -04:00
config option listening
This commit is contained in:
parent
b0574500c4
commit
e8c5e94902
@ -17,7 +17,6 @@ import de.bixilon.minosoft.config.config.account.AccountConfig
|
|||||||
import de.bixilon.minosoft.config.config.chat.ChatConfig
|
import de.bixilon.minosoft.config.config.chat.ChatConfig
|
||||||
import de.bixilon.minosoft.config.config.debug.DebugConfig
|
import de.bixilon.minosoft.config.config.debug.DebugConfig
|
||||||
import de.bixilon.minosoft.config.config.download.DownloadConfig
|
import de.bixilon.minosoft.config.config.download.DownloadConfig
|
||||||
import de.bixilon.minosoft.config.config.eros.ErosConfig
|
|
||||||
import de.bixilon.minosoft.config.config.game.GameConfig
|
import de.bixilon.minosoft.config.config.game.GameConfig
|
||||||
import de.bixilon.minosoft.config.config.general.GeneralConfig
|
import de.bixilon.minosoft.config.config.general.GeneralConfig
|
||||||
import de.bixilon.minosoft.config.config.network.NetworkConfig
|
import de.bixilon.minosoft.config.config.network.NetworkConfig
|
||||||
@ -32,5 +31,4 @@ data class Config(
|
|||||||
val server: ServerConfig = ServerConfig(),
|
val server: ServerConfig = ServerConfig(),
|
||||||
val download: DownloadConfig = DownloadConfig(),
|
val download: DownloadConfig = DownloadConfig(),
|
||||||
val debug: DebugConfig = DebugConfig(),
|
val debug: DebugConfig = DebugConfig(),
|
||||||
val eros: ErosConfig = ErosConfig(),
|
|
||||||
)
|
)
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
/*
|
|
||||||
* Minosoft
|
|
||||||
* Copyright (C) 2021 Moritz Zwerger
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.bixilon.minosoft.config.config.eros
|
|
||||||
|
|
||||||
import com.squareup.moshi.Json
|
|
||||||
|
|
||||||
data class ErosConfig(
|
|
||||||
@Json(name = "show_releases") var showReleases: Boolean = true,
|
|
||||||
@Json(name = "show_snapshots") var showSnapshots: Boolean = false,
|
|
||||||
)
|
|
@ -22,6 +22,15 @@ object GlobalProfileManager {
|
|||||||
ErosProfileManager,
|
ErosProfileManager,
|
||||||
)
|
)
|
||||||
private val SELECTED_PROFILES_TYPE: MapType = Jackson.MAPPER.typeFactory.constructMapType(HashMap::class.java, ResourceLocation::class.java, String::class.java)
|
private val SELECTED_PROFILES_TYPE: MapType = Jackson.MAPPER.typeFactory.constructMapType(HashMap::class.java, ResourceLocation::class.java, String::class.java)
|
||||||
|
val CLASS_MAPPING: Map<Class<out Profile>, ProfileManager<*>>
|
||||||
|
|
||||||
|
init {
|
||||||
|
val classMapping: MutableMap<Class<out Profile>, ProfileManager<*>> = mutableMapOf()
|
||||||
|
for (manager in DEFAULT_MANAGERS) {
|
||||||
|
classMapping[manager.profileClass] = manager
|
||||||
|
}
|
||||||
|
CLASS_MAPPING = classMapping.toMap()
|
||||||
|
}
|
||||||
|
|
||||||
private var initialized = false
|
private var initialized = false
|
||||||
private var loading = true
|
private var loading = true
|
||||||
|
@ -24,6 +24,7 @@ interface ProfileManager<T : Profile> {
|
|||||||
val namespace: ResourceLocation
|
val namespace: ResourceLocation
|
||||||
val latestVersion: Int
|
val latestVersion: Int
|
||||||
val saveLock: ReentrantLock
|
val saveLock: ReentrantLock
|
||||||
|
val profileClass: Class<T>
|
||||||
|
|
||||||
val profiles: HashBiMap<String, T>
|
val profiles: HashBiMap<String, T>
|
||||||
var selected: T
|
var selected: T
|
||||||
@ -93,7 +94,7 @@ interface ProfileManager<T : Profile> {
|
|||||||
if (selected == null || profileNames.isEmpty()) {
|
if (selected == null || profileNames.isEmpty()) {
|
||||||
initDefaultProfile()
|
initDefaultProfile()
|
||||||
}
|
}
|
||||||
var migrated = false
|
var saveFile = false
|
||||||
for (profileName in profileNames) {
|
for (profileName in profileNames) {
|
||||||
val path = getPath(profileName, baseDirectory)
|
val path = getPath(profileName, baseDirectory)
|
||||||
val json: MutableMap<String, Any?>?
|
val json: MutableMap<String, Any?>?
|
||||||
@ -110,14 +111,15 @@ interface ProfileManager<T : Profile> {
|
|||||||
}
|
}
|
||||||
Log.log(LogMessageType.LOAD_PROFILES, LogLevels.INFO) { "Migrated profile ($path) from version $version to $latestVersion" }
|
Log.log(LogMessageType.LOAD_PROFILES, LogLevels.INFO) { "Migrated profile ($path) from version $version to $latestVersion" }
|
||||||
json["version"] = latestVersion
|
json["version"] = latestVersion
|
||||||
migrated = true
|
saveFile = true
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
json = null
|
json = null
|
||||||
|
saveFile = true
|
||||||
}
|
}
|
||||||
|
|
||||||
val profile = load(profileName, json)
|
val profile = load(profileName, json)
|
||||||
if (migrated) {
|
if (saveFile) {
|
||||||
profile.saved = false
|
profile.saved = false
|
||||||
save(profile)
|
save(profile)
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,59 @@
|
|||||||
|
package de.bixilon.minosoft.config.profile.change
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.config.profile.GlobalProfileManager
|
||||||
|
import de.bixilon.minosoft.config.profile.change.listener.ProfileChangeListener
|
||||||
|
import de.bixilon.minosoft.config.profile.profiles.Profile
|
||||||
|
import de.bixilon.minosoft.util.KUtil.synchronizedMapOf
|
||||||
|
import de.bixilon.minosoft.util.KUtil.synchronizedSetOf
|
||||||
|
import de.bixilon.minosoft.util.KUtil.toSynchronizedSet
|
||||||
|
import de.bixilon.minosoft.util.KUtil.unsafeCast
|
||||||
|
import de.bixilon.minosoft.util.collections.SynchronizedMap
|
||||||
|
import java.lang.ref.WeakReference
|
||||||
|
import java.lang.reflect.Field
|
||||||
|
|
||||||
|
object ProfilesChangeManager {
|
||||||
|
private val listeners: SynchronizedMap<Field, SynchronizedMap<Profile?, MutableSet<Pair<WeakReference<Any>, ProfileChangeListener<Any>>>>> = synchronizedMapOf()
|
||||||
|
|
||||||
|
fun <T> register(reference: Any, listener: ProfileChangeListener<T>) {
|
||||||
|
this.listeners.getOrPut(listener.field) { synchronizedMapOf() }.getOrPut(listener.profile) { synchronizedSetOf() }.add(Pair(WeakReference(reference), listener.unsafeCast()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onChange(profile: Profile, field: Field, previous: Any?, value: Any?) {
|
||||||
|
val fieldListeners = listeners[field] ?: return
|
||||||
|
|
||||||
|
fun work(queue: MutableSet<Pair<WeakReference<Any>, ProfileChangeListener<Any>>>) {
|
||||||
|
val toRemove: MutableSet<Pair<WeakReference<Any>, ProfileChangeListener<Any>>> = mutableSetOf()
|
||||||
|
for (pair in queue.toSynchronizedSet()) {
|
||||||
|
val (reference, listener) = pair
|
||||||
|
if (reference.get() == null) {
|
||||||
|
toRemove += pair
|
||||||
|
}
|
||||||
|
listener.invoke(previous.unsafeCast(), value.unsafeCast())
|
||||||
|
}
|
||||||
|
if (toRemove.isNotEmpty()) {
|
||||||
|
if (queue.size == toRemove.size) {
|
||||||
|
queue.clear()
|
||||||
|
} else {
|
||||||
|
queue.removeAll(toRemove)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldListeners[profile]?.let {
|
||||||
|
work(it)
|
||||||
|
if (it.isEmpty()) {
|
||||||
|
fieldListeners -= profile
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val manager = GlobalProfileManager.CLASS_MAPPING[profile::class.java] ?: return
|
||||||
|
if (profile == manager.selected) {
|
||||||
|
fieldListeners[null]?.let {
|
||||||
|
work(it)
|
||||||
|
if (it.isEmpty()) {
|
||||||
|
fieldListeners -= null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
package de.bixilon.minosoft.config.profile.change.listener
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.config.profile.profiles.Profile
|
||||||
|
import java.lang.reflect.Field
|
||||||
|
import kotlin.reflect.KProperty
|
||||||
|
|
||||||
|
interface ProfileChangeListener<T> {
|
||||||
|
val property: KProperty<T>
|
||||||
|
val field: Field
|
||||||
|
val profile: Profile?
|
||||||
|
|
||||||
|
|
||||||
|
fun invoke(previous: T, value: T)
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
package de.bixilon.minosoft.config.profile.change.listener
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.config.profile.change.ProfilesChangeManager
|
||||||
|
import de.bixilon.minosoft.config.profile.profiles.Profile
|
||||||
|
import de.bixilon.minosoft.gui.eros.util.JavaFXUtil
|
||||||
|
import java.lang.reflect.Field
|
||||||
|
import kotlin.reflect.KProperty
|
||||||
|
import kotlin.reflect.jvm.javaField
|
||||||
|
|
||||||
|
class SimpleProfileChangeListener<T>(
|
||||||
|
override val property: KProperty<T>,
|
||||||
|
override val field: Field,
|
||||||
|
override val profile: Profile?,
|
||||||
|
private val callback: (T) -> Unit,
|
||||||
|
) : ProfileChangeListener<T> {
|
||||||
|
|
||||||
|
override fun invoke(previous: T, value: T) {
|
||||||
|
callback(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
fun <T> KProperty<T>.listen(reference: Any, profile: Profile? = null, callback: ((T) -> Unit)) {
|
||||||
|
ProfilesChangeManager.register(reference, SimpleProfileChangeListener(this, javaField!!, profile, callback))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T> KProperty<T>.listenFX(reference: Any, profile: Profile? = null, callback: ((T) -> Unit)) {
|
||||||
|
ProfilesChangeManager.register(reference, SimpleProfileChangeListener(this, javaField!!, profile) { JavaFXUtil.runLater { callback(it) } })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -4,6 +4,7 @@ import de.bixilon.minosoft.config.profile.profiles.Profile
|
|||||||
import de.bixilon.minosoft.config.profile.profiles.eros.ErosProfileManager.delegate
|
import de.bixilon.minosoft.config.profile.profiles.eros.ErosProfileManager.delegate
|
||||||
import de.bixilon.minosoft.config.profile.profiles.eros.ErosProfileManager.latestVersion
|
import de.bixilon.minosoft.config.profile.profiles.eros.ErosProfileManager.latestVersion
|
||||||
import de.bixilon.minosoft.config.profile.profiles.eros.general.GeneralC
|
import de.bixilon.minosoft.config.profile.profiles.eros.general.GeneralC
|
||||||
|
import de.bixilon.minosoft.config.profile.profiles.eros.server.ServerC
|
||||||
|
|
||||||
class ErosProfile(
|
class ErosProfile(
|
||||||
description: String? = null,
|
description: String? = null,
|
||||||
@ -16,6 +17,7 @@ class ErosProfile(
|
|||||||
override var saved: Boolean = true
|
override var saved: Boolean = true
|
||||||
|
|
||||||
val general: GeneralC = GeneralC()
|
val general: GeneralC = GeneralC()
|
||||||
|
val server: ServerC = ServerC()
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return ErosProfileManager.getName(this)
|
return ErosProfileManager.getName(this)
|
||||||
|
@ -14,6 +14,7 @@ object ErosProfileManager : ProfileManager<ErosProfile> {
|
|||||||
override val namespace = "minosoft:eros".toResourceLocation()
|
override val namespace = "minosoft:eros".toResourceLocation()
|
||||||
override val latestVersion = 1
|
override val latestVersion = 1
|
||||||
override val saveLock = ReentrantLock()
|
override val saveLock = ReentrantLock()
|
||||||
|
override val profileClass = ErosProfile::class.java
|
||||||
|
|
||||||
|
|
||||||
private var currentLoadingPath: String? = null
|
private var currentLoadingPath: String? = null
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
package de.bixilon.minosoft.config.profile.profiles.eros.server
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.config.profile.profiles.eros.server.modify.ModifyC
|
||||||
|
|
||||||
|
class ServerC {
|
||||||
|
val modify = ModifyC()
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
package de.bixilon.minosoft.config.profile.profiles.eros.server.modify
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.config.profile.profiles.eros.ErosProfileManager.delegate
|
||||||
|
|
||||||
|
class ModifyC {
|
||||||
|
var showReleases by delegate(true)
|
||||||
|
var showSnapshots by delegate(false)
|
||||||
|
}
|
@ -1,11 +1,14 @@
|
|||||||
package de.bixilon.minosoft.config.profile.util
|
package de.bixilon.minosoft.config.profile.util
|
||||||
|
|
||||||
import de.bixilon.minosoft.config.profile.ProfileManager
|
import de.bixilon.minosoft.config.profile.ProfileManager
|
||||||
|
import de.bixilon.minosoft.config.profile.change.ProfilesChangeManager
|
||||||
|
import de.bixilon.minosoft.config.profile.profiles.Profile
|
||||||
import de.bixilon.minosoft.util.logging.Log
|
import de.bixilon.minosoft.util.logging.Log
|
||||||
import de.bixilon.minosoft.util.logging.LogLevels
|
import de.bixilon.minosoft.util.logging.LogLevels
|
||||||
import de.bixilon.minosoft.util.logging.LogMessageType
|
import de.bixilon.minosoft.util.logging.LogMessageType
|
||||||
import kotlin.properties.ReadWriteProperty
|
import kotlin.properties.ReadWriteProperty
|
||||||
import kotlin.reflect.KProperty
|
import kotlin.reflect.KProperty
|
||||||
|
import kotlin.reflect.jvm.javaField
|
||||||
|
|
||||||
open class ProfileDelegate<V>(
|
open class ProfileDelegate<V>(
|
||||||
private var value: V,
|
private var value: V,
|
||||||
@ -13,7 +16,7 @@ open class ProfileDelegate<V>(
|
|||||||
private val profileManager: ProfileManager<*>,
|
private val profileManager: ProfileManager<*>,
|
||||||
private val profileName: String,
|
private val profileName: String,
|
||||||
) : ReadWriteProperty<Any, V> {
|
) : ReadWriteProperty<Any, V> {
|
||||||
|
private lateinit var profile: Profile
|
||||||
|
|
||||||
override fun getValue(thisRef: Any, property: KProperty<*>): V {
|
override fun getValue(thisRef: Any, property: KProperty<*>): V {
|
||||||
return value
|
return value
|
||||||
@ -23,16 +26,24 @@ open class ProfileDelegate<V>(
|
|||||||
if (checkEquals && this.value == value) {
|
if (checkEquals && this.value == value) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if (!this::profile.isInitialized) {
|
||||||
val profile = profileManager.profiles[profileName]
|
val profile = profileManager.profiles[profileName]
|
||||||
if (profile == null || profile.initializing) {
|
if (profile == null) {
|
||||||
|
this.value = value
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.profile = profile
|
||||||
|
}
|
||||||
|
if (profile.initializing) {
|
||||||
this.value = value
|
this.value = value
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.log(LogMessageType.OTHER, LogLevels.VERBOSE) { "Changed option $property in $thisRef in profile ${profileName::class.java} from ${this.value} to $value" }
|
Log.log(LogMessageType.OTHER, LogLevels.VERBOSE) { "Changed option $property in profile $profileName from ${this.value} to $value" }
|
||||||
profileManager.profiles[profileName]?.saved = false
|
profileManager.profiles[profileName]?.saved = false
|
||||||
|
val previous = this.value
|
||||||
// ToDo: Fire event
|
|
||||||
this.value = value
|
this.value = value
|
||||||
|
|
||||||
|
ProfilesChangeManager.onChange(profile, property.javaField ?: return, previous, value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,9 @@
|
|||||||
package de.bixilon.minosoft.gui.eros.dialog
|
package de.bixilon.minosoft.gui.eros.dialog
|
||||||
|
|
||||||
import de.bixilon.minosoft.Minosoft
|
import de.bixilon.minosoft.Minosoft
|
||||||
|
import de.bixilon.minosoft.config.profile.change.listener.SimpleProfileChangeListener.Companion.listenFX
|
||||||
|
import de.bixilon.minosoft.config.profile.profiles.eros.ErosProfileManager
|
||||||
|
import de.bixilon.minosoft.config.profile.profiles.eros.server.modify.ModifyC
|
||||||
import de.bixilon.minosoft.config.server.Server
|
import de.bixilon.minosoft.config.server.Server
|
||||||
import de.bixilon.minosoft.data.registries.versions.Version
|
import de.bixilon.minosoft.data.registries.versions.Version
|
||||||
import de.bixilon.minosoft.data.registries.versions.VersionTypes
|
import de.bixilon.minosoft.data.registries.versions.VersionTypes
|
||||||
@ -106,22 +109,24 @@ class UpdateServerDialog(
|
|||||||
|
|
||||||
cancelButtonFX.ctext = TranslatableComponents.GENERAL_CANCEL
|
cancelButtonFX.ctext = TranslatableComponents.GENERAL_CANCEL
|
||||||
|
|
||||||
|
val modifyConfig = ErosProfileManager.selected.server.modify
|
||||||
|
|
||||||
|
ModifyC::showReleases.listenFX(this) { showReleasesFX.isSelected = it }
|
||||||
|
ModifyC::showSnapshots.listenFX(this) { showSnapshotsFX.isSelected = it }
|
||||||
|
|
||||||
showReleasesFX.apply {
|
showReleasesFX.apply {
|
||||||
isSelected = Minosoft.config.config.eros.showReleases
|
isSelected = modifyConfig.showReleases
|
||||||
ctext = SHOW_RELEASES
|
ctext = SHOW_RELEASES
|
||||||
setOnAction {
|
setOnAction {
|
||||||
Minosoft.config.config.eros.showReleases = isSelected
|
modifyConfig.showReleases = isSelected
|
||||||
Minosoft.config.saveToFile()
|
|
||||||
refreshVersions()
|
refreshVersions()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
showSnapshotsFX.apply {
|
showSnapshotsFX.apply {
|
||||||
isSelected = Minosoft.config.config.eros.showSnapshots
|
isSelected = modifyConfig.showSnapshots
|
||||||
ctext = SHOW_SNAPSHOTS
|
ctext = SHOW_SNAPSHOTS
|
||||||
setOnAction {
|
setOnAction {
|
||||||
Minosoft.config.config.eros.showSnapshots = isSelected
|
modifyConfig.showSnapshots = isSelected
|
||||||
Minosoft.config.saveToFile()
|
|
||||||
refreshVersions()
|
refreshVersions()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user