Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
M
Mirai
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
MyCard
Mirai
Commits
90185490
Commit
90185490
authored
Jul 30, 2020
by
Him188
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implementations rearrangement
parent
2b0165d8
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
297 additions
and
271 deletions
+297
-271
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/MessageEvent.kt
...commonMain/kotlin/net.mamoe.mirai/message/MessageEvent.kt
+2
-113
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/deprecated.kt
...c/commonMain/kotlin/net.mamoe.mirai/message/deprecated.kt
+133
-0
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/event/JvmMethodListeners.kt
...vmMain/kotlin/net/mamoe/mirai/event/JvmMethodListeners.kt
+8
-155
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/event/internal/EventInternalJvm.kt
...kotlin/net/mamoe/mirai/event/internal/EventInternalJvm.kt
+154
-3
No files found.
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/MessageEvent.kt
View file @
90185490
...
...
@@ -21,12 +21,10 @@ package net.mamoe.mirai.message
import
net.mamoe.mirai.Bot
import
net.mamoe.mirai.contact.*
import
net.mamoe.mirai.event.AbstractEvent
import
net.mamoe.mirai.event.events.BotEvent
import
net.mamoe.mirai.event.subscribe
import
net.mamoe.mirai.message.data.*
import
net.mamoe.mirai.qqandroid.network.Packet
import
net.mamoe.mirai.utils.ExternalImage
import
net.mamoe.mirai.utils.PlannedRemoval
import
net.mamoe.mirai.utils.sendTo
import
net.mamoe.mirai.utils.upload
import
kotlin.jvm.JvmMultifileClass
...
...
@@ -46,7 +44,7 @@ import kotlin.jvm.JvmSynthetic
* @see isContextIdenticalWith 判断语境是否相同
*/
@Suppress
(
"DEPRECATION_ERROR"
)
public
abstract
class
MessageEvent
:
@PlannedRemoval
(
"1.2.0"
)
ContactMessage
(),
public
abstract
class
MessageEvent
:
ContactMessage
(),
BotEvent
,
MessageEventExtensions
<
User
,
Contact
>
{
/**
...
...
@@ -167,112 +165,3 @@ internal expect interface MessageEventPlatformExtensions<out TSender : User, out
val
message
:
MessageChain
val
bot
:
Bot
}
/**
* 已废弃, 请使用 [MessageEvent]
*/
@PlannedRemoval
(
"1.2.0"
)
@Deprecated
(
message
=
"use MessageEvent"
,
replaceWith
=
ReplaceWith
(
"MessageEvent"
,
"net.mamoe.mirai.message.MessageEvent"
),
level
=
DeprecationLevel
.
HIDDEN
)
public
abstract
class
MessagePacketBase
<
out
TSender
:
User
,
out
TSubject
:
Contact
>
:
Packet
,
BotEvent
,
AbstractEvent
()
{
abstract
override
val
bot
:
Bot
public
abstract
val
sender
:
User
public
abstract
val
subject
:
Contact
public
abstract
val
message
:
MessageChain
public
abstract
val
time
:
Int
public
abstract
val
source
:
OnlineMessageSource
.
Incoming
public
abstract
val
senderName
:
String
}
@PlannedRemoval
(
"1.2.0"
)
@Deprecated
(
message
=
"Ambiguous name. Use MessageEvent instead"
,
replaceWith
=
ReplaceWith
(
"MessageEvent"
,
"net.mamoe.mirai.message.MessageEvent"
),
level
=
DeprecationLevel
.
HIDDEN
)
@Suppress
(
"DEPRECATION_ERROR"
)
public
abstract
class
MessagePacket
:
MessagePacketBase
<
User
,
Contact
>(),
BotEvent
,
MessageEventExtensions
<
User
,
Contact
>
{
abstract
override
val
bot
:
Bot
abstract
override
val
sender
:
User
abstract
override
val
subject
:
Contact
abstract
override
val
message
:
MessageChain
abstract
override
val
time
:
Int
abstract
override
val
source
:
OnlineMessageSource
.
Incoming
abstract
override
val
senderName
:
String
}
@PlannedRemoval
(
"1.2.0"
)
@Deprecated
(
message
=
"Ambiguous name. Use MessageEvent instead"
,
replaceWith
=
ReplaceWith
(
"MessageEvent"
,
"net.mamoe.mirai.message.MessageEvent"
),
level
=
DeprecationLevel
.
HIDDEN
)
@Suppress
(
"DEPRECATION_ERROR"
)
public
abstract
class
ContactMessage
:
MessagePacket
(),
BotEvent
,
MessageEventExtensions
<
User
,
Contact
>
{
abstract
override
val
bot
:
Bot
abstract
override
val
sender
:
User
abstract
override
val
subject
:
Contact
abstract
override
val
message
:
MessageChain
abstract
override
val
time
:
Int
abstract
override
val
source
:
OnlineMessageSource
.
Incoming
abstract
override
val
senderName
:
String
}
@PlannedRemoval
(
"1.2.0"
)
@Deprecated
(
message
=
"Ambiguous name. Use FriendMessageEvent instead"
,
replaceWith
=
ReplaceWith
(
"FriendMessageEvent"
,
"net.mamoe.mirai.message.FriendMessageEvent"
),
level
=
DeprecationLevel
.
HIDDEN
)
@Suppress
(
"DEPRECATION_ERROR"
)
public
abstract
class
FriendMessage
:
MessageEvent
()
{
abstract
override
val
bot
:
Bot
abstract
override
val
sender
:
Friend
abstract
override
val
subject
:
Friend
abstract
override
val
message
:
MessageChain
abstract
override
val
time
:
Int
abstract
override
val
source
:
OnlineMessageSource
.
Incoming
.
FromFriend
abstract
override
val
senderName
:
String
}
@PlannedRemoval
(
"1.2.0"
)
@Deprecated
(
message
=
"Ambiguous name. Use GroupMessageEvent instead"
,
replaceWith
=
ReplaceWith
(
"GroupMessageEvent"
,
"net.mamoe.mirai.message.GroupMessageEvent"
),
level
=
DeprecationLevel
.
HIDDEN
)
@Suppress
(
"DEPRECATION_ERROR"
)
public
abstract
class
GroupMessage
:
MessageEvent
()
{
public
abstract
val
group
:
Group
abstract
override
val
bot
:
Bot
abstract
override
val
sender
:
Member
abstract
override
val
subject
:
Group
abstract
override
val
message
:
MessageChain
abstract
override
val
time
:
Int
abstract
override
val
source
:
OnlineMessageSource
.
Incoming
.
FromGroup
abstract
override
val
senderName
:
String
}
@PlannedRemoval
(
"1.2.0"
)
@Deprecated
(
message
=
"Ambiguous name. Use TempMessageEvent instead"
,
replaceWith
=
ReplaceWith
(
"TempMessageEvent"
,
"net.mamoe.mirai.message.TempMessageEvent"
),
level
=
DeprecationLevel
.
HIDDEN
)
public
abstract
class
TempMessage
:
MessageEvent
()
{
abstract
override
val
bot
:
Bot
abstract
override
val
sender
:
Member
abstract
override
val
subject
:
Member
abstract
override
val
message
:
MessageChain
abstract
override
val
time
:
Int
abstract
override
val
source
:
OnlineMessageSource
.
Incoming
.
FromTemp
public
abstract
val
group
:
Group
abstract
override
val
senderName
:
String
}
\ No newline at end of file
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/deprecated.kt
0 → 100644
View file @
90185490
/*
* Copyright 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
*/
@
file
:
Suppress
(
"EXPERIMENTAL_UNSIGNED_LITERALS"
,
"EXPERIMENTAL_API_USAGE"
,
"unused"
,
"DECLARATION_CANT_BE_INLINED"
,
"UNCHECKED_CAST"
,
"NOTHING_TO_INLINE"
)
@
file
:
JvmMultifileClass
@
file
:
JvmName
(
"MessageEventKt"
)
package
net.mamoe.mirai.message
import
net.mamoe.mirai.Bot
import
net.mamoe.mirai.contact.*
import
net.mamoe.mirai.event.AbstractEvent
import
net.mamoe.mirai.event.events.BotEvent
import
net.mamoe.mirai.message.data.MessageChain
import
net.mamoe.mirai.message.data.OnlineMessageSource
import
net.mamoe.mirai.qqandroid.network.Packet
import
kotlin.jvm.JvmMultifileClass
import
kotlin.jvm.JvmName
/**
* 已废弃, 请使用 [MessageEvent]
*/
@Deprecated
(
message
=
"use MessageEvent"
,
replaceWith
=
ReplaceWith
(
"MessageEvent"
,
"net.mamoe.mirai.message.MessageEvent"
),
level
=
DeprecationLevel
.
HIDDEN
)
public
abstract
class
MessagePacketBase
<
out
TSender
:
User
,
out
TSubject
:
Contact
>
:
Packet
,
BotEvent
,
AbstractEvent
()
{
abstract
override
val
bot
:
Bot
public
abstract
val
sender
:
User
public
abstract
val
subject
:
Contact
public
abstract
val
message
:
MessageChain
public
abstract
val
time
:
Int
public
abstract
val
source
:
OnlineMessageSource
.
Incoming
public
abstract
val
senderName
:
String
}
@Deprecated
(
message
=
"Ambiguous name. Use MessageEvent instead"
,
replaceWith
=
ReplaceWith
(
"MessageEvent"
,
"net.mamoe.mirai.message.MessageEvent"
),
level
=
DeprecationLevel
.
HIDDEN
)
@Suppress
(
"DEPRECATION_ERROR"
)
public
abstract
class
MessagePacket
:
MessagePacketBase
<
User
,
Contact
>(),
BotEvent
,
MessageEventExtensions
<
User
,
Contact
>
{
abstract
override
val
bot
:
Bot
abstract
override
val
sender
:
User
abstract
override
val
subject
:
Contact
abstract
override
val
message
:
MessageChain
abstract
override
val
time
:
Int
abstract
override
val
source
:
OnlineMessageSource
.
Incoming
abstract
override
val
senderName
:
String
}
@Deprecated
(
message
=
"Ambiguous name. Use MessageEvent instead"
,
replaceWith
=
ReplaceWith
(
"MessageEvent"
,
"net.mamoe.mirai.message.MessageEvent"
),
level
=
DeprecationLevel
.
HIDDEN
)
@Suppress
(
"DEPRECATION_ERROR"
)
public
abstract
class
ContactMessage
:
MessagePacket
(),
BotEvent
,
MessageEventExtensions
<
User
,
Contact
>
{
abstract
override
val
bot
:
Bot
abstract
override
val
sender
:
User
abstract
override
val
subject
:
Contact
abstract
override
val
message
:
MessageChain
abstract
override
val
time
:
Int
abstract
override
val
source
:
OnlineMessageSource
.
Incoming
abstract
override
val
senderName
:
String
}
@Deprecated
(
message
=
"Ambiguous name. Use FriendMessageEvent instead"
,
replaceWith
=
ReplaceWith
(
"FriendMessageEvent"
,
"net.mamoe.mirai.message.FriendMessageEvent"
),
level
=
DeprecationLevel
.
HIDDEN
)
@Suppress
(
"DEPRECATION_ERROR"
)
public
abstract
class
FriendMessage
:
MessageEvent
()
{
abstract
override
val
bot
:
Bot
abstract
override
val
sender
:
Friend
abstract
override
val
subject
:
Friend
abstract
override
val
message
:
MessageChain
abstract
override
val
time
:
Int
abstract
override
val
source
:
OnlineMessageSource
.
Incoming
.
FromFriend
abstract
override
val
senderName
:
String
}
@Deprecated
(
message
=
"Ambiguous name. Use GroupMessageEvent instead"
,
replaceWith
=
ReplaceWith
(
"GroupMessageEvent"
,
"net.mamoe.mirai.message.GroupMessageEvent"
),
level
=
DeprecationLevel
.
HIDDEN
)
@Suppress
(
"DEPRECATION_ERROR"
)
public
abstract
class
GroupMessage
:
MessageEvent
()
{
public
abstract
val
group
:
Group
abstract
override
val
bot
:
Bot
abstract
override
val
sender
:
Member
abstract
override
val
subject
:
Group
abstract
override
val
message
:
MessageChain
abstract
override
val
time
:
Int
abstract
override
val
source
:
OnlineMessageSource
.
Incoming
.
FromGroup
abstract
override
val
senderName
:
String
}
@Deprecated
(
message
=
"Ambiguous name. Use TempMessageEvent instead"
,
replaceWith
=
ReplaceWith
(
"TempMessageEvent"
,
"net.mamoe.mirai.message.TempMessageEvent"
),
level
=
DeprecationLevel
.
HIDDEN
)
public
abstract
class
TempMessage
:
MessageEvent
()
{
abstract
override
val
bot
:
Bot
abstract
override
val
sender
:
Member
abstract
override
val
subject
:
Member
abstract
override
val
message
:
MessageChain
abstract
override
val
time
:
Int
abstract
override
val
source
:
OnlineMessageSource
.
Incoming
.
FromTemp
public
abstract
val
group
:
Group
abstract
override
val
senderName
:
String
}
\ No newline at end of file
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/event/JvmMethodListeners.kt
View file @
90185490
...
...
@@ -14,15 +14,9 @@
package
net.mamoe.mirai.event
import
kotlinx.coroutines.*
import
java.lang.reflect.Method
import
net.mamoe.mirai.event.internal.registerEvent
import
kotlin.coroutines.CoroutineContext
import
kotlin.coroutines.EmptyCoroutineContext
import
kotlin.reflect.KClass
import
kotlin.reflect.full.IllegalCallableAccessException
import
kotlin.reflect.full.callSuspend
import
kotlin.reflect.full.isSubclassOf
import
kotlin.reflect.jvm.isAccessible
import
kotlin.reflect.jvm.kotlinFunction
/**
* 标注一个函数为事件监听器.
...
...
@@ -154,17 +148,17 @@ public annotation class EventHandler(
* @see Listener.EventPriority 查看优先级相关信息
* @see Event.intercept 拦截事件
*/
public
val
priority
:
Listener
.
EventPriority
=
EventPriority
.
NORMAL
,
public
val
priority
:
Listener
.
EventPriority
=
EventPriority
.
NORMAL
,
/**
* 是否自动忽略被 [取消][CancellableEvent.isCancelled]
* @see CancellableEvent
*/
public
val
ignoreCancelled
:
Boolean
=
true
,
public
val
ignoreCancelled
:
Boolean
=
true
,
/**
* 并发类型
* @see Listener.ConcurrencyKind
*/
public
val
concurrency
:
Listener
.
ConcurrencyKind
=
Listener
.
ConcurrencyKind
.
CONCURRENT
public
val
concurrency
:
Listener
.
ConcurrencyKind
=
Listener
.
ConcurrencyKind
.
CONCURRENT
)
/**
...
...
@@ -227,154 +221,13 @@ public fun <T> T.registerEvents(coroutineContext: CoroutineContext = EmptyCorout
* @see EventHandler 获取更多信息
*/
@JvmOverloads
public
fun
CoroutineScope
.
registerEvents
(
host
:
ListenerHost
,
coroutineContext
:
CoroutineContext
=
EmptyCoroutineContext
)
{
public
fun
CoroutineScope
.
registerEvents
(
host
:
ListenerHost
,
coroutineContext
:
CoroutineContext
=
EmptyCoroutineContext
)
{
for
(
method
in
host
.
javaClass
.
declaredMethods
)
{
method
.
getAnnotation
(
EventHandler
::
class
.
java
)
?.
let
{
method
.
registerEvent
(
host
,
this
,
it
,
coroutineContext
)
}
}
}
@Suppress
(
"UNCHECKED_CAST"
)
private
fun
Method
.
registerEvent
(
owner
:
Any
,
scope
:
CoroutineScope
,
annotation
:
EventHandler
,
coroutineContext
:
CoroutineContext
):
Listener
<
Event
>
{
this
.
isAccessible
=
true
val
kotlinFunction
=
kotlin
.
runCatching
{
this
.
kotlinFunction
}.
getOrNull
()
return
if
(
kotlinFunction
!=
null
)
{
// kotlin functions
val
param
=
kotlinFunction
.
parameters
when
(
param
.
size
)
{
3
->
{
// ownerClass, receiver, event
check
(
param
[
1
].
type
==
param
[
2
].
type
)
{
"Illegal kotlin function ${kotlinFunction.name}. Receiver and param must have same type"
}
check
((
param
[
1
].
type
.
classifier
as
?
KClass
<
*
>)
?.
isSubclassOf
(
Event
::
class
)
==
true
)
{
"Illegal kotlin function ${kotlinFunction.name}. First param or receiver must be subclass of Event, but found ${param[1].type.classifier}"
}
}
2
->
{
// ownerClass, event
check
((
param
[
1
].
type
.
classifier
as
?
KClass
<
*
>)
?.
isSubclassOf
(
Event
::
class
)
==
true
)
{
"Illegal kotlin function ${kotlinFunction.name}. First param or receiver must be subclass of Event, but found ${param[1].type.classifier}"
}
}
else
->
error
(
"function ${kotlinFunction.name} must have one Event param"
)
}
lateinit
var
listener
:
Listener
<
*
>
kotlin
.
runCatching
{
kotlinFunction
.
isAccessible
=
true
}
suspend
fun
callFunction
(
event
:
Event
):
Any
?
{
try
{
return
when
(
param
.
size
)
{
3
->
{
if
(
kotlinFunction
.
isSuspend
)
{
kotlinFunction
.
callSuspend
(
owner
,
event
,
event
)
}
else
withContext
(
Dispatchers
.
IO
)
{
// for safety
kotlinFunction
.
call
(
owner
,
event
,
event
)
}
}
2
->
{
if
(
kotlinFunction
.
isSuspend
)
{
kotlinFunction
.
callSuspend
(
owner
,
event
)
}
else
withContext
(
Dispatchers
.
IO
)
{
// for safety
kotlinFunction
.
call
(
owner
,
event
)
}
}
else
->
error
(
"stub"
)
}
}
catch
(
e
:
IllegalCallableAccessException
)
{
listener
.
completeExceptionally
(
e
)
return
ListeningStatus
.
STOPPED
}
}
require
(!
kotlinFunction
.
returnType
.
isMarkedNullable
)
{
"Kotlin event handlers cannot have nullable return type."
}
require
(
kotlinFunction
.
parameters
.
any
{
it
.
type
.
isMarkedNullable
})
{
"Kotlin event handlers cannot have nullable parameter type."
}
when
(
kotlinFunction
.
returnType
.
classifier
)
{
Unit
::
class
,
Nothing
::
class
-> {
scope.subscribe
Always
(
param
[
1
].
type
.
classifier
as
KClass
<
out
Event
>,
priority
=
annotation
.
priority
,
concurrency
=
annotation
.
concurrency
,
coroutineContext
=
coroutineContext
)
{
if
(
annotation
.
ignoreCancelled
)
{
if
((
this
as
?
CancellableEvent
)
?.
isCancelled
!=
true
)
{
callFunction
(
this
)
}
}
else
callFunction
(
this
)
}.
also
{
listener
=
it
}
}
ListeningStatus
::
class
-> {
scope.subscribe(
param[1].type.classifier as
KClass
<
out
Event
>,
priority
=
annotation
.
priority
,
concurrency
=
annotation
.
concurrency
,
coroutineContext
=
coroutineContext
)
{
if
(
annotation
.
ignoreCancelled
)
{
if
((
this
as
?
CancellableEvent
)
?.
isCancelled
!=
true
)
{
callFunction
(
this
)
as
ListeningStatus
}
else
ListeningStatus
.
LISTENING
}
else
callFunction
(
this
)
as
ListeningStatus
}.
also
{
listener
=
it
}
}
else
->
error
(
"Illegal method return type. Required Void, Nothing or ListeningStatus, found ${kotlinFunction.returnType.classifier}"
)
}
}
else
{
// java methods
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"
}
when
(
this
.
returnType
)
{
Void
::
class
.
java
,
Void
.
TYPE
,
Nothing
::
class
.
java
->
{
scope
.
subscribeAlways
(
paramType
.
kotlin
as
KClass
<
out
Event
>,
priority
=
annotation
.
priority
,
concurrency
=
annotation
.
concurrency
,
coroutineContext
=
coroutineContext
)
{
if
(
annotation
.
ignoreCancelled
)
{
if
((
this
as
?
CancellableEvent
)
?.
isCancelled
!=
true
)
{
withContext
(
Dispatchers
.
IO
)
{
this
@
registerEvent
.
invoke
(
owner
,
this
)
}
}
}
else
withContext
(
Dispatchers
.
IO
)
{
this
@
registerEvent
.
invoke
(
owner
,
this
)
}
}
}
ListeningStatus
::
class
.
java
->
{
scope
.
subscribe
(
paramType
.
kotlin
as
KClass
<
out
Event
>,
priority
=
annotation
.
priority
,
concurrency
=
annotation
.
concurrency
,
coroutineContext
=
coroutineContext
)
{
if
(
annotation
.
ignoreCancelled
)
{
if
((
this
as
?
CancellableEvent
)
?.
isCancelled
!=
true
)
{
withContext
(
Dispatchers
.
IO
)
{
this
@
registerEvent
.
invoke
(
owner
,
this
)
as
ListeningStatus
}
}
else
ListeningStatus
.
LISTENING
}
else
withContext
(
Dispatchers
.
IO
)
{
this
@
registerEvent
.
invoke
(
owner
,
this
)
as
ListeningStatus
}
}
}
else
->
error
(
"Illegal method return type. Required Void or ListeningStatus, but found ${this.returnType.canonicalName}"
)
}
}
}
\ No newline at end of file
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/event/internal/EventInternalJvm.kt
View file @
90185490
...
...
@@ -14,12 +14,18 @@ package net.mamoe.mirai.event.internal
import
kotlinx.coroutines.CoroutineScope
import
kotlinx.coroutines.Dispatchers
import
kotlinx.coroutines.withContext
import
net.mamoe.mirai.event.Event
import
net.mamoe.mirai.event.Listener
import
net.mamoe.mirai.event.ListeningStatus
import
net.mamoe.mirai.event.*
import
java.lang.reflect.Method
import
java.util.function.Consumer
import
java.util.function.Function
import
kotlin.coroutines.CoroutineContext
import
kotlin.coroutines.EmptyCoroutineContext
import
kotlin.reflect.KClass
import
kotlin.reflect.full.IllegalCallableAccessException
import
kotlin.reflect.full.callSuspend
import
kotlin.reflect.full.isSubclassOf
import
kotlin.reflect.jvm.isAccessible
import
kotlin.reflect.jvm.kotlinFunction
@Suppress
(
"FunctionName"
)
internal
fun
<
E
:
Event
>
Class
<
E
>.
_subscribeEventForJaptOnly
(
...
...
@@ -40,4 +46,149 @@ internal fun <E : Event> Class<E>._subscribeEventForJaptOnly(scope: CoroutineSco
EmptyCoroutineContext
,
Listener
.
ConcurrencyKind
.
LOCKED
)
{
withContext
(
Dispatchers
.
IO
)
{
onEvent
.
accept
(
it
)
};
ListeningStatus
.
LISTENING
;
})
}
@Suppress
(
"UNCHECKED_CAST"
)
internal
fun
Method
.
registerEvent
(
owner
:
Any
,
scope
:
CoroutineScope
,
annotation
:
EventHandler
,
coroutineContext
:
CoroutineContext
):
Listener
<
Event
>
{
this
.
isAccessible
=
true
val
kotlinFunction
=
kotlin
.
runCatching
{
this
.
kotlinFunction
}.
getOrNull
()
return
if
(
kotlinFunction
!=
null
)
{
// kotlin functions
val
param
=
kotlinFunction
.
parameters
when
(
param
.
size
)
{
3
->
{
// ownerClass, receiver, event
check
(
param
[
1
].
type
==
param
[
2
].
type
)
{
"Illegal kotlin function ${kotlinFunction.name}. Receiver and param must have same type"
}
check
((
param
[
1
].
type
.
classifier
as
?
KClass
<
*
>)
?.
isSubclassOf
(
Event
::
class
)
==
true
)
{
"Illegal kotlin function ${kotlinFunction.name}. First param or receiver must be subclass of Event, but found ${param[1].type.classifier}"
}
}
2
->
{
// ownerClass, event
check
((
param
[
1
].
type
.
classifier
as
?
KClass
<
*
>)
?.
isSubclassOf
(
Event
::
class
)
==
true
)
{
"Illegal kotlin function ${kotlinFunction.name}. First param or receiver must be subclass of Event, but found ${param[1].type.classifier}"
}
}
else
->
error
(
"function ${kotlinFunction.name} must have one Event param"
)
}
lateinit
var
listener
:
Listener
<
*
>
kotlin
.
runCatching
{
kotlinFunction
.
isAccessible
=
true
}
suspend
fun
callFunction
(
event
:
Event
):
Any
?
{
try
{
return
when
(
param
.
size
)
{
3
->
{
if
(
kotlinFunction
.
isSuspend
)
{
kotlinFunction
.
callSuspend
(
owner
,
event
,
event
)
}
else
withContext
(
Dispatchers
.
IO
)
{
// for safety
kotlinFunction
.
call
(
owner
,
event
,
event
)
}
}
2
->
{
if
(
kotlinFunction
.
isSuspend
)
{
kotlinFunction
.
callSuspend
(
owner
,
event
)
}
else
withContext
(
Dispatchers
.
IO
)
{
// for safety
kotlinFunction
.
call
(
owner
,
event
)
}
}
else
->
error
(
"stub"
)
}
}
catch
(
e
:
IllegalCallableAccessException
)
{
listener
.
completeExceptionally
(
e
)
return
ListeningStatus
.
STOPPED
}
}
require
(!
kotlinFunction
.
returnType
.
isMarkedNullable
)
{
"Kotlin event handlers cannot have nullable return type."
}
require
(
kotlinFunction
.
parameters
.
any
{
it
.
type
.
isMarkedNullable
})
{
"Kotlin event handlers cannot have nullable parameter type."
}
when
(
kotlinFunction
.
returnType
.
classifier
)
{
Unit
::
class
,
Nothing
::
class
-> {
scope.subscribe
Always
(
param
[
1
].
type
.
classifier
as
KClass
<
out
Event
>,
priority
=
annotation
.
priority
,
concurrency
=
annotation
.
concurrency
,
coroutineContext
=
coroutineContext
)
{
if
(
annotation
.
ignoreCancelled
)
{
if
((
this
as
?
CancellableEvent
)
?.
isCancelled
!=
true
)
{
callFunction
(
this
)
}
}
else
callFunction
(
this
)
}.
also
{
listener
=
it
}
}
ListeningStatus
::
class
-> {
scope.subscribe(
param[1].type.classifier as
KClass
<
out
Event
>,
priority
=
annotation
.
priority
,
concurrency
=
annotation
.
concurrency
,
coroutineContext
=
coroutineContext
)
{
if
(
annotation
.
ignoreCancelled
)
{
if
((
this
as
?
CancellableEvent
)
?.
isCancelled
!=
true
)
{
callFunction
(
this
)
as
ListeningStatus
}
else
ListeningStatus
.
LISTENING
}
else
callFunction
(
this
)
as
ListeningStatus
}.
also
{
listener
=
it
}
}
else
->
error
(
"Illegal method return type. Required Void, Nothing or ListeningStatus, found ${kotlinFunction.returnType.classifier}"
)
}
}
else
{
// java methods
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"
}
when
(
this
.
returnType
)
{
Void
::
class
.
java
,
Void
.
TYPE
,
Nothing
::
class
.
java
->
{
scope
.
subscribeAlways
(
paramType
.
kotlin
as
KClass
<
out
Event
>,
priority
=
annotation
.
priority
,
concurrency
=
annotation
.
concurrency
,
coroutineContext
=
coroutineContext
)
{
if
(
annotation
.
ignoreCancelled
)
{
if
((
this
as
?
CancellableEvent
)
?.
isCancelled
!=
true
)
{
withContext
(
Dispatchers
.
IO
)
{
this
@
registerEvent
.
invoke
(
owner
,
this
)
}
}
}
else
withContext
(
Dispatchers
.
IO
)
{
this
@
registerEvent
.
invoke
(
owner
,
this
)
}
}
}
ListeningStatus
::
class
.
java
->
{
scope
.
subscribe
(
paramType
.
kotlin
as
KClass
<
out
Event
>,
priority
=
annotation
.
priority
,
concurrency
=
annotation
.
concurrency
,
coroutineContext
=
coroutineContext
)
{
if
(
annotation
.
ignoreCancelled
)
{
if
((
this
as
?
CancellableEvent
)
?.
isCancelled
!=
true
)
{
withContext
(
Dispatchers
.
IO
)
{
this
@
registerEvent
.
invoke
(
owner
,
this
)
as
ListeningStatus
}
}
else
ListeningStatus
.
LISTENING
}
else
withContext
(
Dispatchers
.
IO
)
{
this
@
registerEvent
.
invoke
(
owner
,
this
)
as
ListeningStatus
}
}
}
else
->
error
(
"Illegal method return type. Required Void or ListeningStatus, but found ${this.returnType.canonicalName}"
)
}
}
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment