mirror of
https://github.com/mamoe/mirai.git
synced 2025-03-26 07:20:09 +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(
|
public inline fun <E : U, U : CoroutineContext.Element> CoroutineContext.getOrElse(
|
||||||
key: CoroutineContext.Key<E>,
|
key: CoroutineContext.Key<E>,
|
||||||
default: () -> U
|
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.CoroutineName
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import net.mamoe.mirai.event.BroadcastControllable
|
import net.mamoe.mirai.event.BroadcastControllable
|
||||||
import net.mamoe.mirai.event.CancellableEvent
|
import net.mamoe.mirai.event.CancellableEvent
|
||||||
import net.mamoe.mirai.event.Event
|
import net.mamoe.mirai.event.Event
|
||||||
import net.mamoe.mirai.event.broadcast
|
|
||||||
import net.mamoe.mirai.internal.QQAndroidBot
|
import net.mamoe.mirai.internal.QQAndroidBot
|
||||||
import net.mamoe.mirai.internal.network.MultiPacket
|
import net.mamoe.mirai.internal.network.MultiPacket
|
||||||
import net.mamoe.mirai.internal.network.Packet
|
import net.mamoe.mirai.internal.network.Packet
|
||||||
import net.mamoe.mirai.internal.network.component.ComponentKey
|
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.internal.network.protocol.packet.*
|
||||||
import net.mamoe.mirai.utils.MiraiLogger
|
import net.mamoe.mirai.utils.MiraiLogger
|
||||||
import net.mamoe.mirai.utils.cast
|
import net.mamoe.mirai.utils.cast
|
||||||
@ -65,6 +64,7 @@ internal class LoggingPacketHandlerAdapter(
|
|||||||
|
|
||||||
internal class EventBroadcasterPacketHandler(
|
internal class EventBroadcasterPacketHandler(
|
||||||
private val targetScope: CoroutineScope,
|
private val targetScope: CoroutineScope,
|
||||||
|
private val components: ComponentStorage,
|
||||||
private val logger: MiraiLogger,
|
private val logger: MiraiLogger,
|
||||||
) : PacketHandler {
|
) : PacketHandler {
|
||||||
|
|
||||||
@ -74,7 +74,7 @@ internal class EventBroadcasterPacketHandler(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val coroutineName = CoroutineName("Mirai-EventDispatcher-${logger.identity}")
|
private val coroutineName = CoroutineName("Mirai-EventDispatcher-${logger.identity}")
|
||||||
private suspend fun impl(packet: Packet) {
|
private fun impl(packet: Packet) {
|
||||||
if (packet is MultiPacket<*>) {
|
if (packet is MultiPacket<*>) {
|
||||||
for (p in packet) {
|
for (p in packet) {
|
||||||
impl(p)
|
impl(p)
|
||||||
@ -84,25 +84,11 @@ internal class EventBroadcasterPacketHandler(
|
|||||||
packet is CancellableEvent && packet.isCancelled -> return
|
packet is CancellableEvent && packet.isCancelled -> return
|
||||||
packet is BroadcastControllable && !packet.shouldBroadcast -> return
|
packet is BroadcastControllable && !packet.shouldBroadcast -> return
|
||||||
packet is Event -> {
|
packet is Event -> {
|
||||||
targetScope.launch(coroutineName) {
|
components[EventDispatcher].broadcastAsync(packet)
|
||||||
try {
|
|
||||||
packet.broadcast()
|
|
||||||
} catch (e: Throwable) {
|
|
||||||
if (logger.isEnabled) {
|
|
||||||
val msg = optimizeEventToString(packet)
|
|
||||||
logger.error(IllegalStateException("Exception while broadcasting event '$msg'", e))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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"
|
override fun toString(): String = "EventBroadcasterPacketHandler"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user