Skip to content

Instantly share code, notes, and snippets.

@gaplo917
Created October 8, 2020 09:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gaplo917/73d72431c8e1a16590fd186522ce18dd to your computer and use it in GitHub Desktop.
Save gaplo917/73d72431c8e1a16590fd186522ce18dd to your computer and use it in GitHub Desktop.
Lazy Delegate Observable
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