diff --git a/mirai-core-api/src/commonMain/kotlin/IMirai.kt b/mirai-core-api/src/commonMain/kotlin/IMirai.kt index 2becc2f6e..9688a397f 100644 --- a/mirai-core-api/src/commonMain/kotlin/IMirai.kt +++ b/mirai-core-api/src/commonMain/kotlin/IMirai.kt @@ -20,8 +20,8 @@ import net.mamoe.kjbb.JvmBlockingBridge import net.mamoe.mirai.contact.* import net.mamoe.mirai.data.UserProfile import net.mamoe.mirai.event.Event +import net.mamoe.mirai.event._EventBroadcast import net.mamoe.mirai.event.broadcast -import net.mamoe.mirai.event.broadcastImpl import net.mamoe.mirai.event.events.BotInvitedJoinGroupRequestEvent import net.mamoe.mirai.event.events.MemberJoinRequestEvent import net.mamoe.mirai.event.events.NewFriendRequestEvent @@ -307,7 +307,7 @@ public interface IMirai : LowLevelApiAccessor { * 广播一个事件. 由 [Event.broadcast] 调用. */ public suspend fun broadcastEvent(event: Event) { - event.broadcastImpl() + _EventBroadcast.implementation.broadcastImpl(event) } } diff --git a/mirai-core-api/src/commonMain/kotlin/event/Event.kt b/mirai-core-api/src/commonMain/kotlin/event/Event.kt index fa04cc5bd..a20cbf29c 100644 --- a/mirai-core-api/src/commonMain/kotlin/event/Event.kt +++ b/mirai-core-api/src/commonMain/kotlin/event/Event.kt @@ -145,43 +145,53 @@ public interface CancellableEvent : Event { * @see __broadcastJava Java 使用 */ @JvmSynthetic -public suspend fun E.broadcast(): E = apply { Mirai.broadcastEvent(this) } +public suspend fun E.broadcast(): E = _EventBroadcast.implementation.broadcastPublic(this) - -@JvmName("broadcastImpl") // avoid mangling -internal suspend fun E.broadcastImpl(): E { - val event = this - check(event is AbstractEvent) { - "Events must extend AbstractEvent" +/** + * @since 2.7-M1 + */ +@Suppress("ClassName") +internal open class _EventBroadcast { + companion object { + @Volatile + @JvmStatic + var implementation: _EventBroadcast = _EventBroadcast() } - if (event is BroadcastControllable && !event.shouldBroadcast) { + open suspend fun broadcastPublic(event: E): E = event.apply { Mirai.broadcastEvent(this) } + + @JvmName("broadcastImpl") // avoid mangling + internal suspend fun broadcastImpl(event: E): E { + check(event is AbstractEvent) { "Events must extend AbstractEvent" } + + if (event is BroadcastControllable && !event.shouldBroadcast) { + return event + } + event.broadCastLock.withLock { + event._intercepted = false + if (EventDisabled) return@withLock + logEvent(event) + callAndRemoveIfRequired(event) + } + return event } - event.broadCastLock.withLock { - event._intercepted = false - if (EventDisabled) return@withLock - logEvent(event) - callAndRemoveIfRequired(event) - } - return this -} - -private fun logEvent(event: Event) { - if (event is Packet.NoEventLog) return - if (event is Packet.NoLog) return - if (event is MessageEvent) return // specially handled in [LoggingPacketHandlerAdapter] + private fun logEvent(event: Event) { + if (event is Packet.NoEventLog) return + if (event is Packet.NoLog) return + if (event is MessageEvent) return // specially handled in [LoggingPacketHandlerAdapter] // if (this is Packet) return@withLock // all [Packet]s are logged in [LoggingPacketHandlerAdapter] - if (event is BotEvent) { - event.bot.logger.verbose { "Event: $event" } - } else { - topLevelEventLogger.verbose { "Event: $event" } + if (event is BotEvent) { + event.bot.logger.verbose { "Event: $event" } + } else { + topLevelEventLogger.verbose { "Event: $event" } + } } -} -private val topLevelEventLogger by lazy { MiraiLogger.create("EventPipeline") } + private val topLevelEventLogger by lazy { MiraiLogger.create("EventPipeline") } +} /** * 在 Java 广播一个事件的唯一途径. diff --git a/mirai-core-api/src/jvmTest/kotlin/event/EventChannelTest.kt b/mirai-core-api/src/jvmTest/kotlin/event/EventChannelTest.kt index 0d7a841e6..97b58f9b6 100644 --- a/mirai-core-api/src/jvmTest/kotlin/event/EventChannelTest.kt +++ b/mirai-core-api/src/jvmTest/kotlin/event/EventChannelTest.kt @@ -44,12 +44,17 @@ internal class EventChannelTest { @BeforeEach fun x() { runBlocking { semaphore.acquire() } + _EventBroadcast.implementation = object : _EventBroadcast() { + override suspend fun broadcastPublic(event: E): E = + broadcastImpl(event) // do not call MiraiImpl + } } @AfterEach fun s() { GlobalEventListeners.clear() runBlocking { semaphore.release() } + _EventBroadcast.implementation = _EventBroadcast() // restore } @Test