Quellcode durchsuchen

added
- first version of new style C code generator
- support for fork synchronization points

terfloth@itemis.de vor 13 Jahren
Ursprung
Commit
c061020560
30 geänderte Dateien mit 940 neuen und 83 gelöschten Zeilen
  1. 8 7
      plugins/org.yakindu.sct.generator.c/.classpath
  2. 6 0
      plugins/org.yakindu.sct.generator.c/.project
  3. 3 1
      plugins/org.yakindu.sct.generator.c/META-INF/MANIFEST.MF
  4. 17 0
      plugins/org.yakindu.sct.generator.c/plugin.xml
  5. 26 0
      plugins/org.yakindu.sct.generator.c/src/org/yakindu/sct/generator/c/Base.xtend
  6. 45 0
      plugins/org.yakindu.sct.generator.c/src/org/yakindu/sct/generator/c/CSCTGenerator.xtend
  7. 103 0
      plugins/org.yakindu.sct.generator.c/src/org/yakindu/sct/generator/c/Naming.xtend
  8. 42 0
      plugins/org.yakindu.sct.generator.c/src/org/yakindu/sct/generator/c/Navigation.xtend
  9. 161 0
      plugins/org.yakindu.sct.generator.c/src/org/yakindu/sct/generator/c/Statemachine.xtend
  10. 67 0
      plugins/org.yakindu.sct.generator.c/src/org/yakindu/sct/generator/c/Timer.xtend
  11. 41 0
      plugins/org.yakindu.sct.generator.c/src/org/yakindu/sct/generator/c/Types.xtend
  12. 1 0
      plugins/org.yakindu.sct.generator.core/META-INF/MANIFEST.MF
  13. 4 1
      plugins/org.yakindu.sct.generator.core/build.properties
  14. 1 1
      plugins/org.yakindu.sct.generator.core/src/org/yakindu/sct/generator/core/impl/AbstractSExecModelGenerator.java
  15. 29 2
      plugins/org.yakindu.sct.generator.core/src/org/yakindu/sct/generator/core/impl/GenericJavaBasedGenerator.java
  16. 2 1
      plugins/org.yakindu.sct.generator.core/src/org/yakindu/sct/generator/core/impl/IExecutionFlowGenerator.java
  17. 61 0
      plugins/org.yakindu.sct.generator.core/src/org/yakindu/sct/generator/core/impl/SimpleResourceFileSystemAccess.java
  18. 1 0
      plugins/org.yakindu.sct.generator.core/src/org/yakindu/sct/generator/core/util/GeneratorUtils.java
  19. 1 0
      plugins/org.yakindu.sct.model.sexec.edit/plugin.properties
  20. 24 0
      plugins/org.yakindu.sct.model.sexec.edit/src/org/yakindu/sct/model/sexec/provider/ExecutionRegionItemProvider.java
  21. 2 0
      plugins/org.yakindu.sct.model.sexec/model/sexec.ecore
  22. 14 0
      plugins/org.yakindu.sct.model.sexec/model/sexec.ecorediag
  23. 19 0
      plugins/org.yakindu.sct.model.sexec/src/org/yakindu/sct/model/sexec/ExecutionRegion.java
  24. 29 1
      plugins/org.yakindu.sct.model.sexec/src/org/yakindu/sct/model/sexec/SexecPackage.java
  25. 38 0
      plugins/org.yakindu.sct.model.sexec/src/org/yakindu/sct/model/sexec/impl/ExecutionRegionImpl.java
  26. 11 0
      plugins/org.yakindu.sct.model.sexec/src/org/yakindu/sct/model/sexec/impl/SexecPackageImpl.java
  27. 170 66
      plugins/org.yakindu.sct.model.sexec/src/org/yakindu/sct/model/sexec/transformation/BehaviorMapping.xtend
  28. 1 1
      plugins/org.yakindu.sct.model.sexec/src/org/yakindu/sct/model/sexec/transformation/ModelSequencer.xtend
  29. 11 2
      plugins/org.yakindu.sct.model.sexec/src/org/yakindu/sct/model/sexec/transformation/SexecElementMapping.xtend
  30. 2 0
      plugins/org.yakindu.sct.model.sexec/src/org/yakindu/sct/model/sexec/transformation/StructureMapping.xtend

+ 8 - 7
plugins/org.yakindu.sct.generator.c/.classpath

@@ -1,7 +1,8 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
-	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="xtend-gen"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>

+ 6 - 0
plugins/org.yakindu.sct.generator.c/.project

@@ -25,10 +25,16 @@
 			<arguments>
 			</arguments>
 		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.xtext.ui.shared.xtextBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
 	</buildSpec>
 	<natures>
 		<nature>org.eclipse.jdt.core.javanature</nature>
 		<nature>org.eclipse.pde.PluginNature</nature>
 		<nature>org.eclipse.xtend.shared.ui.xtendXPandNature</nature>
+		<nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
 	</natures>
 </projectDescription>

+ 3 - 1
plugins/org.yakindu.sct.generator.c/META-INF/MANIFEST.MF

@@ -18,7 +18,9 @@ Require-Bundle: org.yakindu.sct.model.sexec,
  org.yakindu.sct.model.stext,
  org.yakindu.sct.generator.core;bundle-version="1.0.0",
  org.yakindu.sct.generator.genmodel;bundle-version="1.0.0",
- org.yakindu.base.types;bundle-version="1.0.0"
+ org.yakindu.base.types;bundle-version="1.0.0",
+ org.eclipse.xtext.xbase.lib;bundle-version="2.3.0",
+ org.eclipse.xtext.builder;bundle-version="2.3.0"
 Bundle-RequiredExecutionEnvironment: J2SE-1.5
 Export-Package: org.yakindu.sct.generator.c,
  org.yakindu.sct.generator.c.features,

+ 17 - 0
plugins/org.yakindu.sct.generator.c/plugin.xml

@@ -12,6 +12,14 @@
             id="yakindu::c"
             name="YAKINDU C Code Generator">
       </SCTGenerator>
+      <SCTGenerator
+            class="org.yakindu.sct.generator.c.CSCTGenerator"
+            contentType="statechart"
+            elementRefType="org.yakindu.sct.model.sgraph.Statechart"
+            description="SCT C Code Generator"
+            id="yakindu::c_new"
+            name="SCT C Code Generator">
+      </SCTGenerator>
    </extension>
    <extension
          point="org.yakindu.sct.generator.core.featuretypes">
@@ -20,6 +28,11 @@
             generatorId="yakindu::c"
             uri="platform:/plugin/org.yakindu.sct.generator.c/library/FeatureTypeLibrary.xmi">
       </FeatureLibrary>
+      <FeatureLibrary
+            defaultProvider="org.yakindu.sct.generator.c.features.CDefaultFeatureValueProvider"
+            generatorId="yakindu::c_new"
+            uri="platform:/plugin/org.yakindu.sct.generator.c/library/FeatureTypeLibrary.xmi">
+      </FeatureLibrary>
    </extension>
    <extension
          point="org.yakindu.sct.generator.core.extensions">
@@ -27,5 +40,9 @@
             fileExtension="sct"
             generatorId="yakindu::c">
       </ExtensionGeneratorMapping>
+      <ExtensionGeneratorMapping
+            fileExtension="sct"
+            generatorId="yakindu::c_new">
+      </ExtensionGeneratorMapping>
    </extension>
 </plugin>

+ 26 - 0
plugins/org.yakindu.sct.generator.c/src/org/yakindu/sct/generator/c/Base.xtend

@@ -0,0 +1,26 @@
+package org.yakindu.sct.generator.c
+
+import org.yakindu.sct.model.sgen.GeneratorEntry
+import org.yakindu.base.types.Type
+
+class Base {
+	
+		def licenseHeader(GeneratorEntry it) {
+//		 .getFeatureConfiguration(getLicenseFeature())!=null
+//		&& this.genEntry().getFeatureConfiguration(getLicenseFeature()).getParameterValue(getLicenseText()) != null then
+//		this.genEntry().getFeatureConfiguration(getLicenseFeature()).getParameterValue(getLicenseText()).getStringValue()
+//	else 
+//		null;	
+	}
+	
+	def cPrimitive(Type it) {
+		switch (if (it == null) 'void' else name ) {
+			case 'void' 	: 'void'
+			case 'integer'	: 'sc_integer'
+			case 'real'		: 'sc_real'
+			case 'boolean'	: 'sc_boolean'
+			case 'string'	: 'sc_string'
+		}
+	}
+	
+}

+ 45 - 0
plugins/org.yakindu.sct.generator.c/src/org/yakindu/sct/generator/c/CSCTGenerator.xtend

@@ -0,0 +1,45 @@
+package org.yakindu.sct.generator.c
+
+import com.google.inject.Inject
+import org.eclipse.xtext.generator.IFileSystemAccess
+import org.yakindu.sct.generator.core.impl.IExecutionFlowGenerator
+import org.yakindu.sct.model.sexec.ExecutionFlow
+import org.yakindu.sct.model.sgen.GeneratorEntry
+import org.yakindu.sct.model.sgraph.Statechart
+
+/**
+ * This is the C code generators main class. 
+ * 
+ * @author Axel Terfloth
+ */
+class CSCTGenerator implements IExecutionFlowGenerator {
+	 
+	@Inject extension Types
+	@Inject extension Timer 
+	@Inject extension Statemachine
+ 	
+
+//	override public runGenerator(Statechart statechart, GeneratorEntry entry) {
+//		entry.injector.injectMembers(this);
+//		
+//		val flow = statechart.createExecutionFlow(entry)
+//		//val fsa = entry.fileSystemAccess
+//				
+//		flow.generateStatemachineH(statechart, fsa)
+//	}
+	
+	
+	
+	override generate(ExecutionFlow flow, GeneratorEntry entry, IFileSystemAccess fsa) {
+
+		flow.generateTypesH(flow.sourceElement as Statechart, fsa)
+		
+		flow.generateTimerH(flow.sourceElement as Statechart, fsa)
+		flow.generateTimerC(flow.sourceElement as Statechart, fsa)
+
+		flow.generateStatemachineH(flow.sourceElement as Statechart, fsa)
+
+	}
+
+	
+}

+ 103 - 0
plugins/org.yakindu.sct.generator.c/src/org/yakindu/sct/generator/c/Naming.xtend

@@ -0,0 +1,103 @@
+package org.yakindu.sct.generator.c
+
+import org.yakindu.sct.model.sexec.ExecutionFlow
+import org.yakindu.sct.model.stext.stext.InterfaceScope
+import com.google.inject.Inject
+import org.yakindu.sct.model.stext.stext.InternalScope
+import org.yakindu.sct.model.sgraph.Scope
+import org.yakindu.sct.model.stext.stext.VariableDefinition
+import org.yakindu.sct.model.stext.stext.EventDefinition
+
+class Naming {
+
+	@Inject extension Navigation
+	
+	def module(ExecutionFlow it) {
+		name.asIdentifier.toFirstUpper	
+	}
+	
+	def timerModule(ExecutionFlow it) {
+		'sc_timer'	
+	}
+	
+	def typesModule(ExecutionFlow it) {
+		'sc_types'	
+	}
+	
+	def dispatch type(ExecutionFlow it) {
+		name.asIdentifier.toFirstUpper	
+	}
+	
+	def timerType(ExecutionFlow it) {
+		'SCTimer'
+	}
+	
+	def statesEnumType(ExecutionFlow it) {
+		module + 'States'	
+	}
+	
+	def module(InterfaceScope it) {
+		flow.module + (if (name == null || name.empty) 'Default' else name).asIdentifier.toFirstUpper	
+	}
+	
+	def dispatch type(InterfaceScope it) {
+		flow.module + 'Iface' + (if (name == null || name.empty) '' else name).asIdentifier.toFirstUpper	
+	}
+	
+	def dispatch instance(InterfaceScope it) {
+		'iface' + (if (name == null || name.empty) '' else name).asIdentifier.toFirstUpper	
+	}
+	
+	def dispatch instance(Scope it) {
+		'timeEvents'
+	}
+	
+	def dispatch type(InternalScope it) {
+		flow.module + 'Internal'	
+	}
+	
+	def dispatch type(Scope it) {
+		flow.module + 'TimeEvents'	
+	}
+	
+	def dispatch instance(InternalScope it) {
+		'internal'
+	}
+	
+	def functionPrefix(Scope it) {
+		type.toFirstLower	
+	}
+
+
+	def asRaiser(EventDefinition it) {
+		scope.functionPrefix + '_raise_' + name.asIdentifier.toFirstLower	
+	}
+	
+	def asRaised(EventDefinition it) {
+		scope.functionPrefix + '_israised_' + name.asIdentifier.toFirstLower	
+	}
+	
+	def asGetter(EventDefinition it) {
+		scope.functionPrefix + '_get_' + name.asIdentifier.toFirstLower	+ '_value'
+	}
+	
+	def asGetter(VariableDefinition it) {
+		scope.functionPrefix + '_get_' + name.asIdentifier.toFirstLower	
+	}
+	
+	def asSetter(VariableDefinition it) {
+		scope.functionPrefix + '_set_' + name.asIdentifier.toFirstLower	
+	}
+	
+	
+	def h(String it) { it + ".h" }
+	def c(String it) { it + ".c" }
+	
+	def define(String it) { it.replaceAll('\\.', '_').toUpperCase }
+	
+	
+	def asIdentifier(String it) {
+		replaceAll('[^a-z&&[^A-Z&&[^0-9]]]', '_')
+	}
+	
+}

+ 42 - 0
plugins/org.yakindu.sct.generator.c/src/org/yakindu/sct/generator/c/Navigation.xtend

@@ -0,0 +1,42 @@
+package org.yakindu.sct.generator.c
+
+import org.yakindu.sct.model.sexec.ExecutionFlow
+import org.yakindu.sct.model.stext.stext.InterfaceScope
+import java.util.Collection
+import org.yakindu.sct.model.sexec.StateVector
+import org.yakindu.sct.model.stext.stext.InternalScope
+import org.yakindu.sct.model.sgraph.Scope
+import org.yakindu.sct.model.sexec.TimeEvent
+import org.yakindu.sct.model.sgraph.Declaration
+import org.yakindu.sct.model.stext.stext.EventDefinition
+
+class Navigation {
+	
+	def ExecutionFlow flow(Scope scope) {
+		if (scope.eContainer instanceof ExecutionFlow) scope.eContainer as ExecutionFlow
+		else null
+	}
+	
+	def ExecutionFlow flow(Declaration it) {
+		scope?.flow
+	}
+	
+	def Scope scope(Declaration it) {
+		if (eContainer instanceof Scope) eContainer as Scope
+		else null
+	}
+	
+	
+	def empty (StateVector sv) {
+		sv == null || sv.size == 0
+	}
+	
+	def isTimed (ExecutionFlow it) {
+		scopes.filter( s | s.declarations.filter( typeof(TimeEvent) ).size > 0).size > 0
+	}
+	
+	def hasValue (EventDefinition it) {
+		type != null && type.name != 'void'
+	}
+	
+}

+ 161 - 0
plugins/org.yakindu.sct.generator.c/src/org/yakindu/sct/generator/c/Statemachine.xtend

@@ -0,0 +1,161 @@
+package org.yakindu.sct.generator.c
+
+import com.google.inject.Inject
+import org.eclipse.xtext.generator.IFileSystemAccess
+import org.yakindu.sct.model.sexec.ExecutionFlow
+import org.yakindu.sct.model.sgraph.Statechart
+import org.yakindu.sct.model.stext.stext.InterfaceScope
+import org.yakindu.sct.model.stext.stext.EventDefinition
+import org.yakindu.sct.model.stext.stext.VariableDefinition
+import org.yakindu.sct.model.stext.stext.InternalScope
+import org.yakindu.sct.model.sgraph.Declaration
+import org.yakindu.sct.model.sgraph.Scope
+import org.yakindu.sct.model.stext.stext.StatechartScope
+import org.yakindu.sct.model.sexec.TimeEvent
+import org.yakindu.sct.model.stext.stext.Direction
+
+class Statemachine {
+	
+	@Inject extension Naming cNaming
+	@Inject extension Navigation
+	@Inject extension Base
+	
+	def generateStatemachineH(ExecutionFlow flow, Statechart sc, IFileSystemAccess fsa) {
+		 fsa.generateFile(flow.module.h, flow.statemachineHContent )
+	}
+	
+	
+	
+	def statemachineHContent(ExecutionFlow it) '''
+			#ifndef «module.define»_H_
+			#define «module.define»_H_
+
+			#include "«typesModule.h»"
+			#include "«timerModule.h»"
+
+			#ifdef __cplusplus
+			extern "C" {
+			#endif 
+
+			«statesEnumDecl»
+			
+			«FOR s : it.scopes»«s.scopeTypeDecl»«ENDFOR»
+			
+			«statemachineTypeDecl»
+
+			/* Initializes the «type» state machine data structures. Must be called before first usage.*/
+			extern void «type.toFirstLower»_init(«type»* handle «IF timed», «timerType»* timer«ENDIF»);
+			
+			/* Activates the state machine */
+			extern void «type.toFirstLower»_enter(«type»* handle);
+			
+			/* Deactivates the state machine */
+			extern void «type.toFirstLower»_exit(«type»* handle);
+			
+			/* Performs a 'run to completion' step. */
+			extern void «type.toFirstLower»_runCycle(«type»* handle);
+
+			«FOR s : it.scopes.filter( typeof(InterfaceScope) )»
+			«s.scopeFunctionPrototypes»
+			
+			«ENDFOR»
+			
+			#ifdef __cplusplus
+			}
+			#endif 
+			
+			#endif /* «module.define»_H_ */
+	'''
+
+	def statesEnumDecl(ExecutionFlow it) '''
+		// enumeration of all states 
+		typedef enum {
+			«FOR state : states »
+			«state.name.asIdentifier» ,
+			«ENDFOR»
+			last_state
+		} «statesEnumType»;
+	'''
+
+
+	def dispatch structDeclaration(EventDefinition it) '''
+		sc_boolean «name.asIdentifier»_raised;
+		«IF type != null && type.name != 'void'»«type.cPrimitive»  «name.asIdentifier»_value;«ENDIF»
+	'''
+
+	def dispatch structDeclaration(TimeEvent it) '''
+		sc_boolean «name.asIdentifier»_raised;
+	'''
+
+	def dispatch structDeclaration(VariableDefinition it) '''
+		«IF type.name != 'void'»«type.cPrimitive»  «name.asIdentifier»;«ENDIF»
+	'''
+	
+	def dispatch structDeclaration(Declaration it) ''''''
+	
+	
+	def dispatch scopeTypeDecl(Scope it) '''
+		// Type definition of the data structure for the «it.type» interface scope.
+		typedef struct {
+			«FOR d : declarations »
+			«d.structDeclaration »
+			«ENDFOR»
+		} «it.type»;
+
+	'''	
+
+//	def dispatch scopeTypeDecl(Scope it) ''''''	
+
+	def statemachineTypeDecl(ExecutionFlow it) '''
+		// the maximum number of orthogonal states defines the dimension of the state configuration vector.
+		#define MAX_ORTHOGONAL_STATES «stateVector.size»
+		«IF ! historyVector.empty»
+		// dimension of the state configuration vector for history states
+		#define MAX_HISTORY_STATES «historyVector.size»«ENDIF»
+		
+		// Type definition of the data structure for the «type» state machine.
+		// This data structure has to be allocated by the client code.
+		typedef struct {
+			«statesEnumType» stateConfVector[MAX_ORTHOGONAL_STATES];
+			«IF ! historyVector.empty»«statesEnumType» historyVector[MAX_HISTORY_STATES];«ENDIF»
+			sc_ushort stateConfVectorPosition; 
+			
+			«FOR iScope : scopes »
+			«iScope.type» «iScope.instance»;
+			«ENDFOR»
+			
+			«IF timed»SCTimer*    timer;«ENDIF»
+		} «type»;
+	'''
+
+
+	def dispatch scopeFunctionPrototypes(StatechartScope it) '''
+		«FOR d : declarations »
+		«d.functionPrototypes »
+		«ENDFOR»
+	'''	
+
+	def dispatch scopeFunctionPrototypes(Object it) ''''''	
+	
+
+	def dispatch functionPrototypes(Declaration it) ''''''
+
+	def dispatch functionPrototypes(EventDefinition it) '''
+		«IF direction == Direction::IN»
+		extern «type.cPrimitive» «asRaiser»(«it.flow.type»* handle«valueParams»);
+		«ELSE»
+		extern sc_boolean «asRaised»(«it.flow.type»* handle);
+		extern «type.cPrimitive» «asGetter»(«it.flow.type»* handle);
+		«ENDIF»
+	'''
+
+	def dispatch functionPrototypes(VariableDefinition it) '''
+		extern «type.cPrimitive» «it.asGetter»(«it.flow.type»* handle);
+		«IF ! readonly »extern void «asSetter»(«it.flow.type»* handle, «type.cPrimitive» value);«ENDIF»
+	'''
+
+	def valueParams(EventDefinition it) {
+		if (hasValue) ', ' + type.cPrimitive + ' value' 
+		else ''
+	}
+}

+ 67 - 0
plugins/org.yakindu.sct.generator.c/src/org/yakindu/sct/generator/c/Timer.xtend

@@ -0,0 +1,67 @@
+package org.yakindu.sct.generator.c
+
+import com.google.inject.Inject
+import org.eclipse.xtext.generator.IFileSystemAccess
+import org.yakindu.sct.model.sexec.ExecutionFlow
+import org.yakindu.sct.model.sgraph.Statechart
+
+class Timer {
+	
+	@Inject extension Naming
+	
+	def generateTimerH(ExecutionFlow flow, Statechart sc, IFileSystemAccess fsa) {
+		 fsa.generateFile(flow.timerModule.h, flow.timerHContent)
+	}
+	
+	def generateTimerC(ExecutionFlow flow, Statechart sc, IFileSystemAccess fsa) {
+		 fsa.generateFile(flow.timerModule.c, flow.timerCContent)
+	}
+	
+	
+	def timerHContent(ExecutionFlow it)  '''
+		#ifndef «timerModule.define»_H_
+		#define «timerModule.define»_H_
+		
+		#include "«typesModule.h»"
+		
+		#ifdef __cplusplus
+		extern "C" {
+		#endif 
+		
+		typedef void(*setTimerFPtr)(uint32_t evid, const uint32_t time_ms, sc_boolean periodic);
+		typedef void(*unsetTimerFPtr)(const uint32_t evid);
+		
+		typedef struct {
+		
+			/* callback functions */
+			setTimerFPtr   setTimer;
+			unsetTimerFPtr unsetTimer;
+		
+		}  «timerType»;
+		
+		extern void sc_timer_setFPtr(«timerType»* handle, setTimerFPtr stfptr, unsetTimerFPtr utfptr);
+		extern void sc_timer_exit(«timerType»* handle);
+		
+		#ifdef __cplusplus
+		}
+		#endif 
+		 
+		#endif /* «timerModule.define»_H_ */
+	'''
+		
+	def timerCContent(ExecutionFlow it) '''
+		#include "«timerModule.h»"
+		
+		void sc_timer_setFPtr(«timerType»* handle, setTimerFPtr stfptr, unsetTimerFPtr utfptr)
+		{
+		
+			handle->setTimer = stfptr;
+			handle->unsetTimer = utfptr;
+		
+		}
+		
+		void sc_timer_exit(«timerType»* handle)
+		{
+		}
+	'''
+}

+ 41 - 0
plugins/org.yakindu.sct.generator.c/src/org/yakindu/sct/generator/c/Types.xtend

@@ -0,0 +1,41 @@
+package org.yakindu.sct.generator.c
+
+import org.yakindu.sct.model.sexec.ExecutionFlow
+import org.yakindu.sct.model.sgraph.Statechart
+import org.eclipse.xtext.generator.IFileSystemAccess
+import com.google.inject.Inject
+
+class Types {
+	
+	@Inject extension Naming
+	 
+	def generateTypesH(ExecutionFlow flow, Statechart sc, IFileSystemAccess fsa) {
+		 fsa.generateFile(flow.typesModule.h, flow.typesHContent)
+	}
+	
+	
+	def typesHContent(ExecutionFlow it) '''
+		#ifndef «typesModule.define»_H_
+		#define «typesModule.define»_H_
+		
+		#ifdef __cplusplus
+		extern "C" {
+		#endif 
+		
+		#include <stdint.h>
+		 				
+		typedef int_fast16_t sc_short;
+		typedef uint_fast16_t sc_ushort;
+		typedef int32_t sc_integer; 
+		typedef uint32_t sc_uinteger; 
+		typedef enum { bool_false = 0, bool_true = 1 } sc_boolean;
+		typedef double sc_real;
+		typedef char* sc_string;
+		
+		#ifdef __cplusplus
+		}
+		#endif 
+		 
+		#endif /* «typesModule.define»_H_ */
+	'''
+}

+ 1 - 0
plugins/org.yakindu.sct.generator.core/META-INF/MANIFEST.MF

@@ -20,6 +20,7 @@ Require-Bundle: org.eclipse.ui,
  org.yakindu.sct.model.sgen;bundle-version="1.0.0",
  org.eclipse.core.expressions,
  org.yakindu.base.types;bundle-version="1.0.0",
+ org.eclipse.xtext.builder;bundle-version="2.3.0",
  org.yakindu.sct.commons;bundle-version="1.0.0"
 Bundle-RequiredExecutionEnvironment: J2SE-1.5
 Bundle-ActivationPolicy: lazy

+ 4 - 1
plugins/org.yakindu.sct.generator.core/build.properties

@@ -3,5 +3,8 @@ output.. = bin/
 bin.includes = META-INF/,\
                .,\
                plugin.xml,\
-               library/
+               library/,\
+               src/org/yakindu/sct/generator/core/extensions/ExecutionModelCoreExtensions.ext,\
+               src/org/yakindu/sct/generator/core/extensions/TypeAnalyzerExtensions.ext,\
+               src/org/yakindu/sct/generator/core/extensions/WorkspaceCoreExtensions.ext
 src.includes = library/

+ 1 - 1
plugins/org.yakindu.sct.generator.core/src/org/yakindu/sct/generator/core/impl/AbstractSExecModelGenerator.java

@@ -62,7 +62,7 @@ public abstract class AbstractSExecModelGenerator extends
 		if (this instanceof IExecutionFlowGenerator) {
 			IExecutionFlowGenerator flowGenerator = (IExecutionFlowGenerator) this;
 			flowGenerator.generate(createExecutionFlow(statechart, entry),
-					entry);
+					entry, null);
 		}
 		super.runGenerator(statechart, entry);
 	}

+ 29 - 2
plugins/org.yakindu.sct.generator.core/src/org/yakindu/sct/generator/core/impl/GenericJavaBasedGenerator.java

@@ -10,15 +10,18 @@
  */
 package org.yakindu.sct.generator.core.impl;
 
+import static org.yakindu.sct.generator.core.features.ICoreFeatureConstants.OUTLET_FEATURE_TARGET_FOLDER;
 import static org.yakindu.sct.generator.core.features.impl.IGenericJavaFeatureConstants.CONFIGURATION_MODULE;
 import static org.yakindu.sct.generator.core.features.impl.IGenericJavaFeatureConstants.GENERATOR_CLASS;
 import static org.yakindu.sct.generator.core.features.impl.IGenericJavaFeatureConstants.GENERATOR_PROJECT;
 import static org.yakindu.sct.generator.core.features.impl.IGenericJavaFeatureConstants.TEMPLATE_FEATURE;
+import static org.yakindu.sct.generator.core.util.GeneratorUtils.getOutletFeatureConfiguration;
 
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.Path;
 import org.eclipse.emf.common.util.URI;
+import org.eclipse.xtext.generator.IFileSystemAccess;
 import org.eclipse.xtext.util.Strings;
 import org.yakindu.sct.commons.WorkspaceClassLoaderFactory;
 import org.yakindu.sct.generator.core.AbstractWorkspaceGenerator;
