Skip to content

Commit ffd97e6

Browse files
authored
Prepare for module configurations (#254)
1 parent a95655f commit ffd97e6

File tree

15 files changed

+179
-96
lines changed

15 files changed

+179
-96
lines changed

BotCommands-core/src/main/kotlin/io/github/freya022/botcommands/api/core/config/BAppEmojisConfig.kt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@ import io.github.freya022.botcommands.internal.core.config.ConfigDSL
66
import io.github.freya022.botcommands.internal.core.config.ConfigurationValue
77

88
@InjectedService
9-
interface BAppEmojisConfig {
9+
interface BAppEmojisConfig : IConfig, BAppEmojisConfigProps {
10+
override val configType get() = BAppEmojisConfig::class.java
11+
}
12+
13+
interface BAppEmojisConfigProps {
1014
/**
1115
* Allows uploading application emojis at startup, and retrieving them from [AppEmojisRegistry].
1216
*
@@ -32,7 +36,7 @@ interface BAppEmojisConfig {
3236
}
3337

3438
@ConfigDSL
35-
class BAppEmojisConfigBuilder internal constructor() : BAppEmojisConfig {
39+
class BAppEmojisConfigBuilder internal constructor() : BAppEmojisConfigProps {
3640
@set:JvmName("enable")
3741
override var enable: Boolean = false
3842

@@ -44,4 +48,4 @@ class BAppEmojisConfigBuilder internal constructor() : BAppEmojisConfig {
4448
override val enable: Boolean = this@BAppEmojisConfigBuilder.enable
4549
override val deleteOnOutOfSlots = this@BAppEmojisConfigBuilder.deleteOnOutOfSlots
4650
}
47-
}
51+
}

BotCommands-core/src/main/kotlin/io/github/freya022/botcommands/api/core/config/BApplicationConfig.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,11 @@ import java.nio.file.Path
3030
import kotlin.io.path.Path
3131

3232
@InjectedService
33-
interface BApplicationConfig {
33+
interface BApplicationConfig : IConfig, BApplicationConfigProps {
34+
override val configType get() = BApplicationConfig::class.java
35+
}
36+
37+
interface BApplicationConfigProps {
3438
/**
3539
* Whether application commands should be listened for.
3640
*
@@ -157,7 +161,7 @@ interface BApplicationConfig {
157161
}
158162

159163
@ConfigDSL
160-
class BApplicationConfigBuilder internal constructor() : BApplicationConfig {
164+
class BApplicationConfigBuilder internal constructor() : BApplicationConfigProps {
161165
@set:JvmName("enable")
162166
override var enable: Boolean = true
163167
@Deprecated("Replaced by 'guildsToUpdate'", replaceWith = ReplaceWith("guildToUpdate"))

BotCommands-core/src/main/kotlin/io/github/freya022/botcommands/api/core/config/BComponentsConfig.kt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,11 @@ import io.github.freya022.botcommands.internal.core.config.ConfigDSL
99
import io.github.freya022.botcommands.internal.core.config.ConfigurationValue
1010

1111
@InjectedService
12-
interface BComponentsConfig {
12+
interface BComponentsConfig : IConfig, BComponentsConfigProps {
13+
override val configType get() = BComponentsConfig::class.java
14+
}
15+
16+
interface BComponentsConfigProps {
1317
/**
1418
* Allows loading component services,
1519
* such as [Components], [Buttons] and [SelectMenus].
@@ -27,12 +31,12 @@ interface BComponentsConfig {
2731
}
2832

2933
@ConfigDSL
30-
class BComponentsConfigBuilder internal constructor() : BComponentsConfig {
34+
class BComponentsConfigBuilder internal constructor() : BComponentsConfigProps {
3135
@set:JvmName("enable")
3236
override var enable: Boolean = false
3337

3438
@JvmSynthetic
3539
internal fun build() = object : BComponentsConfig {
3640
override val enable: Boolean = this@BComponentsConfigBuilder.enable
3741
}
38-
}
42+
}

BotCommands-core/src/main/kotlin/io/github/freya022/botcommands/api/core/config/BConfig.kt

Lines changed: 95 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,49 @@ import io.github.freya022.botcommands.api.core.annotations.BEventListener
77
import io.github.freya022.botcommands.api.core.requests.PriorityGlobalRestRateLimiter
88
import io.github.freya022.botcommands.api.core.service.ClassGraphProcessor
99
import io.github.freya022.botcommands.api.core.service.annotations.InjectedService
10-
import io.github.freya022.botcommands.api.core.utils.enumSetOf
11-
import io.github.freya022.botcommands.api.core.utils.loggerOf
12-
import io.github.freya022.botcommands.api.core.utils.toImmutableList
13-
import io.github.freya022.botcommands.api.core.utils.toImmutableSet
10+
import io.github.freya022.botcommands.api.core.utils.*
1411
import io.github.freya022.botcommands.api.core.waiter.EventWaiter
1512
import io.github.freya022.botcommands.internal.core.config.ConfigDSL
1613
import io.github.freya022.botcommands.internal.core.config.ConfigurationValue
14+
import io.github.freya022.botcommands.internal.utils.putIfAbsentOrThrow
15+
import io.github.freya022.botcommands.internal.utils.throwInternal
1716
import io.github.oshai.kotlinlogging.KotlinLogging
1817
import net.dv8tion.jda.api.events.Event
1918
import net.dv8tion.jda.api.requests.GatewayIntent
2019
import net.dv8tion.jda.api.requests.RestRateLimiter
2120
import net.dv8tion.jda.api.utils.messages.MessageCreateData
2221
import org.intellij.lang.annotations.Language
22+
import kotlin.reflect.KClass
2323

2424
@InjectedService
25-
interface BConfig {
25+
interface BConfig : IConfig, BConfigProps {
26+
override val configType get() = BConfig::class.java
27+
28+
val eventManagerConfig: BEventManagerConfig
29+
val serviceConfig: BServiceConfig
30+
val databaseConfig: BDatabaseConfig
31+
val localizationConfig: BLocalizationConfig
32+
val appEmojisConfig: BAppEmojisConfig
33+
val textConfig: BTextConfig
34+
val applicationConfig: BApplicationConfig
35+
val modalsConfig: BModalsConfig
36+
val componentsConfig: BComponentsConfig
37+
val coroutineScopesConfig: BCoroutineScopesConfig
38+
39+
/**
40+
* An immutable collection of all [registered][BConfigBuilder.withConfig] configuration objects.
41+
*/
42+
val configs: Collection<IConfig>
43+
44+
/**
45+
* Gets a configuration of the provided type, or `null` if none were [registered][BConfigBuilder.withConfig].
46+
*
47+
* @param type The type of configuration to get, based on [configType].
48+
*/
49+
fun <T : IConfig> getConfigOrNull(type: Class<T>): T?
50+
}
51+
52+
interface BConfigProps {
2653
/**
2754
* Predefined user IDs of the bot owners, allowing bypassing cooldowns, user permission checks,
2855
* and having [hidden commands][Hidden] shown.
@@ -106,21 +133,24 @@ interface BConfig {
106133
val ignoreRestRateLimiter: Boolean
107134

108135
val classGraphProcessors: List<ClassGraphProcessor>
109-
110-
val eventManagerConfig: BEventManagerConfig
111-
val serviceConfig: BServiceConfig
112-
val databaseConfig: BDatabaseConfig
113-
val localizationConfig: BLocalizationConfig
114-
val appEmojisConfig: BAppEmojisConfig
115-
val textConfig: BTextConfig
116-
val applicationConfig: BApplicationConfig
117-
val modalsConfig: BModalsConfig
118-
val componentsConfig: BComponentsConfig
119-
val coroutineScopesConfig: BCoroutineScopesConfig
120136
}
121137

138+
/**
139+
* Gets a configuration of the provided type, or `null` if none were [registered][BConfigBuilder.withConfig].
140+
*
141+
* @param type The type of configuration to get, based on [configType][BConfig.configType].
142+
*/
143+
fun <T : IConfig> BConfig.getConfigOrNull(type: KClass<T>): T? = getConfigOrNull(type.java)
144+
145+
/**
146+
* Gets a configuration of the provided type, or `null` if none were [registered][BConfigBuilder.withConfig].
147+
*
148+
* @param T The type of configuration to get, based on [configType][BConfig.configType].
149+
*/
150+
inline fun <reified T : IConfig> BConfig.getConfigOrNull(): T? = getConfigOrNull(T::class.java)
151+
122152
@ConfigDSL
123-
class BConfigBuilder : BConfig {
153+
class BConfigBuilder : BConfigProps {
124154
override val packages: MutableSet<String> = HashSet()
125155
override val classes: MutableSet<Class<*>> = HashSet()
126156

@@ -139,16 +169,18 @@ class BConfigBuilder : BConfig {
139169

140170
override val classGraphProcessors: MutableList<ClassGraphProcessor> = arrayListOf()
141171

142-
override val eventManagerConfig = BEventManagerConfigBuilder()
143-
override val serviceConfig = BServiceConfigBuilder()
144-
override val databaseConfig = BDatabaseConfigBuilder()
145-
override val localizationConfig = BLocalizationConfigBuilder()
146-
override val appEmojisConfig = BAppEmojisConfigBuilder()
147-
override val textConfig = BTextConfigBuilder()
148-
override val applicationConfig = BApplicationConfigBuilder()
149-
override val modalsConfig = BModalsConfigBuilder()
150-
override val componentsConfig = BComponentsConfigBuilder()
151-
override val coroutineScopesConfig = BCoroutineScopesConfigBuilder()
172+
private val _configs: MutableMap<Class<out IConfig>, IConfig> = hashMapOf()
173+
174+
val eventManagerConfig = BEventManagerConfigBuilder()
175+
val serviceConfig = BServiceConfigBuilder()
176+
val databaseConfig = BDatabaseConfigBuilder()
177+
val localizationConfig = BLocalizationConfigBuilder()
178+
val appEmojisConfig = BAppEmojisConfigBuilder()
179+
val textConfig = BTextConfigBuilder()
180+
val applicationConfig = BApplicationConfigBuilder()
181+
val modalsConfig = BModalsConfigBuilder()
182+
val componentsConfig = BComponentsConfigBuilder()
183+
val coroutineScopesConfig = BCoroutineScopesConfigBuilder()
152184

153185
/**
154186
* Predefined user IDs of the bot owners, allowing bypassing cooldowns, user permission checks,
@@ -278,6 +310,19 @@ class BConfigBuilder : BConfig {
278310
componentsConfig.apply(block)
279311
}
280312

313+
/**
314+
* Registers the provided configuration, once configured, it cannot be modified or overwritten.
315+
*
316+
* @param newConfig The new configuration
317+
*
318+
* @throws IllegalStateException If a config of the same type was already registered
319+
*/
320+
fun withConfig(newConfig: IConfig) {
321+
_configs.putIfAbsentOrThrow(newConfig.configType, newConfig) { _ ->
322+
"Cannot reassign configuration of ${newConfig.configType.simpleNestedName}, please configure it entirely then assign once"
323+
}
324+
}
325+
281326
fun build(): BConfig {
282327
val logger = KotlinLogging.loggerOf<BConfig>()
283328
if (disableExceptionsInDMs)
@@ -303,6 +348,29 @@ class BConfigBuilder : BConfig {
303348
override val modalsConfig = this@BConfigBuilder.modalsConfig.build()
304349
override val componentsConfig = this@BConfigBuilder.componentsConfig.build()
305350
override val coroutineScopesConfig = this@BConfigBuilder.coroutineScopesConfig.build()
351+
private val _configs = (this@BConfigBuilder._configs + mapOf(
352+
this.configType to this,
353+
eventManagerConfig.configType to eventManagerConfig,
354+
serviceConfig.configType to serviceConfig,
355+
databaseConfig.configType to databaseConfig,
356+
localizationConfig.configType to localizationConfig,
357+
appEmojisConfig.configType to appEmojisConfig,
358+
textConfig.configType to textConfig,
359+
applicationConfig.configType to applicationConfig,
360+
modalsConfig.configType to modalsConfig,
361+
componentsConfig.configType to componentsConfig,
362+
coroutineScopesConfig.configType to coroutineScopesConfig,
363+
)).unmodifiableView()
364+
override val configs get() = _configs.values
365+
366+
override fun <T : IConfig> getConfigOrNull(type: Class<T>): T? {
367+
val config = _configs[type] ?: return null
368+
if (!type.isInstance(config)) {
369+
throwInternal("$config (${config.javaClass.name}) is not an instance of ${type.name}")
370+
}
371+
372+
return type.cast(config)
373+
}
306374
}
307375
}
308376
}

BotCommands-core/src/main/kotlin/io/github/freya022/botcommands/api/core/config/BCoroutineScopesConfig.kt

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,15 @@ import io.github.freya022.botcommands.api.core.hooks.EventDispatcher
55
import io.github.freya022.botcommands.api.core.service.annotations.InjectedService
66
import io.github.freya022.botcommands.api.core.utils.namedDefaultScope
77
import io.github.freya022.botcommands.internal.core.config.ConfigDSL
8-
import io.github.freya022.botcommands.internal.utils.throwState
98
import kotlinx.coroutines.CoroutineScope
109
import java.util.concurrent.Executor
1110

1211
@InjectedService
13-
interface BCoroutineScopesConfig {
12+
interface BCoroutineScopesConfig : IConfig, BCoroutineScopesConfigProps {
13+
override val configType get() = BCoroutineScopesConfig::class.java
14+
}
15+
16+
interface BCoroutineScopesConfigProps {
1417
val eventManagerScope: CoroutineScope //Used by [[CoroutineEventManagerImpl]]
1518
val commandUpdateScope: CoroutineScope //Not used much
1619
/**
@@ -32,18 +35,7 @@ fun interface CoroutineScopeFactory {
3235
}
3336

3437
@ConfigDSL
35-
class BCoroutineScopesConfigBuilder internal constructor() : BCoroutineScopesConfig {
36-
override val eventManagerScope: Nothing get() = throwState("Cannot get a coroutine scope from the builder")
37-
override val commandUpdateScope: Nothing get() = throwState("Cannot get a coroutine scope from the builder")
38-
override val eventDispatcherScope: Nothing get() = throwState("Cannot get a coroutine scope from the builder")
39-
override val textCommandsScope: Nothing get() = throwState("Cannot get a coroutine scope from the builder")
40-
override val applicationCommandsScope: Nothing get() = throwState("Cannot get a coroutine scope from the builder")
41-
override val componentScope: Nothing get() = throwState("Cannot get a coroutine scope from the builder")
42-
override val componentTimeoutScope: Nothing get() = throwState("Cannot get a coroutine scope from the builder")
43-
override val modalScope: Nothing get() = throwState("Cannot get a coroutine scope from the builder")
44-
override val modalTimeoutScope: Nothing get() = throwState("Cannot get a coroutine scope from the builder")
45-
override val paginationTimeoutScope: Nothing get() = throwState("Cannot get a coroutine scope from the builder")
46-
38+
class BCoroutineScopesConfigBuilder internal constructor() {
4739
var eventManagerScopeFactory: CoroutineScopeFactory = defaultFactory("Event manager", 4)
4840
var commandUpdateScopeFactory: CoroutineScopeFactory = defaultFactory("Command updater", 1)
4941
var eventDispatcherScopeFactory: CoroutineScopeFactory = defaultFactory("Event dispatcher", 4)

BotCommands-core/src/main/kotlin/io/github/freya022/botcommands/api/core/config/BDatabaseConfig.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@ import kotlin.time.toJavaDuration
1111
import kotlin.time.toKotlinDuration
1212

1313
@InjectedService
14-
interface BDatabaseConfig {
14+
interface BDatabaseConfig : IConfig, BDatabaseConfigProps {
15+
override val configType get() = BDatabaseConfig::class.java
16+
}
17+
18+
interface BDatabaseConfigProps {
1519
/**
1620
* Whether transactions should trigger a coroutine dump & thread dump
1721
* when running longer than the [max transaction duration][ConnectionSupplier.maxTransactionDuration]
@@ -67,7 +71,7 @@ interface BDatabaseConfig {
6771
}
6872

6973
@ConfigDSL
70-
class BDatabaseConfigBuilder internal constructor() : BDatabaseConfig {
74+
class BDatabaseConfigBuilder internal constructor() : BDatabaseConfigProps {
7175
@set:DevConfig
7276
@set:JvmName("dumpLongTransactions")
7377
override var dumpLongTransactions: Boolean = false

BotCommands-core/src/main/kotlin/io/github/freya022/botcommands/api/core/config/BEventManagerConfig.kt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,11 @@ import kotlin.time.toJavaDuration
1010
import kotlin.time.toKotlinDuration
1111

1212
@InjectedService
13-
interface BEventManagerConfig {
13+
interface BEventManagerConfig : IConfig, BEventManagerConfigProps {
14+
override val configType get() = BEventManagerConfig::class.java
15+
}
1416

17+
interface BEventManagerConfigProps {
1518
/**
1619
* The time applied to all event listeners by default before their coroutine is cancelled.
1720
*
@@ -42,8 +45,7 @@ interface BEventManagerConfig {
4245
}
4346

4447
@ConfigDSL
45-
class BEventManagerConfigBuilder internal constructor() : BEventManagerConfig {
46-
48+
class BEventManagerConfigBuilder internal constructor() : BEventManagerConfigProps {
4749
@set:JvmSynthetic
4850
override var defaultTimeout: Duration? = null
4951

BotCommands-core/src/main/kotlin/io/github/freya022/botcommands/api/core/config/BLocalizationConfig.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,11 @@ import io.github.freya022.botcommands.internal.core.config.ConfigDSL
99
import io.github.freya022.botcommands.internal.core.config.ConfigurationValue
1010

1111
@InjectedService
12-
interface BLocalizationConfig {
12+
interface BLocalizationConfig : IConfig, BLocalizationConfigProps {
13+
override val configType get() = BLocalizationConfig::class.java
14+
}
15+
16+
interface BLocalizationConfigProps {
1317
/**
1418
* Localization bundles available for localizing interaction responses, with [LocalizableInteraction],
1519
* not to be confused with those used to [localize commands][BApplicationConfigBuilder.addLocalizations].
@@ -30,7 +34,7 @@ interface BLocalizationConfig {
3034
}
3135

3236
@ConfigDSL
33-
class BLocalizationConfigBuilder internal constructor() : BLocalizationConfig {
37+
class BLocalizationConfigBuilder internal constructor() : BLocalizationConfigProps {
3438
override val responseBundles: MutableSet<String> = hashSetOf()
3539

3640
/**

BotCommands-core/src/main/kotlin/io/github/freya022/botcommands/api/core/config/BModalsConfig.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@ import io.github.freya022.botcommands.internal.core.config.ConfigDSL
66
import io.github.freya022.botcommands.internal.core.config.ConfigurationValue
77

88
@InjectedService
9-
interface BModalsConfig {
9+
interface BModalsConfig : IConfig, BModalsConfigProps {
10+
override val configType get() = BModalsConfig::class.java
11+
}
12+
13+
interface BModalsConfigProps {
1014
/**
1115
* Whether modal interactions should be listened for.
1216
*
@@ -21,7 +25,7 @@ interface BModalsConfig {
2125
}
2226

2327
@ConfigDSL
24-
class BModalsConfigBuilder internal constructor() : BModalsConfig {
28+
class BModalsConfigBuilder internal constructor() : BModalsConfigProps {
2529
@set:JvmName("enable")
2630
override var enable: Boolean = true
2731

BotCommands-core/src/main/kotlin/io/github/freya022/botcommands/api/core/config/BServiceConfig.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,11 @@ import io.github.freya022.botcommands.internal.utils.putIfAbsentOrThrow
1313
import kotlin.reflect.KClass
1414

1515
@InjectedService
16-
interface BServiceConfig {
16+
interface BServiceConfig : IConfig, BServiceConfigProps {
17+
override val configType get() = BServiceConfig::class.java
18+
}
19+
20+
interface BServiceConfigProps {
1721
/**
1822
* Enables debugging of service loading.
1923
*
@@ -25,7 +29,7 @@ interface BServiceConfig {
2529
}
2630

2731
@ConfigDSL
28-
class BServiceConfigBuilder internal constructor() : BServiceConfig {
32+
class BServiceConfigBuilder internal constructor() : BServiceConfigProps {
2933
override var debug: Boolean = false
3034

3135
private val _serviceSuppliers: MutableMap<KClass<*>, ServiceSupplier<*>> = hashMapOf()

0 commit comments

Comments
 (0)