Untitled
unknown
kotlin
4 years ago
2.2 kB
12
Indexable
package com.voraapp.vora.base
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.launch
abstract class BaseViewModel<S : State, A : Action, E : Effect, H : ActionHandler<S, A>>(
private val actionHandler: H,
) : ViewModel() {
abstract val initialState: S
private val _states: MutableStateFlow<S> by lazy { MutableStateFlow(initialState) }
val states: StateFlow<S>
get() = _states
private val actions = Channel<A>()
val effects = Channel<E>()
fun offer(action: A) {
viewModelScope.launch {
actions.send(action)
}
}
@Suppress("UNCHECKED_CAST")
protected fun observeActions() {
viewModelScope.launch {
actions.receiveAsFlow().onEach {
when (val action = actionHandler.handle(states.value, it)) {
is EffectResult -> {
sendEffects(action.effects as List<E>)
}
is StateResult -> {
println("sinan: state: ${action.state}")
_states.emit(action.state as S)
}
}
}.collect()
}
}
private suspend fun sendEffects(effects: List<E>) {
effects.forEach {
this.effects.send(it)
}
}
}
abstract class ActionHandler<S : State, A : Action> {
abstract suspend fun handle(state: S, action: A): Result
}
fun <E : Effect> ActionHandler<*, *>.effect(e: E): Result = EffectResult(listOf(e))
fun <E : Effect> ActionHandler<*, *>.effects(e: List<E>): Result = EffectResult(e)
fun <S : State> ActionHandler<S, *>.state(s: S): Result = StateResult(s)
interface Action
interface State
interface Effect
sealed class Result
internal data class EffectResult(val effects: List<Effect>) : Result()
internal data class StateResult(val state: State) : Result()Editor is loading...