Skip to content

Instantly share code, notes, and snippets.

@LouisCAD
Last active September 5, 2018 10:48
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 LouisCAD/d9d1adbd3b4fd36d9dc121658fefd16f to your computer and use it in GitHub Desktop.
Save LouisCAD/d9d1adbd3b4fd36d9dc121658fefd16f to your computer and use it in GitHub Desktop.
import kotlinx.coroutines.experimental.channels.ConflatedChannel
import kotlinx.coroutines.experimental.channels.ReceiveChannel
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
abstract class ConflatedValues<CV : ConflatedValues<CV, T>, T> private constructor(
private val updateChannel: ConflatedChannel<T>,
private val conflateAll: CV.() -> T
) : ReceiveChannel<T> by updateChannel {
constructor(conflateAll: CV.() -> T) : this(ConflatedChannel(), conflateAll)
/** Can be called from a subclass method to perform an arbitrary update/refresh. */
protected fun triggerUpdate() {
@Suppress("UNCHECKED_CAST")
updateChannel.offer((this as CV).conflateAll())
}
protected fun <E> conflatedValue(initialValue: E): ReadWriteProperty<Any?, E> = Value(initialValue)
private inner class Value<E>(private var value: E) : ReadWriteProperty<Any?, E> {
override fun getValue(thisRef: Any?, property: KProperty<*>) = value
override fun setValue(thisRef: Any?, property: KProperty<*>, value: E) {
this.value = value // TODO: Allow optional ignore if values are equal
triggerUpdate()
}
}
init {
updateChannel.invokeOnClose { onClose() }
}
protected open fun onClose() = Unit
}
abstract class ConflatedUpdates<CV : ConflatedUpdates<CV>> : ConflatedValues<CV, Unit>({})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment