mirror of
https://github.com/mamoe/mirai.git
synced 2025-03-09 19:50:27 +08:00
Broadcast BotReloginEvent stably
This commit is contained in:
parent
b8de3f77ff
commit
b02fa15b33
@ -43,7 +43,9 @@ import net.mamoe.mirai.internal.network.handler.state.safe
|
||||
import net.mamoe.mirai.internal.network.impl.netty.ForceOfflineException
|
||||
import net.mamoe.mirai.internal.network.impl.netty.NettyNetworkHandlerFactory
|
||||
import net.mamoe.mirai.internal.utils.subLogger
|
||||
import net.mamoe.mirai.utils.*
|
||||
import net.mamoe.mirai.utils.BotConfiguration
|
||||
import net.mamoe.mirai.utils.MiraiLogger
|
||||
import net.mamoe.mirai.utils.lateinitMutableProperty
|
||||
import kotlin.contracts.contract
|
||||
|
||||
internal fun Bot.asQQAndroidBot(): QQAndroidBot {
|
||||
@ -91,10 +93,10 @@ internal open class QQAndroidBot constructor(
|
||||
previous: BaseStateImpl,
|
||||
new: BaseStateImpl
|
||||
) {
|
||||
eventDispatcher.broadcastAsync(BotOnlineEvent(bot)).onSuccess {
|
||||
eventDispatcher.broadcastAsync(BotOnlineEvent(bot)).thenBroadcast(eventDispatcher) {
|
||||
if (!shouldBroadcastRelogin.compareAndSet(false, true)) {
|
||||
eventDispatcher.broadcastAsync(BotReloginEvent(bot, new.getCause()))
|
||||
}
|
||||
BotReloginEvent(bot, new.getCause())
|
||||
} else null
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,6 +34,14 @@ internal interface EventDispatcher {
|
||||
*/
|
||||
fun broadcastAsync(event: Event, additionalContext: CoroutineContext = EmptyCoroutineContext): EventBroadcastJob
|
||||
|
||||
/**
|
||||
* Implementor must call `event.broadcast()` within a coroutine with [EventDispatcherScopeFlag]
|
||||
*/
|
||||
fun broadcastAsync(
|
||||
additionalContext: CoroutineContext = EmptyCoroutineContext,
|
||||
event: suspend () -> Event?,
|
||||
): EventBroadcastJob
|
||||
|
||||
/**
|
||||
* Join all jobs. Joins also jobs launched during this call.
|
||||
*/
|
||||
@ -58,6 +66,13 @@ internal value class EventBroadcastJob(
|
||||
if (it == null) action()
|
||||
}
|
||||
}
|
||||
|
||||
inline fun thenBroadcast(eventDispatcher: EventDispatcher, crossinline event: suspend () -> Event?) {
|
||||
eventDispatcher.broadcastAsync {
|
||||
job.join()
|
||||
event()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -93,6 +108,18 @@ internal open class EventDispatcherImpl(
|
||||
return EventBroadcastJob(job)
|
||||
}
|
||||
|
||||
override fun broadcastAsync(additionalContext: CoroutineContext, event: suspend () -> Event?): EventBroadcastJob {
|
||||
val job = launch(
|
||||
additionalContext + EventDispatcherScopeFlag,
|
||||
start = CoroutineStart.UNDISPATCHED
|
||||
) {
|
||||
event()?.let { broadcast(it) }
|
||||
}
|
||||
// UNDISPATCHED: starts the coroutine NOW in the current thread until its first suspension point,
|
||||
// so that after `broadcastAsync` the job is always already started and `joinBroadcast` will work normally.
|
||||
return EventBroadcastJob(job)
|
||||
}
|
||||
|
||||
protected 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() }
|
||||
|
Loading…
Reference in New Issue
Block a user