Przeglądaj źródła

Transformation supports simple flat orthogonal statecharts:
- simple initial entries
- simple event trigger
- simple state to state transitions
- statechart enter sequence

terfloth@itemis.de 14 lat temu
rodzic
commit
c37a710ffb
16 zmienionych plików z 464 dodań i 66 usunięć
  1. 1 1
      plugins/org.yakindu.sct.generator.cpp/src/org/yakindu/sct/generator/cpp/templates/Dump.xpt
  2. BIN
      plugins/org.yakindu.sct.model.sexec.edit/icons/full/ctool16/CreateExecutionFlow_enterSequence_Cycle.gif
  3. BIN
      plugins/org.yakindu.sct.model.sexec.edit/icons/full/ctool16/CreateExecutionFlow_enterSequence_Sequence.gif
  4. 1 0
      plugins/org.yakindu.sct.model.sexec.edit/plugin.properties
  5. 35 0
      plugins/org.yakindu.sct.model.sexec.edit/src/org/yakindu/sct/model/sexec/provider/ExecutionFlowItemProvider.java
  6. 2 0
      plugins/org.yakindu.sct.model.sexec/model/sexec.ecore
  7. 27 0
      plugins/org.yakindu.sct.model.sexec/src/org/yakindu/sct/model/sexec/ExecutionFlow.java
  8. 29 1
      plugins/org.yakindu.sct.model.sexec/src/org/yakindu/sct/model/sexec/SexecPackage.java
  9. 66 0
      plugins/org.yakindu.sct.model.sexec/src/org/yakindu/sct/model/sexec/impl/ExecutionFlowImpl.java
  10. 11 0
      plugins/org.yakindu.sct.model.sexec/src/org/yakindu/sct/model/sexec/impl/SexecPackageImpl.java
  11. 56 3
      plugins/org.yakindu.sct.model.sexec/src/org/yakindu/sct/model/sexec/transformation/ModelSequencer.xtend
  12. 2 1
      test-plugins/org.yakindu.sct.generator.cpp.test/META-INF/MANIFEST.MF
  13. 32 15
      test-plugins/org.yakindu.sct.generator.cpp.test/src/org/yakindu/sct/generator/cpp/test/generator/CPPGeneratorTest.java
  14. 1 0
      test-plugins/org.yakindu.sct.model.sexec.test/META-INF/MANIFEST.MF
  15. 127 45
      test-plugins/org.yakindu.sct.model.sexec.test/src/org/yakindu/sct/model/sexec/transformation/test/ModelSequencerTest.java
  16. 74 0
      test-plugins/org.yakindu.sct.model.sexec.test/src/org/yakindu/sct/model/sexec/transformation/test/SCTTestUtil.java

+ 1 - 1
plugins/org.yakindu.sct.generator.cpp/src/org/yakindu/sct/generator/cpp/templates/Dump.xpt

@@ -59,5 +59,5 @@ Cycle: 
 
 
 «DEFINE code FOR ElementReferenceExpression -»
-«this.value.toString()»-«this.value.name -»
+«this.value.name -»
 «ENDDEFINE»

BIN
plugins/org.yakindu.sct.model.sexec.edit/icons/full/ctool16/CreateExecutionFlow_enterSequence_Cycle.gif


BIN
plugins/org.yakindu.sct.model.sexec.edit/icons/full/ctool16/CreateExecutionFlow_enterSequence_Sequence.gif


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

@@ -49,3 +49,4 @@ _UI_Unknown_feature = Unspecified
 
 _UI_If_thenStep_feature = Then Step
 _UI_If_elseStep_feature = Else Step
+_UI_ExecutionFlow_enterSequence_feature = Enter Sequence

+ 35 - 0
plugins/org.yakindu.sct.model.sexec.edit/src/org/yakindu/sct/model/sexec/provider/ExecutionFlowItemProvider.java

@@ -109,6 +109,7 @@ public class ExecutionFlowItemProvider
 			super.getChildrenFeatures(object);
 			childrenFeatures.add(SexecPackage.Literals.EXECUTION_FLOW__STATES);
 			childrenFeatures.add(SexecPackage.Literals.EXECUTION_FLOW__SEQUENCES);
+			childrenFeatures.add(SexecPackage.Literals.EXECUTION_FLOW__ENTER_SEQUENCE);
 		}
 		return childrenFeatures;
 	}
@@ -168,6 +169,7 @@ public class ExecutionFlowItemProvider
 				return;
 			case SexecPackage.EXECUTION_FLOW__STATES:
 			case SexecPackage.EXECUTION_FLOW__SEQUENCES:
+			case SexecPackage.EXECUTION_FLOW__ENTER_SEQUENCE:
 				fireNotifyChanged(new ViewerNotification(notification, notification.getNotifier(), true, false));
 				return;
 		}
@@ -199,6 +201,39 @@ public class ExecutionFlowItemProvider
 			(createChildParameter
 				(SexecPackage.Literals.EXECUTION_FLOW__SEQUENCES,
 				 SexecFactory.eINSTANCE.createCycle()));
