Merge remote-tracking branch 'origin/master'

This commit is contained in:
ryoii 2020-02-17 23:10:59 +08:00
commit db13a867cf
2 changed files with 31 additions and 4 deletions

View File

@ -28,6 +28,8 @@ import kotlin.contracts.contract
/** /**
* 订阅来自所有 [Bot] 的所有联系人的消息事件. 联系人可以是任意群或任意好友或临时会话. * 订阅来自所有 [Bot] 的所有联系人的消息事件. 联系人可以是任意群或任意好友或临时会话.
*
* @see CoroutineScope.incoming
*/ */
@UseExperimental(ExperimentalContracts::class) @UseExperimental(ExperimentalContracts::class)
@MessageDsl @MessageDsl
@ -49,6 +51,8 @@ inline fun <R> CoroutineScope.subscribeMessages(crossinline listeners: MessageSu
/** /**
* 订阅来自所有 [Bot] 的所有群消息事件 * 订阅来自所有 [Bot] 的所有群消息事件
*
* @see CoroutineScope.incoming
*/ */
@UseExperimental(ExperimentalContracts::class) @UseExperimental(ExperimentalContracts::class)
@MessageDsl @MessageDsl
@ -65,6 +69,8 @@ inline fun <R> CoroutineScope.subscribeGroupMessages(crossinline listeners: Mess
/** /**
* 订阅来自所有 [Bot] 的所有好友消息事件 * 订阅来自所有 [Bot] 的所有好友消息事件
*
* @see CoroutineScope.incoming
*/ */
@UseExperimental(ExperimentalContracts::class) @UseExperimental(ExperimentalContracts::class)
@MessageDsl @MessageDsl
@ -81,6 +87,8 @@ inline fun <R> CoroutineScope.subscribeFriendMessages(crossinline listeners: Mes
/** /**
* 订阅来自这个 [Bot] 的所有联系人的消息事件. 联系人可以是任意群或任意好友或临时会话. * 订阅来自这个 [Bot] 的所有联系人的消息事件. 联系人可以是任意群或任意好友或临时会话.
*
* @see CoroutineScope.incoming
*/ */
@UseExperimental(ExperimentalContracts::class) @UseExperimental(ExperimentalContracts::class)
@MessageDsl @MessageDsl
@ -97,6 +105,8 @@ inline fun <R> Bot.subscribeMessages(crossinline listeners: MessageSubscribersBu
/** /**
* 订阅来自这个 [Bot] 的所有群消息事件 * 订阅来自这个 [Bot] 的所有群消息事件
*
* @see CoroutineScope.incoming
*/ */
@UseExperimental(ExperimentalContracts::class) @UseExperimental(ExperimentalContracts::class)
@MessageDsl @MessageDsl
@ -113,6 +123,8 @@ inline fun <R> Bot.subscribeGroupMessages(crossinline listeners: MessageSubscrib
/** /**
* 订阅来自这个 [Bot] 的所有好友消息事件. * 订阅来自这个 [Bot] 的所有好友消息事件.
*
* @see CoroutineScope.incoming
*/ */
@UseExperimental(ExperimentalContracts::class) @UseExperimental(ExperimentalContracts::class)
@MessageDsl @MessageDsl
@ -129,9 +141,15 @@ inline fun <R> Bot.subscribeFriendMessages(crossinline listeners: MessageSubscri
/** /**
* 返回一个指定事件的接收通道 * 返回一个指定事件的接收通道
*
* @param capacity [Channel] 的参数, 参见 [Channel.Factory] 中的常量.
*
* @see subscribeFriendMessages
* @see subscribeMessages
* @see subscribeGroupMessages
*/ */
inline fun <reified E : Event> Bot.incoming(): ReceiveChannel<E> { inline fun <reified E : Event> CoroutineScope.incoming(capacity: Int = Channel.RENDEZVOUS): ReceiveChannel<E> {
return Channel<E>(8).apply { return Channel<E>(capacity).apply {
subscribeAlways<E> { subscribeAlways<E> {
send(this) send(this)
} }

View File

@ -90,6 +90,15 @@ internal object EventListenerManager {
private val lock = atomic(false) private val lock = atomic(false)
private fun setLockValue(value: Boolean) {
lock.value = value
}
@Suppress("BooleanLiteralArgument")
private fun trySetLockTrue(): Boolean {
return lock.compareAndSet(false, true)
}
@Suppress("UNCHECKED_CAST", "BooleanLiteralArgument") @Suppress("UNCHECKED_CAST", "BooleanLiteralArgument")
internal tailrec fun <E : Event> get(clazz: KClass<out E>): EventListeners<E> { internal tailrec fun <E : Event> get(clazz: KClass<out E>): EventListeners<E> {
registries.forEach { registries.forEach {
@ -97,10 +106,10 @@ internal object EventListenerManager {
return it.listeners as EventListeners<E> return it.listeners as EventListeners<E>
} }
} }
if (lock.compareAndSet(false, true)) { if (trySetLockTrue()) {
val registry = Registry(clazz, EventListeners()) val registry = Registry(clazz, EventListeners())
registries.addLast(registry) registries.addLast(registry)
lock.value = false setLockValue(false)
return registry.listeners as EventListeners<E> return registry.listeners as EventListeners<E>
} }
return get(clazz) return get(clazz)