Skip to content

Instantly share code, notes, and snippets.

@RoryKelly
Created December 9, 2020 22:09
Show Gist options
  • Save RoryKelly/d75b5b1f66a1c7cb74b12e7eb58075d9 to your computer and use it in GitHub Desktop.
Save RoryKelly/d75b5b1f66a1c7cb74b12e7eb58075d9 to your computer and use it in GitHub Desktop.
Kotlin Flow State Machine
fun <T> Flow<T>.stateMachine(configuration: StateChanges<T>.() -> Unit): Flow<StateChanges<T>> = flow {
var oldState: T? = null
distinctUntilChanged().collect { value ->
emit(StateChanges(oldState, value))
oldState = value
}
}.onEach {
configuration(it)
}
data class StateChanges<T>(val oldState: T? = null, val newState: T) {
@FlowPreview
@ExperimentalCoroutinesApi
inline fun <reified R : T> onEnter(enterBlock: () -> Unit) {
if (oldState !is R && newState is R) {
enterBlock()
}
}
@FlowPreview
@ExperimentalCoroutinesApi
inline fun <reified R : T> onReenter(enterBlock: () -> Unit) {
if (oldState is R && newState is R) {
enterBlock()
}
}
@FlowPreview
@ExperimentalCoroutinesApi
inline fun <reified R : T> onExit(enterBlock: () -> Unit) {
if (oldState is R && newState !is R) {
enterBlock()
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment