diff --git a/ts-core/src/main/kotlin/cn/tursom/core/netty/LazyChannel.kt b/ts-core/src/main/kotlin/cn/tursom/core/netty/LazyChannel.kt new file mode 100644 index 0000000..7944c52 --- /dev/null +++ b/ts-core/src/main/kotlin/cn/tursom/core/netty/LazyChannel.kt @@ -0,0 +1,187 @@ +package cn.tursom.core.netty + +import io.netty.buffer.ByteBufAllocator +import io.netty.channel.* +import io.netty.util.Attribute +import io.netty.util.AttributeKey +import java.net.SocketAddress + +class LazyChannel( + val getChannel: () -> Channel?, +) : Channel { + override fun attr(key: AttributeKey?): Attribute { + return getChannel()!!.attr(key) + } + + override fun hasAttr(key: AttributeKey?): Boolean { + return getChannel()!!.hasAttr(key) + } + + override fun bind(localAddress: SocketAddress?): ChannelFuture { + return getChannel()!!.bind(localAddress) + } + + override fun bind(localAddress: SocketAddress?, promise: ChannelPromise?): ChannelFuture { + return getChannel()!!.bind(localAddress, promise) + } + + override fun connect(remoteAddress: SocketAddress?): ChannelFuture { + return getChannel()!!.connect(remoteAddress) + } + + override fun connect(remoteAddress: SocketAddress?, localAddress: SocketAddress?): ChannelFuture { + return getChannel()!!.connect(remoteAddress, localAddress) + } + + override fun connect(remoteAddress: SocketAddress?, promise: ChannelPromise?): ChannelFuture { + return getChannel()!!.connect(remoteAddress, promise) + } + + override fun connect( + remoteAddress: SocketAddress?, + localAddress: SocketAddress?, + promise: ChannelPromise?, + ): ChannelFuture { + return getChannel()!!.connect(remoteAddress, localAddress, promise) + } + + override fun disconnect(): ChannelFuture { + return getChannel()!!.disconnect() + } + + override fun disconnect(promise: ChannelPromise?): ChannelFuture { + return getChannel()!!.disconnect(promise) + } + + override fun close(): ChannelFuture { + return getChannel()!!.close() + } + + override fun close(promise: ChannelPromise?): ChannelFuture { + return getChannel()!!.close(promise) + } + + override fun deregister(): ChannelFuture { + return getChannel()!!.deregister() + } + + override fun deregister(promise: ChannelPromise?): ChannelFuture { + return getChannel()!!.deregister(promise) + } + + override fun read(): Channel { + return getChannel()!!.read() + } + + override fun write(msg: Any?): ChannelFuture { + return getChannel()!!.write(msg) + } + + override fun write(msg: Any?, promise: ChannelPromise?): ChannelFuture { + return getChannel()!!.write(msg, promise) + } + + override fun flush(): Channel { + return getChannel()!!.flush() + } + + override fun writeAndFlush(msg: Any?, promise: ChannelPromise?): ChannelFuture { + return getChannel()!!.writeAndFlush(msg, promise) + } + + override fun writeAndFlush(msg: Any?): ChannelFuture { + return getChannel()!!.writeAndFlush(msg) + } + + override fun newPromise(): ChannelPromise { + return getChannel()!!.newPromise() + } + + override fun newProgressivePromise(): ChannelProgressivePromise { + return getChannel()!!.newProgressivePromise() + } + + override fun newSucceededFuture(): ChannelFuture { + return getChannel()!!.newSucceededFuture() + } + + override fun newFailedFuture(cause: Throwable?): ChannelFuture { + return getChannel()!!.newFailedFuture(cause) + } + + override fun voidPromise(): ChannelPromise { + return getChannel()!!.voidPromise() + } + + override fun compareTo(other: Channel?): Int { + return getChannel()!!.compareTo(other) + } + + override fun id(): ChannelId { + return getChannel()!!.id() + } + + override fun eventLoop(): EventLoop { + return getChannel()!!.eventLoop() + } + + override fun parent(): Channel { + return getChannel()!!.parent() + } + + override fun config(): ChannelConfig { + return getChannel()!!.config() + } + + override fun isOpen(): Boolean { + return getChannel()!!.isOpen + } + + override fun isRegistered(): Boolean { + return getChannel()!!.isRegistered + } + + override fun isActive(): Boolean { + return getChannel()!!.isActive + } + + override fun metadata(): ChannelMetadata { + return getChannel()!!.metadata() + } + + override fun localAddress(): SocketAddress { + return getChannel()!!.localAddress() + } + + override fun remoteAddress(): SocketAddress { + return getChannel()!!.remoteAddress() + } + + override fun closeFuture(): ChannelFuture { + return getChannel()!!.closeFuture() + } + + override fun isWritable(): Boolean { + return getChannel()!!.isWritable + } + + override fun bytesBeforeUnwritable(): Long { + return getChannel()!!.bytesBeforeUnwritable() + } + + override fun bytesBeforeWritable(): Long { + return getChannel()!!.bytesBeforeWritable() + } + + override fun unsafe(): Channel.Unsafe { + return getChannel()!!.unsafe() + } + + override fun pipeline(): ChannelPipeline { + return getChannel()!!.pipeline() + } + + override fun alloc(): ByteBufAllocator { + return getChannel()!!.alloc() + } +} diff --git a/ts-core/ts-delegation/build.gradle.kts b/ts-core/ts-delegation/build.gradle.kts index 47ef1dc..74a720e 100644 --- a/ts-core/ts-delegation/build.gradle.kts +++ b/ts-core/ts-delegation/build.gradle.kts @@ -5,6 +5,7 @@ plugins { dependencies { implementation(project(":ts-core")) + compileOnly(group = "io.netty", name = "netty-all", version = "4.1.43.Final") } @kotlin.Suppress("UNCHECKED_CAST") diff --git a/ts-core/ts-delegation/src/main/kotlin/cn/tursom/core/delegation/ext/NettyAttributeDelegation.kt b/ts-core/ts-delegation/src/main/kotlin/cn/tursom/core/delegation/ext/NettyAttributeDelegation.kt new file mode 100644 index 0000000..0d823ab --- /dev/null +++ b/ts-core/ts-delegation/src/main/kotlin/cn/tursom/core/delegation/ext/NettyAttributeDelegation.kt @@ -0,0 +1,35 @@ +package cn.tursom.core.delegation.ext + +import cn.tursom.core.delegation.MutableDelegatedField +import cn.tursom.core.netty.LazyChannel +import io.netty.channel.Channel +import io.netty.util.AttributeKey + +class NettyAttributeDelegation( + private val channel: Channel, + private val attachmentKey: AttributeKey, +) : MutableDelegatedField { + override fun getValue(): V { + return channel.attr(attachmentKey).get() + } + + override fun setValue(value: V) { + channel.attr(attachmentKey).set(value) + } + + companion object { + fun T.attributeDelegation( + channel: Channel, + attachmentKey: AttributeKey, + ): MutableDelegatedField { + return NettyAttributeDelegation(channel, attachmentKey) + } + + fun T.attributeDelegation( + attachmentKey: AttributeKey, + channel: () -> Channel?, + ): MutableDelegatedField { + return NettyAttributeDelegation(LazyChannel(channel), attachmentKey) + } + } +}