Skip to content
This repository was archived by the owner on Dec 10, 2025. It is now read-only.

Commit 363d85c

Browse files
committed
refactor: replace LambdaWrapperHolder with ByteBuddy for invoker generation
- Switched from `LambdaWrapperHolder` to ByteBuddy for creating listener method invokers. - Simplified invoker generation logic using dynamic type creation. - Removed redundant `LambdaWrapperHolder` initialization and annotations.
1 parent 4454c0e commit 363d85c

File tree

1 file changed

+91
-60
lines changed
  • surf-cloud-core/surf-cloud-core-common/src/main/kotlin/dev/slne/surf/cloud/core/common/netty/registry/listener

1 file changed

+91
-60
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,76 +1,128 @@
11
package dev.slne.surf.cloud.core.common.netty.registry.listener
22

3-
import dev.slne.surf.cloud.api.common.netty.exception.SurfNettyListenerRegistrationException
43
import dev.slne.surf.cloud.api.common.netty.packet.NettyPacket
54
import dev.slne.surf.cloud.api.common.netty.packet.NettyPacketInfo
6-
import tech.hiddenproject.aide.reflection.LambdaWrapperHolder
7-
import tech.hiddenproject.aide.reflection.annotation.Invoker
5+
import net.bytebuddy.ByteBuddy
6+
import net.bytebuddy.description.method.MethodDescription
7+
import net.bytebuddy.dynamic.loading.ClassLoadingStrategy
8+
import net.bytebuddy.implementation.FieldAccessor
9+
import net.bytebuddy.implementation.MethodCall
10+
import net.bytebuddy.implementation.bytecode.assign.Assigner
11+
import net.bytebuddy.matcher.ElementMatchers
812
import java.lang.reflect.Method
13+
import java.lang.reflect.Modifier
914

