commonMain.org.brightify.hyperdrive.property.impl.BindingObservableProperty.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of runtime Show documentation
Show all versions of runtime Show documentation
Hyperdrive implementation that's needed for observations and such
package org.brightify.hyperdrive.property.impl
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect
import org.brightify.hyperdrive.CancellationToken
import org.brightify.hyperdrive.Lifecycle
import org.brightify.hyperdrive.property.MutableObservableProperty
import org.brightify.hyperdrive.property.ObservableProperty
import org.brightify.hyperdrive.property.defaultEqualityPolicy
internal class BindingObservableProperty(
initialValue: T,
private val boundFlow: Flow,
lifecycle: Lifecycle,
private val equalityPolicy: ObservableProperty.EqualityPolicy = defaultEqualityPolicy(),
private val readMapping: (U) -> T,
private val setter: (T) -> Unit,
): MutableObservableProperty {
private var valueStorage: T = initialValue
override var value: T
get() = valueStorage
set(newValue) {
if (equalityPolicy.isEqual(value, newValue)) { return }
listeners.runNotifyingListeners(newValue) {
valueStorage = it
setter(it)
}
}
private val listeners = ValueChangeListenerHandler(this)
init {
lifecycle.whileAttached {
// TODO: We want to ignore changes we made. Equality policy should be enough, but we better do it smarter.
boundFlow.collect { newValue ->
val mappedNewValue = readMapping(newValue)
if (equalityPolicy.isEqual(value, mappedNewValue)) { return@collect }
listeners.runNotifyingListeners(mappedNewValue) {
valueStorage = it
}
}
}
}
override fun addListener(listener: ObservableProperty.Listener): CancellationToken = listeners.addListener(listener)
override fun removeListener(listener: ObservableProperty.Listener) = listeners.removeListener(listener)
}