@@ -38,15 +41,17 @@ import com.google.inject.util.Modules;
  */
 public class GenericJavaBasedGenerator extends AbstractSExecModelGenerator {
 
+	
 	@Override
 	protected com.google.inject.Injector createInjector(GeneratorEntry entry) {
 		return Guice.createInjector(createModule(entry));
 	}
 
 	@Override
-	protected Module createModule(GeneratorEntry entry) {
+	protected Module createModule(final GeneratorEntry entry) {
 		Module defaultModule = super.createModule(entry);
 
+		
 		String overridingModuleClass = null;
 		FeatureConfiguration featureConfiguration = entry
 				.getFeatureConfiguration(TEMPLATE_FEATURE);
@@ -95,6 +100,7 @@ public class GenericJavaBasedGenerator extends AbstractSExecModelGenerator {
 		String templateClass = entry.getFeatureConfiguration(TEMPLATE_FEATURE)
 				.getParameterValue(GENERATOR_CLASS).getStringValue();
 		final ClassLoader classLoader = getClassLoader(entry);
+		IFileSystemAccess fsa = getFileSystemAccess(entry);
 		try {
 			Class<?> delegateGeneratorClass = (Class<?>) classLoader
 					.loadClass(templateClass);
@@ -105,7 +111,7 @@ public class GenericJavaBasedGenerator extends AbstractSExecModelGenerator {
 			}
 			if (delegate instanceof IExecutionFlowGenerator) {
 				IExecutionFlowGenerator flowGenerator = (IExecutionFlowGenerator) delegate;
-				flowGenerator.generate(createExecutionFlow(flow, entry), entry);
+				flowGenerator.generate(createExecutionFlow(flow, entry), entry, fsa);
 			}
 			if (delegate instanceof ISGraphGenerator) {
 				ISGraphGenerator graphGenerator = (ISGraphGenerator) delegate;
@@ -138,4 +144,25 @@ public class GenericJavaBasedGenerator extends AbstractSExecModelGenerator {
 		return project;
 	}
 
+	
+	/**
+	 * Provides a pre configured IFileSystemAccess instance
+	 */
+	public IFileSystemAccess getFileSystemAccess(GeneratorEntry entry) {
+		
+		SimpleResourceFileSystemAccess fileSystemAccess = new SimpleResourceFileSystemAccess(); 
+		fileSystemAccess.setProject(getTargetProject(entry));
+		
+		FeatureConfiguration outletConfig = getOutletFeatureConfiguration(entry);
+		String targetFolder = outletConfig
+				.getParameterValue(OUTLET_FEATURE_TARGET_FOLDER).getExpression().toString();		
+		
+		fileSystemAccess.setOutputPath(IFileSystemAccess.DEFAULT_OUTPUT, targetFolder);
+		
+		
+		return fileSystemAccess;
+	}
+	
+	
+	
 }

+ 2 - 1
plugins/org.yakindu.sct.generator.core/src/org/yakindu/sct/generator/core/impl/IExecutionFlowGenerator.java

@@ -1,9 +1,10 @@
 package org.yakindu.sct.generator.core.impl;
 
+import org.eclipse.xtext.generator.IFileSystemAccess;
 import org.yakindu.sct.model.sexec.ExecutionFlow;
 import org.yakindu.sct.model.sgen.GeneratorEntry;
 
 public interface IExecutionFlowGenerator {
 
-	abstract void generate(ExecutionFlow flow, GeneratorEntry entry);
+	abstract void generate(ExecutionFlow flow, GeneratorEntry entry, IFileSystemAccess fsa);
 }

+ 61 - 0
plugins/org.yakindu.sct.generator.core/src/org/yakindu/sct/generator/core/impl/SimpleResourceFileSystemAccess.java

@@ -0,0 +1,61 @@
+package org.yakindu.sct.generator.core.impl;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.xtext.builder.EclipseResourceFileSystemAccess2;
+import org.eclipse.xtext.generator.OutputConfiguration;
+import org.eclipse.xtext.util.StringInputStream;
+
+public class SimpleResourceFileSystemAccess extends EclipseResourceFileSystemAccess2 {
+
+	
+	public void generateFile(String fileName, String outputName, CharSequence contents) {
+
+		OutputConfiguration outputConfig = getOutputConfig(outputName);
+		
+		IFolder folder = getFolder(outputConfig);
+		
+		if (!folder.exists()) {
+			if (outputConfig.isCreateOutputDirectory()) {
+				try {
+					createFolder(folder);
+				} catch (CoreException e) {
+					throw new RuntimeException(e);
+				}
+			} else {
+				return;
+			}
+		}
+		
+		IFile file = getFile(fileName, outputName);
+		CharSequence postProcessedContent = postProcess(fileName, outputName, contents);
+		String contentsAsString = postProcessedContent.toString(); 
+		if (file.exists()) {
+			if (outputConfig.isOverrideExistingResources()) {
+				try {
+					StringInputStream newContent = getInputStream(contentsAsString, getEncoding(file));
+					if (hasContentsChanged(file, newContent)) {
+						newContent.reset();
+						file.setContents(newContent, true, true, null);
+						if (file.isDerived() != outputConfig.isSetDerivedProperty()) {
+							setDerived(file, outputConfig.isSetDerivedProperty());
+						}
+					} 
+				} catch (CoreException e) {
+					throw new RuntimeException(e);
+				}
+			}
+		} else {
+			try {
+				ensureParentExists(file);
+				file.create(getInputStream(contentsAsString, getEncoding(file)), true, null);
+				if (outputConfig.isSetDerivedProperty()) {
+					setDerived(file, true);
+				}
+			} catch (CoreException e) {
+				throw new RuntimeException(e);
+			}
+		}
+	}
+}

+ 1 - 0
plugins/org.yakindu.sct.generator.core/src/org/yakindu/sct/generator/core/util/GeneratorUtils.java

@@ -75,6 +75,7 @@ public class GeneratorUtils {
 		return project;
 	}
 
+	/** Gets the target folder path as a File that includes the project location */
 	public static File getTargetFolder(GeneratorEntry entry) {
 		String targetFolder = getOutletFeatureConfiguration(entry)
 				.getParameterValue(

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

@@ -135,3 +135,4 @@ _UI_ExecutionFlow_reactions_feature = Reactions
 _UI_ExecutionFlow_entryAction_feature = Entry Action
 _UI_ExecutionFlow_exitAction_feature = Exit Action
 _UI_ExecutionSynchronization_type = Execution Synchronization
+_UI_ExecutionRegion_nodes_feature = Nodes

+ 24 - 0
plugins/org.yakindu.sct.model.sexec.edit/src/org/yakindu/sct/model/sexec/provider/ExecutionRegionItemProvider.java

@@ -14,6 +14,7 @@ import org.eclipse.emf.common.notify.AdapterFactory;
 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;
@@ -61,10 +62,33 @@ public class ExecutionRegionItemProvider
 		if (itemPropertyDescriptors == null) {
 			super.getPropertyDescriptors(object);
 
+			addNodesPropertyDescriptor(object);
 		}
 		return itemPropertyDescriptors;
 	}
 
+	/**
+	 * This adds a property descriptor for the Nodes feature.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	protected void addNodesPropertyDescriptor(Object object) {
+		itemPropertyDescriptors.add
+			(createItemPropertyDescriptor
+				(((ComposeableAdapterFactory)adapterFactory).getRootAdapterFactory(),
+				 getResourceLocator(),
+				 getString("_UI_ExecutionRegion_nodes_feature"),
+				 getString("_UI_PropertyDescriptor_description", "_UI_ExecutionRegion_nodes_feature", "_UI_ExecutionRegion_type"),
+				 SexecPackage.Literals.EXECUTION_REGION__NODES,
+				 true,
+				 false,
+				 true,
+				 null,
+				 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

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

@@ -52,6 +52,8 @@
         containment="true"/>
     <eStructuralFeatures xsi:type="ecore:EReference" name="historyVector" eType="#//StateVector"
         containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="nodes" upperBound="-1"
+        eType="#//ExecutionNode"/>
   </eClassifiers>
   <eClassifiers xsi:type="ecore:EClass" name="ExecutionEntry" eSuperTypes="#//ExecutionNode"/>
   <eClassifiers xsi:type="ecore:EClass" name="ExecutionChoice" eSuperTypes="#//ExecutionNode"/>

+ 14 - 0
plugins/org.yakindu.sct.model.sexec/model/sexec.ecorediag

@@ -1117,4 +1117,18 @@
     <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_K4NtEKllEeG8AdiDsntVng" id="(0.21768707482993196,0.14285714285714285)"/>
     <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_K4NtEallEeG8AdiDsntVng" id="(0.7843137254901961,0.6666666666666666)"/>
   </edges>
+  <edges xmi:type="notation:Edge" xmi:id="_dOHDkLA6EeGEHaPk4RI2_A" type="3002" source="_niQXgEjtEeGFD_vuePSd-Q" target="_HXl7QBulEeGIWuhy_7gRFw">
+    <children xmi:type="notation:Node" xmi:id="_dOI4wLA6EeGEHaPk4RI2_A" type="4011">
+      <layoutConstraint xmi:type="notation:Location" xmi:id="_dOI4wbA6EeGEHaPk4RI2_A" x="-11" y="13"/>
+    </children>
+    <children xmi:type="notation:Node" xmi:id="_dOJf0LA6EeGEHaPk4RI2_A" type="4012">
+      <layoutConstraint xmi:type="notation:Location" xmi:id="_dOJf0bA6EeGEHaPk4RI2_A" x="-45" y="13"/>
+    </children>
+    <styles xmi:type="notation:ConnectorStyle" xmi:id="_dOHDkbA6EeGEHaPk4RI2_A" lineColor="4210752"/>
+    <styles xmi:type="notation:FontStyle" xmi:id="_dOHDkrA6EeGEHaPk4RI2_A" fontColor="4210752" fontName="Lucida Grande" fontHeight="10"/>
+    <element xmi:type="ecore:EReference" href="sexec.ecore#//ExecutionRegion/nodes"/>
+    <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_dOHDk7A6EeGEHaPk4RI2_A" points="[9, -7, -235, 331]$[137, -115, -107, 223]$[137, -338, -107, 0]$[242, -338, -2, 0]"/>
+    <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_dORboLA6EeGEHaPk4RI2_A" id="(0.7058823529411765,0.19047619047619047)"/>
+    <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_dORbobA6EeGEHaPk4RI2_A" id="(0.029411764705882353,0.5476190476190477)"/>
+  </edges>
 </notation:Diagram>

+ 19 - 0
plugins/org.yakindu.sct.model.sexec/src/org/yakindu/sct/model/sexec/ExecutionRegion.java

@@ -6,6 +6,8 @@
  */
 package org.yakindu.sct.model.sexec;
 
+import org.eclipse.emf.common.util.EList;
+
 
 /**
  * <!-- begin-user-doc -->
@@ -18,6 +20,7 @@ package org.yakindu.sct.model.sexec;
  *   <li>{@link org.yakindu.sct.model.sexec.ExecutionRegion#getDeepEnterSequence <em>Deep Enter Sequence</em>}</li>
  *   <li>{@link org.yakindu.sct.model.sexec.ExecutionRegion#getShallowEnterSequence <em>Shallow Enter Sequence</em>}</li>
  *   <li>{@link org.yakindu.sct.model.sexec.ExecutionRegion#getHistoryVector <em>History Vector</em>}</li>
+ *   <li>{@link org.yakindu.sct.model.sexec.ExecutionRegion#getNodes <em>Nodes</em>}</li>
  * </ul>
  * </p>
  *
@@ -104,4 +107,20 @@ public interface ExecutionRegion extends ExecutionScope {
 	 * @generated
 	 */
 	void setHistoryVector(StateVector value);
+
+	/**
+	 * Returns the value of the '<em><b>Nodes</b></em>' reference list.
+	 * The list contents are of type {@link org.yakindu.sct.model.sexec.ExecutionNode}.
+	 * <!-- begin-user-doc -->
+	 * <p>
+	 * If the meaning of the '<em>Nodes</em>' reference list isn't clear,
+	 * there really should be more of a description here...
+	 * </p>
+	 * <!-- end-user-doc -->
+	 * @return the value of the '<em>Nodes</em>' reference list.
+	 * @see org.yakindu.sct.model.sexec.SexecPackage#getExecutionRegion_Nodes()
+	 * @model
+	 * @generated
+	 */
+	EList<ExecutionNode> getNodes();
 } // ExecutionRegion

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

@@ -752,6 +752,15 @@ public interface SexecPackage extends EPackage {
 	 */
 	int EXECUTION_REGION__HISTORY_VECTOR = EXECUTION_SCOPE_FEATURE_COUNT + 2;
 
+	/**
+	 * The feature id for the '<em><b>Nodes</b></em>' reference list.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 * @ordered
+	 */
+	int EXECUTION_REGION__NODES = EXECUTION_SCOPE_FEATURE_COUNT + 3;
+
 	/**
 	 * The number of structural features of the '<em>Execution Region</em>' class.
 	 * <!-- begin-user-doc -->
@@ -759,7 +768,7 @@ public interface SexecPackage extends EPackage {
 	 * @generated
 	 * @ordered
 	 */
-	int EXECUTION_REGION_FEATURE_COUNT = EXECUTION_SCOPE_FEATURE_COUNT + 3;
+	int EXECUTION_REGION_FEATURE_COUNT = EXECUTION_SCOPE_FEATURE_COUNT + 4;
 
 	/**
 	 * The meta object id for the '{@link org.yakindu.sct.model.sexec.impl.ExecutionEntryImpl <em>Execution Entry</em>}' class.
@@ -2521,6 +2530,17 @@ public interface SexecPackage extends EPackage {
 	 */
 	EReference getExecutionRegion_HistoryVector();
 
+	/**
+	 * Returns the meta object for the reference list '{@link org.yakindu.sct.model.sexec.ExecutionRegion#getNodes <em>Nodes</em>}'.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @return the meta object for the reference list '<em>Nodes</em>'.
+	 * @see org.yakindu.sct.model.sexec.ExecutionRegion#getNodes()
+	 * @see #getExecutionRegion()
+	 * @generated
+	 */
+	EReference getExecutionRegion_Nodes();
+
 	/**
 	 * Returns the meta object for class '{@link org.yakindu.sct.model.sexec.ExecutionEntry <em>Execution Entry</em>}'.
 	 * <!-- begin-user-doc -->
@@ -3464,6 +3484,14 @@ public interface SexecPackage extends EPackage {
 		 */
 		EReference EXECUTION_REGION__HISTORY_VECTOR = eINSTANCE.getExecutionRegion_HistoryVector();
 
+		/**
+		 * The meta object literal for the '<em><b>Nodes</b></em>' reference list feature.
+		 * <!-- begin-user-doc -->
+		 * <!-- end-user-doc -->
+		 * @generated
+		 */
+		EReference EXECUTION_REGION__NODES = eINSTANCE.getExecutionRegion_Nodes();
+
 		/**
 		 * The meta object literal for the '{@link org.yakindu.sct.model.sexec.impl.ExecutionEntryImpl <em>Execution Entry</em>}' class.
 		 * <!-- begin-user-doc -->

+ 38 - 0
plugins/org.yakindu.sct.model.sexec/src/org/yakindu/sct/model/sexec/impl/ExecutionRegionImpl.java

@@ -6,11 +6,15 @@
  */
 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.EObjectResolvingEList;
+import org.yakindu.sct.model.sexec.ExecutionNode;
 import org.yakindu.sct.model.sexec.ExecutionRegion;
 import org.yakindu.sct.model.sexec.Sequence;
 import org.yakindu.sct.model.sexec.SexecPackage;
@@ -26,6 +30,7 @@ import org.yakindu.sct.model.sexec.StateVector;
  *   <li>{@link org.yakindu.sct.model.sexec.impl.ExecutionRegionImpl#getDeepEnterSequence <em>Deep Enter Sequence</em>}</li>
  *   <li>{@link org.yakindu.sct.model.sexec.impl.ExecutionRegionImpl#getShallowEnterSequence <em>Shallow Enter Sequence</em>}</li>
  *   <li>{@link org.yakindu.sct.model.sexec.impl.ExecutionRegionImpl#getHistoryVector <em>History Vector</em>}</li>
+ *   <li>{@link org.yakindu.sct.model.sexec.impl.ExecutionRegionImpl#getNodes <em>Nodes</em>}</li>
  * </ul>
  * </p>
  *
@@ -59,6 +64,15 @@ public class ExecutionRegionImpl extends ExecutionScopeImpl implements Execution
 	 * @ordered
 	 */
 	protected StateVector historyVector;
+	/**
+	 * The cached value of the '{@link #getNodes() <em>Nodes</em>}' reference list.
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @see #getNodes()
+	 * @generated
+	 * @ordered
+	 */
+	protected EList<ExecutionNode> nodes;
 	/**
 	 * <!-- begin-user-doc -->
 	 * <!-- end-user-doc -->
@@ -207,6 +221,18 @@ public class ExecutionRegionImpl extends ExecutionScopeImpl implements Execution
 			eNotify(new ENotificationImpl(this, Notification.SET, SexecPackage.EXECUTION_REGION__HISTORY_VECTOR, newHistoryVector, newHistoryVector));
 	}
 
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public EList<ExecutionNode> getNodes() {
+		if (nodes == null) {
+			nodes = new EObjectResolvingEList<ExecutionNode>(ExecutionNode.class, this, SexecPackage.EXECUTION_REGION__NODES);
+		}
+		return nodes;
+	}
+
 	/**
 	 * <!-- begin-user-doc -->
 	 * <!-- end-user-doc -->
@@ -239,6 +265,8 @@ public class ExecutionRegionImpl extends ExecutionScopeImpl implements Execution
 				return getShallowEnterSequence();
 			case SexecPackage.EXECUTION_REGION__HISTORY_VECTOR:
 				return getHistoryVector();
+			case SexecPackage.EXECUTION_REGION__NODES:
+				return getNodes();
 		}
 		return super.eGet(featureID, resolve, coreType);
 	}
@@ -248,6 +276,7 @@ public class ExecutionRegionImpl extends ExecutionScopeImpl implements Execution
 	 * <!-- end-user-doc -->
 	 * @generated
 	 */
+	@SuppressWarnings("unchecked")
 	@Override
 	public void eSet(int featureID, Object newValue) {
 		switch (featureID) {
@@ -260,6 +289,10 @@ public class ExecutionRegionImpl extends ExecutionScopeImpl implements Execution
 			case SexecPackage.EXECUTION_REGION__HISTORY_VECTOR:
 				setHistoryVector((StateVector)newValue);
 				return;
+			case SexecPackage.EXECUTION_REGION__NODES:
+				getNodes().clear();
+				getNodes().addAll((Collection<? extends ExecutionNode>)newValue);
+				return;
 		}
 		super.eSet(featureID, newValue);
 	}
@@ -281,6 +314,9 @@ public class ExecutionRegionImpl extends ExecutionScopeImpl implements Execution
 			case SexecPackage.EXECUTION_REGION__HISTORY_VECTOR:
 				setHistoryVector((StateVector)null);
 				return;
+			case SexecPackage.EXECUTION_REGION__NODES:
+				getNodes().clear();
+				return;
 		}
 		super.eUnset(featureID);
 	}
@@ -299,6 +335,8 @@ public class ExecutionRegionImpl extends ExecutionScopeImpl implements Execution
 				return shallowEnterSequence != null;
 			case SexecPackage.EXECUTION_REGION__HISTORY_VECTOR:
 				return historyVector != null;
+			case SexecPackage.EXECUTION_REGION__NODES:
+				return nodes != null && !nodes.isEmpty();
 		}
 		return super.eIsSet(featureID);
 	}

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

@@ -575,6 +575,15 @@ public class SexecPackageImpl extends EPackageImpl implements SexecPackage {
 		return (EReference)executionRegionEClass.getEStructuralFeatures().get(2);
 	}
 
+	/**
+	 * <!-- begin-user-doc -->
+	 * <!-- end-user-doc -->
+	 * @generated
+	 */
+	public EReference getExecutionRegion_Nodes() {
+		return (EReference)executionRegionEClass.getEStructuralFeatures().get(3);
+	}
+
 	/**
 	 * <!-- begin-user-doc -->
 	 * <!-- end-user-doc -->
@@ -1247,6 +1256,7 @@ public class SexecPackageImpl extends EPackageImpl implements SexecPackage {
 		createEReference(executionRegionEClass, EXECUTION_REGION__DEEP_ENTER_SEQUENCE);
 		createEReference(executionRegionEClass, EXECUTION_REGION__SHALLOW_ENTER_SEQUENCE);
 		createEReference(executionRegionEClass, EXECUTION_REGION__HISTORY_VECTOR);
+		createEReference(executionRegionEClass, EXECUTION_REGION__NODES);
 
 		executionEntryEClass = createEClass(EXECUTION_ENTRY);
 
@@ -1445,6 +1455,7 @@ public class SexecPackageImpl extends EPackageImpl implements SexecPackage {
 		initEReference(getExecutionRegion_DeepEnterSequence(), this.getSequence(), null, "deepEnterSequence", null, 0, 1, ExecutionRegion.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
 		initEReference(getExecutionRegion_ShallowEnterSequence(), this.getSequence(), null, "shallowEnterSequence", null, 0, 1, ExecutionRegion.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
 		initEReference(getExecutionRegion_HistoryVector(), this.getStateVector(), null, "historyVector", null, 0, 1, ExecutionRegion.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
+		initEReference(getExecutionRegion_Nodes(), this.getExecutionNode(), null, "nodes", null, 0, -1, ExecutionRegion.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED);
 
 		initEClass(executionEntryEClass, ExecutionEntry.class, "ExecutionEntry", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS);
 

+ 170 - 66
plugins/org.yakindu.sct.model.sexec/src/org/yakindu/sct/model/sexec/transformation/BehaviorMapping.xtend

@@ -34,7 +34,14 @@ import org.yakindu.sct.model.stext.stext.TimeEventSpec
 import org.yakindu.sct.model.sgraph.Vertex
 import org.yakindu.sct.model.sgraph.Pseudostate
 import org.yakindu.sct.model.sgraph.Synchronization
-import org.yakindu.sct.model.sexec.ExecutionSynchronization
+import org.yakindu.sct.model.sexec.ExecutionSynchronization
+import apple.awt.CRenderer$Tracer
+import org.yakindu.sct.model.sexec.ExecutionNode
+import org.yakindu.sct.model.sgraph.FinalState
+import org.yakindu.sct.model.sexec.ExecutionEntry
+import java.util.ArrayList
+import java.util.HashSet
+import java.util.Set
 
  
 
@@ -111,7 +118,14 @@ class BehaviorMapping {
 
 	def ExecutionSynchronization mapSyncTransition(Synchronization sync) {
 		val _sync = sync.create
-		_sync.reactions.addAll( sync.outgoingTransitions.map(t | t.mapTransition) )
+		val transitions = sync.outgoingTransitions
+		val r = transitions.head.create
+		_sync.reactions.add(r)
+		
+		// map multiple transitions to one reaction
+		r.effect = transitions.mapToEffect(r)
+		
+//		_sync.reactions.addAll( sync.outgoingTransitions.map(t | t.mapTransition) )
 		return _sync
 	}
 
@@ -229,7 +243,7 @@ class BehaviorMapping {
 	def dispatch Reaction mapTransition(Transition t, Vertex source, Vertex target) {
 		val r = t.create 
 		if (t.trigger != null) r.check = mapToCheck(t.trigger)
-		r.effect = mapToEffect(t, r)
+		r.effect = mapToEffect(newArrayList(t), r)
 		
 		return r
 	}
@@ -258,7 +272,11 @@ class BehaviorMapping {
 		var Statement condition = r.check.condition
 //		if (t.trigger != null) condition = t.trigger.buildCondition
 		
-		for ( trans : target.incomingTransitions.filter( trans | trans != t )) { 
+		val joinTransitions = target.incomingTransitions
+			.filter( jt | jt.source instanceof State)
+			.sortBy( jt | (jt.source as State).create.stateVector.offset )
+		
+		for ( trans : joinTransitions.filter( trans | trans != t )) { 
 			if (trans.source instanceof State) { 
 				condition = condition.conjunct(stext.active(trans.source as State))
 				if (trans.trigger != null) condition = condition.conjunct(trans.trigger.buildCondition)			
@@ -266,9 +284,8 @@ class BehaviorMapping {
 		}
 		r.check.condition = condition	
 		
-		// map effects
-		// TODO: add effects of sibling transitions
-		r.effect = mapToEffect(t, r)
+		// map effects of all transitions as a compound effect
+		r.effect = mapToEffect(joinTransitions, r)
 		
 		return r
 	}
@@ -363,69 +380,156 @@ class BehaviorMapping {
 		if (trace.addTraceSteps) { sequence.steps += r.newTraceReactionFired() }
 		
 
-		// define entry behavior of the transition
-		
-		// first process all composite states on the path to the target state in top-down-order
-		t.entryScopes().drop(1).toList.reverse.fold(sequence, [seq, scope | {
-			if (scope instanceof ExecutionRegion) { 
-				// if we enter a region than we have to process the sibling regions
-			
-				val siblingRegions = scope.superScope.subScopes
-				
-				// process higher order sibling regions
-				for ( region : siblingRegions.take(siblingRegions.indexOf(scope)) ) {
-					if (region.enterSequence != null) {
-						seq.steps.add(region.enterSequence.newCall)
-					}
-				}
-			} 
-			
-			if (scope instanceof ExecutionState) {
-				// perform entry on the transition path 			
-				if ((scope as ExecutionState).entryAction != null) seq.steps.add((scope as ExecutionState).entryAction.newCall)
-				if ( trace.addTraceSteps ) seq.steps.add( (scope as ExecutionState).newTraceStateEntered )
-				
-			}
-			seq
-		}])
-		
-		
-		// second process the target state entry behavior
-		if (t.target != null ) {
-
-			// perform entry on the transition path 			
-			if ( t.target instanceof RegularState) {
-				sequence.steps.add((t.target as RegularState).create.enterSequence.newCall )	
-			} else if ( t.target instanceof Choice ) {
-				sequence.steps.add((t.target as Choice).create.reactSequence.newCall )	
-			} else if ( t.target instanceof Entry ) {
-				sequence.steps.add((t.target as Entry).create.reactSequence.newCall )	
-			} else if ( t.target instanceof Synchronization ) {
-				sequence.steps.add((t.target as Synchronization).create.reactSequence.newCall )	
-			}
-		}
-		
-		
-		// third - process all entry behavior that has to be executed after the target state behavior in bottom-up-order
+		// define entry behavior of the transition
+		
+		sequence.steps.addAll( mapToStateConfigurationEnterSequence( newArrayList(t) ).steps )
 		
-		t.entryScopes().drop(1).fold(sequence, [seq, scope | {
-			if (scope instanceof ExecutionRegion) { 
-				// if we enter a region than we have to process the sibling regions
-			
-				val siblingRegions = scope.superScope.subScopes
-				
-				// process lower order sibling regions 
-				for ( region : siblingRegions.drop(siblingRegions.indexOf(scope)+1) ) {
-					if (region.enterSequence != null) {
-						seq.steps.add(region.enterSequence.newCall)
-					}
-				}
-			} 
-			seq
-		}])
 		
 		return sequence
 	}
+	
+	/**
+	 * Creates a compound effect that can consist of multiple transitions.
+	 */
+	def Sequence mapToEffect(List<Transition> transitions, Reaction r) {
+		val sequence = sexec.factory.createSequence 
+
+		// define exit behavior of transition
+		
+		// first process the exit behavior of orthogonal states that hase to be performed before source exit
+		val exitStates = transitions.get(0).exitStates.toList
+		for ( t : transitions ) {
+			exitStates.retainAll(t.exitStates.toList)
+		}
+		val topExitState = exitStates.last
+		
+		if (topExitState != null) {
+			val exitSequence = topExitState.create.exitSequence
+			if (exitSequence != null) {
+				sequence.steps.add(exitSequence.newCall)
+			}
+		}
+
+		// map transition actions
+		for ( t : transitions ) {
+			if (t.effect != null) sequence.steps.add(t.effect.mapEffect)	
+			if (trace.addTraceSteps) { sequence.steps += t.create.newTraceReactionFired() }
+		}
+	
+	
+		// define entry behavior of the transition	
+		sequence.steps.addAll( mapToStateConfigurationEnterSequence( transitions ).steps )
+		
+		return sequence
+	}
+	
+	/**
+	 * Calcuates a sequence to enter one or more states. Entering multiple states is required for fork, where parts of a state 
+	 * configuration is specified.
+	 */
+	def Sequence mapToStateConfigurationEnterSequence(List<Transition> transitions) {
+	
+		// precondition : common source vertex
+		// ? precondition : targets are Regular States ?
+		
+		val sequence = sexec.factory.createSequence 
+
+		// determine start entry scope
+		val entryScopes = transitions.get(0).entryScopes.drop(1).toList.reverse
+		for ( t: transitions ) {
+			entryScopes.retainAll(t.entryScopes)
+		}
+		val entryScope = entryScopes.head
+		
+		// determine all target vertices
+		val targets = transitions.map( t | t.target.mapped)
+		
+		// recursively extend the sequence by entering the scope for the specified targets		
+		if (entryScope != null) entryScope.addEnterStepsForTargetsToSequence( targets, sequence)	
+		else {
+			for ( t : targets ) t.addEnterStepsForTargetsToSequence(targets, sequence)
+ 		}	
+	
+		return sequence
+	}
+	
+	
+
+	def dispatch void addEnterStepsForTargetsToSequence(ExecutionState it, List<ExecutionNode> targets, Sequence seq) {
+
+		if ( targets.contains(it) ) {
+			seq.steps.add( it.enterSequence.newCall )		
+		}
+		else {
+			if ( it.entryAction != null ) seq.steps.add(it.entryAction.newCall)
+			if ( trace.addTraceSteps ) seq.steps.add(it.newTraceStateEntered)
+			
+			for (  subScope : it.subScopes ) {
+				subScope.addEnterStepsForTargetsToSequence(targets, seq)
+			}
+		}
+
+	}
+
+
+	def dispatch void addEnterStepsForTargetsToSequence(ExecutionRegion it, List<ExecutionNode> targets, Sequence seq) {
+		
+		// if a target is a direct node
+		val target =  targets.filter( t | it.nodes.contains( t )).head 
+		if (target != null) {
+			target.addEnterStepsForTargetsToSequence(targets, seq)
+			return
+		}
+		
+		// if the execution region contains targets 
+		if ( allNodes.exists( n | targets.contains(n) ) ) {
+			for ( s : subScopes ) {
+				if ( s.allNodes.exists( n | targets.contains(n)))
+					s.addEnterStepsForTargetsToSequence(targets, seq)
+			}
+		} else {
+			seq.steps.add(it.enterSequence.newCall)
+		}
+	}
+	
+	
+	def dispatch Set<ExecutionNode> allNodes(ExecutionRegion it) {
+		val allNodes = new HashSet<ExecutionNode>()
+		allNodes.addAll(nodes)
+
+		for ( s : subScopes ) {
+			allNodes.addAll( s.allNodes )
+		}
+		
+		allNodes
+	}
+	
+	def dispatch Set<ExecutionNode> allNodes(ExecutionState it) {
+		val allNodes = new HashSet<ExecutionNode>()
+		allNodes.add(it)
+
+		for ( s : subScopes ) {
+			allNodes.addAll( s.allNodes )
+		}
+		
+		allNodes
+	}
+		
+	
+	def dispatch void addEnterStepsForTargetsToSequence(ExecutionChoice it, List<ExecutionNode> targets, Sequence seq) {
+		seq.steps.add( reactSequence.newCall )	
+	}
+	
+	def dispatch void addEnterStepsForTargetsToSequence(ExecutionEntry it, List<ExecutionNode> targets, Sequence seq) {
+		seq.steps.add( reactSequence.newCall )	
+	}
+	
+	def dispatch void addEnterStepsForTargetsToSequence(ExecutionSynchronization it, List<ExecutionNode> targets, Sequence seq) {
+		seq.steps.add( reactSequence.newCall )	
+	}
+	
+	
+	
 	
 	def List<ExecutionScope> entryScopes(Transition t) {
 		val l = t.target.containers

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

@@ -39,8 +39,8 @@ class ModelSequencer {
 		// during mapping the basic structural elements will be mapped from the source statechart to the execution flow
 		sc.mapScopes(ef)
 		sc.mapRegularStates(ef)
-		sc.mapRegions(ef)
 		sc.mapPseudoStates(ef)
+		sc.mapRegions(ef)
 		sc.mapTimeEvents(ef)
 
 		// calculate state vectors

+ 11 - 2
plugins/org.yakindu.sct.model.sexec/src/org/yakindu/sct/model/sexec/transformation/SexecElementMapping.xtend

@@ -52,6 +52,7 @@ import org.yakindu.sct.model.stext.stext.TimeEventType
 import org.yakindu.sct.model.stext.stext.VariableDefinition
 import org.yakindu.sct.model.sexec.ExecutionSynchronization
 import org.yakindu.sct.model.sgraph.Synchronization
+import org.yakindu.sct.model.sexec.ExecutionNode
  
 
 
@@ -65,7 +66,7 @@ import org.yakindu.sct.model.sgraph.Synchronization
 	@Inject extension SexecExtensions sexec
 	
 
-	def ExecutionFlow create r : sexecFactory.createExecutionFlow create(Statechart statechart){
+	def  ExecutionFlow create r : sexecFactory.createExecutionFlow create(Statechart statechart){
 		r.name = statechart.name
 		r.sourceElement = statechart
 	}
@@ -108,7 +109,7 @@ import org.yakindu.sct.model.sgraph.Synchronization
 	
 	def OperationDefinition create r : EcoreUtil::copy(v) create(OperationDefinition v) {}
 	
-	
+	 
 	def ExecutionState create r : sexecFactory.createExecutionState create(RegularState state){
 		if (state != null) {
 			val n = state.parentRegion.vertices.filter(typeof (FinalState)).toList.indexOf(state)
@@ -270,6 +271,14 @@ import org.yakindu.sct.model.sgraph.Synchronization
 		return r
 	}
 
+
+	def dispatch ExecutionNode mapped(State s) { s.create }
+	def dispatch ExecutionNode mapped(FinalState s) { s.create }
+	def dispatch ExecutionNode mapped(Choice s) { s.create }
+	def dispatch ExecutionNode mapped(Entry s) { s.create }
+	def dispatch ExecutionNode mapped(Synchronization s) { s.create }
+
+
 	//--------- UTILS ---------------
 	def sexecFactory() { SexecFactory::eINSTANCE }
 	def stextFactory() { StextFactory::eINSTANCE }

+ 2 - 0
plugins/org.yakindu.sct.model.sexec/src/org/yakindu/sct/model/sexec/transformation/StructureMapping.xtend

@@ -18,6 +18,7 @@ import org.yakindu.sct.model.sgraph.Statechart
 import org.yakindu.sct.model.stext.stext.EventDefinition
 import org.yakindu.sct.model.stext.stext.OperationDefinition
 import org.yakindu.sct.model.stext.stext.VariableDefinition
+import org.yakindu.sct.model.sgraph.Vertex
 
 
 class StructureMapping {
@@ -114,6 +115,7 @@ class StructureMapping {
 		else _region.superScope = (region.composite as State).create
 
 		_region.subScopes.addAll( region.vertices.filter( typeof(RegularState) ).map( v | v.create as ExecutionScope ) )
+		_region.nodes.addAll( region.vertices.filter( typeof(Vertex) ).map( v | v.mapped  ) )
 
 		return _region
 	}