Add support for delegating config properties
- Changed the return value of all getData() methods to allow using the result for property delegation - This allows using the config properties like any other property in Kotlin - Also delegating the underlying ConfigData object to the delegate (heh) so that the result can still be used from Java normally - It does require one notable change though: using the IConfigData interface *everywhere* - One problematic part for this is ListConfigData, as a much more elaborate IConfigData<ListConfigData<T>.List> needs to be used for list configs - Also using the display name for MC users heh
This commit is contained in:
parent
cd108dc787
commit
a26c16565f
8 changed files with 29 additions and 19 deletions
|
@ -74,7 +74,7 @@ class ComponentCommand : ICommand2MC() {
|
||||||
val oc = getComponentOrError(plugin, component, sender)
|
val oc = getComponentOrError(plugin, component, sender)
|
||||||
if (!oc.isPresent) return true
|
if (!oc.isPresent) return true
|
||||||
setComponentEnabled(oc.get(), enable)
|
setComponentEnabled(oc.get(), enable)
|
||||||
if (permanent) oc.get().shouldBeEnabled.set(enable)
|
if (permanent) oc.get().shouldBeEnabled = enable
|
||||||
sender.sendMessage("${oc.get().javaClass.simpleName} ${if (enable) "en" else "dis"}abled ${if (permanent) "permanently" else "temporarily"}.")
|
sender.sendMessage("${oc.get().javaClass.simpleName} ${if (enable) "en" else "dis"}abled ${if (permanent) "permanently" else "temporarily"}.")
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
TBMCCoreAPI.SendException(
|
TBMCCoreAPI.SendException(
|
||||||
|
|
|
@ -23,7 +23,7 @@ object ComponentManager {
|
||||||
* Enables components based on a configuration - any component registered afterwards will be also enabled
|
* Enables components based on a configuration - any component registered afterwards will be also enabled
|
||||||
*/
|
*/
|
||||||
fun enableComponents() {
|
fun enableComponents() {
|
||||||
components.values.stream().filter { c: Component<out JavaPlugin> -> c.shouldBeEnabled.get() }
|
components.values.stream().filter { c: Component<out JavaPlugin> -> c.shouldBeEnabled }
|
||||||
.forEach { c ->
|
.forEach { c ->
|
||||||
try {
|
try {
|
||||||
setComponentEnabled(c, true)
|
setComponentEnabled(c, true)
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
package buttondevteam.core.component.channel
|
package buttondevteam.core.component.channel
|
||||||
|
|
||||||
import buttondevteam.core.ComponentManager.get
|
import buttondevteam.core.ComponentManager.get
|
||||||
import buttondevteam.lib.architecture.ConfigData
|
|
||||||
import buttondevteam.lib.architecture.IHaveConfig
|
import buttondevteam.lib.architecture.IHaveConfig
|
||||||
import buttondevteam.lib.architecture.ListConfigData
|
|
||||||
import buttondevteam.lib.chat.Color
|
import buttondevteam.lib.chat.Color
|
||||||
import buttondevteam.lib.player.ChromaGamerBase
|
import buttondevteam.lib.player.ChromaGamerBase
|
||||||
import org.bukkit.Bukkit
|
import org.bukkit.Bukkit
|
||||||
|
@ -53,16 +51,16 @@ open class Channel
|
||||||
* Must start with a color code
|
* Must start with a color code
|
||||||
*/
|
*/
|
||||||
@JvmField
|
@JvmField
|
||||||
val displayName: ConfigData<String> =
|
val displayName = component.config.getData("${this.identifier}.displayName", this.defDisplayName)
|
||||||
component.config.getData("${this.identifier}.displayName", this.defDisplayName)
|
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val color: ConfigData<Color> = component.config.getData("${this.identifier}.color",
|
val color = component.config.getData(
|
||||||
|
"${this.identifier}.color",
|
||||||
this.defColor, { c -> Color.valueOf((c as String)) }, Color::toString
|
this.defColor, { c -> Color.valueOf((c as String)) }, Color::toString
|
||||||
)
|
)
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val extraIdentifiers: ListConfigData<String> = component.config.getListData("${this.identifier}.IDs", listOf())
|
val extraIdentifiers = component.config.getListData("${this.identifier}.IDs", listOf<String>())
|
||||||
|
|
||||||
val isGlobal: Boolean
|
val isGlobal: Boolean
|
||||||
get() = filterAndErrorMSG == null
|
get() = filterAndErrorMSG == null
|
||||||
|
|
|
@ -27,8 +27,7 @@ abstract class Component<TP : JavaPlugin> {
|
||||||
private val data //TODO
|
private val data //TODO
|
||||||
: IHaveConfig? = null
|
: IHaveConfig? = null
|
||||||
|
|
||||||
val shouldBeEnabled: ConfigData<Boolean>
|
var shouldBeEnabled by config.getData("enabled", javaClass.getAnnotation(ComponentMetadata::class.java)?.enabledByDefault ?: true)
|
||||||
get() = config.getData("enabled", javaClass.getAnnotation(ComponentMetadata::class.java)?.enabledByDefault ?: true)
|
|
||||||
|
|
||||||
fun log(message: String) {
|
fun log(message: String) {
|
||||||
plugin.logger.info("[$className] $message")
|
plugin.logger.info("[$className] $message")
|
||||||
|
@ -210,7 +209,7 @@ abstract class Component<TP : JavaPlugin> {
|
||||||
component.updateConfig()
|
component.updateConfig()
|
||||||
_components[component.javaClass] = component
|
_components[component.javaClass] = component
|
||||||
if (plugin is ButtonPlugin) plugin.componentStack.push(component)
|
if (plugin is ButtonPlugin) plugin.componentStack.push(component)
|
||||||
if (ComponentManager.areComponentsEnabled() && component.shouldBeEnabled.get()) {
|
if (ComponentManager.areComponentsEnabled() && component.shouldBeEnabled) {
|
||||||
return try { //Enable components registered after the previous ones getting enabled
|
return try { //Enable components registered after the previous ones getting enabled
|
||||||
setComponentEnabled(component, true)
|
setComponentEnabled(component, true)
|
||||||
true
|
true
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package buttondevteam.lib.architecture
|
package buttondevteam.lib.architecture
|
||||||
|
|
||||||
|
import buttondevteam.lib.architecture.config.ConfigDataDelegate
|
||||||
|
import buttondevteam.lib.architecture.config.ConfigDataDelegate.Companion.delegate
|
||||||
import buttondevteam.lib.architecture.config.IConfigData
|
import buttondevteam.lib.architecture.config.IConfigData
|
||||||
import org.bukkit.configuration.ConfigurationSection
|
import org.bukkit.configuration.ConfigurationSection
|
||||||
import java.util.function.Function
|
import java.util.function.Function
|
||||||
|
@ -41,7 +43,7 @@ class IHaveConfig(
|
||||||
getter: Function<Any, T>? = null,
|
getter: Function<Any, T>? = null,
|
||||||
setter: Function<T, Any>? = null,
|
setter: Function<T, Any>? = null,
|
||||||
readOnly: Boolean = false
|
readOnly: Boolean = false
|
||||||
): ConfigData<T> {
|
): ConfigDataDelegate<T> {
|
||||||
val safeSetter = setter ?: Function { it ?: throw RuntimeException("No setter specified for nullable config data $path!") }
|
val safeSetter = setter ?: Function { it ?: throw RuntimeException("No setter specified for nullable config data $path!") }
|
||||||
return getData(path, getter ?: Function { it as T }, safeSetter, safeSetter.apply(def), readOnly)
|
return getData(path, getter ?: Function { it as T }, safeSetter, safeSetter.apply(def), readOnly)
|
||||||
}
|
}
|
||||||
|
@ -65,10 +67,10 @@ class IHaveConfig(
|
||||||
setter: Function<T, Any>,
|
setter: Function<T, Any>,
|
||||||
primitiveDef: Any,
|
primitiveDef: Any,
|
||||||
readOnly: Boolean = false
|
readOnly: Boolean = false
|
||||||
): ConfigData<T> {
|
): ConfigDataDelegate<T> {
|
||||||
val data =
|
val data =
|
||||||
datamap[path] ?: ConfigData(this, path, primitiveDef, getter, setter, readOnly).also { datamap[path] = it }
|
datamap[path] ?: ConfigData(this, path, primitiveDef, getter, setter, readOnly).also { datamap[path] = it }
|
||||||
return data as ConfigData<T>
|
return (data as ConfigData<T>).delegate()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -86,7 +88,7 @@ class IHaveConfig(
|
||||||
elementGetter: Function<Any?, T>? = null,
|
elementGetter: Function<Any?, T>? = null,
|
||||||
elementSetter: Function<T, Any?>? = null,
|
elementSetter: Function<T, Any?>? = null,
|
||||||
readOnly: Boolean = false
|
readOnly: Boolean = false
|
||||||
): ListConfigData<T> {
|
): ConfigDataDelegate<ListConfigData<T>.List> {
|
||||||
var data = datamap[path]
|
var data = datamap[path]
|
||||||
if (data == null) datamap[path] = ListConfigData(
|
if (data == null) datamap[path] = ListConfigData(
|
||||||
this,
|
this,
|
||||||
|
@ -97,7 +99,7 @@ class IHaveConfig(
|
||||||
readOnly
|
readOnly
|
||||||
).also { data = it }
|
).also { data = it }
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
return data as ListConfigData<T>
|
return (data as ListConfigData<T>).delegate()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
package buttondevteam.lib.architecture.config
|
||||||
|
|
||||||
|
import kotlin.reflect.KProperty
|
||||||
|
|
||||||
|
class ConfigDataDelegate<T>(val data: IConfigData<T>) : IConfigData<T> by data {
|
||||||
|
operator fun getValue(thisRef: Any?, property: KProperty<*>): T = data.get()
|
||||||
|
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) = data.set(value)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun <T> IConfigData<T>.delegate() = ConfigDataDelegate(this)
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,7 +4,6 @@ import buttondevteam.core.MainPlugin
|
||||||
import buttondevteam.core.component.channel.Channel
|
import buttondevteam.core.component.channel.Channel
|
||||||
import buttondevteam.core.component.channel.Channel.Companion.getChannels
|
import buttondevteam.core.component.channel.Channel.Companion.getChannels
|
||||||
import buttondevteam.lib.TBMCCoreAPI
|
import buttondevteam.lib.TBMCCoreAPI
|
||||||
import buttondevteam.lib.architecture.ConfigData
|
|
||||||
import buttondevteam.lib.architecture.ConfigData.Companion.saveNow
|
import buttondevteam.lib.architecture.ConfigData.Companion.saveNow
|
||||||
import buttondevteam.lib.architecture.IHaveConfig
|
import buttondevteam.lib.architecture.IHaveConfig
|
||||||
import buttondevteam.lib.chat.Command2Sender
|
import buttondevteam.lib.chat.Command2Sender
|
||||||
|
@ -160,7 +159,7 @@ abstract class ChromaGamerBase : Command2Sender {
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------
|
//-----------------------------------------------------------------
|
||||||
val channel: ConfigData<Channel>
|
val channel
|
||||||
get() = config.getData("channel", Channel.globalChat,
|
get() = config.getData("channel", Channel.globalChat,
|
||||||
{ id ->
|
{ id ->
|
||||||
getChannels().filter { it.identifier.equals(id as String, ignoreCase = true) }
|
getChannels().filter { it.identifier.equals(id as String, ignoreCase = true) }
|
||||||
|
|
|
@ -55,7 +55,7 @@ abstract class TBMCPlayerBase : ChromaGamerBase() {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getName(): String {
|
override fun getName(): String {
|
||||||
return playerName.get()
|
return player?.displayName ?: playerName.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun checkChannelInGroup(group: String?): Channel.RecipientTestResult {
|
override fun checkChannelInGroup(group: String?): Channel.RecipientTestResult {
|
||||||
|
|
Loading…
Reference in a new issue