mirror of
https://github.com/mamoe/mirai.git
synced 2025-02-06 01:28:22 +08:00
parent
12b59edb96
commit
7994bcec0e
@ -14,6 +14,7 @@
|
||||
package net.mamoe.mirai.event
|
||||
|
||||
import kotlinx.coroutines.*
|
||||
import net.mamoe.mirai.utils.EventListenerLikeJava
|
||||
import java.lang.reflect.Method
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlin.coroutines.EmptyCoroutineContext
|
||||
@ -238,6 +239,23 @@ public fun CoroutineScope.registerEvents(
|
||||
}
|
||||
}
|
||||
|
||||
private fun Method.isKotlinFunction(): Boolean {
|
||||
|
||||
if (getDeclaredAnnotation(EventListenerLikeJava::class.java) != null) return false
|
||||
if (declaringClass.getDeclaredAnnotation(EventListenerLikeJava::class.java) != null) return false
|
||||
|
||||
@Suppress("RemoveRedundantQualifierName") // for strict
|
||||
return declaringClass.getDeclaredAnnotation(kotlin.Metadata::class.java) != null
|
||||
}
|
||||
|
||||
private fun Method.invokeWithErrorReport(self: Any?, vararg args: Any?): Any? = try {
|
||||
invoke(self, *args)
|
||||
} catch (exception: IllegalArgumentException) {
|
||||
throw IllegalArgumentException(
|
||||
"Internal Error: $exception, method=${this}, this=$self, arguments=$args, please report to https://github.com/mamoe/mirai",
|
||||
exception
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private fun Method.registerEvent(
|
||||
@ -248,7 +266,7 @@ private fun Method.registerEvent(
|
||||
): Listener<Event> {
|
||||
this.isAccessible = true
|
||||
val kotlinFunction = kotlin.runCatching { this.kotlinFunction }.getOrNull()
|
||||
return if (kotlinFunction != null) {
|
||||
return if (kotlinFunction != null && isKotlinFunction()) {
|
||||
// kotlin functions
|
||||
|
||||
val param = kotlinFunction.parameters
|
||||
@ -337,7 +355,7 @@ private fun Method.registerEvent(
|
||||
|
||||
val paramType = this.parameters[0].type
|
||||
check(this.parameterCount == 1 && Event::class.java.isAssignableFrom(paramType)) {
|
||||
"Illegal method parameter. Required one exact Event subclass. found $paramType"
|
||||
"Illegal method parameter. Required one exact Event subclass. found ${this.parameters.contentToString()}"
|
||||
}
|
||||
when (this.returnType) {
|
||||
Void::class.java, Void.TYPE, Nothing::class.java -> {
|
||||
@ -350,11 +368,11 @@ private fun Method.registerEvent(
|
||||
if (annotation.ignoreCancelled) {
|
||||
if ((this as? CancellableEvent)?.isCancelled != true) {
|
||||
withContext(Dispatchers.IO) {
|
||||
this@registerEvent.invoke(owner, this)
|
||||
this@registerEvent.invokeWithErrorReport(owner, this@subscribeAlways)
|
||||
}
|
||||
}
|
||||
} else withContext(Dispatchers.IO) {
|
||||
this@registerEvent.invoke(owner, this)
|
||||
this@registerEvent.invokeWithErrorReport(owner, this@subscribeAlways)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -368,11 +386,11 @@ private fun Method.registerEvent(
|
||||
if (annotation.ignoreCancelled) {
|
||||
if ((this as? CancellableEvent)?.isCancelled != true) {
|
||||
withContext(Dispatchers.IO) {
|
||||
this@registerEvent.invoke(owner, this) as ListeningStatus
|
||||
this@registerEvent.invokeWithErrorReport(owner, this@subscribe) as ListeningStatus
|
||||
}
|
||||
} else ListeningStatus.LISTENING
|
||||
} else withContext(Dispatchers.IO) {
|
||||
this@registerEvent.invoke(owner, this) as ListeningStatus
|
||||
this@registerEvent.invokeWithErrorReport(owner, this@subscribe) as ListeningStatus
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -60,4 +60,12 @@ internal annotation class PlannedRemoval(val version: String)
|
||||
@PlannedRemoval("2.0-M2")
|
||||
internal annotation class MemberDeprecatedApi(val message: String)
|
||||
|
||||
/**
|
||||
* 该注解仅用于测试 EventHandler
|
||||
*
|
||||
* 标注了此注解的意为像处理 java 方法那样处理 kotlin 方法
|
||||
*/
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
internal annotation class EventListenerLikeJava
|
||||
|
||||
|
||||
|
@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019-2020 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.event;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import static kotlin.test.AssertionsKt.assertEquals;
|
||||
|
||||
public class JvmMethodEventsTestJava extends SimpleListenerHost {
|
||||
private final AtomicInteger called = new AtomicInteger(0);
|
||||
|
||||
@EventHandler
|
||||
public void ev(TestEvent event) {
|
||||
called.incrementAndGet();
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public Void ev2(TestEvent event) {
|
||||
called.incrementAndGet();
|
||||
return null;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public ListeningStatus ev3(TestEvent event) {
|
||||
called.incrementAndGet();
|
||||
return ListeningStatus.LISTENING;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void ev(TestEvent event, TestEvent event2) {
|
||||
called.incrementAndGet();
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public Void ev2(TestEvent event, TestEvent event2) {
|
||||
called.incrementAndGet();
|
||||
return null;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public ListeningStatus ev3(TestEvent event, TestEvent event2) {
|
||||
called.incrementAndGet();
|
||||
return ListeningStatus.LISTENING;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
Events.registerEvents(this);
|
||||
EventKt.broadcast(new TestEvent());
|
||||
assertEquals(6, called.get(), null);
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2019-2020 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.event
|
||||
|
||||
import net.mamoe.mirai.JavaFriendlyAPI
|
||||
import net.mamoe.mirai.utils.EventListenerLikeJava
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@EventListenerLikeJava
|
||||
@JavaFriendlyAPI
|
||||
internal class JvmMethodEventsTestJava : SimpleListenerHost() {
|
||||
private val called = AtomicInteger(0)
|
||||
|
||||
@EventHandler
|
||||
fun ev(event: TestEvent?) {
|
||||
called.incrementAndGet()
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
fun ev2(event: TestEvent?): Void? {
|
||||
called.incrementAndGet()
|
||||
return null
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
fun ev3(event: TestEvent?): ListeningStatus? {
|
||||
called.incrementAndGet()
|
||||
return ListeningStatus.LISTENING
|
||||
}
|
||||
|
||||
@Test
|
||||
fun test() {
|
||||
this.registerEvents()
|
||||
TestEvent().__broadcastJava()
|
||||
assertEquals(3, called.get(), null)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user