+
+		newChildDescriptors.add
+			(createChildParameter
+				(SexecPackage.Literals.EXECUTION_FLOW__ENTER_SEQUENCE,
+				 SexecFactory.eINSTANCE.createSequence()));
+
+		newChildDescriptors.add
+			(createChildParameter
+				(SexecPackage.Literals.EXECUTION_FLOW__ENTER_SEQUENCE,
+				 SexecFactory.eINSTANCE.createCycle()));
+	}
+
+	/**
+	 * This returns the label text for {@link org.eclipse.emf.edit.command.CreateChildCommand}.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	@Override
+	public String getCreateChildText(Object owner, Object feature, Object child, Collection<?> selection) {
+		Object childFeature = feature;
+		Object childObject = child;
+
+		boolean qualify =
+			childFeature == SexecPackage.Literals.EXECUTION_FLOW__SEQUENCES ||
+			childFeature == SexecPackage.Literals.EXECUTION_FLOW__ENTER_SEQUENCE;
+
+		if (qualify) {
+			return getString
+				("_UI_CreateChild_text2",
+				 new Object[] { getTypeText(childObject), getFeatureText(childFeature), getTypeText(owner) });
+		}
+		return super.getCreateChildText(owner, feature, child, selection);
 	}
 
 	/**

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

@@ -8,6 +8,8 @@
         eType="#//ExecutionState" containment="true"/>
     <eStructuralFeatures xsi:type="ecore:EReference" name="sequences" upperBound="-1"
         eType="#//Sequence" containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="enterSequence" eType="#//Sequence"
+        containment="true"/>
   </eClassifiers>
   <eClassifiers xsi:type="ecore:EClass" name="ExecutionState" eSuperTypes="#//NamedElement">
     <eStructuralFeatures xsi:type="ecore:EAttribute" name="simpleName" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>

+ 27 - 0
plugins/org.yakindu.sct.model.sexec/src/org/yakindu/sct/model/sexec/ExecutionFlow.java

@@ -21,6 +21,7 @@ import org.eclipse.emf.ecore.EObject;
  * <ul>
  *   <li>{@link org.yakindu.sct.model.sexec.ExecutionFlow#getStates <em>States</em>}</li>
  *   <li>{@link org.yakindu.sct.model.sexec.ExecutionFlow#getSequences <em>Sequences</em>}</li>
+ *   <li>{@link org.yakindu.sct.model.sexec.ExecutionFlow#getEnterSequence <em>Enter Sequence</em>}</li>
  * </ul>
  * </p>
  *
@@ -61,4 +62,30 @@ public interface ExecutionFlow extends ScopedElement, NamedElement {
 	 */
 	EList<Sequence> getSequences();
 
+	/**
+	 * Returns the value of the '<em><b>Enter Sequence</b></em>' containment reference.
+	 * <!-- begin-user-doc -->
+	 * <p>
+	 * If the meaning of the '<em>Enter Sequence</em>' containment reference isn't clear,
+	 * there really should be more of a description here...
+	 * </p>
+	 * <!-- end-user-doc -->
+	 * @return the value of the '<em>Enter Sequence</em>' containment reference.
+	 * @see #setEnterSequence(Sequence)
+	 * @see org.yakindu.sct.model.sexec.SexecPackage#getExecutionFlow_EnterSequence()
+	 * @model containment="true"
+	 * @generated
+	 */
+	Sequence getEnterSequence();
+
+	/**
+	 * Sets the value of the '{@link org.yakindu.sct.model.sexec.ExecutionFlow#getEnterSequence <em>Enter Sequence</em>}' containment reference.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @param value the new value of the '<em>Enter Sequence</em>' containment reference.
+	 * @see #getEnterSequence()
+	 * @generated
+	 */
+	void setEnterSequence(Sequence value);
+
 } // ExecutionFlow

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

@@ -106,6 +106,15 @@ public interface SexecPackage extends EPackage {
 	 */
 	int EXECUTION_FLOW__SEQUENCES = SGraphPackage.SCOPED_ELEMENT_FEATURE_COUNT + 2;
 
+	/**
+	 * The feature id for the '<em><b>Enter Sequence</b></em>' containment reference.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	int EXECUTION_FLOW__ENTER_SEQUENCE = SGraphPackage.SCOPED_ELEMENT_FEATURE_COUNT + 3;
+
 	/**
 	 * The number of structural features of the '<em>Execution Flow</em>' class.
 	 * <!-- begin-user-doc -->
@@ -113,7 +122,7 @@ public interface SexecPackage extends EPackage {
 	 * @generated
 	 * @ordered
 	 */
-	int EXECUTION_FLOW_FEATURE_COUNT = SGraphPackage.SCOPED_ELEMENT_FEATURE_COUNT + 3;
+	int EXECUTION_FLOW_FEATURE_COUNT = SGraphPackage.SCOPED_ELEMENT_FEATURE_COUNT + 4;
 
 	/**
 	 * The meta object id for the '{@link org.yakindu.sct.model.sexec.impl.NamedElementImpl <em>Named Element</em>}' class.
@@ -545,6 +554,17 @@ public interface SexecPackage extends EPackage {
 	 */
 	EReference getExecutionFlow_Sequences();
 
+	/**
+	 * Returns the meta object for the containment reference '{@link org.yakindu.sct.model.sexec.ExecutionFlow#getEnterSequence <em>Enter Sequence</em>}'.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the meta object for the containment reference '<em>Enter Sequence</em>'.
+	 * @see org.yakindu.sct.model.sexec.ExecutionFlow#getEnterSequence()
+	 * @see #getExecutionFlow()
+	 * @generated
+	 */
+	EReference getExecutionFlow_EnterSequence();
+
 	/**
 	 * Returns the meta object for class '{@link org.yakindu.sct.model.sexec.ExecutionState <em>Execution State</em>}'.
 	 * <!-- begin-user-doc -->
@@ -825,6 +845,14 @@ public interface SexecPackage extends EPackage {
 		 */
 		EReference EXECUTION_FLOW__SEQUENCES = eINSTANCE.getExecutionFlow_Sequences();
 
+		/**
+		 * The meta object literal for the '<em><b>Enter Sequence</b></em>' containment reference feature.
+		 * <!-- begin-user-doc -->
+		 * <!-- end-user-doc -->
+		 * @generated
+		 */
+		EReference EXECUTION_FLOW__ENTER_SEQUENCE = eINSTANCE.getExecutionFlow_EnterSequence();
+
 		/**
 		 * The meta object literal for the '{@link org.yakindu.sct.model.sexec.impl.ExecutionStateImpl <em>Execution State</em>}' class.
 		 * <!-- begin-user-doc -->

+ 66 - 0
plugins/org.yakindu.sct.model.sexec/src/org/yakindu/sct/model/sexec/impl/ExecutionFlowImpl.java

@@ -39,6 +39,7 @@ import org.yakindu.sct.model.sgraph.impl.ScopedElementImpl;
  *   <li>{@link org.yakindu.sct.model.sexec.impl.ExecutionFlowImpl#getName <em>Name</em>}</li>
  *   <li>{@link org.yakindu.sct.model.sexec.impl.ExecutionFlowImpl#getStates <em>States</em>}</li>
  *   <li>{@link org.yakindu.sct.model.sexec.impl.ExecutionFlowImpl#getSequences <em>Sequences</em>}</li>
+ *   <li>{@link org.yakindu.sct.model.sexec.impl.ExecutionFlowImpl#getEnterSequence <em>Enter Sequence</em>}</li>
  * </ul>
  * </p>
  *
@@ -85,6 +86,16 @@ public class ExecutionFlowImpl extends ScopedElementImpl implements ExecutionFlo
 	 */
 	protected EList<Sequence> sequences;
 
+	/**
+	 * The cached value of the '{@link #getEnterSequence() <em>Enter Sequence</em>}' containment reference.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getEnterSequence()
+	 * @generated
+	 * @ordered
+	 */
+	protected Sequence enterSequence;
+
 	/**
 	 * <!-- begin-user-doc -->
 	 * <!-- end-user-doc -->
@@ -149,6 +160,49 @@ public class ExecutionFlowImpl extends ScopedElementImpl implements ExecutionFlo
 		return sequences;
 	}
 
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public Sequence getEnterSequence() {
+		return enterSequence;
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public NotificationChain basicSetEnterSequence(Sequence newEnterSequence, NotificationChain msgs) {
+		Sequence oldEnterSequence = enterSequence;
+		enterSequence = newEnterSequence;
+		if (eNotificationRequired()) {
+			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, SexecPackage.EXECUTION_FLOW__ENTER_SEQUENCE, oldEnterSequence, newEnterSequence);
+			if (msgs == null) msgs = notification; else msgs.add(notification);
+		}
+		return msgs;
+	}
+
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public void setEnterSequence(Sequence newEnterSequence) {
+		if (newEnterSequence != enterSequence) {
+			NotificationChain msgs = null;
+			if (enterSequence != null)
+				msgs = ((InternalEObject)enterSequence).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - SexecPackage.EXECUTION_FLOW__ENTER_SEQUENCE, null, msgs);
+			if (newEnterSequence != null)
+				msgs = ((InternalEObject)newEnterSequence).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - SexecPackage.EXECUTION_FLOW__ENTER_SEQUENCE, null, msgs);
+			msgs = basicSetEnterSequence(newEnterSequence, msgs);
+			if (msgs != null) msgs.dispatch();
+		}
+		else if (eNotificationRequired())
+			eNotify(new ENotificationImpl(this, Notification.SET, SexecPackage.EXECUTION_FLOW__ENTER_SEQUENCE, newEnterSequence, newEnterSequence));
+	}
+
 	/**
 	 * <!-- begin-user-doc -->
 	 * <!-- end-user-doc -->
@@ -161,6 +215,8 @@ public class ExecutionFlowImpl extends ScopedElementImpl implements ExecutionFlo
 				return ((InternalEList<?>)getStates()).basicRemove(otherEnd, msgs);
 			case SexecPackage.EXECUTION_FLOW__SEQUENCES:
 				return ((InternalEList<?>)getSequences()).basicRemove(otherEnd, msgs);
+			case SexecPackage.EXECUTION_FLOW__ENTER_SEQUENCE:
+				return basicSetEnterSequence(null, msgs);
 		}
 		return super.eInverseRemove(otherEnd, featureID, msgs);
 	}
@@ -179,6 +235,8 @@ public class ExecutionFlowImpl extends ScopedElementImpl implements ExecutionFlo
 				return getStates();
 			case SexecPackage.EXECUTION_FLOW__SEQUENCES:
 				return getSequences();
+			case SexecPackage.EXECUTION_FLOW__ENTER_SEQUENCE:
+				return getEnterSequence();
 		}
 		return super.eGet(featureID, resolve, coreType);
 	}
@@ -203,6 +261,9 @@ public class ExecutionFlowImpl extends ScopedElementImpl implements ExecutionFlo
 				getSequences().clear();
 				getSequences().addAll((Collection<? extends Sequence>)newValue);
 				return;
+			case SexecPackage.EXECUTION_FLOW__ENTER_SEQUENCE:
+				setEnterSequence((Sequence)newValue);
+				return;
 		}
 		super.eSet(featureID, newValue);
 	}
@@ -224,6 +285,9 @@ public class ExecutionFlowImpl extends ScopedElementImpl implements ExecutionFlo
 			case SexecPackage.EXECUTION_FLOW__SEQUENCES:
 				getSequences().clear();
 				return;
+			case SexecPackage.EXECUTION_FLOW__ENTER_SEQUENCE:
+				setEnterSequence((Sequence)null);
+				return;
 		}
 		super.eUnset(featureID);
 	}
@@ -242,6 +306,8 @@ public class ExecutionFlowImpl extends ScopedElementImpl implements ExecutionFlo
 				return states != null && !states.isEmpty();
 			case SexecPackage.EXECUTION_FLOW__SEQUENCES:
 				return sequences != null && !sequences.isEmpty();
+			case SexecPackage.EXECUTION_FLOW__ENTER_SEQUENCE:
+				return enterSequence != null;
 		}
 		return super.eIsSet(featureID);
 	}

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

@@ -201,6 +201,15 @@ public class SexecPackageImpl extends EPackageImpl implements SexecPackage {
 		return (EReference)executionFlowEClass.getEStructuralFeatures().get(1);
 	}
 
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public EReference getExecutionFlow_EnterSequence() {
+		return (EReference)executionFlowEClass.getEStructuralFeatures().get(2);
+	}
+
 	/**
 	 * <!-- begin-user-doc -->
 	 * <!-- end-user-doc -->
@@ -430,6 +439,7 @@ public class SexecPackageImpl extends EPackageImpl implements SexecPackage {
 		executionFlowEClass = createEClass(EXECUTION_FLOW);
 		createEReference(executionFlowEClass, EXECUTION_FLOW__STATES);
 		createEReference(executionFlowEClass, EXECUTION_FLOW__SEQUENCES);
+		createEReference(executionFlowEClass, EXECUTION_FLOW__ENTER_SEQUENCE);
 
 		executionStateEClass = createEClass(EXECUTION_STATE);
 		createEAttribute(executionStateEClass, EXECUTION_STATE__SIMPLE_NAME);
@@ -511,6 +521,7 @@ public class SexecPackageImpl extends EPackageImpl implements SexecPackage {
 		initEClass(executionFlowEClass, ExecutionFlow.class, "ExecutionFlow", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS);
 		initEReference(getExecutionFlow_States(), this.getExecutionState(), null, "states", null, 0, -1, ExecutionFlow.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
 		initEReference(getExecutionFlow_Sequences(), this.getSequence(), null, "sequences", null, 0, -1, ExecutionFlow.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
+		initEReference(getExecutionFlow_EnterSequence(), this.getSequence(), null, "enterSequence", null, 0, 1, ExecutionFlow.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
 
 		initEClass(executionStateEClass, ExecutionState.class, "ExecutionState", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS);
 		initEAttribute(getExecutionState_SimpleName(), ecorePackage.getEString(), "simpleName", null, 0, 1, ExecutionState.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);

+ 56 - 3
plugins/org.yakindu.sct.model.sexec/src/org/yakindu/sct/model/sexec/transformation/ModelSequencer.xtend

@@ -29,6 +29,11 @@ import org.yakindu.sct.model.sgraph.Scope
 import org.yakindu.sct.model.stext.stext.EventDefinition
 import org.yakindu.sct.model.stext.stext.VariableDefinition
 import apple.awt.CRenderer$Tracer
+import org.yakindu.sct.model.sgraph.Region
+import org.yakindu.sct.model.sgraph.Entry
+import org.yakindu.sct.model.sgraph.SGraphPackage
+import org.yakindu.sct.model.sexec.EnterState
+import org.yakindu.sct.model.sexec.ExitState
 
 class ModelSequencer {
 	
@@ -42,7 +47,9 @@ class ModelSequencer {
 		sc.mapExecutionFlow(ef)
 		sc.mapScopes(ef)
 		
-		ef
+		ef.defineEnterSequence(sc)
+		
+		return ef
 	}
 	
 	
@@ -114,7 +121,12 @@ class ModelSequencer {
 	def If buildTransitionSequence(Transition t) {
 		var ifStep = sexecFactory.createIf
 		if (t.trigger != null) ifStep.condition = t.trigger.buildCondition 
-		ifStep	
+		val thenSequence = sexecFactory.createSequence 
+		ifStep.thenStep = thenSequence
+		if (t.source != null) thenSequence.steps.add(newExitStateStep(t.source as State))		
+		if (t.target != null) thenSequence.steps.add(newEnterStateStep(t.target as State))
+		
+		return ifStep	
 	}
 	
 	
@@ -155,9 +167,50 @@ class ModelSequencer {
 	}
 	
 	
-		//--------- UTILS ---------------
+	/************** Calculating execution sequences **************/
+	
+	
+	def defineEnterSequence(ExecutionFlow flow, Statechart sc) {
+		val enterSteps = sc.regions.map(r | r.entry.target?.newEnterStateStep).filter(e | e != null)
+		val enterSequence = sexecFactory.createSequence
+		enterSequence.name = "enter"
+		enterSteps.forEach(e | enterSequence.steps.add(e));
+		flow.enterSequence = enterSequence
+		return enterSequence
+	}
+	
+	
+	def newEnterStateStep(State s) {
+		var ess  = null as EnterState
+		if (s != null) {
+			ess = sexecFactory.createEnterState
+			ess.state = s.create	
+		}
+		return ess
+	}
+	
+	def newExitStateStep(State s) {
+		var ess  = null as ExitState
+		if (s != null) {
+			ess = sexecFactory.createExitState
+			ess.state = s.create	
+		}
+		return ess
+	}
+	
+	
+	//--------- UTILS ---------------
 	def sexecFactory() { SexecFactory::eINSTANCE }
 	def stextFactory() { StextFactory::eINSTANCE }
 	
 	
+	
+	def entry(Region r) {
+		r.vertices.findFirst(v | v instanceof Entry && (v.name == null || v.name == 'default') ) as Entry
+	}
+	
+	
+	def target(Entry entry) {
+		entry?.outgoingTransitions?.get(0)?.target as State
+	}
 }

+ 2 - 1
test-plugins/org.yakindu.sct.generator.cpp.test/META-INF/MANIFEST.MF

@@ -16,6 +16,7 @@ Require-Bundle: org.eclipse.core.runtime,
  org.yakindu.sct.model.stext;bundle-version="1.0.0",
  org.yakindu.sct.model.sexec;bundle-version="1.0.0",
  org.yakindu.sct.generator.cpp;bundle-version="1.0.0",
- org.yakindu.sct.generator.base;bundle-version="1.0.0"
+ org.yakindu.sct.generator.base;bundle-version="1.0.0",
+ org.yakindu.sct.model.sexec.test;bundle-version="1.0.0"
 Bundle-RequiredExecutionEnvironment: J2SE-1.5
 Bundle-ActivationPolicy: lazy

+ 32 - 15
test-plugins/org.yakindu.sct.generator.cpp.test/src/org/yakindu/sct/generator/cpp/test/generator/CPPGeneratorTest.java

@@ -1,6 +1,13 @@
 package org.yakindu.sct.generator.cpp.test.generator;
 
-import static org.junit.Assert.*;
+import static org.yakindu.sct.model.sexec.transformation.test.SCTTestUtil._createEventDefinition;
+import static org.yakindu.sct.model.sexec.transformation.test.SCTTestUtil._createInterfaceScope;
+import static org.yakindu.sct.model.sexec.transformation.test.SCTTestUtil._createReactionTrigger;
+import static org.yakindu.sct.model.sexec.transformation.test.SCTTestUtil._createRegion;
+import static org.yakindu.sct.model.sexec.transformation.test.SCTTestUtil._createRegularEventSpec;
+import static org.yakindu.sct.model.sexec.transformation.test.SCTTestUtil._createState;
+import static org.yakindu.sct.model.sexec.transformation.test.SCTTestUtil._createStatechart;
+import static org.yakindu.sct.model.sexec.transformation.test.SCTTestUtil._createTransition;
 
 import java.net.URL;
 
@@ -12,29 +19,15 @@ import org.junit.Before;
 import org.junit.Test;
 import org.yakindu.sct.generator.base.util.GeneratorBaseUtil;
 import org.yakindu.sct.model.sexec.ExecutionFlow;
-import org.yakindu.sct.model.sexec.If;
 import org.yakindu.sct.model.sexec.transformation.ModelSequencer;
 import org.yakindu.sct.model.sexec.transformation.SequencerModule;
-import org.yakindu.sct.model.sgraph.Declaration;
-import org.yakindu.sct.model.sgraph.Reaction;
 import org.yakindu.sct.model.sgraph.Region;
-import org.yakindu.sct.model.sgraph.SGraphFactory;
-import org.yakindu.sct.model.sgraph.Scope;
-import org.yakindu.sct.model.sgraph.ScopedElement;
 import org.yakindu.sct.model.sgraph.State;
 import org.yakindu.sct.model.sgraph.Statechart;
-import org.yakindu.sct.model.sgraph.Statement;
 import org.yakindu.sct.model.sgraph.Transition;
-import org.yakindu.sct.model.sgraph.Vertex;
-import org.yakindu.sct.model.stext.stext.ElementReferenceExpression;
 import org.yakindu.sct.model.stext.stext.EventDefinition;
 import org.yakindu.sct.model.stext.stext.InterfaceScope;
-import org.yakindu.sct.model.stext.stext.LogicalOrExpression;
 import org.yakindu.sct.model.stext.stext.ReactionTrigger;
-import org.yakindu.sct.model.stext.stext.RegularEventSpec;
-import org.yakindu.sct.model.stext.stext.StextFactory;
-import org.yakindu.sct.model.stext.stext.Type;
-import org.yakindu.sct.model.stext.stext.VariableDefinition;
 
 import com.google.inject.Guice;
 import com.google.inject.Inject;
@@ -79,5 +72,29 @@ public class CPPGeneratorTest extends AbstractGeneratorTest {
 	}
 
 	
+	
+	@Test public void testSimpleModel() throws Exception {
+
+		IProject project = super.createTestProject("CPPGeneratorTest_2", true);
+
+		
+		Statechart sc = _createStatechart("test");
+		InterfaceScope s_scope = _createInterfaceScope("Interface", sc);
+		EventDefinition e1 = _createEventDefinition("e1", s_scope);
+		Region r = _createRegion("main", sc);
+		State s1 = _createState("S1", r);
+		State s2 = _createState("S2", r);
+		Transition t = _createTransition(s1, s2);
+		ReactionTrigger tr1 = _createReactionTrigger(t);
+		_createRegularEventSpec(e1, tr1);
+
+		ExecutionFlow flow = sequencer.transform(sc);
+
+
+		String templatePath = "org::yakindu::sct::generator::cpp::templates::Main::main";
+
+		GeneratorBaseUtil.generate(flow, templatePath, project,
+				"src-gen");
+	}
 
 }

+ 1 - 0
test-plugins/org.yakindu.sct.model.sexec.test/META-INF/MANIFEST.MF

@@ -17,3 +17,4 @@ Require-Bundle: org.eclipse.core.runtime,
  org.yakindu.sct.model.sexec;bundle-version="1.0.0",
  org.yakindu.sct.generator.cpp;bundle-version="1.0.0",
  org.yakindu.sct.generator.base;bundle-version="1.0.0"
+Export-Package: org.yakindu.sct.model.sexec.transformation.test

+ 127 - 45
test-plugins/org.yakindu.sct.model.sexec.test/src/org/yakindu/sct/model/sexec/transformation/test/ModelSequencerTest.java

@@ -6,8 +6,12 @@ import static org.yakindu.sct.model.sexec.transformation.test.SCTTestUtil.*;
 
 import org.junit.Before;
 import org.junit.Test;
+import org.yakindu.sct.model.sexec.EnterState;
 import org.yakindu.sct.model.sexec.ExecutionFlow;
+import org.yakindu.sct.model.sexec.ExecutionState;
+import org.yakindu.sct.model.sexec.ExitState;
 import org.yakindu.sct.model.sexec.If;
+import org.yakindu.sct.model.sexec.Sequence;
 import org.yakindu.sct.model.sexec.transformation.ModelSequencer;
 import org.yakindu.sct.model.sexec.transformation.SequencerModule;
 import org.yakindu.sct.model.sgraph.Declaration;
@@ -47,8 +51,7 @@ public class ModelSequencerTest {
 		injector.injectMembers(this);
 	}
 
-	
-	
+		
 	/**
 	 * The name of the execution flow must be equal to the statechart name.
 	 */
@@ -88,6 +91,127 @@ public class ModelSequencerTest {
 	}
 
 
+	/** 
+	 * the scope name must be mapped.
+	 */
+	@Test public void testScopeName() {
+		InterfaceScope scope = _createInterfaceScope("abc", null);
+		assertEquals(scope.getName(), ((InterfaceScope) sequencer.map(scope)).getName());
+	}
+	
+	/** 
+	 * An InternalScope must be mapped to an InternalScope.
+	 */
+	@Test public void testMapEmptyInternalScope() {
+		InternalScope scope = _createInternalScope(null);
+		Scope _scope = sequencer.map(scope);
+		
+		assertTrue(_scope instanceof InternalScope);
+	}
+	
+	
+	@Test
+	public void testMapScope() {
+
+		InterfaceScope scope = _createInterfaceScope(null, null);
+		EventDefinition e1 = _createEventDefinition("e1", scope);
+		EventDefinition e2 = _createEventDefinition("e2", scope);
+		VariableDefinition v1 = _createVariableDefinition("v1", Type.INTEGER, scope);
+		
+		Scope _scope = sequencer.map(scope);
+
+		assertTrue(_scope instanceof InterfaceScope);
+		assertEquals(3, _scope.getDeclarations().size());
+		
+		
+		for ( int i =0; i<_scope.getDeclarations().size(); i++) {			
+			Declaration s_decl = scope.getDeclarations().get(i);
+			Declaration r_decl = _scope.getDeclarations().get(i);
+			
+			assertNotSame(s_decl, r_decl);	
+			assertEquals(s_decl.getName(), r_decl.getName());	
+			assertEquals(s_decl.getClass(), r_decl.getClass());	
+		}
+	}
+	
+	
+	/**
+	 * In the simplest case the a stet without an actions will be entered.
+	 */
+	@Test public void testSCEnterSequence_SimpleFlatTSC() {
+		SimpleFlatTSC tsc = new SimpleFlatTSC();
+		
+		ExecutionFlow flow = sequencer.transform(tsc.sc);
+		
+		assertNotNull(flow.getEnterSequence());
+		assertEquals(1, flow.getEnterSequence().getSteps().size());
+
+		EnterState enterState = (EnterState) flow.getEnterSequence().getSteps().get(0);
+		assertEquals(tsc.s1.getName(), enterState.getState().getSimpleName());
+	}
+	
+	
+	/**
+	 * For each top level region a EnterState step must be performed.
+	 */
+	@Test public void testSCEnterSequence_OrthogonalFlatTSC() {
+		OrthogonalFlatTSC tsc = new OrthogonalFlatTSC();
+		
+		ExecutionFlow flow = sequencer.transform(tsc.sc);
+		
+		assertNotNull(flow.getEnterSequence());
+		assertEquals(2, flow.getEnterSequence().getSteps().size());
+
+		EnterState enterState = (EnterState) flow.getEnterSequence().getSteps().get(0);
+		assertEquals(tsc.s1.getName(), enterState.getState().getSimpleName());
+
+		enterState = (EnterState) flow.getEnterSequence().getSteps().get(1);
+		assertEquals(tsc.s3.getName(), enterState.getState().getSimpleName());
+	
+	}
+	
+	
+	
+	@Test public void testStateCycle_SimpleFlatTSC() {
+		OrthogonalFlatTSC tsc = new OrthogonalFlatTSC();
+		
+		ExecutionFlow flow = sequencer.transform(tsc.sc);
+
+		// test state with one outgoing transition
+		ExecutionState s1 = flow.getStates().get(0);
+		ExecutionState s2 = flow.getStates().get(1);
+		assertEquals(tsc.s1.getName(), s1.getSimpleName());
+		assertEquals(tsc.s2.getName(), s2.getSimpleName());
+		assertNotNull(s1.getCycle());
+		
+		If _if = (If) s1.getCycle().getSteps().get(0);
+		assertNotNull(_if.getThenStep());
+		assertTrue(_if.getThenStep() instanceof Sequence);
+		assertNull(_if.getElseStep());
+
+		Sequence seq = (Sequence) _if.getThenStep();
+		assertTrue(seq.getSteps().get(0) instanceof ExitState);
+		assertEquals(s1, ((ExitState)seq.getSteps().get(0)).getState());
+		assertTrue(seq.getSteps().get(1) instanceof EnterState);
+		assertEquals(s2, ((EnterState)seq.getSteps().get(1)).getState());
+
+		
+		// test state with two outgoing transitions
+		ExecutionState s3 = flow.getStates().get(2);
+		assertEquals(tsc.s3.getName(), s3.getSimpleName());
+		assertNotNull(s3.getCycle());
+		
+		_if = (If) s3.getCycle().getSteps().get(0);
+		assertNotNull(_if.getThenStep());
+		assertTrue(_if.getThenStep() instanceof Sequence);
+		assertNotNull(_if.getElseStep());
+		assertTrue(_if.getElseStep() instanceof If);
+
+
+	}
+	
+	
+	
 	/**
 	 * Single trigger events of a Reaction Trigger will be converted into a single condition 
 	 * that consists of a ElementReferenceExpression to the corresponding event definition.
@@ -129,7 +253,7 @@ public class ModelSequencerTest {
 
 	
 	@Test
-	public void testTransitionSequence() {
+	public void testTransitionTriggerSequence() {
 
 		EventDefinition e1 = _createEventDefinition("e1", null);
 		EventDefinition e2 = _createEventDefinition("e2", null);
@@ -154,48 +278,6 @@ public class ModelSequencerTest {
 	}
 
 	
-	/** 
-	 * the scope name must be mapped.
-	 */
-	@Test public void testScopeName() {
-		InterfaceScope scope = _createInterfaceScope("abc", null);
-		assertEquals(scope.getName(), ((InterfaceScope) sequencer.map(scope)).getName());
-	}
-	
-	/** 
-	 * An InternalScope must be mapped to an InternalScope.
-	 */
-	@Test public void testMapEmptyInternalScope() {
-		InternalScope scope = _createInternalScope(null);
-		Scope _scope = sequencer.map(scope);
-		
-		assertTrue(_scope instanceof InternalScope);
-	}
-	
-	
-	@Test
-	public void testMapScope() {
-
-		InterfaceScope scope = _createInterfaceScope(null, null);
-		EventDefinition e1 = _createEventDefinition("e1", scope);
-		EventDefinition e2 = _createEventDefinition("e2", scope);
-		VariableDefinition v1 = _createVariableDefinition("v1", Type.INTEGER, scope);
-		
-		Scope _scope = sequencer.map(scope);
 
-		assertTrue(_scope instanceof InterfaceScope);
-		assertEquals(3, _scope.getDeclarations().size());
-		
-		
-		for ( int i =0; i<_scope.getDeclarations().size(); i++) {			
-			Declaration s_decl = scope.getDeclarations().get(i);
-			Declaration r_decl = _scope.getDeclarations().get(i);
-			
-			assertNotSame(s_decl, r_decl);	
-			assertEquals(s_decl.getName(), r_decl.getName());	
-			assertEquals(s_decl.getClass(), r_decl.getClass());	
-		}
-	}
-	
 	
 }

