This commit is contained in:
tursom 2021-04-12 11:03:33 +08:00
parent 647d989aa1
commit b0cd840376
31 changed files with 585 additions and 125 deletions

View File

@ -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") {

View File

@ -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()
}
}

View File

@ -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)

View File

@ -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<*> 对应的对象
*/

View File

@ -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)
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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>
}

View File

@ -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
}

View File

@ -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)
}

View File

@ -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)
}
}

View File

@ -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))
}

View File

@ -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)
}
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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

View File

@ -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>
}

View File

@ -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
}
}
}
}

View File

@ -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>
}

View File

@ -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)
}
}

View File

@ -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

View File

@ -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
}
}
}

View File

@ -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
}
}
}

View File

@ -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)
}
}
}

View File

@ -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)
}
}
}

View File

@ -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)
}
}

View File

@ -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>>>()
}
}

View File

@ -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>>>()
}
}

View File

@ -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)
}

View File

@ -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
}
}
}