mirror of
https://github.com/mamoe/mirai.git
synced 2025-02-11 05:04:48 +08:00
Prototype EventDispatcher
This commit is contained in:
parent
5d3130448c
commit
b53e546743
@ -75,4 +75,17 @@ public fun CoroutineContext.childScopeContext(
|
||||
public inline fun <E : U, U : CoroutineContext.Element> CoroutineContext.getOrElse(
|
||||
key: CoroutineContext.Key<E>,
|
||||
default: () -> U
|
||||
): U = this[key] ?: default()
|
||||
): U = this[key] ?: default()
|
||||
|
||||
public inline fun <E : CoroutineContext.Element> CoroutineContext.addIfAbsent(
|
||||
key: CoroutineContext.Key<E>,
|
||||
default: () -> CoroutineContext.Element
|
||||
): CoroutineContext = if (this[key] == null) this + default() else this
|
||||
|
||||
public inline fun CoroutineContext.addNameIfAbsent(
|
||||
name: () -> String
|
||||
): CoroutineContext = addIfAbsent(CoroutineName) { CoroutineName(name()) }
|
||||
|
||||
public fun CoroutineContext.addNameHierarchically(
|
||||
name: String
|
||||
): CoroutineContext = this + CoroutineName(this[CoroutineName]?.name?.plus('.')?.plus(name) ?: name)
|
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.internal.network.components
|
||||
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.job
|
||||
import kotlinx.coroutines.launch
|
||||
import net.mamoe.mirai.event.Event
|
||||
import net.mamoe.mirai.event.broadcast
|
||||
import net.mamoe.mirai.internal.network.component.ComponentKey
|
||||
import net.mamoe.mirai.utils.MiraiLogger
|
||||
import net.mamoe.mirai.utils.addNameHierarchically
|
||||
import net.mamoe.mirai.utils.childScope
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlin.coroutines.EmptyCoroutineContext
|
||||
|
||||
internal interface EventDispatcher {
|
||||
suspend fun broadcast(event: Event)
|
||||
fun broadcastAsync(event: Event, additionalContext: CoroutineContext = EmptyCoroutineContext)
|
||||
|
||||
/**
|
||||
* Join all jobs. Joins also jobs launched during this call.
|
||||
*/
|
||||
suspend fun joinBroadcast()
|
||||
|
||||
companion object : ComponentKey<EventDispatcher>
|
||||
}
|
||||
|
||||
|
||||
internal class EventDispatcherImpl(
|
||||
private val lifecycleContext: CoroutineContext,
|
||||
private val logger: MiraiLogger,
|
||||
) : EventDispatcher,
|
||||
CoroutineScope by lifecycleContext
|
||||
.addNameHierarchically("EventDispatcher")
|
||||
.childScope() {
|
||||
|
||||
override suspend fun broadcast(event: Event) {
|
||||
try {
|
||||
event.broadcast()
|
||||
} catch (e: Exception) {
|
||||
if (logger.isEnabled) {
|
||||
val msg = optimizeEventToString(event)
|
||||
logger.error(IllegalStateException("Exception while broadcasting event '$msg'", e))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun broadcastAsync(event: Event, additionalContext: CoroutineContext) {
|
||||
launch(additionalContext) { broadcast(event) }
|
||||
}
|
||||
|
||||
private fun optimizeEventToString(event: Event): String {
|
||||
val qualified = event::class.java.canonicalName ?: return event.toString()
|
||||
return qualified.substringAfter("net.mamoe.mirai.event.events.", "").ifEmpty { event.toString() }
|
||||
}
|
||||
|
||||
override suspend fun joinBroadcast() {
|
||||
for (child in coroutineContext.job.children) {
|
||||
child.join()
|
||||
}
|
||||
}
|
||||
}
|
@ -11,15 +11,14 @@ package net.mamoe.mirai.internal.network.components
|
||||
|
||||
import kotlinx.coroutines.CoroutineName
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import net.mamoe.mirai.event.BroadcastControllable
|
||||
import net.mamoe.mirai.event.CancellableEvent
|
||||
import net.mamoe.mirai.event.Event
|
||||
import net.mamoe.mirai.event.broadcast
|
||||
import net.mamoe.mirai.internal.QQAndroidBot
|
||||
import net.mamoe.mirai.internal.network.MultiPacket
|
||||
import net.mamoe.mirai.internal.network.Packet
|
||||
import net.mamoe.mirai.internal.network.component.ComponentKey
|
||||
import net.mamoe.mirai.internal.network.component.ComponentStorage
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.*
|
||||
import net.mamoe.mirai.utils.MiraiLogger
|
||||
import net.mamoe.mirai.utils.cast
|
||||
@ -65,6 +64,7 @@ internal class LoggingPacketHandlerAdapter(
|
||||
|
||||
internal class EventBroadcasterPacketHandler(
|
||||
private val targetScope: CoroutineScope,
|
||||
private val components: ComponentStorage,
|
||||
private val logger: MiraiLogger,
|
||||
) : PacketHandler {
|
||||
|
||||
@ -74,7 +74,7 @@ internal class EventBroadcasterPacketHandler(
|
||||
}
|
||||
|
||||
private val coroutineName = CoroutineName("Mirai-EventDispatcher-${logger.identity}")
|
||||
private suspend fun impl(packet: Packet) {
|
||||
private fun impl(packet: Packet) {
|
||||
if (packet is MultiPacket<*>) {
|
||||
for (p in packet) {
|
||||
impl(p)
|
||||
@ -84,25 +84,11 @@ internal class EventBroadcasterPacketHandler(
|
||||
packet is CancellableEvent && packet.isCancelled -> return
|
||||
packet is BroadcastControllable && !packet.shouldBroadcast -> return
|
||||
packet is Event -> {
|
||||
targetScope.launch(coroutineName) {
|
||||
try {
|
||||
packet.broadcast()
|
||||
} catch (e: Throwable) {
|
||||
if (logger.isEnabled) {
|
||||
val msg = optimizeEventToString(packet)
|
||||
logger.error(IllegalStateException("Exception while broadcasting event '$msg'", e))
|
||||
}
|
||||
}
|
||||
}
|
||||
components[EventDispatcher].broadcastAsync(packet)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun optimizeEventToString(event: Event): String {
|
||||
val qualified = event::class.java.canonicalName ?: return this.toString()
|
||||
return qualified.substringAfter("net.mamoe.mirai.event.events.")
|
||||
}
|
||||
|
||||
override fun toString(): String = "EventBroadcasterPacketHandler"
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user