diff --git a/README.md b/README.md index 254f7b0cd..caa67b7fc 100644 --- a/README.md +++ b/README.md @@ -67,23 +67,41 @@ simbot的**平台功能**由组件驱动,安装不同的组件库来获得不 ```Kotlin suspend fun main() { - val application = launchSimpleApplication { - // 安装KOOK和QQ频道组件库 - useKook() - useQQGuild() - } - - application.kookBots { - // ... 注册kook bot,并在此之后可处理到kook的相关事件 + launchSimpleApplication { config() } + .joinWith { module() } +} + +fun ApplicationFactoryConfigurer<*, *, *>.config() { + // 安装KOOK和QQ频道组件库 + useKook() + useQQGuild() +} + +/** + * 对已经构建完成的 `Application` 进行配置于应用 + */ +suspend fun Application.module() { + registerBots() + registerListeners() +} + +/** + * 注册所需的bot + */ +suspend fun Application.registerBots() { + // ... 注册kook bot,并在此之后可处理到kook的相关事件 + kookBots { register(...) { ... }.start() } - application.qqGuildBots { - // ... 注册QQ频道bot,并在此之后可处理到QQ频道的相关事件 + + // ... 注册QQ频道bot,并在此之后可处理到QQ频道的相关事件 + qqGuildBots { register(...) { ... }.start() } - - // 注册各种事件处理器 - application.listeners { +} + +fun Application.registerListeners() { + listeners { // 注册一个事件处理器 // ChatChannelMessageEvent 是由simbot API定义的泛用类型,代表所有子频道消息事件 // 其中就包括QQ频道的公域消息事件, 或者KOOK的频道消息事件 @@ -121,9 +139,6 @@ suspend fun main() { - [应用手册][doc-homepage] - [文档引导站&API文档](https://docs.simbot.forte.love) - -> 切换分支到 [v3-dev](https://github.com/simple-robot/simpler-robot/tree/v3-dev) 可查看 simbot v3 的历史分支。 - ## 协助我们 为我们点亮一个 **✨star🌟** 便是能够给予我们继续走下去的最大动力与支持! diff --git a/simbot-api/api/simbot-api.api b/simbot-api/api/simbot-api.api index fa54f2a7b..9dfa60b93 100644 --- a/simbot-api/api/simbot-api.api +++ b/simbot-api/api/simbot-api.api @@ -267,6 +267,7 @@ public abstract interface class love/forte/simbot/application/ApplicationLaunche public final class love/forte/simbot/application/Applications { public static final fun asCompletableFuture (Llove/forte/simbot/application/Application;)Ljava/util/concurrent/CompletableFuture; + public static final fun joinWith (Llove/forte/simbot/application/Application;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static final synthetic fun launchApplication (Llove/forte/simbot/application/ApplicationFactory;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static synthetic fun launchApplication$default (Llove/forte/simbot/application/ApplicationFactory;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; public static final fun launchApplicationAsync (Lkotlinx/coroutines/CoroutineScope;Llove/forte/simbot/application/ApplicationFactory;)Llove/forte/simbot/common/async/Async; @@ -417,6 +418,11 @@ public abstract interface class love/forte/simbot/bot/BotRelations { public abstract fun getGuildRelation ()Llove/forte/simbot/bot/GuildRelation; } +public final class love/forte/simbot/bot/Bots { + public static final fun startAndJoin (Llove/forte/simbot/bot/Bot;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static final fun startIn (Llove/forte/simbot/bot/Bot;Lkotlinx/coroutines/CoroutineScope;)Lkotlinx/coroutines/Job; +} + public class love/forte/simbot/bot/ConflictBotException : love/forte/simbot/bot/BotException { public fun ()V public fun (Ljava/lang/String;)V diff --git a/simbot-api/src/commonMain/kotlin/love/forte/simbot/application/Application.kt b/simbot-api/src/commonMain/kotlin/love/forte/simbot/application/Application.kt index 4ce742453..a410e8acf 100644 --- a/simbot-api/src/commonMain/kotlin/love/forte/simbot/application/Application.kt +++ b/simbot-api/src/commonMain/kotlin/love/forte/simbot/application/Application.kt @@ -4,7 +4,7 @@ * Project https://github.com/simple-robot/simpler-robot * Email ForteScarlet@163.com * - * This file is part of the Simple Robot Library. + * This file is part of the Simple Robot Library (Alias: simple-robot, simbot, etc.). * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -129,3 +129,18 @@ public inline fun Application.listeners(block: EventListenerRegistrar.() -> Unit eventDispatcher.block() } +/** + * 执行完 [block] 后挂起当前 [Application]。 + * + * ```kotlin + * app.joinWith { // this: Application + * // ... + * } + * ``` + * + * @see Application.join + */ +public suspend inline fun T.joinWith(block: T.() -> Unit) { + block() + join() +} diff --git a/simbot-api/src/commonMain/kotlin/love/forte/simbot/bot/Bot.kt b/simbot-api/src/commonMain/kotlin/love/forte/simbot/bot/Bot.kt index ed28ac66f..b5c7c96d9 100644 --- a/simbot-api/src/commonMain/kotlin/love/forte/simbot/bot/Bot.kt +++ b/simbot-api/src/commonMain/kotlin/love/forte/simbot/bot/Bot.kt @@ -21,10 +21,14 @@ * */ +@file:JvmName("Bots") + package love.forte.simbot.bot import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Job import kotlinx.coroutines.cancel +import kotlinx.coroutines.launch import love.forte.simbot.ability.CompletionAware import love.forte.simbot.ability.LifecycleAware import love.forte.simbot.common.collectable.Collectable @@ -37,6 +41,7 @@ import love.forte.simbot.definition.Contact import love.forte.simbot.definition.Guild import love.forte.simbot.suspendrunner.ST import love.forte.simbot.suspendrunner.STP +import kotlin.jvm.JvmName /** * 一个 `Bot`。 @@ -275,3 +280,22 @@ public interface ContactRelation { @STP public suspend fun contactCount(): Int } + +/** + * 启动当前 [Bot] 后挂起。 + * + * @see Bot.start + * @see Bot.join + */ +public suspend fun Bot.startAndJoin() { + start() + join() +} + +/** + * 通过 [scope] 在异步中启动 [Bot]。 + * + * @see Bot.start + */ +public fun Bot.startIn(scope: CoroutineScope): Job = + scope.launch { start() } diff --git a/simbot-api/src/commonMain/kotlin/love/forte/simbot/message/Messages.kt b/simbot-api/src/commonMain/kotlin/love/forte/simbot/message/Messages.kt index 1db0d2a42..206a4659f 100644 --- a/simbot-api/src/commonMain/kotlin/love/forte/simbot/message/Messages.kt +++ b/simbot-api/src/commonMain/kotlin/love/forte/simbot/message/Messages.kt @@ -427,8 +427,9 @@ public fun StringFormat.encodeMessagesToString(messages: Messages): String = public fun StringFormat.decodeMessagesFromString(string: String): Messages = decodeFromString(Messages.serializer, string) - -// TODO delete on stable version +/** + * @suppress 仅针对v4.0.0-dev16及以下的版本的JVM二进制兼容 + */ @Suppress("FunctionName") @Deprecated("仅供临时针对v4.0.0-dev16及以下的版本的JVM二进制兼容", level = DeprecationLevel.HIDDEN) public object MessagesKt { diff --git a/simbot-commons/simbot-common-atomic/src/commonTest/kotlin/AtomicTests.kt b/simbot-commons/simbot-common-atomic/src/commonTest/kotlin/AtomicTests.kt index 07314d6cb..65689dd9f 100644 --- a/simbot-commons/simbot-common-atomic/src/commonTest/kotlin/AtomicTests.kt +++ b/simbot-commons/simbot-common-atomic/src/commonTest/kotlin/AtomicTests.kt @@ -21,11 +21,8 @@ * */ -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.coroutineScope -import kotlinx.coroutines.launch +import kotlinx.coroutines.* import kotlinx.coroutines.test.runTest -import kotlinx.coroutines.withContext import love.forte.simbot.common.atomic.* import kotlin.test.* @@ -139,14 +136,12 @@ class AtomicTests { @Test fun compareAsyncTest() = runTest { val times = 1000 - withContext(Dispatchers.Default) { - coroutineScope { - launch(Dispatchers.Default) { checkAtomicInt(times) } - launch(Dispatchers.Default) { checkAtomicLong(times) } - launch(Dispatchers.Default) { checkAtomicUInt(times) } - launch(Dispatchers.Default) { checkAtomicULong(times) } - launch(Dispatchers.Default) { checkAtomicRef(times) } - } + coroutineScope { + checkAtomicInt(times) + checkAtomicLong(times) + checkAtomicUInt(times) + checkAtomicULong(times) + checkAtomicRef(times) } } @@ -159,6 +154,7 @@ class AtomicTests { launch { atomic += 1 } + yield() } } launch { @@ -166,6 +162,7 @@ class AtomicTests { launch { atomic.update { it + 1 } } + yield() } } }