Extract State Do Actions

Hello! I’m trying to extract all “do actions” of each state of state machines that have a arbitrary nesting of states. What’s the best way of doing that? Here’s a simple example:

action def MyAction;

state def Behavior {

	state unpowered;
    
    state powered {
      do action {
      	myAction : MyAction;
        mySecondAction;
      }
      
      state startup {
      	do action {
        	myThirdAction;
        }
      }
      
	}
}

Each StateUsage exposes its do-action directly as .do_action (and .entry_action / .exit_action for the siblings), so you don’t have to walk StateSubactionMemberships and filter by kind yourself. The only thing you need to add is the recursion, since nested_states gives a state’s direct children only.

import syside

model, _ = syside.load_model(paths=["Behavior.sysml"])

for state in model.nodes(syside.StateUsage):
    do = state.do_action            # the do-action, or None
    if do is None:
        continue
    steps = [u.name for u in do.nested_usages]
    print(f"{state.qualified_name}: {steps}")

On your model this prints:

Behavior::powered: ['myAction', 'mySecondAction']
Behavior::powered::startup: ['myThirdAction']

do.nested_usages gives you the steps inside the do action { ... } block; do itself is the PerformActionUsage if you want the action node rather than its contents.