Przeglądaj źródła

Added state configuration vector position to StateSwitch and create multiple state switches instead of one ( YAKHMI-447 )

terfloth@itemis.de 14 lat temu
rodzic
commit
b15e11f240

+ 11 - 12
plugins/org.yakindu.sct.generator.c/src/org/yakindu/sct/generator/c/templates/CustomStatemachineC.xpt

@@ -23,20 +23,19 @@ Templates for the main statechart c file.
 «ENDDEFINE»
 
 «DEFINE ActionCode FOR StateSwitch»
-«IF this.comment != null»
-/* «this.comment» */
-«ENDIF»
-	switch(((StatemachineBase*)«statemachineHandleName()»)->state[0/* TODO: must be set correctly */]) {
-«FOREACH this.cases AS caseid»
-  case _«caseid.state.simpleName» : {
-  «EXPAND ActionCode FOR caseid.step»
-  break;
-  }
+«IF this.comment != null -»
+	/* «this.comment» */
+«ENDIF -»
+	switch(((StatemachineBase*)«statemachineHandleName()»)->state[ «this.stateConfigurationIdx» ]) {
+«FOREACH this.cases AS caseid -»
+		case _«caseid.state.simpleName» : {
+«EXPAND ActionCode FOR caseid.step-»
+			break;
+		}
 «ENDFOREACH»
-  default:
-    break;
+		default: break;
 	}
-«ENDDEFINE»
+«ENDDEFINE »
 
 «DEFINE ActionCode FOR ScheduleTimeEvent»
 «IF this.comment != null»

+ 1 - 0
plugins/org.yakindu.sct.model.sexec.edit/plugin.properties

@@ -98,3 +98,4 @@ _UI_TraceStateEntered_state_feature = State
 _UI_TraceStateExited_state_feature = State
 _UI_TraceNodeExecuted_type = Trace Node Executed
 _UI_TraceNodeExecuted_node_feature = Node
+_UI_StateSwitch_stateConfigurationIdx_feature = State Configuration Idx

+ 28 - 0
plugins/org.yakindu.sct.model.sexec.edit/src/org/yakindu/sct/model/sexec/provider/StateSwitchItemProvider.java

@@ -15,12 +15,14 @@ import org.eclipse.emf.common.notify.Notification;
 
 import org.eclipse.emf.ecore.EStructuralFeature;
 
+import org.eclipse.emf.edit.provider.ComposeableAdapterFactory;
 import org.eclipse.emf.edit.provider.IEditingDomainItemProvider;
 import org.eclipse.emf.edit.provider.IItemLabelProvider;
 import org.eclipse.emf.edit.provider.IItemPropertyDescriptor;
 import org.eclipse.emf.edit.provider.IItemPropertySource;
 import org.eclipse.emf.edit.provider.IStructuredItemContentProvider;
 import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
+import org.eclipse.emf.edit.provider.ItemPropertyDescriptor;
 import org.eclipse.emf.edit.provider.ViewerNotification;
 
 import org.yakindu.sct.model.sexec.SexecFactory;
@@ -62,10 +64,33 @@ public class StateSwitchItemProvider
 		if (itemPropertyDescriptors == null) {
 			super.getPropertyDescriptors(object);
 
+			addStateConfigurationIdxPropertyDescriptor(object);
 		}
 		return itemPropertyDescriptors;
 	}
 
+	/**
+	 * This adds a property descriptor for the State Configuration Idx feature.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	protected void addStateConfigurationIdxPropertyDescriptor(Object object) {
+		itemPropertyDescriptors.add
+			(createItemPropertyDescriptor
+				(((ComposeableAdapterFactory)adapterFactory).getRootAdapterFactory(),
+				 getResourceLocator(),
+				 getString("_UI_StateSwitch_stateConfigurationIdx_feature"),
+				 getString("_UI_PropertyDescriptor_description", "_UI_StateSwitch_stateConfigurationIdx_feature", "_UI_StateSwitch_type"),
+				 SexecPackage.Literals.STATE_SWITCH__STATE_CONFIGURATION_IDX,
+				 true,
+				 false,
+				 false,
+				 ItemPropertyDescriptor.INTEGRAL_VALUE_IMAGE,
+				 null,
+				 null));
+	}
+
 	/**
 	 * This specifies how to implement {@link #getChildren} and is used to deduce an appropriate feature for an
 	 * {@link org.eclipse.emf.edit.command.AddCommand}, {@link org.eclipse.emf.edit.command.RemoveCommand} or
@@ -133,6 +158,9 @@ public class StateSwitchItemProvider
 		updateChildren(notification);
 
 		switch (notification.getFeatureID(StateSwitch.class)) {
+			case SexecPackage.STATE_SWITCH__STATE_CONFIGURATION_IDX:
+				fireNotifyChanged(new ViewerNotification(notification, notification.getNotifier(), false, true));
+				return;
 			case SexecPackage.STATE_SWITCH__CASES:
 				fireNotifyChanged(new ViewerNotification(notification, notification.getNotifier(), true, false));
 				return;

+ 2 - 0
plugins/org.yakindu.sct.model.sexec/model/sexec.ecore

@@ -111,6 +111,8 @@
   <eClassifiers xsi:type="ecore:EClass" name="StateSwitch" eSuperTypes="#//Step">
     <eStructuralFeatures xsi:type="ecore:EReference" name="cases" upperBound="-1"
         eType="#//StateCase" containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="stateConfigurationIdx"
+        eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt" defaultValueLiteral="0"/>
   </eClassifiers>
   <eClassifiers xsi:type="ecore:EClass" name="StateCase">
     <eStructuralFeatures xsi:type="ecore:EReference" name="state" eType="#//ExecutionState"/>

+ 29 - 1
plugins/org.yakindu.sct.model.sexec/src/org/yakindu/sct/model/sexec/SexecPackage.java

@@ -1288,6 +1288,15 @@ public interface SexecPackage extends EPackage {
 	 */
 	int STATE_SWITCH__CASES = STEP_FEATURE_COUNT + 0;
 
+	/**
+	 * The feature id for the '<em><b>State Configuration Idx</b></em>' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	int STATE_SWITCH__STATE_CONFIGURATION_IDX = STEP_FEATURE_COUNT + 1;
+
 	/**
 	 * The number of structural features of the '<em>State Switch</em>' class.
 	 * <!-- begin-user-doc -->
@@ -1295,7 +1304,7 @@ public interface SexecPackage extends EPackage {
 	 * @generated
 	 * @ordered
 	 */
-	int STATE_SWITCH_FEATURE_COUNT = STEP_FEATURE_COUNT + 1;
+	int STATE_SWITCH_FEATURE_COUNT = STEP_FEATURE_COUNT + 2;
 
 	/**
 	 * The meta object id for the '{@link org.yakindu.sct.model.sexec.impl.StateCaseImpl <em>State Case</em>}' class.
@@ -2168,6 +2177,17 @@ public interface SexecPackage extends EPackage {
 	 */
 	EReference getStateSwitch_Cases();
 
+	/**
+	 * Returns the meta object for the attribute '{@link org.yakindu.sct.model.sexec.StateSwitch#getStateConfigurationIdx <em>State Configuration Idx</em>}'.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the meta object for the attribute '<em>State Configuration Idx</em>'.
+	 * @see org.yakindu.sct.model.sexec.StateSwitch#getStateConfigurationIdx()
+	 * @see #getStateSwitch()
+	 * @generated
+	 */
+	EAttribute getStateSwitch_StateConfigurationIdx();
+
 	/**
 	 * Returns the meta object for class '{@link org.yakindu.sct.model.sexec.StateCase <em>State Case</em>}'.
 	 * <!-- begin-user-doc -->
@@ -2850,6 +2870,14 @@ public interface SexecPackage extends EPackage {
 		 */
 		EReference STATE_SWITCH__CASES = eINSTANCE.getStateSwitch_Cases();
 
+		/**
+		 * The meta object literal for the '<em><b>State Configuration Idx</b></em>' attribute feature.
+		 * <!-- begin-user-doc -->
+		 * <!-- end-user-doc -->
+		 * @generated
+		 */
+		EAttribute STATE_SWITCH__STATE_CONFIGURATION_IDX = eINSTANCE.getStateSwitch_StateConfigurationIdx();
+
 		/**
 		 * The meta object literal for the '{@link org.yakindu.sct.model.sexec.impl.StateCaseImpl <em>State Case</em>}' class.
 		 * <!-- begin-user-doc -->

+ 28 - 0
plugins/org.yakindu.sct.model.sexec/src/org/yakindu/sct/model/sexec/StateSwitch.java

@@ -17,6 +17,7 @@ import org.eclipse.emf.common.util.EList;
  * The following features are supported:
  * <ul>
  *   <li>{@link org.yakindu.sct.model.sexec.StateSwitch#getCases <em>Cases</em>}</li>
+ *   <li>{@link org.yakindu.sct.model.sexec.StateSwitch#getStateConfigurationIdx <em>State Configuration Idx</em>}</li>
  * </ul>
  * </p>
  *
@@ -41,4 +42,31 @@ public interface StateSwitch extends Step {
 	 */
 	EList<StateCase> getCases();
 
+	/**
+	 * Returns the value of the '<em><b>State Configuration Idx</b></em>' attribute.
+	 * The default value is <code>"0"</code>.
+	 * <!-- begin-user-doc -->
+	 * <p>
+	 * If the meaning of the '<em>State Configuration Idx</em>' attribute isn't clear,
+	 * there really should be more of a description here...
+	 * </p>
+	 * <!-- end-user-doc -->
+	 * @return the value of the '<em>State Configuration Idx</em>' attribute.
+	 * @see #setStateConfigurationIdx(int)
+	 * @see org.yakindu.sct.model.sexec.SexecPackage#getStateSwitch_StateConfigurationIdx()
+	 * @model default="0"
+	 * @generated
+	 */
+	int getStateConfigurationIdx();
+
+	/**
+	 * Sets the value of the '{@link org.yakindu.sct.model.sexec.StateSwitch#getStateConfigurationIdx <em>State Configuration Idx</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @param value the new value of the '<em>State Configuration Idx</em>' attribute.
+	 * @see #getStateConfigurationIdx()
+	 * @generated
+	 */
+	void setStateConfigurationIdx(int value);
+
 } // StateSwitch

+ 11 - 0
plugins/org.yakindu.sct.model.sexec/src/org/yakindu/sct/model/sexec/impl/SexecPackageImpl.java

@@ -779,6 +779,15 @@ public class SexecPackageImpl extends EPackageImpl implements SexecPackage {
 		return (EReference)stateSwitchEClass.getEStructuralFeatures().get(0);
 	}
 
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public EAttribute getStateSwitch_StateConfigurationIdx() {
+		return (EAttribute)stateSwitchEClass.getEStructuralFeatures().get(1);
+	}
+
 	/**
 	 * <!-- begin-user-doc -->
 	 * <!-- end-user-doc -->
@@ -1058,6 +1067,7 @@ public class SexecPackageImpl extends EPackageImpl implements SexecPackage {
 
 		stateSwitchEClass = createEClass(STATE_SWITCH);
 		createEReference(stateSwitchEClass, STATE_SWITCH__CASES);
+		createEAttribute(stateSwitchEClass, STATE_SWITCH__STATE_CONFIGURATION_IDX);
 
 		stateCaseEClass = createEClass(STATE_CASE);
 		createEReference(stateCaseEClass, STATE_CASE__STATE);
@@ -1217,6 +1227,7 @@ public class SexecPackageImpl extends EPackageImpl implements SexecPackage {
 
 		initEClass(stateSwitchEClass, StateSwitch.class, "StateSwitch", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS);
 		initEReference(getStateSwitch_Cases(), this.getStateCase(), null, "cases", null, 0, -1, StateSwitch.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
+		initEAttribute(getStateSwitch_StateConfigurationIdx(), ecorePackage.getEInt(), "stateConfigurationIdx", "0", 0, 1, StateSwitch.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
 
 		initEClass(stateCaseEClass, StateCase.class, "StateCase", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS);
 		initEReference(getStateCase_State(), this.getExecutionState(), null, "state", null, 0, 1, StateCase.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);

+ 69 - 0
plugins/org.yakindu.sct.model.sexec/src/org/yakindu/sct/model/sexec/impl/StateSwitchImpl.java

@@ -8,10 +8,12 @@ package org.yakindu.sct.model.sexec.impl;
 
 import java.util.Collection;
 
+import org.eclipse.emf.common.notify.Notification;
 import org.eclipse.emf.common.notify.NotificationChain;
 import org.eclipse.emf.common.util.EList;
 import org.eclipse.emf.ecore.EClass;
 import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.impl.ENotificationImpl;
 import org.eclipse.emf.ecore.util.EObjectContainmentEList;
 import org.eclipse.emf.ecore.util.InternalEList;
 import org.yakindu.sct.model.sexec.SexecPackage;
@@ -26,6 +28,7 @@ import org.yakindu.sct.model.sexec.StateSwitch;
  * The following features are implemented:
  * <ul>
  *   <li>{@link org.yakindu.sct.model.sexec.impl.StateSwitchImpl#getCases <em>Cases</em>}</li>
+ *   <li>{@link org.yakindu.sct.model.sexec.impl.StateSwitchImpl#getStateConfigurationIdx <em>State Configuration Idx</em>}</li>
  * </ul>
  * </p>
  *
@@ -42,6 +45,25 @@ public class StateSwitchImpl extends StepImpl implements StateSwitch {
 	 */
 	protected EList<StateCase> cases;
 
+	/**
+	 * The default value of the '{@link #getStateConfigurationIdx() <em>State Configuration Idx</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getStateConfigurationIdx()
+	 * @generated
+	 * @ordered
+	 */
+	protected static final int STATE_CONFIGURATION_IDX_EDEFAULT = 0;
+	/**
+	 * The cached value of the '{@link #getStateConfigurationIdx() <em>State Configuration Idx</em>}' attribute.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getStateConfigurationIdx()
+	 * @generated
+	 * @ordered
+	 */
+	protected int stateConfigurationIdx = STATE_CONFIGURATION_IDX_EDEFAULT;
+
 	/**
 	 * <!-- begin-user-doc -->
 	 * <!-- end-user-doc -->
@@ -73,6 +95,27 @@ public class StateSwitchImpl extends StepImpl implements StateSwitch {
 		return cases;
 	}
 
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public int getStateConfigurationIdx() {
+		return stateConfigurationIdx;
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public void setStateConfigurationIdx(int newStateConfigurationIdx) {
+		int oldStateConfigurationIdx = stateConfigurationIdx;
+		stateConfigurationIdx = newStateConfigurationIdx;
+		if (eNotificationRequired())
+			eNotify(new ENotificationImpl(this, Notification.SET, SexecPackage.STATE_SWITCH__STATE_CONFIGURATION_IDX, oldStateConfigurationIdx, stateConfigurationIdx));
+	}
+
 	/**
 	 * <!-- begin-user-doc -->
 	 * <!-- end-user-doc -->
@@ -97,6 +140,8 @@ public class StateSwitchImpl extends StepImpl implements StateSwitch {
 		switch (featureID) {
 			case SexecPackage.STATE_SWITCH__CASES:
 				return getCases();
+			case SexecPackage.STATE_SWITCH__STATE_CONFIGURATION_IDX:
+				return getStateConfigurationIdx();
 		}
 		return super.eGet(featureID, resolve, coreType);
 	}
@@ -114,6 +159,9 @@ public class StateSwitchImpl extends StepImpl implements StateSwitch {
 				getCases().clear();
 				getCases().addAll((Collection<? extends StateCase>)newValue);
 				return;
+			case SexecPackage.STATE_SWITCH__STATE_CONFIGURATION_IDX:
+				setStateConfigurationIdx((Integer)newValue);
+				return;
 		}
 		super.eSet(featureID, newValue);
 	}
@@ -129,6 +177,9 @@ public class StateSwitchImpl extends StepImpl implements StateSwitch {
 			case SexecPackage.STATE_SWITCH__CASES:
 				getCases().clear();
 				return;
+			case SexecPackage.STATE_SWITCH__STATE_CONFIGURATION_IDX:
+				setStateConfigurationIdx(STATE_CONFIGURATION_IDX_EDEFAULT);
+				return;
 		}
 		super.eUnset(featureID);
 	}
@@ -143,8 +194,26 @@ public class StateSwitchImpl extends StepImpl implements StateSwitch {
 		switch (featureID) {
 			case SexecPackage.STATE_SWITCH__CASES:
 				return cases != null && !cases.isEmpty();
+			case SexecPackage.STATE_SWITCH__STATE_CONFIGURATION_IDX:
+				return stateConfigurationIdx != STATE_CONFIGURATION_IDX_EDEFAULT;
 		}
 		return super.eIsSet(featureID);
 	}
 
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public String toString() {
+		if (eIsProxy()) return super.toString();
+
+		StringBuffer result = new StringBuffer(super.toString());
+		result.append(" (stateConfigurationIdx: ");
+		result.append(stateConfigurationIdx);
+		result.append(')');
+		return result.toString();
+	}
+
 } //StateSwitchImpl

+ 1 - 0
plugins/org.yakindu.sct.model.sexec/src/org/yakindu/sct/model/sexec/transformation/FlowOptimizer.xtend

@@ -208,6 +208,7 @@ class FlowOptimizer {
 		val _copy = sexecFactory.createStateSwitch
 		_copy.name = _switch.name
 		_copy.comment = _switch.comment
+		_copy.stateConfigurationIdx = _switch.stateConfigurationIdx
 		_copy.cases.addAll( _switch.cases.map( c | c.stepCopy ))
 		
 		_copy

+ 55 - 34
plugins/org.yakindu.sct.model.sexec/src/org/yakindu/sct/model/sexec/transformation/ModelSequencer.xtend

@@ -789,6 +789,17 @@ class ModelSequencer {
 		return maxOrthogonality
 	}
 
+	/** calculates the maximum orthogonality (maximum number of possible active leaf states) of a state */
+	def dispatch int defineStateVectors(FinalState s, int offset) { 
+		
+		val es = s.create
+		es.stateVector = sexecFactory.createStateVector
+		es.stateVector.offset = offset;
+		es.stateVector.size = 1			
+		
+		return 1
+	}
+
 
 
 	/************** Calculating execution sequences **************/
