mirror of
https://github.com/mamoe/mirai.git
synced 2025-04-25 04:50:26 +08:00
Make interface Event
the base type of a event, remove interface Subscribable
This commit is contained in:
parent
474c5686e6
commit
7891ffc136
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid
mirai-core/src
commonMain/kotlin/net.mamoe.mirai
jvmMain/kotlin/net/mamoe/mirai/event
jvmTest/kotlin/net/mamoe/mirai/event
mirai-demos/mirai-demo-gentleman/src/main/kotlin/demo/gentleman
@ -295,7 +295,7 @@ internal fun ImMsgBody.SourceMsg.toMessageChain(): MessageChain {
|
||||
}
|
||||
|
||||
|
||||
@UseExperimental(MiraiInternalAPI::class)
|
||||
@UseExperimental(MiraiInternalAPI::class, ExperimentalUnsignedTypes::class)
|
||||
internal fun List<ImMsgBody.Elem>.joinToMessageChain(message: MessageChain) {
|
||||
this.forEach {
|
||||
when {
|
||||
|
@ -21,10 +21,13 @@ import kotlinx.io.core.use
|
||||
import net.mamoe.mirai.contact.ContactList
|
||||
import net.mamoe.mirai.contact.Member
|
||||
import net.mamoe.mirai.contact.MemberPermission
|
||||
import net.mamoe.mirai.event.events.ForceOfflineEvent
|
||||
import net.mamoe.mirai.data.MultiPacket
|
||||
import net.mamoe.mirai.data.Packet
|
||||
import net.mamoe.mirai.event.*
|
||||
import net.mamoe.mirai.event.BroadcastControllable
|
||||
import net.mamoe.mirai.event.Event
|
||||
import net.mamoe.mirai.event.broadcast
|
||||
import net.mamoe.mirai.event.events.ForceOfflineEvent
|
||||
import net.mamoe.mirai.event.subscribeAlways
|
||||
import net.mamoe.mirai.network.BotNetworkHandler
|
||||
import net.mamoe.mirai.qqandroid.GroupImpl
|
||||
import net.mamoe.mirai.qqandroid.MemberImpl
|
||||
@ -350,7 +353,7 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
|
||||
|
||||
|
||||
// broadcast
|
||||
if (packet is Subscribable) {
|
||||
if (packet is Event) {
|
||||
if (packet is BroadcastControllable) {
|
||||
if (packet.shouldBroadcast) packet.broadcast()
|
||||
} else {
|
||||
|
@ -12,7 +12,7 @@ package net.mamoe.mirai.qqandroid.network.protocol.packet
|
||||
import kotlinx.io.core.*
|
||||
import kotlinx.io.pool.useInstance
|
||||
import net.mamoe.mirai.data.Packet
|
||||
import net.mamoe.mirai.event.Subscribable
|
||||
import net.mamoe.mirai.event.Event
|
||||
import net.mamoe.mirai.qqandroid.QQAndroidBot
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.TroopManagement
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.image.ImgStore
|
||||
@ -20,7 +20,6 @@ import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.image.LongConn
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.MessageSvc
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.OnlinePush
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.list.FriendList
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.login.*
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.login.ConfigPushSvc
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.login.Heartbeat
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.login.StatSvc
|
||||
@ -59,7 +58,7 @@ internal abstract class OutgoingPacketFactory<TPacket : Packet>(
|
||||
final override val receivingCommandName: String get() = commandName
|
||||
|
||||
/**
|
||||
* **解码**服务器的回复数据包. 返回的包若是 [Subscribable], 则会 broadcast.
|
||||
* **解码**服务器的回复数据包. 返回的包若是 [Event], 则会 broadcast.
|
||||
*/
|
||||
abstract suspend fun ByteReadPacket.decode(bot: QQAndroidBot): TPacket
|
||||
|
||||
@ -85,7 +84,7 @@ internal abstract class IncomingPacketFactory<TPacket : Packet>(
|
||||
val responseCommandName: String = ""
|
||||
) : PacketFactory<TPacket>() {
|
||||
/**
|
||||
* **解码**服务器的回复数据包. 返回的包若是 [Subscribable], 则会 broadcast.
|
||||
* **解码**服务器的回复数据包. 返回的包若是 [Event], 则会 broadcast.
|
||||
*/
|
||||
abstract suspend fun ByteReadPacket.decode(bot: QQAndroidBot, sequenceId: Int): TPacket
|
||||
|
||||
|
@ -9,11 +9,11 @@
|
||||
|
||||
package net.mamoe.mirai.data
|
||||
|
||||
import net.mamoe.mirai.event.Subscribable
|
||||
import net.mamoe.mirai.event.Event
|
||||
|
||||
/**
|
||||
* 事件包. 可被监听.
|
||||
*
|
||||
* @see Subscribable
|
||||
* @see Event
|
||||
*/
|
||||
interface EventPacket : Subscribable, Packet
|
||||
interface EventPacket : Event, Packet
|
@ -11,6 +11,7 @@ package net.mamoe.mirai.data
|
||||
|
||||
/**
|
||||
* 从服务器收到的包解析之后的结构化数据.
|
||||
* 它是一个数据包工厂的处理的返回值.
|
||||
*/
|
||||
interface Packet {
|
||||
/**
|
||||
|
@ -17,61 +17,44 @@ import net.mamoe.mirai.event.internal.broadcastInternal
|
||||
import net.mamoe.mirai.utils.MiraiInternalAPI
|
||||
|
||||
/**
|
||||
* 可被监听的.
|
||||
* 可被监听的类, 可以是任何 class 或 object.
|
||||
*
|
||||
* 可以是任何 class 或 object.
|
||||
* 若监听这个类, 监听器将会接收所有事件的广播.
|
||||
*
|
||||
* @see subscribeAlways
|
||||
* @see subscribeWhile
|
||||
*
|
||||
* @see subscribeMessages
|
||||
*/
|
||||
interface Subscribable
|
||||
|
||||
/**
|
||||
* 所有事件的基类.
|
||||
* 若监听这个类, 监听器将会接收所有事件的广播.
|
||||
*
|
||||
* @see [broadcast] 广播事件
|
||||
* @see [subscribe] 监听事件
|
||||
*/
|
||||
abstract class Event : Subscribable {
|
||||
interface Event
|
||||
|
||||
/**
|
||||
* 可被取消的事件
|
||||
*/
|
||||
abstract class CancellableEvent : Event {
|
||||
/**
|
||||
* 事件是否已取消. 事件需实现 [Cancellable] 才可以被取消, 否则这个字段为常量值 false
|
||||
* 事件是否已取消.
|
||||
*/
|
||||
val cancelled: Boolean get() = _cancelled
|
||||
|
||||
private var _cancelled: Boolean = false
|
||||
get() = field.takeIf { this is Cancellable } ?: false
|
||||
private set(value) =
|
||||
if (this is Cancellable) field = value
|
||||
else throw UnsupportedOperationException()
|
||||
|
||||
/**
|
||||
* 取消事件. 事件需实现 [Cancellable] 才可以被取消
|
||||
*
|
||||
* @throws UnsupportedOperationException 如果事件没有实现 [Cancellable]
|
||||
* 取消事件.
|
||||
*/
|
||||
fun cancel() {
|
||||
_cancelled = true
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 实现这个接口的事件([Event])可以被取消. 在广播中取消不会影响广播过程.
|
||||
*/
|
||||
interface Cancellable : Subscribable {
|
||||
val cancelled: Boolean
|
||||
|
||||
fun cancel()
|
||||
}
|
||||
|
||||
/**
|
||||
* 广播一个事件的唯一途径.
|
||||
*/
|
||||
@UseExperimental(MiraiInternalAPI::class)
|
||||
suspend fun <E : Subscribable> E.broadcast(): E = apply {
|
||||
suspend fun <E : Event> E.broadcast(): E = apply {
|
||||
if (this is BotEvent && !(this.bot as BotImpl<*>).onEvent(this)) {
|
||||
return@apply
|
||||
}
|
||||
@ -81,7 +64,7 @@ suspend fun <E : Subscribable> E.broadcast(): E = apply {
|
||||
/**
|
||||
* 可控制是否需要广播这个事件包
|
||||
*/
|
||||
interface BroadcastControllable : Subscribable {
|
||||
interface BroadcastControllable : Event {
|
||||
val shouldBroadcast: Boolean
|
||||
get() = true
|
||||
}
|
@ -39,7 +39,7 @@ enum class ListeningStatus {
|
||||
* 事件监听器.
|
||||
* 由 [subscribe] 等方法返回.
|
||||
*/
|
||||
interface Listener<in E : Subscribable> : CompletableJob {
|
||||
interface Listener<in E : Event> : CompletableJob {
|
||||
suspend fun onEvent(event: E): ListeningStatus
|
||||
}
|
||||
|
||||
@ -47,7 +47,7 @@ interface Listener<in E : Subscribable> : CompletableJob {
|
||||
|
||||
/**
|
||||
* 在指定的 [CoroutineScope] 下订阅所有 [E] 及其子类事件.
|
||||
* 每当 [事件广播][Subscribable.broadcast] 时, [handler] 都会被执行.
|
||||
* 每当 [事件广播][Event.broadcast] 时, [handler] 都会被执行.
|
||||
*
|
||||
* 当 [handler] 返回 [ListeningStatus.STOPPED] 时停止监听.
|
||||
* 或 [Listener] complete 时结束.
|
||||
@ -57,7 +57,7 @@ interface Listener<in E : Subscribable> : CompletableJob {
|
||||
* 例如:
|
||||
* ```kotlin
|
||||
* runBlocking { // this: CoroutineScope
|
||||
* subscribe<Subscribable> { /* 一些处理 */ } // 返回 Listener, 即 CompletableJob
|
||||
* subscribe<Event> { /* 一些处理 */ } // 返回 Listener, 即 CompletableJob
|
||||
* }
|
||||
* foo()
|
||||
* ```
|
||||
@ -66,7 +66,7 @@ interface Listener<in E : Subscribable> : CompletableJob {
|
||||
*
|
||||
* 要创建一个全局都存在的监听, 即守护协程, 请在 [GlobalScope] 下调用本函数:
|
||||
* ```kotlin
|
||||
* GlobalScope.subscribe<Subscribable> { /* 一些处理 */ }
|
||||
* GlobalScope.subscribe<Event> { /* 一些处理 */ }
|
||||
* ```
|
||||
*
|
||||
*
|
||||
@ -75,52 +75,52 @@ interface Listener<in E : Subscribable> : CompletableJob {
|
||||
* bot.subscribe<Subscribe> { /* 一些处理 */ }
|
||||
* ```
|
||||
*/
|
||||
inline fun <reified E : Subscribable> CoroutineScope.subscribe(crossinline handler: suspend E.(E) -> ListeningStatus): Listener<E> =
|
||||
inline fun <reified E : Event> CoroutineScope.subscribe(crossinline handler: suspend E.(E) -> ListeningStatus): Listener<E> =
|
||||
E::class.subscribeInternal(Handler { it.handler(it) })
|
||||
|
||||
/**
|
||||
* 在指定的 [CoroutineScope] 下订阅所有 [E] 及其子类事件.
|
||||
* 每当 [事件广播][Subscribable.broadcast] 时, [listener] 都会被执行.
|
||||
* 每当 [事件广播][Event.broadcast] 时, [listener] 都会被执行.
|
||||
*
|
||||
* 仅当 [Listener] complete 时结束.
|
||||
*
|
||||
* @see subscribe 获取更多说明
|
||||
*/
|
||||
inline fun <reified E : Subscribable> CoroutineScope.subscribeAlways(crossinline listener: suspend E.(E) -> Unit): Listener<E> =
|
||||
inline fun <reified E : Event> CoroutineScope.subscribeAlways(crossinline listener: suspend E.(E) -> Unit): Listener<E> =
|
||||
E::class.subscribeInternal(Handler { it.listener(it); ListeningStatus.LISTENING })
|
||||
|
||||
/**
|
||||
* 在指定的 [CoroutineScope] 下订阅所有 [E] 及其子类事件.
|
||||
* 仅在第一次 [事件广播][Subscribable.broadcast] 时, [listener] 会被执行.
|
||||
* 仅在第一次 [事件广播][Event.broadcast] 时, [listener] 会被执行.
|
||||
*
|
||||
* 在这之前, 可通过 [Listener.complete] 来停止监听.
|
||||
*
|
||||
* @see subscribe 获取更多说明
|
||||
*/
|
||||
inline fun <reified E : Subscribable> CoroutineScope.subscribeOnce(crossinline listener: suspend E.(E) -> Unit): Listener<E> =
|
||||
inline fun <reified E : Event> CoroutineScope.subscribeOnce(crossinline listener: suspend E.(E) -> Unit): Listener<E> =
|
||||
E::class.subscribeInternal(Handler { it.listener(it); ListeningStatus.STOPPED })
|
||||
|
||||
/**
|
||||
* 在指定的 [CoroutineScope] 下订阅所有 [E] 及其子类事件.
|
||||
* 每当 [事件广播][Subscribable.broadcast] 时, [listener] 都会被执行, 直到 [listener] 的返回值 [equals] 于 [valueIfStop]
|
||||
* 每当 [事件广播][Event.broadcast] 时, [listener] 都会被执行, 直到 [listener] 的返回值 [equals] 于 [valueIfStop]
|
||||
*
|
||||
* 可在任意时刻通过 [Listener.complete] 来停止监听.
|
||||
*
|
||||
* @see subscribe 获取更多说明
|
||||
*/
|
||||
inline fun <reified E : Subscribable, T> CoroutineScope.subscribeUntil(valueIfStop: T, crossinline listener: suspend E.(E) -> T): Listener<E> =
|
||||
inline fun <reified E : Event, T> CoroutineScope.subscribeUntil(valueIfStop: T, crossinline listener: suspend E.(E) -> T): Listener<E> =
|
||||
E::class.subscribeInternal(Handler { if (it.listener(it) == valueIfStop) ListeningStatus.STOPPED else ListeningStatus.LISTENING })
|
||||
|
||||
/**
|
||||
* 在指定的 [CoroutineScope] 下订阅所有 [E] 及其子类事件.
|
||||
* 每当 [事件广播][Subscribable.broadcast] 时, [listener] 都会被执行,
|
||||
* 每当 [事件广播][Event.broadcast] 时, [listener] 都会被执行,
|
||||
* 如果 [listener] 的返回值 [equals] 于 [valueIfContinue], 则继续监听, 否则停止
|
||||
*
|
||||
* 可在任意时刻通过 [Listener.complete] 来停止监听.
|
||||
*
|
||||
* @see subscribe 获取更多说明
|
||||
*/
|
||||
inline fun <reified E : Subscribable, T> CoroutineScope.subscribeWhile(valueIfContinue: T, crossinline listener: suspend E.(E) -> T): Listener<E> =
|
||||
inline fun <reified E : Event, T> CoroutineScope.subscribeWhile(valueIfContinue: T, crossinline listener: suspend E.(E) -> T): Listener<E> =
|
||||
E::class.subscribeInternal(Handler { if (it.listener(it) != valueIfContinue) ListeningStatus.STOPPED else ListeningStatus.LISTENING })
|
||||
|
||||
// endregion
|
||||
@ -146,7 +146,7 @@ inline fun <reified E : Subscribable, T> CoroutineScope.subscribeWhile(valueIfCo
|
||||
*/
|
||||
@ListenersBuilderDsl
|
||||
@Suppress("MemberVisibilityCanBePrivate", "unused")
|
||||
inline class ListenerBuilder<out E : Subscribable>(
|
||||
inline class ListenerBuilder<out E : Event>(
|
||||
@PublishedApi internal inline val handlerConsumer: CoroutineCoroutineScope.(Listener<E>) -> Unit
|
||||
) {
|
||||
fun CoroutineCoroutineScope.handler(listener: suspend E.(E) -> ListeningStatus) {
|
||||
|
@ -13,86 +13,120 @@ import net.mamoe.mirai.Bot
|
||||
import net.mamoe.mirai.contact.Group
|
||||
import net.mamoe.mirai.contact.Member
|
||||
import net.mamoe.mirai.contact.MemberPermission
|
||||
import net.mamoe.mirai.data.Packet
|
||||
import net.mamoe.mirai.event.Event
|
||||
import net.mamoe.mirai.utils.WeakRef
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
|
||||
abstract class BotEvent : Event {
|
||||
private lateinit var _bot: Bot
|
||||
open val bot: Bot get() = _bot
|
||||
|
||||
constructor(bot: Bot) : super() {
|
||||
this._bot = bot
|
||||
}
|
||||
|
||||
constructor() : super()
|
||||
/**
|
||||
* 有关一个 [Bot] 的事件
|
||||
*/
|
||||
interface BotEvent : Event {
|
||||
val bot: Bot
|
||||
}
|
||||
|
||||
class BotLoginSucceedEvent(bot: Bot) : BotEvent(bot)
|
||||
/**
|
||||
* [Bot] 登录完成, 好友列表, 群组列表初始化完成
|
||||
*/
|
||||
data class BotLoginSucceedEvent(override val bot: Bot) : BotEvent
|
||||
|
||||
class BotOfflineEvent(bot: Bot) : BotEvent(bot)
|
||||
/**
|
||||
* [Bot] 离线.
|
||||
*/
|
||||
data class BotOfflineEvent(override val bot: Bot) : BotEvent
|
||||
|
||||
class BotReadyEvent(bot: Bot) : BotEvent(bot)
|
||||
/**
|
||||
* 被挤下线
|
||||
*/
|
||||
data class ForceOfflineEvent(
|
||||
override val bot: Bot,
|
||||
val title: String,
|
||||
val tips: String
|
||||
) : BotEvent, Packet
|
||||
|
||||
interface GroupEvent {
|
||||
/**
|
||||
* 有关群的事件
|
||||
*/
|
||||
interface GroupEvent : BotEvent {
|
||||
val group: Group
|
||||
override val bot: Bot
|
||||
get() = group.bot
|
||||
}
|
||||
|
||||
class AddGroupEvent(bot: Bot, override val group: Group) : BotEvent(bot), GroupEvent
|
||||
data class AddGroupEvent(override val group: Group) : BotEvent, GroupEvent
|
||||
|
||||
class RemoveGroupEvent(bot: Bot, override val group: Group) : BotEvent(bot), GroupEvent
|
||||
data class RemoveGroupEvent(override val group: Group) : BotEvent, GroupEvent
|
||||
|
||||
class BotGroupPermissionChangeEvent(
|
||||
bot: Bot,
|
||||
data class BotGroupPermissionChangeEvent(
|
||||
override val group: Group,
|
||||
val origin: MemberPermission,
|
||||
val new: MemberPermission
|
||||
) : BotEvent(bot), GroupEvent
|
||||
) : BotEvent, GroupEvent
|
||||
|
||||
|
||||
interface GroupSettingChangeEvent<T> : GroupEvent {
|
||||
val operator: Member
|
||||
val origin: T
|
||||
val new: T
|
||||
|
||||
override val group: Group
|
||||
get() = operator.group
|
||||
}
|
||||
|
||||
class GroupNameChangeEvent(
|
||||
bot: Bot,
|
||||
override val group: Group,
|
||||
data class GroupNameChangeEvent(
|
||||
override val operator: Member,
|
||||
override val origin: String,
|
||||
override val new: String
|
||||
) : BotEvent(bot), GroupSettingChangeEvent<String>
|
||||
) : BotEvent, GroupSettingChangeEvent<String>
|
||||
|
||||
class GroupMuteAllEvent(
|
||||
bot: Bot,
|
||||
override val group: Group,
|
||||
/**
|
||||
* 群 "全员禁言" 功能开启
|
||||
*/
|
||||
data class GroupMuteAllEvent(
|
||||
override val operator: Member,
|
||||
override val origin: Boolean,
|
||||
override val new: Boolean
|
||||
) : BotEvent(bot), GroupSettingChangeEvent<Boolean>
|
||||
) : BotEvent, GroupSettingChangeEvent<Boolean>
|
||||
|
||||
class GroupConfessTalkEvent(
|
||||
bot: Bot,
|
||||
override val group: Group,
|
||||
data class GroupConfessTalkEvent(
|
||||
override val operator: Member,
|
||||
override val origin: Boolean,
|
||||
override val new: Boolean
|
||||
) : BotEvent(bot), GroupSettingChangeEvent<Boolean>
|
||||
) : BotEvent, GroupSettingChangeEvent<Boolean>
|
||||
|
||||
|
||||
/**
|
||||
* 有关群成员的事件
|
||||
*/
|
||||
interface GroupMemberEvent : GroupEvent {
|
||||
val member: Member
|
||||
override val group: Group
|
||||
get() = member.group
|
||||
}
|
||||
|
||||
class MemberJoinEvent(bot: Bot, override val member: Member) : BotEvent(bot), GroupMemberEvent
|
||||
/**
|
||||
* 成员加入群的事件
|
||||
*/
|
||||
data class MemberJoinEvent(override val member: Member) : BotEvent, GroupMemberEvent
|
||||
|
||||
class MemberLeftEvent(bot: Bot, override val member: Member) : BotEvent(bot), GroupMemberEvent
|
||||
/**
|
||||
* 成员离开群的事件
|
||||
*/
|
||||
sealed class MemberLeftEvent : BotEvent, GroupMemberEvent {
|
||||
/**
|
||||
* 成员被踢出群
|
||||
*/
|
||||
data class Kick(override val member: Member, val operator: Member) : MemberLeftEvent()
|
||||
|
||||
class MemberMuteEvent(bot: Bot, override val member: Member) : BotEvent(bot), GroupMemberEvent
|
||||
/**
|
||||
* 成员主动离开
|
||||
*/
|
||||
data class Quit(override val member: Member) : MemberLeftEvent()
|
||||
}
|
||||
|
||||
class MemberPermissionChangeEvent(
|
||||
bot: Bot,
|
||||
data class MemberPermissionChangeEvent(
|
||||
override val bot: Bot,
|
||||
override val member: Member,
|
||||
val origin: MemberPermission,
|
||||
val new: MemberPermission
|
||||
) : BotEvent(bot), GroupMemberEvent
|
||||
) : BotEvent, GroupMemberEvent
|
||||
|
||||
|
||||
|
@ -1,13 +0,0 @@
|
||||
package net.mamoe.mirai.event.events
|
||||
|
||||
import net.mamoe.mirai.Bot
|
||||
import net.mamoe.mirai.data.Packet
|
||||
|
||||
/**
|
||||
* 被挤下线
|
||||
*/
|
||||
data class ForceOfflineEvent(
|
||||
override val bot: Bot,
|
||||
val title: String,
|
||||
val tips: String
|
||||
) : BotEvent(), Packet
|
@ -7,10 +7,11 @@
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.data
|
||||
package net.mamoe.mirai.event.events
|
||||
|
||||
import net.mamoe.mirai.contact.Group
|
||||
import net.mamoe.mirai.contact.Member
|
||||
import net.mamoe.mirai.data.EventPacket
|
||||
|
||||
|
||||
// region mute
|
@ -10,9 +10,9 @@
|
||||
package net.mamoe.mirai.event.internal
|
||||
|
||||
import kotlinx.coroutines.*
|
||||
import net.mamoe.mirai.event.Event
|
||||
import net.mamoe.mirai.event.Listener
|
||||
import net.mamoe.mirai.event.ListeningStatus
|
||||
import net.mamoe.mirai.event.Subscribable
|
||||
import net.mamoe.mirai.utils.LockFreeLinkedList
|
||||
import net.mamoe.mirai.utils.MiraiDebugAPI
|
||||
import net.mamoe.mirai.utils.MiraiLogger
|
||||
@ -29,14 +29,14 @@ import kotlin.reflect.KClass
|
||||
var EventDisabled = false
|
||||
|
||||
@PublishedApi
|
||||
internal fun <L : Listener<E>, E : Subscribable> KClass<out E>.subscribeInternal(listener: L): L {
|
||||
internal fun <L : Listener<E>, E : Event> KClass<out E>.subscribeInternal(listener: L): L {
|
||||
this.listeners().addLast(listener)
|
||||
return listener
|
||||
}
|
||||
|
||||
@PublishedApi
|
||||
@Suppress("FunctionName")
|
||||
internal fun <E : Subscribable> CoroutineScope.Handler(handler: suspend (E) -> ListeningStatus): Handler<E> {
|
||||
internal fun <E : Event> CoroutineScope.Handler(handler: suspend (E) -> ListeningStatus): Handler<E> {
|
||||
return Handler(coroutineContext[Job], coroutineContext, handler)
|
||||
}
|
||||
|
||||
@ -45,7 +45,7 @@ private inline fun inline(block: () -> Unit) = block()
|
||||
* 事件处理器.
|
||||
*/
|
||||
@PublishedApi
|
||||
internal class Handler<in E : Subscribable>
|
||||
internal class Handler<in E : Event>
|
||||
@PublishedApi internal constructor(parentJob: Job?, private val subscriberContext: CoroutineContext, @JvmField val handler: suspend (E) -> ListeningStatus) :
|
||||
Listener<E>, CompletableJob by Job(parentJob) {
|
||||
|
||||
@ -79,21 +79,21 @@ internal class Handler<in E : Subscribable>
|
||||
/**
|
||||
* 这个事件类的监听器 list
|
||||
*/
|
||||
internal fun <E : Subscribable> KClass<out E>.listeners(): EventListeners<E> = EventListenerManager.get(this)
|
||||
internal fun <E : Event> KClass<out E>.listeners(): EventListeners<E> = EventListenerManager.get(this)
|
||||
|
||||
internal class EventListeners<E : Subscribable> : LockFreeLinkedList<Listener<E>>()
|
||||
internal class EventListeners<E : Event> : LockFreeLinkedList<Listener<E>>()
|
||||
|
||||
/**
|
||||
* 管理每个事件 class 的 [EventListeners].
|
||||
* [EventListeners] 是 lazy 的: 它们只会在被需要的时候才创建和存储.
|
||||
*/
|
||||
internal object EventListenerManager {
|
||||
private data class Registry<E : Subscribable>(val clazz: KClass<E>, val listeners: EventListeners<E>)
|
||||
private data class Registry<E : Event>(val clazz: KClass<E>, val listeners: EventListeners<E>)
|
||||
|
||||
private val registries = LockFreeLinkedList<Registry<*>>()
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
internal fun <E : Subscribable> get(clazz: KClass<out E>): EventListeners<E> {
|
||||
internal fun <E : Event> get(clazz: KClass<out E>): EventListeners<E> {
|
||||
return registries.filteringGetOrAdd({ it.clazz == clazz }) {
|
||||
Registry(
|
||||
clazz,
|
||||
@ -105,7 +105,7 @@ internal object EventListenerManager {
|
||||
|
||||
// inline: NO extra Continuation
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
internal suspend inline fun Subscribable.broadcastInternal() {
|
||||
internal suspend inline fun Event.broadcastInternal() {
|
||||
if (EventDisabled) return
|
||||
|
||||
callAndRemoveIfRequired(this::class.listeners())
|
||||
@ -113,18 +113,18 @@ internal suspend inline fun Subscribable.broadcastInternal() {
|
||||
var supertypes = this::class.supertypes
|
||||
while (true) {
|
||||
val superSubscribableType = supertypes.firstOrNull {
|
||||
it.classifier as? KClass<out Subscribable> != null
|
||||
it.classifier as? KClass<out Event> != null
|
||||
}
|
||||
|
||||
superSubscribableType?.let {
|
||||
callAndRemoveIfRequired((it.classifier as KClass<out Subscribable>).listeners())
|
||||
callAndRemoveIfRequired((it.classifier as KClass<out Event>).listeners())
|
||||
}
|
||||
|
||||
supertypes = (superSubscribableType?.classifier as? KClass<*>)?.supertypes ?: return
|
||||
}
|
||||
}
|
||||
|
||||
private suspend inline fun <E : Subscribable> E.callAndRemoveIfRequired(listeners: EventListeners<E>) {
|
||||
private suspend inline fun <E : Event> E.callAndRemoveIfRequired(listeners: EventListeners<E>) {
|
||||
// atomic foreach
|
||||
listeners.forEach {
|
||||
if (it.onEvent(this) == ListeningStatus.STOPPED) {
|
||||
|
@ -59,14 +59,14 @@ interface Message {
|
||||
infix fun eq(other: Message): Boolean = this == other
|
||||
|
||||
/**
|
||||
* 将 [stringValue] 与 [other] 比较
|
||||
* 将 [toString] 与 [other] 比较
|
||||
*/
|
||||
infix fun eq(other: String): Boolean = this.toString() == other
|
||||
|
||||
operator fun contains(sub: String): Boolean = false
|
||||
|
||||
/**
|
||||
* 把 [this] 连接到 [tail] 的头部. 类似于字符串相加.
|
||||
* 把 `this` 连接到 [tail] 的头部. 类似于字符串相加.
|
||||
*
|
||||
* 例:
|
||||
* ```kotlin
|
||||
@ -92,7 +92,7 @@ interface Message {
|
||||
override fun toString(): String
|
||||
|
||||
operator fun plus(another: Message): MessageChain = this.followedBy(another)
|
||||
operator fun plus(another: String): MessageChain = this.followedBy(another.toString().toMessage())
|
||||
operator fun plus(another: String): MessageChain = this.followedBy(another.toMessage())
|
||||
// `+ ""` will be resolved to `plus(String)` instead of `plus(CharSeq)`
|
||||
operator fun plus(another: CharSequence): MessageChain = this.followedBy(another.toString().toMessage())
|
||||
}
|
||||
|
@ -17,6 +17,6 @@ package net.mamoe.mirai.event
|
||||
object Events {
|
||||
/*
|
||||
@JvmStatic
|
||||
fun <E : Subscribable> subscribe(type: Class<E>, handler: suspend (E) -> ListeningStatus) =
|
||||
fun <E : Event> subscribe(type: Class<E>, handler: suspend (E) -> ListeningStatus) =
|
||||
runBlocking { type.kotlin.subscribe(handler) }*/
|
||||
}
|
||||
|
@ -12,12 +12,11 @@ package net.mamoe.mirai.event
|
||||
import kotlinx.coroutines.CompletableJob
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import net.mamoe.mirai.test.shouldBeEqualTo
|
||||
import kotlin.system.exitProcess
|
||||
import kotlin.test.Test
|
||||
|
||||
|
||||
class TestEvent : Subscribable {
|
||||
class TestEvent : Event {
|
||||
var triggered = false
|
||||
}
|
||||
|
||||
@ -46,7 +45,7 @@ class EventTests {
|
||||
}
|
||||
|
||||
|
||||
open class ParentEvent : Subscribable {
|
||||
open class ParentEvent : Event {
|
||||
var triggered = false
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,7 @@ import net.mamoe.mirai.Bot
|
||||
import net.mamoe.mirai.alsoLogin
|
||||
import net.mamoe.mirai.contact.Member
|
||||
import net.mamoe.mirai.contact.MemberPermission
|
||||
import net.mamoe.mirai.event.Subscribable
|
||||
import net.mamoe.mirai.event.Event
|
||||
import net.mamoe.mirai.event.events.ReceiveFriendAddRequestEvent
|
||||
import net.mamoe.mirai.event.subscribeAlways
|
||||
import net.mamoe.mirai.event.subscribeGroupMessages
|
||||
@ -48,8 +48,8 @@ suspend fun main() {
|
||||
// override config here.
|
||||
}.alsoLogin()
|
||||
|
||||
// 任何可以监听的对象都继承 Subscribable, 因此这个订阅会订阅全部的事件.
|
||||
GlobalScope.subscribeAlways<Subscribable> {
|
||||
// 任何可以监听的对象都继承 Event, 因此这个订阅会订阅全部的事件.
|
||||
GlobalScope.subscribeAlways<Event> {
|
||||
//bot.logger.verbose("收到了一个事件: $this")
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user