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

commonMain.pro.respawn.flowmvi.modules.ActionModule.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.modules

import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.consumeAsFlow
import kotlinx.coroutines.flow.receiveAsFlow
import pro.respawn.flowmvi.api.ActionProvider
import pro.respawn.flowmvi.api.ActionReceiver
import pro.respawn.flowmvi.api.ActionShareBehavior
import pro.respawn.flowmvi.api.DelicateStoreApi
import pro.respawn.flowmvi.api.MVIAction

internal interface ActionModule : ActionProvider, ActionReceiver

internal abstract class ChannelActionModule(
    bufferSize: Int,
    overflow: BufferOverflow,
) : ActionModule {

    protected val delegate = Channel(bufferSize, overflow)

    @DelicateStoreApi
    override fun send(action: A) {
        delegate.trySend(action)
    }
    override suspend fun emit(action: A) = delegate.send(action)
}

internal class DistributingModule(
    bufferSize: Int,
    overflow: BufferOverflow,
) : ChannelActionModule(bufferSize, overflow) {

    override val actions = delegate.receiveAsFlow()
}

internal class ConsumingModule(
    bufferSize: Int,
    overflow: BufferOverflow,
) : ChannelActionModule(bufferSize, overflow) {

    override val actions = delegate.consumeAsFlow()
}

internal class SharedModule(
    replay: Int,
    bufferSize: Int,
    overflow: BufferOverflow,
) : ActionModule {

    private val _actions = MutableSharedFlow(
        replay = replay,
        extraBufferCapacity = bufferSize,
        onBufferOverflow = overflow
    )

    override val actions = _actions.asSharedFlow()

    @DelicateStoreApi
    override fun send(action: A) {
        _actions.tryEmit(action)
    }

    override suspend fun emit(action: A) = _actions.emit(action)
}

internal class ThrowingModule : ActionModule {

    override val actions get() = error(ActionsDisabledMessage)

    @DelicateStoreApi
    override fun send(action: A) = error(ActionsDisabledMessage)
    override suspend fun emit(action: A) = error(ActionsDisabledMessage)

    private companion object {

        private const val ActionsDisabledMessage = "Actions are disabled for this store"
    }
}

internal fun  actionModule(
    behavior: ActionShareBehavior,
): ActionModule = when (behavior) {
    is ActionShareBehavior.Distribute -> DistributingModule(behavior.buffer, behavior.overflow)
    is ActionShareBehavior.Restrict -> ConsumingModule(behavior.buffer, behavior.overflow)
    is ActionShareBehavior.Share -> SharedModule(behavior.replay, behavior.buffer, behavior.overflow)
    is ActionShareBehavior.Disabled -> ThrowingModule()
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy