mirror of
https://github.com/tursom/TursomServer.git
synced 2025-03-25 17:10:07 +08:00
update
This commit is contained in:
parent
647d989aa1
commit
b0cd840376
@ -53,9 +53,6 @@ dependencies {
|
||||
api(kotlin("stdlib-jdk8"))
|
||||
api(kotlin("reflect"))
|
||||
testImplementation(group = "junit", name = "junit", version = "4.12")
|
||||
|
||||
val commonVersion = "1.0.RELEASE"
|
||||
api("com.ddbes", "common-kotlin", commonVersion)
|
||||
}
|
||||
|
||||
tasks.register("install") {
|
||||
|
@ -1,12 +1,26 @@
|
||||
package cn.tursom.core
|
||||
|
||||
open class SimpThreadLocal<T>(private val new: () -> T) : ThreadLocal<T>() {
|
||||
override fun get(): T = super.get() ?: update()
|
||||
open class SimpThreadLocal<T : Any>(
|
||||
private val threadLocal: ThreadLocal<T?>? = null,
|
||||
val new: () -> T,
|
||||
) : ThreadLocal<T>() {
|
||||
override fun get(): T {
|
||||
var value = if (threadLocal != null) threadLocal.get() else super.get()
|
||||
return if (value == null) {
|
||||
value = new()
|
||||
set(value)
|
||||
value
|
||||
} else {
|
||||
value
|
||||
}
|
||||
}
|
||||
|
||||
private fun update(): T {
|
||||
val value = new()
|
||||
set(value)
|
||||
return value
|
||||
override fun set(value: T) {
|
||||
if (threadLocal != null) threadLocal.set(value) else super.set(value)
|
||||
}
|
||||
|
||||
override fun remove() {
|
||||
if (threadLocal != null) threadLocal.remove() else super.remove()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,8 +4,8 @@ import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
class ThreadLocalSimpleDateFormat(
|
||||
val format: String = "YYYY-MM-dd'T'HH:mm:ssZZ"
|
||||
) : SimpThreadLocal<SimpleDateFormat>({
|
||||
val format: String = "YYYY-MM-dd'T'HH:mm:ssZZ",
|
||||
) : SimpThreadLocal<SimpleDateFormat>(null, {
|
||||
SimpleDateFormat(format)
|
||||
}) {
|
||||
fun format(date: Any) = get().format(date)
|
||||
|
@ -112,9 +112,18 @@ inline fun <T, R : Any> Iterable<T>.toSetNotNull(transform: (T) -> R?): Set<R> {
|
||||
}
|
||||
|
||||
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
@Retention(AnnotationRetention.BINARY)
|
||||
//@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY, AnnotationTarget.FUNCTION, AnnotationTarget.CLASS)
|
||||
annotation class UncheckedCast
|
||||
|
||||
@UncheckedCast
|
||||
@Suppress("NOTHING_TO_INLINE", "UNCHECKED_CAST")
|
||||
inline fun <T> Any?.cast() = this as T
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE", "UNCHECKED_CAST")
|
||||
inline fun <T> Any?.uncheckedCast() = this as T
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE", "UNCHECKED_CAST")
|
||||
inline fun <reified T> Any?.castOrNull() = if (this is T) this else null
|
||||
|
||||
@ -280,12 +289,7 @@ inline fun usingNanoTime(action: () -> Unit): Long {
|
||||
}
|
||||
|
||||
inline fun Class<*>.forAllFields(action: (Field) -> Unit) {
|
||||
var clazz = this
|
||||
while (clazz != Any::class.java) {
|
||||
clazz.declaredFields.forEach(action)
|
||||
clazz = clazz.superclass
|
||||
}
|
||||
clazz.declaredFields.forEach(action)
|
||||
allFieldsSequence.forEach(action)
|
||||
}
|
||||
|
||||
val Class<*>.allFields: List<Field>
|
||||
@ -295,6 +299,17 @@ val Class<*>.allFields: List<Field>
|
||||
return fieldList
|
||||
}
|
||||
|
||||
val Class<*>.allFieldsSequence: Sequence<Field>
|
||||
get() = sequence {
|
||||
var clazz = this@allFieldsSequence
|
||||
while (clazz != Any::class.java) {
|
||||
clazz.declaredFields.forEach { field ->
|
||||
yield(field)
|
||||
}
|
||||
clazz = clazz.superclass
|
||||
}
|
||||
}
|
||||
|
||||
fun Class<*>.getFieldForAll(name: String): Field? {
|
||||
forAllFields {
|
||||
if (it.name == name) return it
|
||||
@ -303,12 +318,7 @@ fun Class<*>.getFieldForAll(name: String): Field? {
|
||||
}
|
||||
|
||||
inline fun Class<*>.forAllMethods(action: (Method) -> Unit) {
|
||||
var clazz = this
|
||||
while (clazz != Any::class.java) {
|
||||
clazz.declaredMethods.forEach(action)
|
||||
clazz = clazz.superclass
|
||||
}
|
||||
clazz.declaredMethods.forEach(action)
|
||||
allMethodsSequence.forEach(action)
|
||||
}
|
||||
|
||||
fun Class<*>.getMethodForAll(name: String, vararg parameterTypes: Class<*>?): Method? {
|
||||
@ -325,6 +335,20 @@ val Class<*>.allMethods: List<Method>
|
||||
return fieldList
|
||||
}
|
||||
|
||||
val Class<*>.allMethodsSequence: Sequence<Method>
|
||||
get() = sequence {
|
||||
var clazz = this@allMethodsSequence
|
||||
while (clazz != Any::class.java) {
|
||||
clazz.declaredMethods.forEach {
|
||||
yield(it)
|
||||
}
|
||||
clazz = clazz.superclass
|
||||
}
|
||||
clazz.declaredMethods.forEach {
|
||||
yield(it)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取一个 KProperty<*> 对应的对象
|
||||
*/
|
||||
|
@ -0,0 +1,29 @@
|
||||
package cn.tursom.core.delegation
|
||||
|
||||
import cn.tursom.core.uncheckedCast
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
/**
|
||||
* 当从上一级 MutableDelegatedField 获得到空值时
|
||||
* 自动调用updateValue方法更新值
|
||||
*/
|
||||
class AutoUpdatableMutableDelegatedField<in T, V : Any>(
|
||||
override val delegatedField: MutableDelegatedField<T, V?>,
|
||||
val updateValue: T.(property: KProperty<*>) -> V,
|
||||
) : MutableDelegatedField<T, V> by delegatedField.uncheckedCast(),
|
||||
DecoratorMutableDelegatedField<T, V?> {
|
||||
override fun getValue(thisRef: T, property: KProperty<*>): V {
|
||||
var value = delegatedField.getValue(thisRef, property)
|
||||
if (value == null) {
|
||||
value = thisRef.updateValue(property)
|
||||
delegatedField.setValue(thisRef, property, value)
|
||||
}
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
fun <T, V : Any> MutableDelegatedField<T, V?>.autoUpdate(
|
||||
updateValue: T.(property: KProperty<*>) -> V,
|
||||
): MutableDelegatedField<T, V> {
|
||||
return AutoUpdatableMutableDelegatedField(this, updateValue)
|
||||
}
|
@ -3,7 +3,10 @@ package cn.tursom.core.delegation
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
interface DecoratorDelegateProvider<in T, out V> :
|
||||
DelegateProvider<T, DelegatedField<T, V>>,
|
||||
DecoratorDelegatedField<T, V> {
|
||||
override operator fun provideDelegate(thisRef: T, prop: KProperty<*>): DelegatedField<T, V> = delegatedField
|
||||
DelegateProvider<T, DelegatedField<T, V>>,
|
||||
DecoratorDelegatedField<T, V> {
|
||||
override operator fun provideDelegate(
|
||||
thisRef: T,
|
||||
prop: KProperty<*>,
|
||||
): DelegatedField<T, V> = delegatedField
|
||||
}
|
@ -3,9 +3,9 @@ package cn.tursom.core.delegation
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
interface DecoratorMutableDelegateProvider<in T, V> :
|
||||
DelegateProvider<T, MutableDelegatedField<T, V>>,
|
||||
//DecoratorProvideDelegate<T, V>,
|
||||
DecoratorMutableDelegatedField<T, V> {
|
||||
override operator fun provideDelegate(thisRef: T, prop: KProperty<*>): MutableDelegatedField<T, V> =
|
||||
mutableDelegatedField
|
||||
DelegateProvider<T, MutableDelegatedField<T, V>>,
|
||||
//DecoratorProvideDelegate<T, V>,
|
||||
DecoratorMutableDelegatedField<T, V> {
|
||||
override operator fun provideDelegate(thisRef: T, prop: KProperty<*>): MutableDelegatedField<T, V> =
|
||||
delegatedField
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
package cn.tursom.core.delegation
|
||||
|
||||
interface DecoratorMutableDelegatedField<in T, V> : DecoratorDelegatedField<T, V> {
|
||||
val mutableDelegatedField: MutableDelegatedField<T, V>
|
||||
override val delegatedField: DelegatedField<T, V> get() = mutableDelegatedField
|
||||
override val delegatedField: MutableDelegatedField<T, V>
|
||||
}
|
@ -3,5 +3,5 @@ package cn.tursom.core.delegation
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
interface DelegateProvider<in T, out R> {
|
||||
operator fun provideDelegate(thisRef: T, prop: KProperty<*>): R
|
||||
operator fun provideDelegate(thisRef: T, prop: KProperty<*>): R
|
||||
}
|
||||
|
@ -1,3 +1,8 @@
|
||||
package cn.tursom.core.delegation
|
||||
|
||||
interface DelegatedFieldAttachmentKey<V>
|
||||
import kotlin.reflect.KProperty0
|
||||
|
||||
interface DelegatedFieldAttachmentKey<V> {
|
||||
operator fun get(delegatedField: DelegatedField<*, *>) = delegatedField[this]
|
||||
operator fun get(property0: KProperty0<*>) = property0.getDelegatedAttachmentValue(this)
|
||||
}
|
@ -4,17 +4,17 @@ import java.util.concurrent.Executor
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
class ExecutorMutableDelegatedField<in T, V>(
|
||||
override val mutableDelegatedField: MutableDelegatedField<T, V>,
|
||||
override val delegatedField: MutableDelegatedField<T, V>,
|
||||
private val executor: Executor,
|
||||
) : MutableDelegatedField<T, V> by mutableDelegatedField, DecoratorMutableDelegatedField<T, V> {
|
||||
override fun valueOnSet(thisRef: T, property: KProperty<*>, value: V, oldValue: V) {
|
||||
executor.execute {
|
||||
mutableDelegatedField.valueOnSet(thisRef, property, value, oldValue)
|
||||
) : MutableDelegatedField<T, V> by delegatedField, DecoratorMutableDelegatedField<T, V> {
|
||||
override fun valueOnSet(thisRef: T, property: KProperty<*>, value: V, oldValue: V) {
|
||||
executor.execute {
|
||||
delegatedField.valueOnSet(thisRef, property, value, oldValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun setValue(thisRef: T, property: KProperty<*>, value: V) {
|
||||
valueOnSet(thisRef, property, value, getValue())
|
||||
mutableDelegatedField.setValue(value)
|
||||
}
|
||||
override fun setValue(thisRef: T, property: KProperty<*>, value: V) {
|
||||
valueOnSet(thisRef, property, value, getValue())
|
||||
delegatedField.setValue(value)
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,46 @@
|
||||
package cn.tursom.core.delegation
|
||||
|
||||
import cn.tursom.core.uncheckedCast
|
||||
import java.util.concurrent.TimeUnit
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
class ExpirableMutableDelegatedField<in T, V : Any>(
|
||||
override val delegatedField: MutableDelegatedField<T, V>,
|
||||
val expireMS: Long,
|
||||
) : MutableDelegatedField<T, V?> by delegatedField.uncheckedCast(),
|
||||
DecoratorMutableDelegatedField<T, V> {
|
||||
|
||||
@Volatile
|
||||
private var setTime: Long = 0L
|
||||
|
||||
override fun getValue(thisRef: T, property: KProperty<*>): V? {
|
||||
return if (System.currentTimeMillis() - setTime < expireMS) {
|
||||
delegatedField.uncheckedCast<MutableDelegatedField<T, V?>>().getValue(thisRef, property)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
override fun setValue(thisRef: T, property: KProperty<*>, value: V?) {
|
||||
if (value != null) {
|
||||
delegatedField.setValue(value)
|
||||
setTime = System.currentTimeMillis()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun <T, V : Any> MutableDelegatedField<T, V>.expirable(
|
||||
expireTime: Long,
|
||||
timeUnit: TimeUnit = TimeUnit.MILLISECONDS,
|
||||
): MutableDelegatedField<T, V?> {
|
||||
return ExpirableMutableDelegatedField(this, timeUnit.toMillis(expireTime))
|
||||
}
|
||||
|
||||
@JvmName("expirableTV?")
|
||||
fun <T, V : Any> MutableDelegatedField<T, V?>.expirable(
|
||||
expireTime: Long,
|
||||
timeUnit: TimeUnit = TimeUnit.MILLISECONDS,
|
||||
): MutableDelegatedField<T, V?> {
|
||||
return ExpirableMutableDelegatedField(uncheckedCast(), timeUnit.toMillis(expireTime))
|
||||
}
|
||||
|
@ -1,18 +1,18 @@
|
||||
package cn.tursom.core.delegation
|
||||
|
||||
import cn.tursom.core.cast
|
||||
import cn.tursom.core.uncheckedCast
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
class FilterDelegatedField<in T, V>(
|
||||
override val mutableDelegatedField: MutableDelegatedField<T, V>,
|
||||
override val delegatedField: MutableDelegatedField<T, V>,
|
||||
private val filter: T.(old: V, new: V) -> Boolean,
|
||||
) : MutableDelegatedField<T, V> by mutableDelegatedField, DecoratorMutableDelegatedField<T, V> {
|
||||
) : MutableDelegatedField<T, V> by delegatedField, DecoratorMutableDelegatedField<T, V> {
|
||||
companion object Key : DelegatedFieldAttachmentKey<Boolean>
|
||||
|
||||
private var filterResult = false
|
||||
|
||||
override fun <K> get(key: DelegatedFieldAttachmentKey<K>): K? {
|
||||
return if (key == Key) filterResult.cast() else super.get(key)
|
||||
return if (key == Key) filterResult.uncheckedCast() else super.get(key)
|
||||
}
|
||||
|
||||
override fun setValue(thisRef: T, property: KProperty<*>, value: V) {
|
||||
@ -20,7 +20,7 @@ class FilterDelegatedField<in T, V>(
|
||||
if (!filterResult) {
|
||||
return
|
||||
}
|
||||
mutableDelegatedField.setValue(thisRef, property, value)
|
||||
delegatedField.setValue(thisRef, property, value)
|
||||
}
|
||||
|
||||
override fun valueOnSet(thisRef: T, property: KProperty<*>, value: V, oldValue: V) {
|
||||
@ -28,6 +28,6 @@ class FilterDelegatedField<in T, V>(
|
||||
if (!filterResult) {
|
||||
return
|
||||
}
|
||||
mutableDelegatedField.valueOnSet(thisRef, property, value, oldValue)
|
||||
delegatedField.valueOnSet(thisRef, property, value, oldValue)
|
||||
}
|
||||
}
|
@ -3,8 +3,8 @@ package cn.tursom.core.delegation
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
class GetterDelegatedField<in T, out V>(
|
||||
override val delegatedField: DelegatedField<T, V>,
|
||||
private val getter: DelegatedField<T, V>.(thisRef: T, property: KProperty<*>) -> V,
|
||||
override val delegatedField: DelegatedField<T, V>,
|
||||
private val getter: DelegatedField<T, V>.(thisRef: T, property: KProperty<*>) -> V,
|
||||
) : DelegatedField<T, V> by delegatedField, DecoratorDelegatedField<T, V> {
|
||||
override fun getValue(thisRef: T, property: KProperty<*>): V = delegatedField.getter(thisRef, property)
|
||||
override fun getValue(thisRef: T, property: KProperty<*>): V = delegatedField.getter(thisRef, property)
|
||||
}
|
@ -3,8 +3,8 @@ package cn.tursom.core.delegation
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
class GetterMutableDelegatedField<in T, V>(
|
||||
override val mutableDelegatedField: MutableDelegatedField<T, V>,
|
||||
override val delegatedField: MutableDelegatedField<T, V>,
|
||||
private val getter: MutableDelegatedField<T, V>.(thisRef: T, property: KProperty<*>) -> V,
|
||||
) : MutableDelegatedField<T, V> by mutableDelegatedField, DecoratorMutableDelegatedField<T, V> {
|
||||
override fun getValue(thisRef: T, property: KProperty<*>): V = mutableDelegatedField.getter(thisRef, property)
|
||||
) : MutableDelegatedField<T, V> by delegatedField, DecoratorMutableDelegatedField<T, V> {
|
||||
override fun getValue(thisRef: T, property: KProperty<*>): V = delegatedField.getter(thisRef, property)
|
||||
}
|
@ -3,8 +3,8 @@ package cn.tursom.core.delegation
|
||||
import kotlin.reflect.KMutableProperty0
|
||||
|
||||
class KPropertyMutableDelegatedField<in T, V>(
|
||||
val delegation: KMutableProperty0<V>,
|
||||
val delegation: KMutableProperty0<V>,
|
||||
) : MutableDelegatedField<T, V> {
|
||||
override fun getValue(): V = delegation.get()
|
||||
override fun setValue(value: V) = delegation.set(value)
|
||||
override fun getValue(): V = delegation.get()
|
||||
override fun setValue(value: V) = delegation.set(value)
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package cn.tursom.core.delegation
|
||||
|
||||
/**
|
||||
* 标识一个属性可以被指定的 FieldChangeListener 监听
|
||||
* 属性的实现者应该实现相应的逻辑
|
||||
*/
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
@Retention(AnnotationRetention.BINARY)
|
||||
@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY, AnnotationTarget.FUNCTION, AnnotationTarget.CLASS)
|
||||
annotation class Listenable
|
@ -0,0 +1,6 @@
|
||||
package cn.tursom.core.delegation
|
||||
|
||||
interface ListenableListener<out T, V> : Listener<T, V> {
|
||||
infix fun addListener(listener: T.(old: V, new: V) -> Unit): Listener<T, V>
|
||||
override fun catch(handler: T.(old: V, new: V, e: Throwable) -> Unit): ListenableListener<T, V>
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
package cn.tursom.core.delegation
|
||||
|
||||
import cn.tursom.core.uncheckedCast
|
||||
import java.util.concurrent.ConcurrentLinkedDeque
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
@Listenable
|
||||
class ListenableMutableDelegatedField<T, V>(
|
||||
override val delegatedField: MutableDelegatedField<T, V>,
|
||||
) : MutableDelegatedField<T, V> by delegatedField, DecoratorMutableDelegatedField<T, V> {
|
||||
companion object : DelegatedFieldAttachmentKey<Boolean>
|
||||
|
||||
override fun <K> get(key: DelegatedFieldAttachmentKey<K>): K? {
|
||||
return if (key == Companion) true.uncheckedCast() else super.get(key)
|
||||
}
|
||||
|
||||
private val listenerList = ConcurrentLinkedDeque<T.(old: V, new: V) -> Unit>()
|
||||
|
||||
override fun setValue(thisRef: T, property: KProperty<*>, value: V) {
|
||||
val oldValue = getValue()
|
||||
listenerList.forEach {
|
||||
thisRef.it(oldValue, value)
|
||||
}
|
||||
delegatedField.setValue(thisRef, property, value)
|
||||
}
|
||||
|
||||
override fun valueOnSet(thisRef: T, property: KProperty<*>, value: V, oldValue: V) {
|
||||
listenerList.forEach {
|
||||
thisRef.it(oldValue, value)
|
||||
}
|
||||
delegatedField.valueOnSet(thisRef, property, value, oldValue)
|
||||
}
|
||||
|
||||
fun addListener(listener: T.(old: V, new: V) -> Unit): Listener<T, V> {
|
||||
var catch: (T.(old: V, new: V, e: Throwable) -> Unit)? = null
|
||||
var finally: (T.(old: V, new: V) -> Unit)? = null
|
||||
listenerList.add { old, new ->
|
||||
try {
|
||||
listener(old, new)
|
||||
} catch (e: Throwable) {
|
||||
catch?.invoke(this, old, new, e)
|
||||
} finally {
|
||||
finally?.invoke(this, old, new)
|
||||
}
|
||||
}
|
||||
return object : Listener<T, V> {
|
||||
override fun cancel() = listenerList.remove(listener)
|
||||
|
||||
override fun catch(handler: T.(old: V, new: V, e: Throwable) -> Unit): Listener<T, V> {
|
||||
catch = handler
|
||||
return this
|
||||
}
|
||||
|
||||
override fun finally(handler: T.(old: V, new: V) -> Unit): Listener<T, V> {
|
||||
finally = handler
|
||||
return this
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package cn.tursom.core.delegation
|
||||
|
||||
interface Listener<out T, V> {
|
||||
fun cancel(): Boolean
|
||||
infix fun catch(handler: T.(old: V, new: V, e: Throwable) -> Unit): Listener<T, V>
|
||||
infix fun finally(handler: T.(old: V, new: V) -> Unit): Listener<T, V>
|
||||
}
|
@ -6,23 +6,23 @@ import kotlin.concurrent.withLock
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
class LockMutableDelegatedField<in T, V>(
|
||||
override val mutableDelegatedField: MutableDelegatedField<T, V>,
|
||||
override val delegatedField: MutableDelegatedField<T, V>,
|
||||
private val lock: Lock = ReentrantLock(),
|
||||
) : MutableDelegatedField<T, V> by mutableDelegatedField, DecoratorMutableDelegatedField<T, V> {
|
||||
) : MutableDelegatedField<T, V> by delegatedField, DecoratorMutableDelegatedField<T, V> {
|
||||
constructor(
|
||||
initValue: V,
|
||||
lock: Lock = ReentrantLock(),
|
||||
) : this(MutableDelegatedFieldValue(initValue), lock)
|
||||
|
||||
override fun getValue(thisRef: T, property: KProperty<*>): V = lock.withLock {
|
||||
mutableDelegatedField.getValue(thisRef, property)
|
||||
delegatedField.getValue(thisRef, property)
|
||||
}
|
||||
|
||||
override fun setValue(thisRef: T, property: KProperty<*>, value: V) = lock.withLock {
|
||||
mutableDelegatedField.setValue(thisRef, property, value)
|
||||
delegatedField.setValue(thisRef, property, value)
|
||||
}
|
||||
|
||||
override fun valueOnSet(thisRef: T, property: KProperty<*>, value: V, oldValue: V) = lock.withLock {
|
||||
mutableDelegatedField.valueOnSet(thisRef, property, value, oldValue)
|
||||
delegatedField.valueOnSet(thisRef, property, value, oldValue)
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@ package cn.tursom.core.delegation
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
open class MutableDelegatedFieldValue<in T, V>(
|
||||
private var initValue: V
|
||||
private var initValue: V,
|
||||
) : MutableDelegatedField<T, V> {
|
||||
override fun getValue(): V = initValue
|
||||
override fun getValue(thisRef: T, property: KProperty<*>): V = initValue
|
||||
|
@ -1,7 +1,27 @@
|
||||
package cn.tursom.core.delegation
|
||||
|
||||
import cn.tursom.core.cast
|
||||
import cn.tursom.core.uncheckedCast
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
class NotNullDelegatedField<in T, out V : Any>(
|
||||
override val delegatedField: DelegatedField<T, V?>,
|
||||
) : DelegatedField<T, V> by delegatedField.cast(), DecoratorDelegatedField<T, V?>
|
||||
val ifNull: () -> Nothing = { throw NullPointerException() },
|
||||
) : DelegatedField<T, V> by delegatedField.uncheckedCast(), DecoratorDelegatedField<T, V?> {
|
||||
override fun getValue(): V {
|
||||
val value = delegatedField.getValue()
|
||||
if (value == null) {
|
||||
ifNull()
|
||||
} else {
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
override fun getValue(thisRef: T, property: KProperty<*>): V {
|
||||
val value = delegatedField.getValue(thisRef, property)
|
||||
if (value == null) {
|
||||
ifNull()
|
||||
} else {
|
||||
return value
|
||||
}
|
||||
}
|
||||
}
|
@ -1,8 +1,28 @@
|
||||
package cn.tursom.core.delegation
|
||||
|
||||
import cn.tursom.core.cast
|
||||
import cn.tursom.core.uncheckedCast
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
class NotNullMutableDelegatedField<in T, V : Any>(
|
||||
override val mutableDelegatedField: MutableDelegatedField<T, V?>,
|
||||
) : MutableDelegatedField<T, V> by mutableDelegatedField.cast(), DecoratorMutableDelegatedField<T, V?>
|
||||
override val delegatedField: MutableDelegatedField<T, V?>,
|
||||
val ifNull: () -> Nothing = { throw NullPointerException() },
|
||||
) : MutableDelegatedField<T, V> by delegatedField.uncheckedCast(), DecoratorMutableDelegatedField<T, V?> {
|
||||
override fun getValue(): V {
|
||||
val value = delegatedField.getValue()
|
||||
if (value == null) {
|
||||
ifNull()
|
||||
} else {
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
override fun getValue(thisRef: T, property: KProperty<*>): V {
|
||||
val value = delegatedField.getValue(thisRef, property)
|
||||
if (value == null) {
|
||||
ifNull()
|
||||
} else {
|
||||
return value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,9 +7,9 @@ import kotlin.concurrent.write
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
class ReadWriteLockMutableDelegatedField<in T, V>(
|
||||
override val mutableDelegatedField: MutableDelegatedField<T, V>,
|
||||
override val delegatedField: MutableDelegatedField<T, V>,
|
||||
private val readWriteLock: ReadWriteLock = ReentrantReadWriteLock(),
|
||||
) : MutableDelegatedField<T, V> by mutableDelegatedField, DecoratorMutableDelegatedField<T, V> {
|
||||
) : MutableDelegatedField<T, V> by delegatedField, DecoratorMutableDelegatedField<T, V> {
|
||||
constructor(
|
||||
initValue: V,
|
||||
readWriteLock: ReadWriteLock = ReentrantReadWriteLock(),
|
||||
@ -19,7 +19,7 @@ class ReadWriteLockMutableDelegatedField<in T, V>(
|
||||
val rl = readWriteLock.readLock()
|
||||
rl.lock()
|
||||
try {
|
||||
return mutableDelegatedField.getValue(thisRef, property)
|
||||
return delegatedField.getValue(thisRef, property)
|
||||
} finally {
|
||||
rl.unlock()
|
||||
}
|
||||
@ -27,17 +27,17 @@ class ReadWriteLockMutableDelegatedField<in T, V>(
|
||||
|
||||
override fun setValue(thisRef: T, property: KProperty<*>, value: V) {
|
||||
if (readWriteLock is ReentrantReadWriteLock) readWriteLock.write {
|
||||
mutableDelegatedField.setValue(thisRef, property, value)
|
||||
delegatedField.setValue(thisRef, property, value)
|
||||
} else readWriteLock.writeLock().withLock {
|
||||
mutableDelegatedField.setValue(thisRef, property, value)
|
||||
delegatedField.setValue(thisRef, property, value)
|
||||
}
|
||||
}
|
||||
|
||||
override fun valueOnSet(thisRef: T, property: KProperty<*>, value: V, oldValue: V) {
|
||||
if (readWriteLock is ReentrantReadWriteLock) readWriteLock.write {
|
||||
mutableDelegatedField.valueOnSet(thisRef, property, value, oldValue)
|
||||
delegatedField.valueOnSet(thisRef, property, value, oldValue)
|
||||
} else readWriteLock.writeLock().withLock {
|
||||
mutableDelegatedField.setValue(thisRef, property, value)
|
||||
delegatedField.setValue(thisRef, property, value)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
package cn.tursom.core.delegation
|
||||
|
||||
import cn.tursom.core.getFieldForAll
|
||||
import cn.tursom.core.uncheckedCast
|
||||
import java.lang.reflect.Field
|
||||
|
||||
class ReflectionDelegatedField<in T, V>(
|
||||
private val receiver: T,
|
||||
private val field: Field,
|
||||
) : MutableDelegatedField<T, V> {
|
||||
init {
|
||||
field.isAccessible = true
|
||||
}
|
||||
|
||||
override fun getValue(): V = field.get(receiver).uncheckedCast()
|
||||
|
||||
override fun setValue(value: V) {
|
||||
field.set(receiver, value)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun <T : Any, V> T.superField(
|
||||
fieldName: String,
|
||||
): MutableDelegatedField<T, V> {
|
||||
return ReflectionDelegatedField(this, this.javaClass.getFieldForAll(fieldName)!!)
|
||||
}
|
||||
|
||||
fun <T, V> T.field(
|
||||
field: Field,
|
||||
): MutableDelegatedField<T, V> {
|
||||
return ReflectionDelegatedField(this, field)
|
||||
}
|
||||
|
||||
fun <T, V> T.field(
|
||||
field: Field,
|
||||
type: V,
|
||||
): MutableDelegatedField<T, V> {
|
||||
return ReflectionDelegatedField(this, field)
|
||||
}
|
||||
|
||||
inline fun <T, V> T.field(
|
||||
field: Field,
|
||||
type: () -> V,
|
||||
): MutableDelegatedField<T, V> {
|
||||
return ReflectionDelegatedField(this, field)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,10 +3,10 @@ package cn.tursom.core.delegation
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
class SetterMutableDelegatedField<T, V>(
|
||||
override val mutableDelegatedField: MutableDelegatedField<T, V>,
|
||||
override val delegatedField: MutableDelegatedField<T, V>,
|
||||
val setter: MutableDelegatedField<T, V>.(thisRef: T, property: KProperty<*>, value: V) -> Unit,
|
||||
) : MutableDelegatedField<T, V> by mutableDelegatedField, DecoratorMutableDelegatedField<T, V> {
|
||||
) : MutableDelegatedField<T, V> by delegatedField, DecoratorMutableDelegatedField<T, V> {
|
||||
override fun setValue(thisRef: T, property: KProperty<*>, value: V) {
|
||||
mutableDelegatedField.setter(thisRef, property, value)
|
||||
delegatedField.setter(thisRef, property, value)
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,29 @@
|
||||
package cn.tursom.core.delegation
|
||||
|
||||
import cn.tursom.core.SimpThreadLocal
|
||||
import cn.tursom.core.uncheckedCast
|
||||
import kotlin.reflect.KProperty0
|
||||
|
||||
|
||||
class SimpThreadLocalMutableDelegatedField<in T, V>(
|
||||
private val threadLocal: SimpThreadLocal<V>,
|
||||
val new: () -> V
|
||||
class SimpThreadLocalMutableDelegatedField<in T, V : Any>(
|
||||
private val threadLocal: SimpThreadLocal<V>,
|
||||
) : MutableDelegatedField<T, V> {
|
||||
constructor(new: () -> V) : this(SimpThreadLocal(new = new), new)
|
||||
constructor(new: () -> V) : this(SimpThreadLocal(new = new))
|
||||
|
||||
override fun setValue(value: V) = threadLocal.set(value)
|
||||
override fun getValue(): V = threadLocal.get()
|
||||
|
||||
override fun <K> get(key: DelegatedFieldAttachmentKey<K>): K? {
|
||||
return if (key == Companion || key == ThreadLocalMutableDelegatedField) {
|
||||
threadLocal.uncheckedCast()
|
||||
} else {
|
||||
super.get(key)
|
||||
}
|
||||
}
|
||||
|
||||
override fun setValue(value: V) = threadLocal.set(value)
|
||||
override fun getValue(): V = threadLocal.get()
|
||||
|
||||
companion object : DelegatedFieldAttachmentKey<SimpThreadLocal<*>> {
|
||||
fun <T : Any> getKey() = this.uncheckedCast<DelegatedFieldAttachmentKey<SimpThreadLocal<T>>>()
|
||||
fun <T : Any> getKey(property: KProperty0<T>) =
|
||||
this.uncheckedCast<DelegatedFieldAttachmentKey<SimpThreadLocal<T>>>()
|
||||
}
|
||||
}
|
@ -1,8 +1,25 @@
|
||||
package cn.tursom.core.delegation
|
||||
|
||||
import cn.tursom.core.uncheckedCast
|
||||
import kotlin.reflect.KProperty0
|
||||
|
||||
class ThreadLocalMutableDelegatedField<in T, V>(
|
||||
private val threadLocal: ThreadLocal<V?> = ThreadLocal()
|
||||
private val threadLocal: ThreadLocal<V?> = ThreadLocal(),
|
||||
) : MutableDelegatedField<T, V?> {
|
||||
override fun setValue(value: V?) = threadLocal.set(value)
|
||||
override fun getValue(): V? = threadLocal.get()
|
||||
|
||||
override fun <K> get(key: DelegatedFieldAttachmentKey<K>): K? {
|
||||
return if (key == Companion) {
|
||||
threadLocal.uncheckedCast()
|
||||
} else {
|
||||
super.get(key)
|
||||
}
|
||||
}
|
||||
|
||||
override fun setValue(value: V?) = threadLocal.set(value)
|
||||
override fun getValue(): V? = threadLocal.get()
|
||||
|
||||
companion object : DelegatedFieldAttachmentKey<ThreadLocal<*>> {
|
||||
fun <T> getKey() = this.uncheckedCast<DelegatedFieldAttachmentKey<ThreadLocal<T>>>()
|
||||
fun <T> getKey(property: KProperty0<T>) = this.uncheckedCast<DelegatedFieldAttachmentKey<ThreadLocal<T>>>()
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package cn.tursom.core.delegation
|
||||
|
||||
class UnmonitoredFieldException : Exception {
|
||||
constructor() : super()
|
||||
constructor(message: String?) : super(message)
|
||||
constructor(message: String?, cause: Throwable?) : super(message, cause)
|
||||
constructor(cause: Throwable?) : super(cause)
|
||||
constructor(message: String?, cause: Throwable?, enableSuppression: Boolean, writableStackTrace: Boolean) : super(message, cause, enableSuppression, writableStackTrace)
|
||||
}
|
@ -2,10 +2,8 @@
|
||||
|
||||
package cn.tursom.core.delegation
|
||||
|
||||
import cn.tursom.core.SimpThreadLocal
|
||||
import cn.tursom.core.cast
|
||||
import cn.tursom.core.castOrNull
|
||||
import cn.tursom.core.receiver
|
||||
import cn.tursom.core.*
|
||||
import java.util.concurrent.ConcurrentLinkedQueue
|
||||
import java.util.concurrent.Executor
|
||||
import java.util.concurrent.locks.Lock
|
||||
import java.util.concurrent.locks.ReadWriteLock
|
||||
@ -19,26 +17,37 @@ import kotlin.reflect.full.memberProperties
|
||||
import kotlin.reflect.jvm.isAccessible
|
||||
|
||||
fun getDelegate(obj: Any?, field: String): DelegatedField<*, *>? {
|
||||
obj ?: return null
|
||||
val kProperty1 = obj.javaClass.kotlin.memberProperties.firstOrNull { it.name == field }
|
||||
kProperty1?.isAccessible = true
|
||||
val delegate = kProperty1?.getDelegate(obj)
|
||||
return delegate.castOrNull()
|
||||
obj ?: return null
|
||||
val kProperty1 = obj.javaClass.kotlin.memberProperties.firstOrNull { it.name == field }
|
||||
kProperty1?.isAccessible = true
|
||||
val delegate = kProperty1?.getDelegate(obj)
|
||||
return delegate.castOrNull()
|
||||
}
|
||||
|
||||
val <V> KProperty0<V>.getOwnerDelegated: DelegatedField<*, V>?
|
||||
get() = getDelegate(receiver, name).castOrNull()
|
||||
get() = getDelegate(receiver, name).castOrNull()
|
||||
|
||||
/**
|
||||
* 获取委托过后的值
|
||||
* 不会触发getter方法
|
||||
*/
|
||||
val <V> KProperty0<V>.getDelegatedValue: V?
|
||||
get() {
|
||||
val delegate = getDelegate() ?: getOwnerDelegated
|
||||
return delegate?.castOrNull<DelegatedField<*, V>>()?.getValue()
|
||||
}
|
||||
get() {
|
||||
val delegate = getDelegate() ?: getOwnerDelegated
|
||||
return delegate?.castOrNull<DelegatedField<*, V>>()?.getValue()
|
||||
}
|
||||
|
||||
fun <V> KProperty0<*>.getDelegatedAttachmentValue(key: DelegatedFieldAttachmentKey<V>): V? {
|
||||
val delegated = getOwnerDelegated ?: return null
|
||||
return delegated[key]
|
||||
}
|
||||
|
||||
operator fun <V> KProperty0<*>.get(key: DelegatedFieldAttachmentKey<V>): V? = getDelegatedAttachmentValue(key)
|
||||
|
||||
fun <V> KProperty0<V>.setDelegatedValue(value: V): Boolean {
|
||||
val delegate = getDelegate() ?: getOwnerDelegated
|
||||
delegate.castOrNull<MutableDelegatedField<*, V>>()?.setValue(value) ?: return false
|
||||
return true
|
||||
val delegate = getDelegate() ?: getOwnerDelegated
|
||||
delegate.castOrNull<MutableDelegatedField<*, V>>()?.setValue(value) ?: return false
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
@ -46,50 +55,170 @@ fun <V> KProperty0<V>.setDelegatedValue(value: V): Boolean {
|
||||
*/
|
||||
fun <T, V> T.delegated(value: V): MutableDelegatedField<T, V> = MutableDelegatedFieldValue(value)
|
||||
fun <T, V> T.delegated(@Suppress("UNUSED_PARAMETER") target: T, value: V): MutableDelegatedField<T, V> =
|
||||
MutableDelegatedFieldValue(value)
|
||||
MutableDelegatedFieldValue(value)
|
||||
|
||||
val <V> KProperty0<V>.delegated: DelegatedField<Any, V> get() = KPropertyDelegatedField(this)
|
||||
val <V> KMutableProperty0<V>.delegated: MutableDelegatedField<Any, V> get() = KPropertyMutableDelegatedField(this)
|
||||
val <V : Any> KProperty0<V?>.delegatedNotNull get() = delegated.notNull
|
||||
val <V : Any> KMutableProperty0<out V?>.delegatedNotNull: MutableDelegatedField<Any, V> get() = delegated.notNull
|
||||
fun <V : Any> KProperty0<V?>.delegatedNotNull(ifNull: () -> Nothing) = delegated.notNull(ifNull)
|
||||
fun <V : Any> KMutableProperty0<out V?>.delegatedNotNull(ifNull: () -> Nothing): MutableDelegatedField<Any, V> =
|
||||
delegated.notNull(ifNull)
|
||||
|
||||
val <T, V : Any> DelegatedField<T, V?>.notNull: DelegatedField<T, V> get() = NotNullDelegatedField(this)
|
||||
val <T, V : Any> MutableDelegatedField<T, out V?>.notNull: MutableDelegatedField<T, V>
|
||||
get() = NotNullMutableDelegatedField(cast())
|
||||
get() = NotNullMutableDelegatedField(uncheckedCast())
|
||||
|
||||
fun <T, V : Any> DelegatedField<T, V?>.notNull(ifNull: () -> Nothing): DelegatedField<T, V> =
|
||||
NotNullDelegatedField(this, ifNull)
|
||||
|
||||
fun <T, V : Any> MutableDelegatedField<T, out V?>.notNull(ifNull: () -> Nothing): MutableDelegatedField<T, V> =
|
||||
NotNullMutableDelegatedField(uncheckedCast(), ifNull)
|
||||
|
||||
val <T, V> MutableDelegatedField<T, V>.locked: MutableDelegatedField<T, V> get() = LockMutableDelegatedField(this)
|
||||
fun <T, V> MutableDelegatedField<T, V>.locked(lock: Lock = ReentrantLock()): MutableDelegatedField<T, V> =
|
||||
LockMutableDelegatedField(this, lock)
|
||||
LockMutableDelegatedField(this, lock)
|
||||
|
||||
val <T, V> MutableDelegatedField<T, V>.readWriteLocked: MutableDelegatedField<T, V>
|
||||
get() = ReadWriteLockMutableDelegatedField(this)
|
||||
get() = ReadWriteLockMutableDelegatedField(this)
|
||||
|
||||
fun <T, V> MutableDelegatedField<T, V>.readWriteLocked(readWriteLock: ReadWriteLock = ReentrantReadWriteLock()): MutableDelegatedField<T, V> =
|
||||
ReadWriteLockMutableDelegatedField(this, readWriteLock)
|
||||
ReadWriteLockMutableDelegatedField(this, readWriteLock)
|
||||
|
||||
|
||||
fun <T, V> ThreadLocal<V?>.delegated(): MutableDelegatedField<T, V?> = ThreadLocalMutableDelegatedField(this)
|
||||
fun <T, V> T.delegated(
|
||||
threadLocal: ThreadLocal<V?>,
|
||||
): MutableDelegatedField<T, V?> = ThreadLocalMutableDelegatedField(threadLocal)
|
||||
|
||||
fun <T, V> T.threadLocalDelegated(): MutableDelegatedField<T, V?> = ThreadLocalMutableDelegatedField()
|
||||
fun <T, V> T.threadLocalDelegated(type: Class<V>): MutableDelegatedField<T, V?> = ThreadLocalMutableDelegatedField()
|
||||
fun <T, V : Any> T.threadLocalDelegated(type: KClass<V>): MutableDelegatedField<T, V?> =
|
||||
ThreadLocalMutableDelegatedField()
|
||||
fun <T, V> T.threadLocalDelegated(type: V?): MutableDelegatedField<T, V?> = ThreadLocalMutableDelegatedField()
|
||||
fun <T, V> T.threadLocalDelegated(type: Class<out V?>): MutableDelegatedField<T, V?> =
|
||||
ThreadLocalMutableDelegatedField()
|
||||
|
||||
fun <T, V> T.threadLocalDelegated(new: () -> V): MutableDelegatedField<T, V> = SimpThreadLocalMutableDelegatedField(new)
|
||||
fun <T, V> T.threadLocalDelegated(simpThreadLocal: SimpThreadLocal<V>, new: () -> V): MutableDelegatedField<T, V> =
|
||||
SimpThreadLocalMutableDelegatedField(simpThreadLocal, new)
|
||||
fun <T, V : Any> T.threadLocalDelegated(type: KClass<V>): MutableDelegatedField<T, V?> =
|
||||
ThreadLocalMutableDelegatedField()
|
||||
|
||||
fun <T, V : Any> SimpThreadLocal<V>.delegated(): MutableDelegatedField<T, V> =
|
||||
SimpThreadLocalMutableDelegatedField(this)
|
||||
|
||||
fun <T, V : Any> T.threadLocalDelegated(
|
||||
threadLocal: ThreadLocal<V?> = ThreadLocal(),
|
||||
new: () -> V,
|
||||
): MutableDelegatedField<T, V> = SimpThreadLocalMutableDelegatedField(SimpThreadLocal(threadLocal, new))
|
||||
//fun <T, V> T.threadLocalDelegated(simpThreadLocal: SimpThreadLocal<V>): MutableDelegatedField<T, V> =
|
||||
// SimpThreadLocalMutableDelegatedField(simpThreadLocal)
|
||||
|
||||
fun <T, V> MutableDelegatedField<T, V>.filter(filter: T.(old: V, new: V) -> Boolean): MutableDelegatedField<T, V> =
|
||||
FilterDelegatedField(this, filter)
|
||||
FilterDelegatedField(this, filter)
|
||||
|
||||
fun <T, V> DelegatedField<T, V>.setter(setter: DelegatedField<T, V>.(value: V) -> Unit): DelegatedField<T, V> =
|
||||
SetterDelegatedField(this, setter)
|
||||
SetterDelegatedField(this, setter)
|
||||
|
||||
fun <T, V> MutableDelegatedField<T, V>.setter(setter: MutableDelegatedField<T, V>.(thisRef: T, property: KProperty<*>, value: V) -> Unit): MutableDelegatedField<T, V> =
|
||||
SetterMutableDelegatedField(this, setter)
|
||||
SetterMutableDelegatedField(this, setter)
|
||||
|
||||
fun <T, V> DelegatedField<T, V>.getter(getter: DelegatedField<T, V>.(thisRef: T, property: KProperty<*>) -> V): DelegatedField<T, V> =
|
||||
GetterDelegatedField(this, getter)
|
||||
GetterDelegatedField(this, getter)
|
||||
|
||||
fun <T, V> MutableDelegatedField<T, V>.getter(getter: MutableDelegatedField<T, V>.(thisRef: T, property: KProperty<*>) -> V): MutableDelegatedField<T, V> =
|
||||
GetterMutableDelegatedField(this, getter)
|
||||
GetterMutableDelegatedField(this, getter)
|
||||
|
||||
fun <T, V> MutableDelegatedField<T, V>.withExecutor(executor: Executor): MutableDelegatedField<T, V> =
|
||||
ExecutorMutableDelegatedField(this, executor)
|
||||
ExecutorMutableDelegatedField(this, executor)
|
||||
|
||||
@Listenable
|
||||
fun <V> KMutableProperty0<V>.listenable(): MutableDelegatedField<Any, V> {
|
||||
isAccessible = true
|
||||
val delegate = getDelegate()
|
||||
return if (delegate is MutableDelegatedField<*, *> && delegate[ListenableMutableDelegatedField] == true) {
|
||||
@OptIn(UncheckedCast::class)
|
||||
delegate.cast()
|
||||
} else {
|
||||
@OptIn(UncheckedCast::class)
|
||||
(ListenableMutableDelegatedField(KPropertyMutableDelegatedField(cast())))
|
||||
}
|
||||
}
|
||||
|
||||
@Listenable
|
||||
fun <V> listenable(initValue: V): MutableDelegatedField<Any, V> = ListenableMutableDelegatedField(
|
||||
MutableDelegatedFieldValue(initValue)
|
||||
)
|
||||
|
||||
@Listenable
|
||||
fun <T, V> MutableDelegatedField<T, V>.listenable(): MutableDelegatedField<T, V> =
|
||||
ListenableMutableDelegatedField(this)
|
||||
|
||||
@JvmName("listenable1")
|
||||
@Listenable
|
||||
fun <T, V> listenable(delegatedField: MutableDelegatedField<T, V>): MutableDelegatedField<T, V> =
|
||||
ListenableMutableDelegatedField(delegatedField)
|
||||
|
||||
|
||||
infix operator fun <T, V> ListenableListener<T, V>.plus(listener: T.(old: V, new: V) -> Unit): Listener<T, V> =
|
||||
addListener(listener)
|
||||
|
||||
@OptIn(Listenable::class)
|
||||
fun <V> KProperty0<V>.getListenableMutableDelegatedField(): ListenableMutableDelegatedField<Any, V>? {
|
||||
isAccessible = true
|
||||
var delegate = getDelegate() ?: getDelegate(receiver, name)
|
||||
if (delegate is DelegatedField<*, *>) {
|
||||
while (true) {
|
||||
if (delegate is ListenableMutableDelegatedField<*, *>) {
|
||||
@OptIn(UncheckedCast::class)
|
||||
return delegate.cast()
|
||||
}
|
||||
if (delegate is DecoratorDelegatedField<*, *>) {
|
||||
delegate = delegate.delegatedField
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
} else if (delegate is KProperty0<*> && delegate != this) {
|
||||
@OptIn(UncheckedCast::class)
|
||||
return delegate.cast<KProperty0<V>>().getListenableMutableDelegatedField()
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
inline fun <T, V> T.addChangeListener(
|
||||
property: T.() -> KProperty0<V>,
|
||||
): ListenableListener<T, V> {
|
||||
val kProperty0 = property()
|
||||
|
||||
@OptIn(Listenable::class, UncheckedCast::class)
|
||||
val delegatedField = kProperty0
|
||||
.getListenableMutableDelegatedField()
|
||||
.cast<ListenableMutableDelegatedField<T, V>?>()
|
||||
?: throw UnmonitoredFieldException(kProperty0.toString())
|
||||
return object : ListenableListener<T, V> {
|
||||
private val selfList = ConcurrentLinkedQueue<Listener<T, V>>()
|
||||
override fun addListener(listener: T.(old: V, new: V) -> Unit): Listener<T, V> {
|
||||
@OptIn(Listenable::class)
|
||||
val listener1 = delegatedField.addListener(listener)
|
||||
selfList.add(listener1)
|
||||
return listener1
|
||||
}
|
||||
|
||||
override fun catch(handler: T.(old: V, new: V, e: Throwable) -> Unit): ListenableListener<T, V> {
|
||||
selfList.forEach {
|
||||
it.catch(handler)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
override fun cancel(): Boolean {
|
||||
selfList.forEach {
|
||||
it.cancel()
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun finally(handler: T.(old: V, new: V) -> Unit): Listener<T, V> {
|
||||
selfList.forEach {
|
||||
it.finally(handler)
|
||||
}
|
||||
return this
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user