Created
October 8, 2020 09:01
-
-
Save gaplo917/73d72431c8e1a16590fd186522ce18dd to your computer and use it in GitHub Desktop.
Lazy Delegate Observable
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import kotlin.reflect.KProperty | |
fun someContextValueGetter(): Int { | |
println("Getting Context Value") | |
return 999 | |
} | |
abstract class LazyObs<T> : kotlin.properties.ReadWriteProperty<Any?, T> { | |
private val initialValue by lazy { provideInitialValue() } | |
private var value: T? = null | |
abstract fun provideInitialValue(): T | |
abstract fun onChange(property: KProperty<*>, oldValue: T, newValue: T): Unit | |
override fun getValue(thisRef: Any?, property: KProperty<*>): T { | |
val v = this.value | |
return if (v === null) { | |
this.value = initialValue | |
initialValue | |
} else { | |
v | |
} | |
} | |
override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) { | |
val v = this.value | |
if (v === null) { | |
this.value = initialValue | |
onChange(property, initialValue, value) | |
} else { | |
this.value = value | |
onChange(property, v, value) | |
} | |
} | |
} | |
fun <T : Any> lazyObservable( | |
initialValueProvider: () -> T, | |
onChange: (KProperty<*>, T, T) -> Unit | |
): kotlin.properties.ReadWriteProperty<Any?, T> { | |
return object: LazyObs<T>() { | |
override fun provideInitialValue(): T { | |
return initialValueProvider() | |
} | |
override fun onChange(property: KProperty<*>, oldValue: T, newValue: T) { | |
onChange(property, oldValue, newValue) | |
} | |
} | |
} | |
var changed = false | |
var lazyObs by lazyObservable<Int>(initialValueProvider = { | |
someContextValueGetter() | |
}){ _, oldValue, newValue -> | |
changed = true | |
println("onChanged from $oldValue to $newValue") | |
} | |
println("Context is initialized") | |
println(lazyObs) // 999 | |
println("onChanged is $changed") // false | |
lazyObs = 10 | |
println(lazyObs) // 10 | |
println("onChanged is $changed") // true | |
// The output | |
//Context is initialized | |
//Getting Context Value | |
//999 | |
//onChanged is false | |
//onChanged from 999 to 10 | |
//10 | |
//onChanged is true |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment