fgmacedo / python-statemachine

Python Finite State Machines made easy.
MIT License
906 stars 84 forks source link

Multiple sources in transitions #486

Closed andgineer closed 1 week ago

andgineer commented 2 weeks ago

Description

this is kind of not hard to read

success.to(in_progress, cond='is_running') |
    waiting.to(in_progress, cond='is_running') |
    null_state.to(in_progress, cond='is_running') |
    in_progress.to.itself(internal=True, cond='is_running')

but this is in fact very simple transition if we could use multiple states as transition source: (success | waiting | null_state | in_progress).to(in_progress, cond='is_running')

Maybe I miss something and we can simplify initial transition by other means? And using comprehension does not make it simpler because we have to connect the transitions with "|" operator

fgmacedo commented 2 weeks ago

Hi @andgineer , how are you?

I think that in this case a better construction is to use from_ instead of to, as the target is the same for all those transitions.

Something like this:

from statemachine import State, StateMachine

class StateMachineExample(StateMachine):

    waiting = State(initial=True)
    in_progress = State()
    success = State()
    null_state = State()

    is_running = True

    # your current declaration
    do_something = (
        success.to(in_progress, cond='is_running') |
        waiting.to(in_progress, cond='is_running') |
        null_state.to(in_progress, cond='is_running') |
        in_progress.to.itself(internal=True, cond='is_running')
    )

    # suggestion to use `from_` instead, I keep only the `internal` separated 
    do_something_simplified = in_progress.from_(
        success, waiting, null_state, cond='is_running'
    ) | in_progress.to.itself(internal=True, cond='is_running')

That do you think?

Best regards!

andgineer commented 1 week ago

that fully solve the issue, thank you

great package!