feat: Koin integration

This commit is contained in:
Ahmad Ansori Palembani 2025-05-24 08:38:26 +07:00
parent b22cf439ad
commit 26e5ba9e85
7 changed files with 131 additions and 17 deletions

View file

@ -8,10 +8,6 @@ import org.koin.core.context.GlobalContext.startKoin
suspend fun main() {
startKoin {
modules(appModule)
}
bot {
Logger.setTag("Tsukumogami")

View file

@ -14,12 +14,14 @@ import io.github.null2264.tsukumogami.core.exceptions.CommandNotFound
import io.github.null2264.tsukumogami.core.module.BotModule
import io.github.null2264.tsukumogami.core.commands.IGroup
import io.github.null2264.tsukumogami.core.ext.parseCommandAndArguments
import io.github.null2264.tsukumogami.core.koin.TsukumogamiKoinComponent
import kotlin.reflect.full.callSuspend
import kotlinx.coroutines.runBlocking
import org.koin.core.component.inject
open class Bot internal constructor(): IGroup {
open class Bot internal constructor(): IGroup, TsukumogamiKoinComponent {
lateinit var client: Kord
val client: Kord by inject()
private val modules = mutableMapOf<String, BotModule>()
private val _prefixes = mutableListOf<String>()
val prefixes: List<String> get() = _prefixes.toList()
@ -59,11 +61,6 @@ open class Bot internal constructor(): IGroup {
}
open suspend fun start() {
client = Kord(token).apply {
on<ReadyEvent> { onReady() }
on<MessageCreateEvent> { onMessage(this.message, this) }
}
client.login {
@OptIn(PrivilegedIntent::class)
intents += Intent.MessageContent

View file

@ -1,17 +1,28 @@
package io.github.null2264.tsukumogami.core
import dev.kord.core.Kord
import dev.kord.core.event.gateway.ReadyEvent
import dev.kord.core.event.message.MessageCreateEvent
import dev.kord.core.on
import io.github.null2264.tsukumogami.core.ext.loadModule
import io.github.null2264.tsukumogami.core.koin.TsukumogamiKoinContext
import io.github.null2264.tsukumogami.core.module.BotModule
import kotlin.reflect.KFunction
import kotlinx.coroutines.runBlocking
import org.koin.dsl.bind
class BotBuilder internal constructor(
val bot: Bot
) {
var token: String
get() = bot.token
set(value) {
bot.token = value
var token: String = ""
var kordBuilder: suspend (String) -> Kord = { token ->
Kord(token).apply {
on<ReadyEvent> { bot.onReady() }
on<MessageCreateEvent> { bot.onMessage(this.message, this) }
}
}
fun modules(vararg modules: BotModule) {
modules.forEach(bot::addModule)
@ -23,8 +34,19 @@ class BotBuilder internal constructor(
}
fun bot(clazz: KFunction<Bot> = ::Bot, declaration: BotBuilder.() -> Unit): Bot {
if (TsukumogamiKoinContext.getOrNull() == null)
TsukumogamiKoinContext.startKoin {
}
val bot = clazz.call()
val holder = BotBuilder(bot)
declaration(holder)
val kord = runBlocking {
holder.kordBuilder(holder.token)
}
loadModule { single { kord } bind Kord::class }
loadModule { single { bot } bind Bot::class }
return holder.bot
}

View file

@ -1,4 +1,3 @@
package io.github.null2264.tsukumogami.core.commands
class EmptyArguments : Arguments() {
}
class EmptyArguments : Arguments()

View file

@ -0,0 +1,17 @@
package io.github.null2264.tsukumogami.core.ext
import io.github.null2264.tsukumogami.core.koin.TsukumogamiKoinContext
import org.koin.core.module.Module
import org.koin.dsl.ModuleDeclaration
import org.koin.dsl.module
fun loadModule(
createdAtStart: Boolean = false,
moduleDeclaration: ModuleDeclaration,
): Module {
val moduleObj = module(createdAtStart, moduleDeclaration)
TsukumogamiKoinContext.loadKoinModules(moduleObj)
return moduleObj
}

View file

@ -0,0 +1,8 @@
package io.github.null2264.tsukumogami.core.koin
import org.koin.core.Koin
import org.koin.core.component.KoinComponent
interface TsukumogamiKoinComponent : KoinComponent {
override fun getKoin(): Koin = TsukumogamiKoinContext.get()
}

View file

@ -0,0 +1,75 @@
package io.github.null2264.tsukumogami.core.koin
import org.koin.core.Koin
import org.koin.core.KoinApplication
import org.koin.core.context.KoinContext
import org.koin.core.error.KoinApplicationAlreadyStartedException
import org.koin.core.module.Module
import org.koin.dsl.KoinAppDeclaration
/**
* The [KoinContext] for Tsukumogami.
*
* To use this context, implement [TsukumogamiKoinComponent].
*
* @see org.koin.core.context.GlobalContext
*/
object TsukumogamiKoinContext : KoinContext {
/** The current [Koin] instance. */
private var koin: Koin? = null
/** The current [KoinApplication]. */
private var koinApp: KoinApplication? = null
override fun get(): Koin = koin ?: error("KoinApplication has not been started")
override fun getOrNull(): Koin? = koin
public fun getKoinApplicationOrNull(): KoinApplication? = koinApp
private fun register(koinApplication: KoinApplication) {
if (koin != null) {
throw KoinApplicationAlreadyStartedException("KoinApplication has already been started")
}
koinApp = koinApplication
koin = koinApplication.koin
}
override fun loadKoinModules(module: Module, createEagerInstances: Boolean) {
get().loadModules(listOf(module), createEagerInstances = createEagerInstances)
}
override fun loadKoinModules(modules: List<Module>, createEagerInstances: Boolean) {
get().loadModules(modules, createEagerInstances = createEagerInstances)
}
override fun startKoin(koinApplication: KoinApplication): KoinApplication = synchronized(this) {
register(koinApplication)
koinApplication.createEagerInstances()
koinApplication.allowOverride(true)
return koinApplication
}
override fun startKoin(appDeclaration: KoinAppDeclaration): KoinApplication = synchronized(this) {
val koinApplication = KoinApplication.init()
register(koinApplication)
appDeclaration(koinApplication)
koinApplication.createEagerInstances()
return koinApplication
}
override fun stopKoin() {
koin?.close()
koin = null
}
override fun unloadKoinModules(module: Module) {
get().unloadModules(listOf(module))
}
override fun unloadKoinModules(modules: List<Module>) {
get().unloadModules(modules)
}
}