@@ -905,48 +916,48 @@ class ModelSequencer {
 
 			// first enforce calculation of all child exit sequences
 			state.regions.forEach( r | { r.defineStateExitSequence null })
-			
+
 			// collect leaf states
 			val List<RegularState> leafStates = state.collectLeafStates(new ArrayList<RegularState>())
+			val sVector = execState.stateVector
+	
+			for ( i: sVector.offset .. sVector.offset + sVector.size - 1 ) {
+						
+				val idx = i
+				// create a state switch
+				var StateSwitch sSwitch = sexecFactory.createStateSwitch
+				sSwitch.stateConfigurationIdx = i
+				sSwitch.comment = "Handle exit of all possible states on position " + sSwitch.stateConfigurationIdx + "..."
+								
+				val List<RegularState> posStates = leafStates.filter( rs | rs.create.stateVector.size == 1 && rs.create.stateVector.offset == idx).toList					
+				
+				// create a case for each leaf state				
+				for ( s : posStates ) {
+	
+					val caseSeq = sexecFactory.createSequence
+					caseSeq.steps += s.create.exitSequence.newCall
 
-			// create a state switch
-			val StateSwitch sSwitch = sexecFactory.createStateSwitch
-							
-			// create a case for each leaf state				
-			for ( s : leafStates ) {
+	
+					val exitStates = s.parentStates
+					exitStates.removeAll(state.parentStates)
+					exitStates.remove(s)
+					
+					// include exitAction calls up to the direct child level.
+					exitStates.fold(caseSeq , [ cs, exitState | {
+						 if (exitState.create.exitAction != null) cs.steps.add(exitState.create.exitAction.newCall)
+						 if ( _addTraceSteps ) cs.steps.add(exitState.create.newTraceStateExited)
+						 cs
+					}]) 
+					
+					if (s.create.exitSequence != null) sSwitch.cases.add(s.create.newCase(caseSeq))
+					
+				}
 
-				val caseSeq = sexecFactory.createSequence
-				
-				caseSeq.steps += s.create.exitSequence.newCall
-				
-				val exitStates = s.parentStates
-				exitStates.removeAll(state.parentStates)
-				exitStates.remove(s)
-				
-				// include exitAction calls up to the direct child level.
-				exitStates.fold(caseSeq , [ cs, exitState | {
-					 if (exitState.create.exitAction != null) cs.steps.add(exitState.create.exitAction.newCall)
-					 if ( _addTraceSteps ) cs.steps.add(exitState.create.newTraceStateExited)
-					 cs
-				}]) 
-				
-				if (s.create.exitSequence != null) sSwitch.cases.add(s.create.newCase(caseSeq))
+				seq.steps.add(sSwitch);
 
 			}
 			
-			seq.steps.add(sSwitch);
 			
-	
-//			for ( r : state.subRegions ) {
-//				defineStateExitSequence(r)
-//				
-//				val StateSwitch sSwitch = sexecFactory.createStateSwitch
-//								
-//				for ( s : r.states ) {
-//					if (s.create.exitSequence != null) sSwitch.cases.add(s.create.newCase(s.create.exitSequence.newCall))
-//				}
-//				seq.steps.add(sSwitch);
-//			} 
 		}
 
 		if (execState.exitAction != null) seq.steps.add(execState.exitAction.newCall)
@@ -973,6 +984,16 @@ class ModelSequencer {
 	}
 	
 	
+		
+	def List<RegularState> collectLeafStates(Region region, List<RegularState> leafStates) {
+		for ( v : region.vertices ) {
+			if (v instanceof RegularState) collectLeafStates(v as RegularState, leafStates)
+		}
+
+		return leafStates	
+	}
+	
+	
 	def dispatch isLeaf(RegularState s) { false }
 	
 	def dispatch isLeaf(FinalState s) {true}

+ 2 - 0
plugins/org.yakindu.sct.model.sexec/xtend-gen/org/yakindu/sct/model/sexec/transformation/FlowOptimizer.java

@@ -502,6 +502,8 @@ public class FlowOptimizer {
       _copy.setName(_name);
       String _comment = _switch.getComment();
       _copy.setComment(_comment);
+      int _stateConfigurationIdx = _switch.getStateConfigurationIdx();
+      _copy.setStateConfigurationIdx(_stateConfigurationIdx);
       EList<StateCase> _cases = _copy.getCases();
       EList<StateCase> _cases_1 = _switch.getCases();
       final Function1<StateCase,StateCase> _function = new Function1<StateCase,StateCase>() {

+ 121 - 51
plugins/org.yakindu.sct.model.sexec/xtend-gen/org/yakindu/sct/model/sexec/transformation/ModelSequencer.java

@@ -1600,6 +1600,21 @@ public class ModelSequencer {
     }
   }
   
+  protected int _defineStateVectors(final FinalState s, final int offset) {
+    {
+      ExecutionState _create = this.factory.create(s);
+      final ExecutionState es = _create;
+      SexecFactory _sexecFactory = this.sexecFactory();
+      StateVector _createStateVector = _sexecFactory.createStateVector();
+      es.setStateVector(_createStateVector);
+      StateVector _stateVector = es.getStateVector();
+      _stateVector.setOffset(offset);
+      StateVector _stateVector_1 = es.getStateVector();
+      _stateVector_1.setSize(1);
+      return 1;
+    }
+  }
+  
   public void defineStateEnterSequences(final ExecutionFlow flow, final Statechart sc) {
     EList<Region> _regions = sc.getRegions();
     for (Region r : _regions) {
@@ -1779,63 +1794,103 @@ public class ModelSequencer {
           ArrayList<RegularState> _arrayList = new ArrayList<RegularState>();
           List<RegularState> _collectLeafStates = this.collectLeafStates(state, _arrayList);
           final List<RegularState> leafStates = _collectLeafStates;
-          SexecFactory _sexecFactory_1 = this.sexecFactory();
-          StateSwitch _createStateSwitch = _sexecFactory_1.createStateSwitch();
-          final StateSwitch sSwitch = _createStateSwitch;
-          for (RegularState s : leafStates) {
+          StateVector _stateVector = execState.getStateVector();
+          final StateVector sVector = _stateVector;
+          int _offset = sVector.getOffset();
+          int _offset_1 = sVector.getOffset();
+          int _size = sVector.getSize();
+          int _operator_plus_1 = IntegerExtensions.operator_plus(((Integer)_offset_1), ((Integer)_size));
+          int _operator_minus = IntegerExtensions.operator_minus(((Integer)_operator_plus_1), ((Integer)1));
+          Iterable<Integer> _operator_upTo = IntegerExtensions.operator_upTo(((Integer)_offset), ((Integer)_operator_minus));
+          for (Integer i : _operator_upTo) {
             {
-              SexecFactory _sexecFactory_2 = this.sexecFactory();
-              Sequence _createSequence_1 = _sexecFactory_2.createSequence();
-              final Sequence caseSeq = _createSequence_1;
-              EList<Step> _steps_1 = caseSeq.getSteps();
-              ExecutionState _create_1 = this.factory.create(s);
-              Sequence _exitSequence = _create_1.getExitSequence();
-              Call _newCall = this.factory.newCall(_exitSequence);
-              CollectionExtensions.<Call>operator_add(_steps_1, _newCall);
-              List<RegularState> _parentStates = this.parentStates(s);
-              final List<RegularState> exitStates = _parentStates;
-              List<RegularState> _parentStates_1 = this.parentStates(state);
-              exitStates.removeAll(_parentStates_1);
-              exitStates.remove(s);
-              final Function2<Sequence,RegularState,Sequence> _function_1 = new Function2<Sequence,RegularState,Sequence>() {
-                  public Sequence apply(final Sequence cs , final RegularState exitState) {
-                    Sequence _xblockexpression_1 = null;
-                    {
-                      ExecutionState _create_2 = ModelSequencer.this.factory.create(exitState);
-                      Step _exitAction = _create_2.getExitAction();
-                      boolean _operator_notEquals = ObjectExtensions.operator_notEquals(_exitAction, null);
-                      if (_operator_notEquals) {
-                        EList<Step> _steps_2 = cs.getSteps();
-                        ExecutionState _create_3 = ModelSequencer.this.factory.create(exitState);
-                        Step _exitAction_1 = _create_3.getExitAction();
-                        Call _newCall_1 = ModelSequencer.this.factory.newCall(_exitAction_1);
-                        _steps_2.add(_newCall_1);
-                      }
-                      if (ModelSequencer.this._addTraceSteps) {
-                        EList<Step> _steps_3 = cs.getSteps();
-                        ExecutionState _create_4 = ModelSequencer.this.factory.create(exitState);
-                        TraceStateExited _newTraceStateExited = ModelSequencer.this.newTraceStateExited(_create_4);
-                        _steps_3.add(_newTraceStateExited);
-                      }
-                      _xblockexpression_1 = (cs);
+              final Integer idx = i;
+              SexecFactory _sexecFactory_1 = this.sexecFactory();
+              StateSwitch _createStateSwitch = _sexecFactory_1.createStateSwitch();
+              StateSwitch sSwitch = _createStateSwitch;
+              sSwitch.setStateConfigurationIdx(i);
+              int _stateConfigurationIdx = sSwitch.getStateConfigurationIdx();
+              String _operator_plus_2 = StringExtensions.operator_plus("Handle exit of all possible states on position ", ((Integer)_stateConfigurationIdx));
+              String _operator_plus_3 = StringExtensions.operator_plus(_operator_plus_2, "...");
+              sSwitch.setComment(_operator_plus_3);
+              final Function1<RegularState,Boolean> _function_1 = new Function1<RegularState,Boolean>() {
+                  public Boolean apply(final RegularState rs) {
+                    boolean _operator_and = false;
+                    ExecutionState _create_1 = ModelSequencer.this.factory.create(rs);
+                    StateVector _stateVector_1 = _create_1.getStateVector();
+                    int _size_1 = _stateVector_1.getSize();
+                    boolean _operator_equals = ObjectExtensions.operator_equals(((Integer)_size_1), ((Integer)1));
+                    if (!_operator_equals) {
+                      _operator_and = false;
+                    } else {
+                      ExecutionState _create_2 = ModelSequencer.this.factory.create(rs);
+                      StateVector _stateVector_2 = _create_2.getStateVector();
+                      int _offset_2 = _stateVector_2.getOffset();
+                      boolean _operator_equals_1 = ObjectExtensions.operator_equals(((Integer)_offset_2), idx);
+                      _operator_and = BooleanExtensions.operator_and(_operator_equals, _operator_equals_1);
                     }
-                    return _xblockexpression_1;
+                    return ((Boolean)_operator_and);
                   }
                 };
-              IterableExtensions.<RegularState, Sequence>fold(exitStates, caseSeq, _function_1);
-              ExecutionState _create_5 = this.factory.create(s);
-              Sequence _exitSequence_1 = _create_5.getExitSequence();
-              boolean _operator_notEquals_1 = ObjectExtensions.operator_notEquals(_exitSequence_1, null);
-              if (_operator_notEquals_1) {
-                EList<StateCase> _cases = sSwitch.getCases();
-                ExecutionState _create_6 = this.factory.create(s);
-                StateCase _newCase = this.newCase(_create_6, caseSeq);
-                _cases.add(_newCase);
+              Iterable<RegularState> _filter = IterableExtensions.<RegularState>filter(leafStates, _function_1);
+              List<RegularState> _list = IterableExtensions.<RegularState>toList(_filter);
+              final List<RegularState> posStates = _list;
+              for (RegularState s : posStates) {
+                {
+                  SexecFactory _sexecFactory_2 = this.sexecFactory();
+                  Sequence _createSequence_1 = _sexecFactory_2.createSequence();
+                  final Sequence caseSeq = _createSequence_1;
+                  EList<Step> _steps_1 = caseSeq.getSteps();
+                  ExecutionState _create_3 = this.factory.create(s);
+                  Sequence _exitSequence = _create_3.getExitSequence();
+                  Call _newCall = this.factory.newCall(_exitSequence);
+                  CollectionExtensions.<Call>operator_add(_steps_1, _newCall);
+                  List<RegularState> _parentStates = this.parentStates(s);
+                  final List<RegularState> exitStates = _parentStates;
+                  List<RegularState> _parentStates_1 = this.parentStates(state);
+                  exitStates.removeAll(_parentStates_1);
+                  exitStates.remove(s);
+                  final Function2<Sequence,RegularState,Sequence> _function_2 = new Function2<Sequence,RegularState,Sequence>() {
+                      public Sequence apply(final Sequence cs , final RegularState exitState) {
+                        Sequence _xblockexpression_1 = null;
+                        {
+                          ExecutionState _create_4 = ModelSequencer.this.factory.create(exitState);
+                          Step _exitAction = _create_4.getExitAction();
+                          boolean _operator_notEquals = ObjectExtensions.operator_notEquals(_exitAction, null);
+                          if (_operator_notEquals) {
+                            EList<Step> _steps_2 = cs.getSteps();
+                            ExecutionState _create_5 = ModelSequencer.this.factory.create(exitState);
+                            Step _exitAction_1 = _create_5.getExitAction();
+                            Call _newCall_1 = ModelSequencer.this.factory.newCall(_exitAction_1);
+                            _steps_2.add(_newCall_1);
+                          }
+                          if (ModelSequencer.this._addTraceSteps) {
+                            EList<Step> _steps_3 = cs.getSteps();
+                            ExecutionState _create_6 = ModelSequencer.this.factory.create(exitState);
+                            TraceStateExited _newTraceStateExited = ModelSequencer.this.newTraceStateExited(_create_6);
+                            _steps_3.add(_newTraceStateExited);
+                          }
+                          _xblockexpression_1 = (cs);
+                        }
+                        return _xblockexpression_1;
+                      }
+                    };
+                  IterableExtensions.<RegularState, Sequence>fold(exitStates, caseSeq, _function_2);
+                  ExecutionState _create_7 = this.factory.create(s);
+                  Sequence _exitSequence_1 = _create_7.getExitSequence();
+                  boolean _operator_notEquals_1 = ObjectExtensions.operator_notEquals(_exitSequence_1, null);
+                  if (_operator_notEquals_1) {
+                    EList<StateCase> _cases = sSwitch.getCases();
+                    ExecutionState _create_8 = this.factory.create(s);
+                    StateCase _newCase = this.newCase(_create_8, caseSeq);
+                    _cases.add(_newCase);
+                  }
+                }
               }
+              EList<Step> _steps_4 = seq.getSteps();
+              _steps_4.add(sSwitch);
             }
           }
-          EList<Step> _steps_4 = seq.getSteps();
-          _steps_4.add(sSwitch);
         }
       }
       Step _exitAction_2 = execState.getExitAction();
@@ -1880,6 +1935,18 @@ public class ModelSequencer {
     }
   }
   
+  public List<RegularState> collectLeafStates(final Region region, final List<RegularState> leafStates) {
+    {
+      EList<Vertex> _vertices = region.getVertices();
+      for (Vertex v : _vertices) {
+        if ((v instanceof org.yakindu.sct.model.sgraph.RegularState)) {
+          this.collectLeafStates(((RegularState) v), leafStates);
+        }
+      }
+      return leafStates;
+    }
+  }
+  
   protected boolean _isLeaf(final RegularState s) {
     return false;
   }
@@ -2285,7 +2352,10 @@ public class ModelSequencer {
   }
   
   public int defineStateVectors(final Vertex s, final Integer offset) {
-    if ((s instanceof State)
+    if ((s instanceof FinalState)
+         && (offset instanceof Integer)) {
+      return _defineStateVectors((FinalState)s, (Integer)offset);
+    } else if ((s instanceof State)
          && (offset instanceof Integer)) {
       return _defineStateVectors((State)s, (Integer)offset);
     } else if ((s instanceof Vertex)

+ 6 - 3
test-plugins/org.yakindu.sct.model.sexec.test/src/org/yakindu/sct/model/sexec/transformation/test/ModelSequencerStateTest.java

@@ -343,17 +343,20 @@ public class ModelSequencerStateTest extends ModelSequencerTest {
 		
 		assertNotNull(_s1.getExitAction());
 		assertNotNull(_s1.getExitSequence());
-		assertEquals(2, _s1.getExitSequence().getSteps().size());
+		assertEquals(3, _s1.getExitSequence().getSteps().size());
 		
 		Step _switch =  _s1.getExitSequence().getSteps().get(0);
-		assertStateSwitch(_switch, _s2, _s3, _s4, _s5, _s6);
+		assertStateSwitch(_switch, _s2, _s3);
 		assertCall( assertedSequence(assertedStateCase(_switch, _s2).getStep()), 0, _s2.getExitSequence());
 		assertCall( assertedSequence(assertedStateCase(_switch, _s3).getStep()), 0, _s3.getExitSequence());
+
+		_switch =  _s1.getExitSequence().getSteps().get(1);
+		assertStateSwitch(_switch, _s4, _s5, _s6);
 		assertCall( assertedSequence(assertedStateCase(_switch, _s4).getStep()), 0, _s4.getExitSequence());
 		assertCall( assertedSequence(assertedStateCase(_switch, _s5).getStep()), 0, _s5.getExitSequence());
 		assertCall( assertedSequence(assertedStateCase(_switch, _s6).getStep()), 0, _s6.getExitSequence());
 
-		assertCall(_s1.getExitSequence(), 1, _s1.getExitAction());
+		assertCall(_s1.getExitSequence(), 2, _s1.getExitAction());
 	}