Reputation: 1
I've created a state machine defining it's states, events and transitions using KStateMachine
. When an event is sent to the state machine, the state is changed accordingly.
Since the UI has nothing to do with the state machine, it still needs to show elements based on the current state of the state machine
In the example below, how would I notify the UI that a state from the state machine has changed?
@Singleton
class StateManager() : IStateManager {
private var stateMachine: StateMachine? = null
init {
runBlocking {
startupMachine()
}
}
private suspend fun startupMachine() {
val scope = CoroutineScope(Dispatchers.IO)
stateMachine = createStateMachine(scope) {
addInitialState(State.Initializing)
addState(State.Starting) {
transition<Event.Initializing> {
targetState = State.Initializing
}
}
addState(State.Initializing) {
transition<Event.Initialized> {
targetState = State.Initialized
}
}
onStateEntry { state, _ ->
println("Received new state of $state")
}
}
}
override suspend fun processEvent(event: StateEvent) {
stateMachine!!.processEvent(event)
}
}
Upvotes: 0
Views: 350
Reputation: 330
You can use flow of states, it a built-in library feature.
This is a source code: https://github.com/KStateMachine/kstatemachine/blob/5f07bf4f850ee99630588b4bb03d24c5abac6337/kstatemachine-coroutines/src/commonMain/kotlin/ru/nsk/kstatemachine/statemachine/StateMachineFlow.kt#L95
Upvotes: 0
Reputation: 10175
You expose a StateFlow as a property, per the documentation:
class StateManager() : IStateManager {
private val _stateFlow: MutableStateFlow(State.Default)
val stateFlow = _stateFlow.asStateFlow()
...
You collect it wherever you care about it (in this case your UI), again, per the documentation
class YourUi {
fun startCollecting() {
myStateManager.stateFlow.collect {
updateUiWith(it)
}
}
}
And you "fire events" by updating the value:
onStateEntry { state, _ ->
println("Received new state of $state")
_stateFlow.value = state
}
Upvotes: 1