1015
class RegisteredListener(
1116
private val bean: Any,
12-
listenerMethod: Method,
17+
private val listenerMethod: Method,
1318
packetClassIndex: Int,
1419
packetInfoIndex: Int,
1520
private val suspending: Boolean
1621
) {
17-
private var invoker: Any
22+
val owner: Any get() = bean
23+
24+
private val invoker: Any
1825
private val invokerType: InvokerType
1926

2027
init {
2128
val params = listenerMethod.parameterTypes
22-
23-
if (params.size == 1 || (params.size == 2 && suspending)) { // Only NettyPacket
24-
val clazz =
25-
if (suspending) RegisteredListenerSuspendInvoker1::class else RegisteredListenerInvoker1::class
26-
27-
this.invoker = LambdaWrapperHolder.DEFAULT.wrap(listenerMethod, clazz.java).wrapper
28-
this.invokerType = InvokerType.ONE_PARAM
29-
} else if (params.size == 2 || (params.size == 3 && suspending)) { // NettyPacket and NettyPacketInfo
30-
if (packetClassIndex == 0 && packetInfoIndex == 1) { // Normal order (NettyPacket, NettyPacketInfo)
31-
val clazz =
32-
if (suspending) RegisteredListenerSuspendInvoker2::class else RegisteredListenerInvoker2::class
33-
34-
this.invoker = LambdaWrapperHolder.DEFAULT.wrap(listenerMethod, clazz.java).wrapper
35-
this.invokerType = InvokerType.TWO_PARAMS
36-
} else if (packetInfoIndex == 0 && packetClassIndex == 1) { // Reversed order (NettyPacketInfo, NettyPacket)
37-
val clazz =
38-
if (suspending) RegisteredListenerSuspendInvoker2Rev::class else RegisteredListenerInvoker2Rev::class
39-
40-
this.invoker = LambdaWrapperHolder.DEFAULT.wrap(listenerMethod, clazz.java).wrapper
41-
this.invokerType = InvokerType.TWO_PARAMS_REVERSED
42-
} else {
43-
throw SurfNettyListenerRegistrationException("Invalid parameter order")
44-
}
29+
val beanLoader: ClassLoader = bean.javaClass.classLoader
30+
31+
if (params.size == 1 || (params.size == 2 && suspending)) {
32+
invokerType = InvokerType.ONE_PARAM
33+
invoker = generateInvoker(
34+
iface = if (suspending) RegisteredListenerSuspendInvoker1::class.java else RegisteredListenerInvoker1::class.java,
35+
loader = beanLoader,
36+
ownerArg = bean,
37+
paramOrder = if (suspending) intArrayOf(1, 2) else intArrayOf(1)
38+
)
39+
} else if (params.size == 2 || (params.size == 3 && suspending)) {
40+
val reversed = packetInfoIndex == 0 && packetClassIndex == 1
41+
invokerType = if (reversed) InvokerType.TWO_PARAMS_REVERSED else InvokerType.TWO_PARAMS
42+
invoker = generateInvoker(
43+
iface = when {
44+
suspending && !reversed -> RegisteredListenerSuspendInvoker2::class.java
45+
suspending && reversed -> RegisteredListenerSuspendInvoker2Rev::class.java
46+
!suspending && !reversed -> RegisteredListenerInvoker2::class.java
47+
else -> RegisteredListenerInvoker2Rev::class.java
48+
},
49+
loader = beanLoader,
50+
ownerArg = bean,
51+
paramOrder = when {
52+
suspending && !reversed -> intArrayOf(1, 2, 3) // packet, info, cont
53+
suspending && reversed -> intArrayOf(2, 1, 3) // info, packet, cont
54+
!suspending && !reversed -> intArrayOf(1, 2) // packet, info
55+
else -> intArrayOf(2, 1) // info, packet
56+
}
57+
)
4558
} else {
46-
throw SurfNettyListenerRegistrationException("Invalid number of parameters")
59+
error("Invalid number of parameters for listener method: ${listenerMethod.name} in ${bean.javaClass.name}. Method must take exactly one parameter of type NettyPacket or two parameters of type NettyPacket and NettyPacketInfo.")
4760
}
4861
}
4962

50-
suspend fun handle(packet: NettyPacket, info: NettyPacketInfo) = when (invokerType) {
51-
InvokerType.ONE_PARAM -> {
52-
if (suspending) {
63+
suspend fun handle(packet: NettyPacket, info: NettyPacketInfo) {
64+
when (invokerType) {
65+
InvokerType.ONE_PARAM -> if (suspending) {
5366
(invoker as RegisteredListenerSuspendInvoker1).handle(bean, packet)
5467
} else {
5568
(invoker as RegisteredListenerInvoker1).handle(bean, packet)
5669
}
57-
}
5870

59-
InvokerType.TWO_PARAMS -> {
60-
if (suspending) {
71+
InvokerType.TWO_PARAMS -> if (suspending) {
6172
(invoker as RegisteredListenerSuspendInvoker2).handle(bean, packet, info)
6273
} else {
6374
(invoker as RegisteredListenerInvoker2).handle(bean, packet, info)
6475
}
65-
}
6676

67-
InvokerType.TWO_PARAMS_REVERSED -> {
68-
if (suspending) {
77+
InvokerType.TWO_PARAMS_REVERSED -> if (suspending) {
6978
(invoker as RegisteredListenerSuspendInvoker2Rev).handle(bean, info, packet)
7079
} else {
7180
(invoker as RegisteredListenerInvoker2Rev).handle(bean, info, packet)
7281
}
7382
}
83+
84+
}
85+
86+
private fun <I> generateInvoker(
87+
iface: Class<I>,
88+
loader: ClassLoader,
89+
ownerArg: Any,
90+
paramOrder: IntArray
91+
): I {
92+
val baseCall = if (Modifier.isStatic(listenerMethod.modifiers)) {
93+
MethodCall.invoke(listenerMethod).on(listenerMethod.declaringClass)
94+
} else {
95+
MethodCall.invoke(listenerMethod).onArgument(0)
96+
}
97+
val callWithArgs = paramOrder.fold(baseCall) { acc, idx -> acc.withArgument(idx) }
98+
val finalCall = callWithArgs.withAssigner(
99+
Assigner.DEFAULT,
100+
Assigner.Typing.DYNAMIC
101+
)
102+
103+
val dynamicType = ByteBuddy()
104+
.subclass(Any::class.java)
105+
.implement(iface)
106+
.defineField("owner", Any::class.java, Modifier.PRIVATE or Modifier.FINAL)
107+
.defineConstructor(Modifier.PUBLIC)
108+
.withParameters(Any::class.java)
109+
.intercept(
110+
MethodCall.invoke(Object::class.java.getConstructor())
111+
.andThen(FieldAccessor.ofField("owner").setsArgumentAt(0))
112+
)
113+
.method(
114+
ElementMatchers.named<MethodDescription>("handle")
115+
.and(ElementMatchers.isDeclaredBy(iface))
116+
)
117+
.intercept(finalCall)
118+
.make()
119+
.load(loader, ClassLoadingStrategy.Default.INJECTION)
120+
.loaded
121+
122+
val constructor = dynamicType.getDeclaredConstructor(Any::class.java)
123+
124+
@Suppress("UNCHECKED_CAST")
125+
return constructor.newInstance(ownerArg) as I
74126
}
75127

76128
private enum class InvokerType {
@@ -79,48 +131,27 @@ class RegisteredListener(
79131
TWO_PARAMS_REVERSED
80132
}
81133

82-
// region Standard Invokers
83134
fun interface RegisteredListenerInvoker1 {
84-
@Invoker
85135
fun handle(caller: Any, packet: NettyPacket)
86136
}
87137

88138
fun interface RegisteredListenerInvoker2 {
89-
@Invoker
90139
fun handle(caller: Any, packet: NettyPacket, info: NettyPacketInfo)
91140
}
92141

93142
fun interface RegisteredListenerInvoker2Rev {
94-
@Invoker
95143
fun handle(caller: Any, info: NettyPacketInfo, packet: NettyPacket)
96144
}
97-
// endregion
98145

99-
// region Suspend Invokers for Kotlin coroutines
100146
fun interface RegisteredListenerSuspendInvoker1 {
101-
@Invoker
102147
suspend fun handle(caller: Any, packet: NettyPacket)
103148
}
104149

105150
fun interface RegisteredListenerSuspendInvoker2 {
106-
@Invoker
107151
suspend fun handle(caller: Any, packet: NettyPacket, info: NettyPacketInfo)
108152
}
109153

110154
fun interface RegisteredListenerSuspendInvoker2Rev {
111-
@Invoker
112155
suspend fun handle(caller: Any, info: NettyPacketInfo, packet: NettyPacket)
113156
}
114-
// endregion
115-
116-
companion object {
117-
init {
118-
LambdaWrapperHolder.DEFAULT.add(RegisteredListenerInvoker1::class.java)
119-
LambdaWrapperHolder.DEFAULT.add(RegisteredListenerInvoker2::class.java)
120-
LambdaWrapperHolder.DEFAULT.add(RegisteredListenerInvoker2Rev::class.java)
121-
LambdaWrapperHolder.DEFAULT.add(RegisteredListenerSuspendInvoker1::class.java)
122-
LambdaWrapperHolder.DEFAULT.add(RegisteredListenerSuspendInvoker2::class.java)
123-
LambdaWrapperHolder.DEFAULT.add(RegisteredListenerSuspendInvoker2Rev::class.java)
124-
}
125-
}
126-
}
157+
}

0 commit comments

Comments
 (0)