commonMain.org.brightify.hyperdrive.property.impl.MapDeferredObservableProperty.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.channels.BufferOverflow
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.first
import org.brightify.hyperdrive.CancellationToken
import org.brightify.hyperdrive.property.DeferredObservableProperty
import org.brightify.hyperdrive.property.ObservableProperty
import org.brightify.hyperdrive.utils.Optional
import org.brightify.hyperdrive.utils.map
import org.brightify.hyperdrive.utils.someOrDefault
internal class MapDeferredObservableProperty(
private val mapped: DeferredObservableProperty,
private val transform: (T) -> U,
private val equalityPolicy: ObservableProperty.EqualityPolicy,
): DeferredObservableProperty, DeferredObservableProperty.Listener {
private val listeners = ValueChangeListenerHandler(this)
override var latestValue: Optional = mapped.latestValue.map(transform)
private val valueFlow = MutableSharedFlow(extraBufferCapacity = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST)
init {
mapped.addListener(this)
}
override suspend fun await(): U = coroutineScope {
latestValue.someOrDefault {
nextValue()
}
}
override suspend fun nextValue(): U = coroutineScope {
valueFlow.first()
}
override fun valueDidChange(oldValue: Optional, newValue: T) {
val currentValue = latestValue
val newTransformedValue = transform(newValue)
if (currentValue is Optional.Some && equalityPolicy.isEqual(currentValue.value, newTransformedValue)) { return }
listeners.runNotifyingListeners(newTransformedValue) {
latestValue = Optional.Some(it)
valueFlow.tryEmit(it)
}
}
override fun addListener(listener: DeferredObservableProperty.Listener): CancellationToken = listeners.addListener(listener)
override fun removeListener(listener: DeferredObservableProperty.Listener) = listeners.removeListener(listener)
}