+ 74 - 0
test-plugins/org.yakindu.sct.model.sexec.test/src/org/yakindu/sct/model/sexec/transformation/test/SCTTestUtil.java

@@ -1,5 +1,16 @@
 package org.yakindu.sct.model.sexec.transformation.test;
 
+import static org.yakindu.sct.model.sexec.transformation.test.SCTTestUtil._createEventDefinition;
+import static org.yakindu.sct.model.sexec.transformation.test.SCTTestUtil._createInterfaceScope;
+import static org.yakindu.sct.model.sexec.transformation.test.SCTTestUtil._createReactionTrigger;
+import static org.yakindu.sct.model.sexec.transformation.test.SCTTestUtil._createRegion;
+import static org.yakindu.sct.model.sexec.transformation.test.SCTTestUtil._createRegularEventSpec;
+import static org.yakindu.sct.model.sexec.transformation.test.SCTTestUtil._createState;
+import static org.yakindu.sct.model.sexec.transformation.test.SCTTestUtil._createStatechart;
+import static org.yakindu.sct.model.sexec.transformation.test.SCTTestUtil._createTransition;
+
+import org.yakindu.sct.model.sgraph.Entry;
+import org.yakindu.sct.model.sgraph.EntryKind;
 import org.yakindu.sct.model.sgraph.Reaction;
 import org.yakindu.sct.model.sgraph.Region;
 import org.yakindu.sct.model.sgraph.SGraphFactory;
@@ -85,6 +96,15 @@ public class SCTTestUtil {
 		return state;
 	}
 	
+	public static Entry _createEntry(EntryKind kind, String name, Region r) {
+		Entry entry = SGraphFactory.eINSTANCE.createEntry();
+		if (kind != null) entry.setKind(kind);  
+			else entry.setKind(EntryKind.INITIAL);
+		entry.setName(name);
+		if (r!=null) r.getVertices().add(entry);
+		return entry;
+	}
+	
 	public static Transition _createTransition(Vertex source, Vertex target) {
 		Transition t = SGraphFactory.eINSTANCE.createTransition();
 		t.setSource(source);
@@ -93,5 +113,59 @@ public class SCTTestUtil {
 	}
 	
 	
+	public static class SimpleFlatTSC {
+		
+		public Statechart sc = _createStatechart("test");
+		public InterfaceScope s_scope = _createInterfaceScope("Interface", sc);
+		public EventDefinition e1 = _createEventDefinition("e1", s_scope);
+		public Region r = _createRegion("main", sc);
+		public Entry entry = _createEntry(EntryKind.INITIAL, null, r);
+		public State s1 = _createState("S1", r);
+		public State s2 = _createState("S2", r);
+		public Transition t0 = _createTransition(entry, s1);
+		public Transition t1 = _createTransition(s1, s2);
+		public ReactionTrigger tr1 = _createReactionTrigger(t1);
+		
+		public SimpleFlatTSC() {
+			_createRegularEventSpec(e1, tr1);
+		}
+
+	}
+	
+
+	public static class OrthogonalFlatTSC {
+		
+		public Statechart sc = _createStatechart("test");
+		public InterfaceScope s_scope = _createInterfaceScope("Interface", sc);
+		public EventDefinition e1 = _createEventDefinition("e1", s_scope);
+		public EventDefinition e2 = _createEventDefinition("e2", s_scope);
+		
+		public Region r1 = _createRegion("first", sc);
+		public Entry entry_r1 = _createEntry(EntryKind.INITIAL, null, r1);
+		public State s1 = _createState("S1", r1);
+		public State s2 = _createState("S2", r1);
+		public Transition t0 = _createTransition(entry_r1, s1);
+		public Transition t1 = _createTransition(s1, s2);
+		public ReactionTrigger r1_tr1 = _createReactionTrigger(t1);
+		
+		public Region r2 = _createRegion("second", sc);
+		public Entry entry_r2 = _createEntry(EntryKind.INITIAL, null, r2);
+		public State s3 = _createState("S3", r2);
+		public State s4 = _createState("S4", r2);
+		public Transition t0_r2 = _createTransition(entry_r2, s3);
+		public Transition t1_r2 = _createTransition(s3, s4);
+		public Transition t2_r2 = _createTransition(s3, s4);
+		public ReactionTrigger r2_tr1 = _createReactionTrigger(t1_r2);
+		public ReactionTrigger r2_tr2 = _createReactionTrigger(t2_r2);
+
+		public OrthogonalFlatTSC() {
+			_createRegularEventSpec(e1, r1_tr1);
+			
+			_createRegularEventSpec(e1, r2_tr1);
+			_createRegularEventSpec(e2, r2_tr2);
+		}
+
+	}
+	
 
 }