Junction

Junctions are graphical objects that enable branching of one transition to multiple transitions. Junctions enable developers to create highly efficient, readable and at the same time complex decision trees for their application.

Junctions are represented by a "circle" that can be dragged and dropped on the state machine chart.

A Junctions can be source or destination of transitions and the transitions that are connected to a junction are called Transition Branches. A chain of transitions that go from one state to another state is called a Transition Path, and or a transition path to be valid, the guards and conditions of all of its branches should be valid.

To put the Junctions in the coding terms, they are similar to nested if/else statements. Once a transition reaches a junction, the state machine evaluates the outgoing transitions of that junction, in order of their priorities until one transition is rendered valid. If no valid transition if found out of a junction, the path leading to that junction will be rendered invalid as well.

Use Cases

Junctions can be used to implement the following features.

  • Implementing for or while loops, by having transitions out of a Junction loop back to the Junction itself
  • Transition from multiple source state to one common destination state
  • Transition from one state to several destination states based on some conditions
  • Implementing self-loops, where exit and entry actions of a state are executed back-to-back in a single execution cycle

Execution

Lets assume the following state machine, where the "state1" is active and the state machine evaluates the connected transitions to determine if any one of the is valid:

the equivalent C code for this state machine is:

switch(active_state){
    case state1:
        if(c1){
            a1; //condition action
            if(c2){
                a2; //condition action
                b1; //transition action
                b2; //transition action
                state1_exit();
                state2_entry();
                active_state = state2;
            }else if(c3){
                a3;     //condition action
                if(c4){
                    a4; //condition action
                    b1; //transition action
                    b3; //transition action
                    b4; //transition action
                    state1_exit();
                    state2_entry();
                    active_state = state2;
                }
            }
        }else if(c5){
            a5; //condition action
            b5; //transition action
            state1_exit();
            state2_entry();
            active_state = state2;
        }else{
            state1_during();
        }
    case state2:
        ...
}

As you can see from the above code, the condition actions get executed immediately after the transition condition and guard (which is omitted here) are valid. However, the transition actions are executed one after another after the last branch of the path is rendered to be valid.

Also, the junctions create nested if statements (branching) and for for the state machine to go from one state to another, all the branches in one path should be valid, all at the same time.