KStateMachine / kstatemachine

KStateMachine is a Kotlin DSL library for creating state machines and statecharts.
https://kstatemachine.github.io/kstatemachine/
Boost Software License 1.0
339 stars 19 forks source link

Export to PlantUml: GuardedTransitionOnBuilder are not drawn in diagram #82

Closed oyanyev closed 4 months ago

oyanyev commented 5 months ago

When state transition is configured using GuardedTransitionOnBuilder, such a transition between states is not drawn in diagram

nsk90 commented 5 months ago

Yes this is known limitation of export implementation.

https://nsk90.github.io/kstatemachine/#plantuml:~:text=%5B!NOTE%5D%20Currently%20transitions,export%20is%20running.

To make it possible some code analysis should be executed at export moment. To understand all possible lambda result values. But even then it will not work at scale, only in some simple cases that could be solved without running a code to pass all possible branches inside lambda functions.

I thought about other possible solution, to allow a user provide some meta information about such lambdas (saying what states the function can return). This is simple, but requires manual control.

You can offer something else.

oyanyev commented 5 months ago

Sad, but true

oyanyev commented 5 months ago

Alternatively, can suggest solution which can work for me. I am using transitionOn to take data not from transition, but from another (not parent state). Current implementation forces to use data form event:

        if (this.parent == transitionParams.direction.targetState) {
            when (val event = transitionParams.event) {
                is DataEvent<*> -> assignData(event)               <=== 
                is WrappedEvent -> assignData(event.event)
                is FinishedEvent -> assign(dataExtractor.extractFinishedEvent(transitionParams, event))
                else -> assign(dataExtractor.extract(transitionParams))
            }

Will it have sense to use custom DataExtractor prior to assignData(event)? And defaultDataExtractor() will be used as a fallback only

when (val event = transitionParams.event) {
                is DataEvent<*> -> dataExtractor?.extract(transitionParams) ?: assignData(event)               <=== 
                is WrappedEvent -> assignData(event.event)
                is FinishedEvent -> assign(dataExtractor.extractFinishedEvent(transitionParams, event))
                else -> assign(defaultDataExtractor().extract(transitionParams))
            }
nsk90 commented 4 months ago

This is partly solved in https://github.com/nsk90/kstatemachine/releases/tag/v0.26.0 by unsafeCallConditionalLambdas flag