Skip to content

Instantly share code, notes, and snippets.

@fvilarino
Last active April 12, 2021 23:28
Show Gist options
  • Save fvilarino/2f17ddce69dbce937c45af944e13ea9a to your computer and use it in GitHub Desktop.
Save fvilarino/2f17ddce69dbce937c45af944e13ea9a to your computer and use it in GitHub Desktop.
MVI ViewModel
/**
* Marker class for the view state
*/
interface State
/**
* Marker class for View Intents
*/
interface MviIntent
/**
* Marker class for the reducer actions
*/
interface ReduceAction
private const val FLOW_BUFFER_CAPACITY = 64
abstract class MviViewModel<S : State, I : MviIntent, R : ReduceAction>(
initialState: S
) : ViewModel() {
private val stateFlow = MutableStateFlow<S>(initialState)
val state: StateFlow<S> = stateFlow.asStateFlow()
private val intentFlow = MutableSharedFlow<I>(extraBufferCapacity = FLOW_BUFFER_CAPACITY)
private val reduceFlow = MutableSharedFlow<R>(extraBufferCapacity = FLOW_BUFFER_CAPACITY)
init {
intentFlow
.onEach { intent ->
executeIntent(intent)
}
.launchIn(viewModelScope)
reduceFlow
.onEach { action ->
stateFlow.value = reduce(stateFlow.value, action)
}
.launchIn(viewModelScope)
}
fun onIntent(mviIntent: I) {
intentFlow.tryEmit(mviIntent)
}
protected fun handle(reduceAction: R) {
reduceFlow.tryEmit(reduceAction)
}
protected abstract suspend fun executeIntent(mviIntent: I)
protected abstract fun reduce(state: S, reduceAction: R): S
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment