Commit 7891ffc1 authored by Him188's avatar Him188

Make `interface Event` the base type of a event, remove `interface Subscribable`

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