Skip to content

Instantly share code, notes, and snippets.

@fluidsonic
Last active December 30, 2019 14:17
Show Gist options
  • Save fluidsonic/2950322899188d7112200a681f02c5fe to your computer and use it in GitHub Desktop.
Save fluidsonic/2950322899188d7112200a681f02c5fe to your computer and use it in GitHub Desktop.
import kotlin.reflect.KProperty
import kotlin.reflect.KProperty0
import kotlin.reflect.jvm.isAccessible
class SomeClass {
var someProperty by observable(1)
}
fun main() {
val someObject = SomeClass()
someObject::someProperty.observe { new, old ->
println("Property has changed from $old to $new.")
}
someObject.someProperty = 5
// Property has changed from 1 to 5.
}
class ObservableProperty<T>(private var value: T) {
private val listeners = mutableListOf<(T, T) -> Unit>()
fun addListener(listener: (new: T, old: T) -> Unit) {
listeners += listener
}
operator fun getValue(thisRef: Any?, property: KProperty<*>) =
value
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
val oldValue = this.value
this.value = value
for (listener in listeners)
listener(value, oldValue)
}
}
fun <T> observable(initialValue: T) =
ObservableProperty(initialValue)
fun <T> KProperty0<T>.observe(listener: (new: T, old: T) -> Unit) {
isAccessible = true
(getDelegate() as ObservableProperty<T>).addListener(listener)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment