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

androidMain.tech.skot.view.live.SKLiveDataCommon.kt Maven / Gradle / Ivy

There is a newer version: 1.2.9
Show newest version
package tech.skot.view.live

abstract class SKLiveDataCommon(initialValue: D) {

    private var version = 0
    val observers: MutableSet = mutableSetOf()


    var value: D = initialValue
        protected set(newVal) {
            if (newVal != field) {
                field = newVal
                version++
                notify(newVal, version)
            }
        }

    init {
        notify(initialValue, version)
    }

    private var activeCount = 0
        set(value) {
            if (field == 0 && value > 0) {
                onActive()
            }
            if (value == 0 && field > 0) {
                onInactive()
            }
            field = value
        }

    //called on transition 0 active observer to 1
    protected open fun onActive() = Unit

    //called on transition 1 active observer to 0
    protected open fun onInactive() = Unit

    protected open fun hasActiveObserver() = activeCount > 0

    fun notify(newValue: D, newVersion: Int) {
        observers.forEach {
            it.notify(newValue, newVersion)
        }
    }


    abstract inner class Observer(val onChanged: (d: D) -> Unit) {
        var lastVersion = -1
        var mActive: Boolean = false
            set(value) {
                if (field != value) {
                    activeCount += if (value) 1 else -1
                }
                field = value
            }

        abstract fun shouldBeActive(): Boolean

        fun onBecomeActive() {
            mActive = true
            if (lastVersion < version) {

                onChanged([email protected])
                lastVersion = version
            }
        }

        fun onBecomeInactive() {
            mActive = false
        }

        fun onDestroy() {
            mActive = false
            observers.remove(this)
        }

        fun notify(value: D, valueVersion: Int) {
            if (!mActive) return
            if (!shouldBeActive()) {
                mActive = false
                return
            }
            if (lastVersion < valueVersion) {
                onChanged(value)
                lastVersion = valueVersion
            }
        }
    }

    inner class AlwaysObserver(
            onChanged: (d: D) -> Unit
    ) : Observer(onChanged) {
        override fun shouldBeActive() = true

        fun plug() {
            observeForEver(this)
        }

        fun unPug() {
            removeObserver(this)
        }
    }

    fun observeForEver(
            onChanged: (d: D) -> Unit
    ): AlwaysObserver {
        val observer = AlwaysObserver(onChanged)
        observeForEver(observer)
        return observer
    }

    fun makeAlwaysObserver(
            onChanged: (d: D) -> Unit
    ) = AlwaysObserver(onChanged)

    fun observeForEver(observer: AlwaysObserver) {
        observers.add(observer)
        observer.onBecomeActive()
    }

    fun removeObserver(observer: Observer) {
        observer.onBecomeInactive()
        observers.remove(observer)
    }

    fun debug() =
            "value: $value ${observers.size} observers dont ${observers.count { it.mActive }} actifs activeCount $activeCount"


}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy