ru.hnau.jutils.producer.combine.CombineProducer.kt Maven / Gradle / Ivy
package ru.hnau.jutils.producer.combine
import ru.hnau.jutils.helpers.Box
import ru.hnau.jutils.helpers.toBox
import ru.hnau.jutils.producer.Producer
import ru.hnau.jutils.producer.StateProducer
import ru.hnau.jutils.producer.detacher.ProducerDetachers
abstract class CombineProducer(
private val producer1: Producer,
private val producer2: Producer
) : StateProducer() {
companion object {
fun create(
producer1: Producer,
producer2: Producer,
combiner: (P1, P2) -> R
): Producer = object : CombineProducer(
producer1,
producer2
) {
override fun combine(param1: P1, param2: P2) =
combiner.invoke(param1, param2)
}
}
private var param1: Box? = null
set(value) {
field = value
onParamReceived()
}
private var param2: Box? = null
set(value) {
field = value
onParamReceived()
}
private val detachers = ProducerDetachers()
private fun onParamReceived() = synchronized(this) {
val param1 = this.param1 ?: return
val param2 = this.param2 ?: return
val result = combine(param1.value, param2.value)
update(result)
}
protected abstract fun combine(param1: P1, param2: P2): R
override fun onFirstAttached() {
super.onFirstAttached()
producer1.attach(detachers) { param1 = it.toBox() }
producer2.attach(detachers) { param2 = it.toBox() }
}
override fun onLastDetached() {
super.onLastDetached()
detachers.detachAllAndClear()
}
}