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

commonMain.com.arkivanov.mvikotlin.rx.internal.BaseSubject.kt Maven / Gradle / Ivy

The newest version!
package com.arkivanov.mvikotlin.rx.internal

import com.arkivanov.mvikotlin.rx.Disposable
import com.arkivanov.mvikotlin.rx.Observer

internal open class BaseSubject : Subject {

    private val serializer = Serializer(::onEvent)
    private var observers: MutableMap>? = LinkedHashMap()

    override val isActive: Boolean get() = observers != null

    override fun subscribe(observer: Observer): Disposable {
        val disposable = Disposable { serializer.onNext(Event.OnDispose(this)) }
        serializer.onNext(Event.OnSubscribe(observer, disposable))

        return disposable
    }

    override fun onNext(value: T) {
        serializer.onNext(Event.OnNext(value))
    }

    override fun onComplete() {
        serializer.onNext(Event.OnComplete)
    }

    private fun onEvent(event: Event) {
        when (event) {
            is Event.OnSubscribe -> onSubscribeEvent(event.observer, event.disposable)
            is Event.OnNext -> onNextEvent(event.value)
            is Event.OnComplete -> onCompleteEvent()
            is Event.OnDispose -> onDisposeEvent(event.disposable)
        }.let {}
    }

    private fun onSubscribeEvent(observer: Observer, disposable: Disposable) {
        val currentObservers = observers
        if (currentObservers == null) {
            observer.onComplete()
            disposable.dispose()
        } else {
            currentObservers[disposable] = observer
            onAfterSubscribe(observer)
        }
    }

    protected open fun onAfterSubscribe(observer: Observer) {
    }

    private fun onNextEvent(value: T) {
        onBeforeNext(value)

        observers?.values?.forEach {
            it.onNext(value)
        }
    }

    protected open fun onBeforeNext(value: T) {
    }

    private fun onCompleteEvent() {
        observers?.forEach { (disposable, observer) ->
            observer.onComplete()
            disposable.dispose()
        }

        observers = null
    }

    private fun onDisposeEvent(disposable: Disposable) {
        observers?.remove(disposable)
    }

    private sealed class Event {
        class OnSubscribe(
            val observer: Observer,
            val disposable: Disposable
        ) : Event()

        class OnNext(val value: T) : Event()
        data object OnComplete : Event()
        class OnDispose(val disposable: Disposable) : Event()
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy