From 141b5a4e2f3c77d7f1a0f6a2a02db755418a2b9f Mon Sep 17 00:00:00 2001 From: Him188 <Him188@mamoe.net> Date: Sun, 27 Oct 2019 03:48:45 +0800 Subject: [PATCH] Adjust function visibility and enhance efficiency --- .../net.mamoe.mirai/event/Subscribers.kt | 66 ++++++++++++------- .../event/internal/InternalEventListeners.kt | 19 +++--- 2 files changed, 52 insertions(+), 33 deletions(-) diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/Subscribers.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/Subscribers.kt index f303fd3ed..d856ffefb 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/Subscribers.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/Subscribers.kt @@ -3,6 +3,7 @@ package net.mamoe.mirai.event import net.mamoe.mirai.event.internal.Handler +import net.mamoe.mirai.event.internal.Listener import net.mamoe.mirai.event.internal.subscribeInternal import kotlin.reflect.KClass @@ -43,26 +44,41 @@ suspend inline fun <reified E : Event> subscribeWhileNull(noinline listener: sus // region KClass 的扩展方法 (不推荐) -suspend fun <E : Event> KClass<E>.subscribe(handler: suspend (E) -> ListeningStatus) = this.subscribeInternal(Handler(handler)) +@PublishedApi +internal suspend fun <E : Event> KClass<E>.subscribe(handler: suspend (E) -> ListeningStatus) = this.subscribeInternal(Handler(handler)) -suspend fun <E : Event> KClass<E>.subscribeAlways(listener: suspend (E) -> Unit) = this.subscribeInternal(Handler { listener(it); ListeningStatus.LISTENING }) +@PublishedApi +internal suspend fun <E : Event> KClass<E>.subscribeAlways(listener: suspend (E) -> Unit) = this.subscribeInternal(Handler { listener(it); ListeningStatus.LISTENING }) -suspend fun <E : Event> KClass<E>.subscribeOnce(listener: suspend (E) -> Unit) = this.subscribeInternal(Handler { listener(it); ListeningStatus.STOPPED }) +@PublishedApi +internal suspend fun <E : Event> KClass<E>.subscribeOnce(listener: suspend (E) -> Unit) = this.subscribeInternal(Handler { listener(it); ListeningStatus.STOPPED }) -suspend fun <E : Event, T> KClass<E>.subscribeUntil(valueIfStop: T, listener: suspend (E) -> T) = +@PublishedApi +internal suspend fun <E : Event, T> KClass<E>.subscribeUntil(valueIfStop: T, listener: suspend (E) -> T) = subscribeInternal(Handler { if (listener(it) === valueIfStop) ListeningStatus.STOPPED else ListeningStatus.LISTENING }) -suspend fun <E : Event> KClass<E>.subscribeUntilFalse(listener: suspend (E) -> Boolean) = subscribeUntil(false, listener) -suspend fun <E : Event> KClass<E>.subscribeUntilTrue(listener: suspend (E) -> Boolean) = subscribeUntil(true, listener) -suspend fun <E : Event> KClass<E>.subscribeUntilNull(listener: suspend (E) -> Any?) = subscribeUntil(null, listener) +@PublishedApi +internal suspend fun <E : Event> KClass<E>.subscribeUntilFalse(listener: suspend (E) -> Boolean) = subscribeUntil(false, listener) + +@PublishedApi +internal suspend fun <E : Event> KClass<E>.subscribeUntilTrue(listener: suspend (E) -> Boolean) = subscribeUntil(true, listener) + +@PublishedApi +internal suspend fun <E : Event> KClass<E>.subscribeUntilNull(listener: suspend (E) -> Any?) = subscribeUntil(null, listener) -suspend fun <E : Event, T> KClass<E>.subscribeWhile(valueIfContinue: T, listener: suspend (E) -> T) = +@PublishedApi +internal suspend fun <E : Event, T> KClass<E>.subscribeWhile(valueIfContinue: T, listener: suspend (E) -> T) = subscribeInternal(Handler { if (listener(it) !== valueIfContinue) ListeningStatus.STOPPED else ListeningStatus.LISTENING }) -suspend fun <E : Event> KClass<E>.subscribeWhileFalse(listener: suspend (E) -> Boolean) = subscribeWhile(false, listener) -suspend fun <E : Event> KClass<E>.subscribeWhileTrue(listener: suspend (E) -> Boolean) = subscribeWhile(true, listener) -suspend fun <E : Event> KClass<E>.subscribeWhileNull(listener: suspend (E) -> Any?) = subscribeWhile(null, listener) +@PublishedApi +internal suspend fun <E : Event> KClass<E>.subscribeWhileFalse(listener: suspend (E) -> Boolean) = subscribeWhile(false, listener) + +@PublishedApi +internal suspend fun <E : Event> KClass<E>.subscribeWhileTrue(listener: suspend (E) -> Boolean) = subscribeWhile(true, listener) + +@PublishedApi +internal suspend fun <E : Event> KClass<E>.subscribeWhileNull(listener: suspend (E) -> Any?) = subscribeWhile(null, listener) // endregion @@ -73,7 +89,8 @@ suspend fun <E : Event> KClass<E>.subscribeWhileNull(listener: suspend (E) -> An * @see ListenerBuilder */ @ListenersBuilderDsl -suspend fun <E : Event> KClass<E>.subscribeAll(listeners: suspend ListenerBuilder<E>.() -> Unit) { +@PublishedApi +internal suspend fun <E : Event> KClass<E>.subscribeAll(listeners: suspend ListenerBuilder<E>.() -> Unit) { with(ListenerBuilder<E> { this.subscribeInternal(it) }) { listeners() } @@ -105,27 +122,28 @@ suspend inline fun <reified E : Event> subscribeAll(noinline listeners: suspend @ListenersBuilderDsl @Suppress("MemberVisibilityCanBePrivate", "unused") inline class ListenerBuilder<out E : Event>( - private val handlerConsumer: suspend (Handler<in E>) -> Unit + @PublishedApi + internal inline val handlerConsumer: suspend (Listener<E>) -> Unit ) { - suspend fun handler(listener: suspend (E) -> ListeningStatus) { + suspend inline fun handler(noinline listener: suspend (E) -> ListeningStatus) { handlerConsumer(Handler(listener)) } - suspend fun always(listener: suspend (E) -> Unit) = handler { listener(it); ListeningStatus.LISTENING } + suspend inline fun always(noinline listener: suspend (E) -> Unit) = handler { listener(it); ListeningStatus.LISTENING } - suspend fun <T> until(until: T, listener: suspend (E) -> T) = handler { if (listener(it) === until) ListeningStatus.STOPPED else ListeningStatus.LISTENING } - suspend fun untilFalse(listener: suspend (E) -> Boolean) = until(false, listener) - suspend fun untilTrue(listener: suspend (E) -> Boolean) = until(true, listener) - suspend fun untilNull(listener: suspend (E) -> Any?) = until(null, listener) + suspend inline fun <T> until(until: T, noinline listener: suspend (E) -> T) = handler { if (listener(it) === until) ListeningStatus.STOPPED else ListeningStatus.LISTENING } + suspend inline fun untilFalse(noinline listener: suspend (E) -> Boolean) = until(false, listener) + suspend inline fun untilTrue(noinline listener: suspend (E) -> Boolean) = until(true, listener) + suspend inline fun untilNull(noinline listener: suspend (E) -> Any?) = until(null, listener) - suspend fun <T> `while`(until: T, listener: suspend (E) -> T) = handler { if (listener(it) !== until) ListeningStatus.STOPPED else ListeningStatus.LISTENING } - suspend fun whileFalse(listener: suspend (E) -> Boolean) = `while`(false, listener) - suspend fun whileTrue(listener: suspend (E) -> Boolean) = `while`(true, listener) - suspend fun whileNull(listener: suspend (E) -> Any?) = `while`(null, listener) + suspend inline fun <T> `while`(until: T, noinline listener: suspend (E) -> T) = handler { if (listener(it) !== until) ListeningStatus.STOPPED else ListeningStatus.LISTENING } + suspend inline fun whileFalse(noinline listener: suspend (E) -> Boolean) = `while`(false, listener) + suspend inline fun whileTrue(noinline listener: suspend (E) -> Boolean) = `while`(true, listener) + suspend inline fun whileNull(noinline listener: suspend (E) -> Any?) = `while`(null, listener) - suspend fun once(block: suspend (E) -> Unit) = handler { block(it); ListeningStatus.STOPPED } + suspend inline fun once(noinline listener: suspend (E) -> Unit) = handler { listener(it); ListeningStatus.STOPPED } } @DslMarker diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/internal/InternalEventListeners.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/internal/InternalEventListeners.kt index 7f4069dee..9e3e450a1 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/internal/InternalEventListeners.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/internal/InternalEventListeners.kt @@ -9,6 +9,7 @@ import net.mamoe.mirai.event.EventScope import net.mamoe.mirai.event.ListeningStatus import net.mamoe.mirai.event.events.BotEvent import net.mamoe.mirai.utils.internal.inlinedRemoveIf +import kotlin.jvm.JvmField import kotlin.reflect.KClass /** @@ -38,9 +39,11 @@ internal suspend fun <E : Event> KClass<E>.subscribeInternal(listener: Listener< //启动协程并等待正在进行的广播结束, 然后将缓存转移到主监听者列表 //启动后的协程马上就会因为锁而被挂起 mainMutex.withLock { - if (cache.size != 0) { - addAll(cache) - cache.clear() + cacheMutex.withLock { + if (cache.size != 0) { + addAll(cache) + cache.clear() + } } } } @@ -55,11 +58,8 @@ sealed class Listener<in E : Event> { abstract suspend fun onEvent(event: E): ListeningStatus } -/** - * Lambda 监听器. - * 不推荐直接使用该类 - */ -class Handler<E : Event>(val handler: suspend (E) -> ListeningStatus) : Listener<E>() { +@PublishedApi +internal class Handler<E : Event>(@JvmField val handler: suspend (E) -> ListeningStatus) : Listener<E>() { override suspend fun onEvent(event: E): ListeningStatus = handler.invoke(event) } @@ -68,7 +68,8 @@ class Handler<E : Event>(val handler: suspend (E) -> ListeningStatus) : Listener * 所有的非 [BotEvent] 的事件都不会被处理 * 所有的 [BotEvent.bot] `!==` `bot` 的事件都不会被处理 */ -class HandlerWithBot<E : Event>(val bot: Bot, val handler: suspend Bot.(E) -> ListeningStatus) : Listener<E>() { +@PublishedApi +internal class HandlerWithBot<E : Event>(val bot: Bot, @JvmField val handler: suspend Bot.(E) -> ListeningStatus) : Listener<E>() { override suspend fun onEvent(event: E): ListeningStatus = with(bot) { if (event !is BotEvent || event.bot !== this) { return ListeningStatus.LISTENING