All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.noheltcj.rxcommon.operators.CombineLatest.kt Maven / Gradle / Ivy

package com.noheltcj.rxcommon.operators

import com.noheltcj.rxcommon.Source
import com.noheltcj.rxcommon.disposables.Disposable
import com.noheltcj.rxcommon.disposables.Disposables
import com.noheltcj.rxcommon.emitters.ColdEmitter
import com.noheltcj.rxcommon.emitters.Emitter
import com.noheltcj.rxcommon.observers.AllObserver
import com.noheltcj.rxcommon.observers.Observer

class CombineLatest(
    private val sourceOne: Source,
    private val sourceTwo: Source,
    private inline val transform: (S1, S2) -> R
) : Source {
  val emitter: Emitter = ColdEmitter {}

  override fun subscribe(observer: Observer): Disposable {
    emitter.addObserver(observer)

    var sourceOneLastElement: S1? = null
    var sourceTwoLastElement: S2? = null

    var completedOne = false

    fun onSourceCompleted() {
      if (!emitter.isDisposed && completedOne) {
        emitter.complete()
      } else {
        completedOne = true
      }
    }

    val upstreamOneDisposable = sourceOne.subscribe(
        AllObserver(
            onNext = {
              sourceOneLastElement = it
              sourceTwoLastElement?.run { emitter.next(transform(it, this)) }
            },
            onError = { emitter.terminate(it) },
            onComplete = { onSourceCompleted() }
        )
    )
    val upstreamTwoDisposable = sourceTwo.subscribe(
        AllObserver(
            onNext = {
              sourceTwoLastElement = it
              sourceOneLastElement?.run { emitter.next(transform(this, it)) }
            },
            onError = { emitter.terminate(it) },
            onComplete = { onSourceCompleted() }
        )
    )

    return Disposables.create {
      emitter.removeObserver(observer)
      upstreamOneDisposable.dispose()
      upstreamTwoDisposable.dispose()
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy