Closed nsk90 closed 1 year ago
This works great now, thank you!
Now I stumbled into the next thing I'm not sure how to resolve :) Perhaps you will have some ideas how to implement this or suggest a workaround.
The thing is that when I receive the FinishedEvent
I want to select targetState
and it can be either of FinalDataState
or a simple State
.
But currently I cannot do that because I handle FinishedEvent
by using transition
dsl builder and it doesn't allow me to set FinalDataState
as a targetState
, because it accepts only inheritors of State
.
The code may illustrate a bit better:
createStateMachine {
lateinit var state2: State
lateinit var finalDataState: FinalDataState<Int>
state("state1") {
initialState("state12") {
}
transitionOn<FinishedEvent> {
targetState = {
when(event.data as Result) {
Result.Success -> state2 // <-- this is State
Result.Error -> {
// somehow switch to FinalDataState and pass Int = 42 as data...???
finalDataState
}
}
}
}
}
state2 = state("state2")
finalDataState = finalDataState<Int>("final1")
}
What I tried:
dataTransition
and handle only Result.Error
in there, but I cannot use FinishedEvent
, because it is not a DataEvent
.Yeah, this is expected behaviour. I call it transition type-safety =)
You should be able to bypass it by using transitionConditionally
function to define transition. Please try it (there is no limitation to State subclasses)
But be careful. When you set DataState as a target of some transition, this transition currently must be triggered only by DataEvent
not just simple Event
. (or exception is thrown)
Generally speaking this limitation may be released as in recent library versions I have added defaultData
and lastData
to DataState
, so now technically it may be entered with any event type without exception (if default value was supplied).
So in your case FinalEvent is not DataEvent and I suppose you may see this exception error("$event does not contain data required by $this")
.
If everything works like I expect, I think exception may be replaced with usage of lastData
now, same like it is done for implicit DataState activation.
When we have sub-states and they have a
finalDataState
, when it is reached, I want to be somehow able to extract the data fromFinishedEvent
and depending on this data move to some other state in parent.Currently
FinishedEvent
is does not have adata
field. In xstate.js IIRC all events have "payload" field. In KStateMachine this is explicit:Event
andDataEvent
. MaybeFinishedEvent
can be data event? Or would this be not the right solution... I'm not sure, wanted to describe the usecase, maybe you'll be able to think of a nice solution.Here is the sample of what I have tried to do:
Originally posted by @dimsuz in https://github.com/nsk90/kstatemachine/issues/54#issuecomment-1271914942