Tinder / StateMachine

A Kotlin and Swift DSL for finite state machine
Other
1.98k stars 128 forks source link

Access all possible events from a certain state? #8

Open Rob117 opened 5 years ago

Rob117 commented 5 years ago

If this is confusing, please let me know.

Given the test code:

val stateMachine = StateMachine.create<State, Event, SideEffect> {
    initialState(State.Solid)
    state<State.Solid> {
        on<Event.OnMelted> {
            transitionTo(State.Liquid, SideEffect.LogMelted)
        }
    }
    state<State.Liquid> {
        on<Event.OnFroze> {
            transitionTo(State.Solid, SideEffect.LogFrozen)
        }
        on<Event.OnVaporized> {
            transitionTo(State.Gas, SideEffect.LogVaporized)
        }
    }
    state<State.Gas> {
        on<Event.OnCondensed> {
            transitionTo(State.Liquid, SideEffect.LogCondensed)
        }
    }
    onTransition {
        val validTransition = it as? StateMachine.Transition.Valid ?: return@onTransition
        when (validTransition.sideEffect) {
            SideEffect.LogMelted -> logger.log(ON_MELTED_MESSAGE)
            SideEffect.LogFrozen -> logger.log(ON_FROZEN_MESSAGE)
            SideEffect.LogVaporized -> logger.log(ON_VAPORIZED_MESSAGE)
            SideEffect.LogCondensed -> logger.log(ON_CONDENSED_MESSAGE)
        }
    }
}

I want to know how I could, for example, do stateMachine.validEventsFor(State.Liquid) // -> list(Event.OnFroze, event.OnVaporized)

Is there a way to do this, even with reflection?

zhxnlai commented 5 years ago

@Rob117 operations like stateMachine.validEventsFor(State.Liquid) // -> list(Event.OnFroze, event.OnVaporized) are not well supported because of the way state machine is implemented.

What state<State.Solid>, on<Event.OnCondensed>, on("A State"), and on("An Event") create are matchers, which are defined by a list of closures stored here.

Because the relationship between states and events is computed at runtime using closures, I don't think it is possible to extract all valid events for a state.

Rob117 commented 5 years ago

Got it. I statically defined an event list, and it worked for my use case. Thank you for your response though!