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

commonMain.pro.respawn.flowmvi.plugins.WhileSubscribedPlugin.kt Maven / Gradle / Ivy

Go to download

A Kotlin Multiplatform MVI library based on plugins that is simple, fast, powerful & flexible

There is a newer version: 3.0.0
Show newest version
package pro.respawn.flowmvi.plugins

import kotlinx.atomicfu.atomic
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import pro.respawn.flowmvi.api.FlowMVIDSL
import pro.respawn.flowmvi.api.MVIAction
import pro.respawn.flowmvi.api.MVIIntent
import pro.respawn.flowmvi.api.MVIState
import pro.respawn.flowmvi.api.PipelineContext
import pro.respawn.flowmvi.api.StorePlugin
import pro.respawn.flowmvi.dsl.StoreBuilder
import pro.respawn.flowmvi.dsl.plugin

/**
 * Create and install a new [whileSubscribed] plugin. See the parent's function docs for more info.
 */
@FlowMVIDSL
public inline fun  StoreBuilder.whileSubscribed(
    name: String? = null,
    minSubscriptions: Int = 1,
    crossinline block: suspend PipelineContext.() -> Unit,
): Unit = install(whileSubscribedPlugin(name, minSubscriptions, block))

/**
 *  Create a new plugin that invokes [block] the **first time** the store is being subscribed to.
 * Nothing is invoked when more subscribers appear, however, the block will be invoked again
 * if the first subscriber appears again.
 * The block will be canceled when the store is closed, **not** when the subscriber disappears.
 * You can safely suspend inside [block] as it's invoked asynchronously.
 * @see StorePlugin.onSubscribe
 */
@FlowMVIDSL
public inline fun  whileSubscribedPlugin(
    name: String? = null,
    minSubscriptions: Int = 1,
    crossinline block: suspend PipelineContext.() -> Unit,
): StorePlugin = plugin {
    this.name = name
    var job by atomic(null)
    onSubscribe { _, subscribers ->
        if (subscribers == minSubscriptions - 1) {
            job = launch { block() }
        }
    }
    onUnsubscribe { subscribers ->
        if (subscribers == minSubscriptions - 1) job?.cancel()
    }
}