Просмотр исходного кода

OPEN - issue YAKHMI-895: Create new SCT C++ Code generator
https://intern.itemis.de/jira/browse/YAKHMI-895

markus.muehlbrandt@gmail.com 12 лет назад
Родитель
Сommit
9e94a8b771
19 измененных файлов с 464 добавлено и 103 удалено
  1. 3 3
      plugins/org.yakindu.sct.generator.cpp/src/org/yakindu/sct/generator/cpp/CppGenerator.xtend
  2. 164 0
      plugins/org.yakindu.sct.generator.cpp/src/org/yakindu/sct/generator/cpp/ExpressionCode.xtend
  3. 100 0
      plugins/org.yakindu.sct.generator.cpp/src/org/yakindu/sct/generator/cpp/FlowCode.xtend
  4. 47 10
      plugins/org.yakindu.sct.generator.cpp/src/org/yakindu/sct/generator/cpp/Naming.xtend
  5. 11 0
      plugins/org.yakindu.sct.generator.cpp/src/org/yakindu/sct/generator/cpp/Navigation.xtend
  6. 44 21
      plugins/org.yakindu.sct.generator.cpp/src/org/yakindu/sct/generator/cpp/StatemachineHeader.xtend
  7. 58 44
      plugins/org.yakindu.sct.generator.cpp/src/org/yakindu/sct/generator/cpp/StatemachineImplementation.xtend
  8. 7 6
      plugins/org.yakindu.sct.generator.cpp/src/org/yakindu/sct/generator/cpp/IStatemachine.xtend
  9. 13 10
      plugins/org.yakindu.sct.generator.cpp/src/org/yakindu/sct/generator/cpp/ITimedStatemachine.xtend
  10. 12 9
      plugins/org.yakindu.sct.generator.cpp/src/org/yakindu/sct/generator/cpp/ITimerService.xtend
  11. 1 0
      plugins/org.yakindu.sct.generator.cpp/src/org/yakindu/sct/generator/cpp/Types.xtend
  12. BIN
      plugins/org.yakindu.sct.generator.cpp/xtend-gen/org/yakindu/sct/generator/cpp/.CppGenerator.java._trace
  13. BIN
      plugins/org.yakindu.sct.generator.cpp/xtend-gen/org/yakindu/sct/generator/cpp/.IStatemachine.java._trace
  14. BIN
      plugins/org.yakindu.sct.generator.cpp/xtend-gen/org/yakindu/sct/generator/cpp/.ITimedStatemachine.java._trace
  15. BIN
      plugins/org.yakindu.sct.generator.cpp/xtend-gen/org/yakindu/sct/generator/cpp/.ITimerService.java._trace
  16. BIN
      plugins/org.yakindu.sct.generator.cpp/xtend-gen/org/yakindu/sct/generator/cpp/.Naming.java._trace
  17. BIN
      plugins/org.yakindu.sct.generator.cpp/xtend-gen/org/yakindu/sct/generator/cpp/.Navigation.java._trace
  18. BIN
      plugins/org.yakindu.sct.generator.cpp/xtend-gen/org/yakindu/sct/generator/cpp/.Types.java._trace
  19. 4 0
      plugins/org.yakindu.sct.model.sexec/src/org/yakindu/sct/model/sexec/extensions/SExecExtensions.xtend

+ 3 - 3
plugins/org.yakindu.sct.generator.cpp/src/org/yakindu/sct/generator/cpp/CppGenerator.xtend

@@ -25,9 +25,9 @@ import org.yakindu.sct.model.sgraph.Statechart
 class CppGenerator implements IExecutionFlowGenerator {
 	 
 	@Inject extension Types
-	@Inject extension ITimedStatemachine
-	@Inject extension ITimerService
-	@Inject extension IStatemachine
+	@Inject extension TimedStatemachineInterface
+	@Inject extension TimerServiceInterface
+	@Inject extension StatemachineInterface
 	@Inject extension StatemachineHeader
 	@Inject extension StatemachineImplementation
 

+ 164 - 0
plugins/org.yakindu.sct.generator.cpp/src/org/yakindu/sct/generator/cpp/ExpressionCode.xtend

@@ -0,0 +1,164 @@
+package org.yakindu.sct.generator.cpp
+
+import org.yakindu.sct.model.stext.stext.BoolLiteral
+import org.yakindu.sct.model.stext.stext.EventRaisingExpression
+import com.google.inject.Inject
+import org.yakindu.sct.model.stext.stext.ActiveStateReferenceExpression
+import org.yakindu.sct.model.stext.stext.EventValueReferenceExpression
+import org.yakindu.sct.model.stext.stext.Expression
+import org.yakindu.sct.model.sgraph.Event
+import org.yakindu.sct.model.stext.stext.VariableDefinition
+import org.yakindu.sct.model.stext.stext.ElementReferenceExpression
+import org.yakindu.sct.model.stext.stext.OperationDefinition
+import org.yakindu.sct.model.stext.stext.FeatureCall
+import org.yakindu.sct.model.stext.stext.PrimitiveValueExpression
+import org.yakindu.sct.model.stext.stext.AssignmentExpression
+import org.yakindu.sct.model.stext.stext.LogicalOrExpression
+import org.yakindu.sct.model.stext.stext.LogicalAndExpression
+import org.yakindu.sct.model.stext.stext.LogicalNotExpression
+import org.yakindu.sct.model.stext.stext.LogicalRelationExpression
+import org.yakindu.sct.model.stext.stext.BitwiseAndExpression
+import org.yakindu.sct.model.stext.stext.BitwiseOrExpression
+import org.yakindu.sct.model.stext.stext.BitwiseXorExpression
+import org.yakindu.sct.model.stext.stext.ShiftExpression
+import org.yakindu.sct.model.stext.stext.NumericalAddSubtractExpression
+import org.yakindu.sct.model.stext.stext.NumericalMultiplyDivideExpression
+import org.yakindu.sct.model.stext.stext.NumericalUnaryExpression
+import org.yakindu.sct.model.stext.stext.ParenthesizedExpression
+import org.yakindu.sct.model.stext.types.ISTextTypeInferrer
+import org.yakindu.sct.model.stext.types.ISTextTypeSystem
+import org.yakindu.sct.model.sgraph.Statement
+import org.yakindu.sct.model.stext.stext.Literal
+import org.yakindu.sct.model.stext.stext.StringLiteral
+import org.yakindu.sct.model.stext.stext.IntLiteral
+import org.yakindu.sct.model.stext.stext.RealLiteral
+import org.yakindu.sct.model.stext.stext.HexLiteral
+
+class ExpressionCode //extends org.yakindu.sct.generator.c.ExpressionCode 
+{
+	
+	@Inject extension Naming
+	@Inject extension Navigation
+	@Inject extension ISTextTypeSystem
+	@Inject extension ISTextTypeInferrer
+	
+	/* Refering to declared elements */
+	
+	def dispatch CharSequence code (ElementReferenceExpression it) {
+		it.code(it.definition)
+	}
+		
+	def dispatch CharSequence code (FeatureCall it) {
+		it.code(it.definition)
+	}
+		
+	def dispatch CharSequence code (Expression it, Event target) 
+		'''«target.access»'''
+		
+	def dispatch CharSequence code (Expression it, VariableDefinition target) 
+		'''«target.access»'''
+	
+	def dispatch CharSequence code (ElementReferenceExpression it, OperationDefinition target) 
+		'''«target.access»(«FOR arg:args SEPARATOR ', '»«arg.code»«ENDFOR»)'''
+	
+	def dispatch CharSequence code (FeatureCall it, OperationDefinition target) 
+		'''«target.access»(«FOR arg:args SEPARATOR ', '»«arg.code»«ENDFOR»)'''
+	
+	
+	def dispatch CharSequence code (Statement it) 
+		'''#error TODO: generate code for «getClass().name»'''
+
+	
+	/* HANDLING LITERALS */
+	def dispatch CharSequence code (Literal it)
+		'''#error unknown literal type «getClass().name» '''
+	
+	
+	def dispatch CharSequence code (StringLiteral it) 
+		'''"«value.escaped»"'''	
+		
+	def String escaped(String it) {
+		return it.replace("\"", "\\\"");
+	}
+	
+
+	def dispatch CharSequence code (BoolLiteral it) 
+		'''«IF value»true«ELSE»false«ENDIF»'''	
+
+	def dispatch CharSequence code (IntLiteral it) 
+		'''«value.toString»'''	
+
+	def dispatch CharSequence code (RealLiteral it) 
+		'''«value.toString»'''	
+		
+	def dispatch CharSequence code (HexLiteral it) 
+		'''0x«Integer::toHexString(value)»'''	
+
+	def dispatch CharSequence code (PrimitiveValueExpression it) 
+		'''«value.code»'''	
+
+		
+	/* Statements */
+	
+	def dispatch CharSequence code (AssignmentExpression it)
+		'''«varRef.code» «operator.literal» «expression.code»'''
+		
+	def dispatch CharSequence code (EventRaisingExpression it)
+		'''
+		«IF value != null»
+			«event.definition.event.valueAccess» = «value.code»;
+		«ENDIF»
+		«event.definition.event.access» = bool_true'''	
+
+
+	/* Logical Expressions */
+	
+	def dispatch CharSequence code (LogicalOrExpression it)
+		'''«rightOperand.code» || «leftOperand.code»'''
+		
+	def dispatch CharSequence code (LogicalAndExpression it)
+		'''«rightOperand.code» && «leftOperand.code»'''
+	 	
+	def dispatch CharSequence code (LogicalNotExpression it)
+		'''! «operand.code»'''
+		
+	def dispatch CharSequence code (LogicalRelationExpression it) '''
+		«IF leftOperand.inferType.type.stringType»
+			(strcmp(«leftOperand.code», «rightOperand.code») «operator.literal» 0)
+		«ELSE»«leftOperand.code» «operator.literal» «rightOperand.code»«ENDIF»'''
+	
+	/* Bitwise Operations */
+	
+	def dispatch CharSequence code (BitwiseAndExpression it)
+		'''«leftOperand.code» & «rightOperand.code»'''
+	
+	def dispatch CharSequence code (BitwiseOrExpression it)
+		'''«leftOperand.code» | «rightOperand.code»'''
+	
+	def dispatch CharSequence code (BitwiseXorExpression it)
+		'''«leftOperand.code» ^ «rightOperand.code»'''
+	
+	def dispatch CharSequence code (ShiftExpression it)
+		'''«leftOperand.code» «operator.literal» «rightOperand.code»'''
+
+	/* Numerical operations */
+	
+	def dispatch CharSequence code (NumericalAddSubtractExpression it)
+		'''«leftOperand.code» «operator.literal» «rightOperand.code»'''
+	
+	def dispatch CharSequence code (NumericalMultiplyDivideExpression it)
+		'''«leftOperand.code» «operator.literal» «rightOperand.code»'''
+	
+	def dispatch CharSequence code (NumericalUnaryExpression it)
+		'''«operator.literal» «operand.code»'''
+	
+	/* TODO: check if event is active */
+	def dispatch CharSequence code (EventValueReferenceExpression it)
+		'''«value.definition.event.valueAccess»'''
+	
+	def dispatch CharSequence code (ActiveStateReferenceExpression it)
+		'''«flow.nameOfIsActiveFunction»(«value.fullyQualifiedName»)'''
+	
+	def dispatch CharSequence code (ParenthesizedExpression it)
+		'''(«expression.code»)'''
+}

+ 100 - 0
plugins/org.yakindu.sct.generator.cpp/src/org/yakindu/sct/generator/cpp/FlowCode.xtend

@@ -0,0 +1,100 @@
+package org.yakindu.sct.generator.cpp
+
+import org.yakindu.sct.model.sexec.SaveHistory
+import org.yakindu.sct.model.sexec.HistoryEntry
+import org.yakindu.sct.model.sexec.StateSwitch
+import org.yakindu.sct.model.sexec.ScheduleTimeEvent
+import org.yakindu.sct.model.sexec.UnscheduleTimeEvent
+import org.yakindu.sct.model.sexec.Call
+import com.google.inject.Inject
+import org.yakindu.sct.model.sexec.Check
+import org.yakindu.sct.model.sexec.CheckRef
+import org.yakindu.sct.model.sexec.EnterState
+import org.yakindu.sct.model.sexec.ExitState
+import org.yakindu.sct.model.sexec.Execution
+import org.yakindu.sct.model.sexec.Sequence
+
+class FlowCode extends org.yakindu.sct.generator.c.FlowCode {
+	
+	@Inject extension Naming
+	@Inject extension Navigation
+	@Inject extension ExpressionCode
+	
+	override dispatch CharSequence code(SaveHistory it) '''
+		«stepComment»
+		historyVector[«region.historyVector.offset»] = stateConfVector[«region.stateVector.offset»];
+	'''
+	
+	override dispatch CharSequence code(HistoryEntry it) '''
+		«stepComment»
+		if (historyVector[«region.historyVector.offset»] != «last_state») {
+			«historyStep.code»
+		} «IF initialStep != null»else {
+			«initialStep.code»
+		} «ENDIF»
+	'''
+
+	override dispatch CharSequence code(StateSwitch it) '''
+		«stepComment»
+		«IF historyRegion != null»
+			switch(historyVector[ «historyRegion.historyVector.offset» ]) {
+		«ELSE»
+			switch(stateConfVector[ «stateConfigurationIdx» ]) {
+		«ENDIF»
+			«FOR caseid : cases»
+				case «caseid.state.name.asIdentifier» : {
+					«caseid.step.code»
+					break;
+				}
+			«ENDFOR»
+			default: break;
+		}
+	'''
+
+	override dispatch CharSequence code(ScheduleTimeEvent it) '''
+		«stepComment»
+		«timerServiceInstance»->setTimer(this, (sc_eventid) &«timeEventsInstance»[«timeEvent.indexOf»] , «timeValue.code», «IF timeEvent.periodic»true«ELSE»false«ENDIF»);
+	'''
+
+	override dispatch CharSequence code(UnscheduleTimeEvent it) '''
+		«stepComment»
+		«timerServiceInstance»->unsetTimer(this, (sc_eventid) &«timeEventsInstance»[«timeEvent.indexOf»]);		
+	'''
+	
+	override dispatch CharSequence code(Execution it) 
+		'''«statement.code»;'''
+	
+	override dispatch CharSequence code(Call it) 
+		'''«step.functionName»();'''
+	
+	override dispatch CharSequence code(Sequence it) '''
+		«IF comment != null»
+			{
+				«stepComment»
+				«FOR s : steps»
+					«s.code»
+				«ENDFOR»
+			}
+		«ELSE»
+			«FOR s : steps»
+				«s.code»
+			«ENDFOR»
+		«ENDIF»
+	'''	
+	
+	override dispatch CharSequence code(Check it) 
+		'''«IF condition != null»«condition.code»«ELSE»true«ENDIF»'''
+	
+	override dispatch CharSequence code(CheckRef it) 
+		'''«IF check != null»«check.functionName»()«ELSE»true«ENDIF»'''
+	
+	override dispatch CharSequence code(EnterState it) '''
+		stateConfVector[«state.stateVector.offset»] = «state.name.asEscapedIdentifier»;
+		stateConfVectorPosition = «state.stateVector.offset»;
+	'''
+
+	override dispatch CharSequence code(ExitState it) '''
+		stateConfVector[«state.stateVector.offset»] = «last_state»;
+		stateConfVectorPosition = «state.stateVector.offset»;
+	'''
+}

+ 47 - 10
plugins/org.yakindu.sct.generator.cpp/src/org/yakindu/sct/generator/cpp/Naming.xtend

@@ -16,18 +16,24 @@ import org.yakindu.sct.model.stext.stext.EventDefinition
 import org.yakindu.sct.model.stext.stext.InterfaceScope
 import org.yakindu.sct.model.stext.stext.OperationDefinition
 import org.yakindu.sct.model.stext.stext.VariableDefinition
+import org.yakindu.sct.model.stext.stext.InternalScope
+import org.yakindu.sct.model.sgraph.Event
+import com.google.inject.Inject
+import org.yakindu.sct.model.sexec.TimeEvent
 
 class Naming extends org.yakindu.sct.generator.c.Naming {
 	
+	@Inject extension Navigation;
+	
 	def hpp(String it) { it + ".hpp" }
 	def cpp(String it) { it + ".cpp" }
 	
 	def abstractModule(ExecutionFlow it) {
-		'I'+module()	
+		module() + 'Interface'	
 	}
 	
-	def iStatemachine() {
-		'IStatemachine'
+	def statemachineInterface() {
+		'StatemachineInterface'
 	}
 	
 	def orthogonalStatesConst() {
@@ -38,19 +44,27 @@ class Naming extends org.yakindu.sct.generator.c.Naming {
 		'maxHistoryStates'
 	}
 	
-	def iTimedStatemachine() {
-		'ITimedStatemachine'
+	def timedStatemachineInterface() {
+		'TimedStatemachineInterface'
+	}
+	
+	def timerServiceInterface() {
+		'TimerServiceInterface'
 	}
 	
-	def iTimerService() {
-		'ITimerService'
+	def timerServiceInstance() {
+		'timerService'
 	}
 	
-	def timeEvent() {
-		'TimeEvent'
+	def timeEventsInstance() {
+		'timeEvents'
 	}
 	
-	def String getInterfaceName(InterfaceScope it) {  
+	override dispatch instance(InternalScope it) {
+		'iface' + interfaceName.asIdentifier.toFirstUpper	
+	}
+	
+	def dispatch String getInterfaceName(InterfaceScope it) {  
 		if (name != null) {
 			return "SCI" + name.toFirstUpper()
 		}
@@ -59,6 +73,10 @@ class Naming extends org.yakindu.sct.generator.c.Naming {
 		}
 	}
 	
+	def dispatch String getInterfaceName(InternalScope it) {  
+		"InternalSCIScope"
+	}
+	
 	def String getInterfaceOperationCallbackName(InterfaceScope it) {
 		interfaceName + "OperationCallback"
 	}
@@ -95,7 +113,26 @@ class Naming extends org.yakindu.sct.generator.c.Naming {
 		segments.fold("", [s, seg | s + if (seg.empty) "" else "_" + seg]).asIdentifier
 	}
 	
+	override nameOfRaiseTimeEventFunction(ExecutionFlow it) {
+		"raiseTimeEvent"
+	}
+	
 	override nameOfIsActiveFunction(ExecutionFlow it) {
 		"isActive"
 	}
+	
+	override dispatch access (VariableDefinition it) 
+		'''«scope.instance»->«name.asEscapedIdentifier»'''
+
+	override dispatch access (OperationDefinition it) 
+		'''«asFunction»'''
+		
+	override dispatch access (Event it) 
+		'''«scope.instance»->«name.asIdentifier.raised»'''
+	
+	def dispatch access(TimeEvent it)
+		'''«timeEventsInstance»[«indexOf»]'''
+	
+	override valueAccess(Event it) 
+		'''«scope.instance»->«name.asIdentifier.value»'''
 }

+ 11 - 0
plugins/org.yakindu.sct.generator.cpp/src/org/yakindu/sct/generator/cpp/Navigation.xtend

@@ -2,9 +2,16 @@ package org.yakindu.sct.generator.cpp
 
 import org.yakindu.sct.model.sgraph.Scope
 import org.yakindu.sct.model.stext.stext.OperationDefinition
+import org.yakindu.sct.model.sexec.ExecutionFlow
+import org.yakindu.sct.model.stext.stext.StatechartScope
+import org.yakindu.sct.model.sexec.TimeEvent
 
 class Navigation extends org.yakindu.sct.generator.c.Navigation {
 	
+	def getStatechartScopes(ExecutionFlow it) {
+		scopes.filter(typeof(StatechartScope))
+	}
+	
 	def operations(Scope it) {
 		declarations.filter(typeof(OperationDefinition));
 	}
@@ -12,4 +19,8 @@ class Navigation extends org.yakindu.sct.generator.c.Navigation {
 	def hasOperations(Scope it) {
 		!operations.isEmpty;
 	}
+	
+	def indexOf(TimeEvent it) {
+		scope.declarations.filter(typeof(TimeEvent)).toList.indexOf(it);
+	}
 }

+ 44 - 21
plugins/org.yakindu.sct.generator.cpp/src/org/yakindu/sct/generator/cpp/StatemachineHeader.xtend

@@ -29,6 +29,7 @@ import org.yakindu.sct.model.stext.stext.VariableDefinition
 import java.util.List
 import org.yakindu.sct.model.sexec.Step
 import org.yakindu.sct.model.sexec.Check
+import org.yakindu.sct.model.stext.stext.StatechartScope
 
 class StatemachineHeader extends Statemachine {
 	
@@ -48,9 +49,9 @@ class StatemachineHeader extends Statemachine {
 		#define «module().define»_H_
 
 		#include "«typesModule.hpp»"
-		#include "«iStatemachine.hpp»"
+		#include "«statemachineInterface.hpp»"
 		«IF timed»
-			#include "«iTimedStatemachine.hpp»"
+			#include "«timedStatemachineInterface.hpp»"
 		«ENDIF»
 
 		/*! \file Header of the state machine '«name»'.
@@ -62,7 +63,7 @@ class StatemachineHeader extends Statemachine {
 			
 				«statesEnumDecl»
 				
-				«FOR s : it.scopes»«s.createScope(entry)»«ENDFOR»
+				«FOR s : it.scopes»«s.createScope()»«ENDFOR»
 				
 				«publicFunctionPrototypes»
 				
@@ -71,6 +72,8 @@ class StatemachineHeader extends Statemachine {
 			
 			private:
 			
+				«FOR s : scopes.filter(typeof(InternalScope))»«s.createInterface»«ENDFOR»
+			
 				«statemachineTypeDecl»
 				
 				«functionPrototypes»
@@ -84,31 +87,31 @@ class StatemachineHeader extends Statemachine {
 		var String interfaces = "";
 
 		if (flow.timed) {
-			interfaces = interfaces + "public " +iTimedStatemachine+", "
+			interfaces = interfaces + "public " +timedStatemachineInterface+", "
 		}
 
-		interfaces = interfaces + "public " + iStatemachine
+		interfaces = interfaces + "public " + statemachineInterface
 		
 		return interfaces;
 	}
 	
-	def private createScope(Scope scope, GeneratorEntry entry) {
+	def private createScope(Scope scope) {
 		switch scope {
-			InterfaceScope: scope.createScope(entry)
-			InternalScope: scope.createScope
+			InterfaceScope: scope.createScope()
+			InternalScope: scope.createPublicScope
 		}
 	}
 	
-	def private createScope(InterfaceScope scope, GeneratorEntry entry)
+	def private createScope(InterfaceScope scope)
 	'''
-		«scope.createInterface(entry
+		«scope.createInterface()»
 «««		«scope.createListenerInterface(entry)»
 		«scope.createOperationCallbackInterface»
 		
 		«scope.interfaceName»* get«scope.interfaceName»();
 	'''
 	
-	def private createInterface(InterfaceScope scope, GeneratorEntry entry)
+	def private createInterface(StatechartScope scope)
 	'''
 		//! Inner class for «scope.interfaceName» interface scope.
 		class «scope.interfaceName» {
@@ -125,7 +128,7 @@ class StatemachineHeader extends Statemachine {
 		};
 	'''
 	
-	def private createScope(InternalScope scope) {
+	def private createPublicScope(InternalScope scope) {
 		'''
 		«IF scope.hasOperations()»
 			class «internalOperationCallbackName» {
@@ -168,17 +171,26 @@ class StatemachineHeader extends Statemachine {
 
 	override statemachineTypeDecl(ExecutionFlow it) '''
 		//! the maximum number of orthogonal states defines the dimension of the state configuration vector.
-		const sc_integer «orthogonalStatesConst» = «stateVector.size»;
+		static const sc_integer «orthogonalStatesConst» = «stateVector.size»;
 		«IF hasHistory»
 		//! dimension of the state configuration vector for history states
-		const sc_integer «historyStatesConst» = «historyVector.size»;«ENDIF»
+		static const sc_integer «historyStatesConst» = «historyVector.size»;«ENDIF»
+		
+		«IF timed»
+			«timerServiceInterface»* «timerServiceInstance»;
+			sc_boolean «timeEventsInstance»[«timeEvents.size»];
+		«ENDIF»
 		
-		«IF timed»sc_boolean timeEvents[«timeEvents.size»];«ENDIF»
 		«statesEnumType» stateConfVector[«orthogonalStatesConst»];
+		
 		«IF hasHistory»«statesEnumType» historyVector[«historyStatesConst»];«ENDIF»
 		sc_ushort stateConfVectorPosition;
+		
+		«FOR s : scopes.filter(typeof(StatechartScope))»
+			const «s.interfaceName»* «s.instance»;
+		«ENDFOR»
 	'''
-
+	
 	def publicFunctionPrototypes(ExecutionFlow it) '''
 		«IStatemachineFunctions»
 		
@@ -197,16 +209,27 @@ class StatemachineHeader extends Statemachine {
 		void runCycle();
 	'''
 	
-	def ITimedStatemachineFunctions() '''
-		void setTimerService(ITimerService* timerService);
+	def ITimedStatemachineFunctions(ExecutionFlow it) '''
+		void setTimerService(«timerServiceInterface»* timerService);
 		
-		ITimerService* getTimerService();
+		«timerServiceInterface»* getTimerService();
 		
-		void raiseTimeEvent(sc_eventid event);
+		void «nameOfRaiseTimeEventFunction»(sc_eventid event);
 	'''
 	
 	override dispatch functionPrototypes(EventDefinition it) '''
-		«IF direction == Direction::IN»
+		«IF direction == Direction::LOCAL»
+			/*! Raises the in event '«name»' that is defined in the «scope.scopeDescription». */ 
+			void «asRaiser»(«valueParams»);
+			
+			/*! Checks if the out event '«name»' that is defined in the «scope.scopeDescription» has been raised. */ 
+			sc_boolean «asRaised»();
+			«IF hasValue»
+				/*! Gets the value of the out event '«name»' that is defined in the «scope.scopeDescription». */ 
+				«type.targetLanguageName» «asGetter»();
+				
+			«ENDIF»
+		«ELSEIF direction == Direction::IN»
 		/*! Raises the in event '«name»' that is defined in the «scope.scopeDescription». */ 
 		void «asRaiser»(«valueParams»);
 		

+ 58 - 44
plugins/org.yakindu.sct.generator.cpp/src/org/yakindu/sct/generator/cpp/StatemachineImplementation.xtend

@@ -19,9 +19,7 @@ import org.yakindu.sct.model.sexec.Step
 import org.yakindu.sct.model.sgraph.Statechart
 import org.yakindu.sct.model.sgen.GeneratorEntry
 import org.yakindu.sct.generator.core.types.ICodegenTypeSystemAccess
-import org.yakindu.sct.generator.c.GenmodelEntries
-import org.yakindu.sct.model.sexec.extensions.SExecExtensions
-import org.yakindu.sct.generator.c.FlowCode
+import org.yakindu.sct.generator.c.GenmodelEntries
 
 class StatemachineImplementation {
 	
@@ -29,8 +27,7 @@ class StatemachineImplementation {
 	@Inject extension Navigation
 	@Inject extension FlowCode
 	@Inject extension GenmodelEntries
-	@Inject extension ICodegenTypeSystemAccess
-	@Inject extension SExecExtensions
+	@Inject extension ICodegenTypeSystemAccess
 	
 	def generateStatemachineImplemenation(ExecutionFlow flow, Statechart sc, IFileSystemAccess fsa, GeneratorEntry entry) {
 		 fsa.generateFile(flow.module.cpp, flow.statemachineContent(entry) )
@@ -66,7 +63,7 @@ class StatemachineImplementation {
 	
 	
 	def initFunction(ExecutionFlow it) '''
-		void init()
+		void «module»::init()
 		{
 			int i;
 
@@ -75,9 +72,9 @@ class StatemachineImplementation {
 			
 			«IF hasHistory»
 			for (i = 0; i < «historyStatesConst»; ++i)
-				historyVector[i] = «last_state»;
-			«ENDIF»
+				historyVector[i] = «last_state»;
 			
+			«ENDIF»
 			stateConfVectorPosition = 0;
 		
 			clearInEvents();
@@ -91,63 +88,63 @@ class StatemachineImplementation {
 	'''
 	
 	def enterFunction(ExecutionFlow it) '''
-		void «type.toFirstLower»_enter(«scHandleDecl»)
+		void «module»::enter()
 		{
 			«enterSequences.defaultSequence.code»
 		}
 	'''
 	
 	def exitFunction(ExecutionFlow it) '''
-		void «type.toFirstLower»_exit(«scHandleDecl»)
+		void «module»::exit()
 		{
 			«exitSequence.code»
 		}
 	'''
 	
 	def clearInEventsFunction(ExecutionFlow it) '''
-		static void clearInEvents(«scHandleDecl») {
+		void «module»::clearInEvents() {
 			«FOR scope : it.scopes»
 				«FOR event : scope.incomingEvents»
-				«event.access» = bool_false;
+				«event.access» = false;
 				«ENDFOR»
 			«ENDFOR»
 			«IF hasLocalScope»
 				«FOR event : internalScope.events»
-				«event.access» = bool_false; 
+				«event.access» = false; 
 				«ENDFOR»
 			«ENDIF»
 			«IF timed»
 				«FOR event : timeEventScope.events»
-				«event.access» = bool_false; 
+				«event.access» = false; 
 				«ENDFOR»
 			«ENDIF»
 		}
 	'''
 	
 	def clearOutEventsFunction(ExecutionFlow it) '''
-		static void clearOutEvents(«scHandleDecl») {
+		void «module»::clearOutEvents() {
 			«FOR scope : it.scopes»
 				«FOR event : scope.outgoingEvents»
-				«event.access» = bool_false;
+				«event.access» = false;
 				«ENDFOR»
 			«ENDFOR»
 		}
 	'''
 	
 	def runCycleFunction(ExecutionFlow it) '''
-		void «type.toFirstLower»_runCycle(«scHandleDecl») {
+		void «module»::runCycle() {
 			
-			clearOutEvents(«scHandle»);
+			clearOutEvents();
 			
-			for («scHandle»->stateConfVectorPosition = 0;
-				«scHandle»->stateConfVectorPosition < «type.toUpperCase»_MAX_ORTHOGONAL_STATES;
-				«scHandle»->stateConfVectorPosition++) {
+			for (stateConfVectorPosition = 0;
+				stateConfVectorPosition < «orthogonalStatesConst»;
+				stateConfVectorPosition++) {
 					
-				switch («scHandle»->stateConfVector[handle->stateConfVectorPosition]) {
+				switch (stateConfVector[stateConfVectorPosition]) {
 				«FOR state : states»
 					«IF state.reactSequence!=null»
 					case «state.name.asEscapedIdentifier» : {
-						«state.reactSequence.functionName»(«scHandle»);
+						«state.reactSequence.functionName»();
 						break;
 					}
 					«ENDIF»
@@ -157,31 +154,31 @@ class StatemachineImplementation {
 				}
 			}
 			
-			clearInEvents(«scHandle»);
+			clearInEvents();
 		}
 	'''
 	
 	def raiseTimeEventFunction(ExecutionFlow it) '''
 		«IF timed»
-			void «nameOfRaiseTimeEventFunction»(«type»* handle, sc_eventid evid) {
-				if ( ((intptr_t)evid) >= ((intptr_t)&(«scHandle»->timeEvents))
-					&&  ((intptr_t)evid) < ((intptr_t)&(«scHandle»->timeEvents)) + sizeof(«timeEventScope.type»)) {
-					*(sc_boolean*)evid = bool_true;
+			void «module»::«nameOfRaiseTimeEventFunction»(sc_eventid evid) {
+				if ( ((intptr_t)evid) >= ((intptr_t)&(timeEvents))
+					&&  ((intptr_t)evid) < ((intptr_t)&(timeEvents)) + sizeof(timeEvents)) {
+					*(sc_boolean*)evid = true;
 				}		
 			}
 		«ENDIF»
 	'''
 	
 	def isActiveFunction(ExecutionFlow it) '''
-		sc_boolean «nameOfIsActiveFunction»(«scHandleDecl», «statesEnumType» state) {
+		sc_boolean «module»::«nameOfIsActiveFunction»(«statesEnumType» state) {
 			switch (state) {
 				«FOR s : states»
 				case «s.name.asIdentifier» : 
-					return (sc_boolean) («IF s.leaf»«scHandle»->stateConfVector[«s.stateVector.offset»] == «s.name.asIdentifier»
-					«ELSE»«scHandle»->stateConfVector[«s.stateVector.offset»] >= «s.name.asIdentifier»
-						&& «scHandle»->stateConfVector[«s.stateVector.offset»] <= «s.subStates.last.name.asIdentifier»«ENDIF»);
+					return (sc_boolean) («IF s.leaf»stateConfVector[«s.stateVector.offset»] == «s.name.asIdentifier»
+					«ELSE»stateConfVector[«s.stateVector.offset»] >= «s.name.asIdentifier»
+						&& stateConfVector[«s.stateVector.offset»] <= «s.subStates.last.name.asIdentifier»«ENDIF»);
 				«ENDFOR»
-				default: return bool_false;
+				default: return false;
 			}
 		}
 	'''
@@ -191,34 +188,53 @@ class StatemachineImplementation {
 	 */
 	
 	def interfaceFunctions(ExecutionFlow it) '''
-		«FOR scope : interfaceScopes»
+		«FOR scope : statechartScopes»
 			«FOR event : scope.incomingEvents»
-				void «event.asRaiser»(«scHandleDecl»«event.valueParams») {
+				void «module»::«scope.interfaceName»::«event.asRaiser»(«event.valueParams») {
 					«IF event.hasValue»
 					«event.valueAccess» = value;
 					«ENDIF»
-					«event.access» = bool_true;
+					«event.access» = true;
 				}
 			«ENDFOR»
 			
 			«FOR event : scope.outgoingEvents»
-				sc_boolean «event.asRaised»(«scHandleDecl») {
+				sc_boolean «module»::«scope.interfaceName»::«event.asRaised»() {
 					return «event.access»;
 				}
 				«IF event.hasValue» 
-					«event.type.targetLanguageName» «event.asGetter»(«scHandleDecl») {
+					«event.type.targetLanguageName» «module»::«scope.interfaceName»::«event.asGetter»() {
 						//TODO: Check if event is not raised
 						return «event.valueAccess»;
 					}
 				«ENDIF»
+			«ENDFOR»
+			
+			«FOR event : scope.localEvents»
+				void «module»::«scope.interfaceName»::«event.asRaiser»(«event.valueParams») {
+					«IF event.hasValue»
+					«event.valueAccess» = value;
+					«ENDIF»
+					«event.access» = true;
+				}
+				
+				sc_boolean «module»::«scope.interfaceName»::«event.asRaised»() {
+					return «event.access»;
+				}
+				«IF event.hasValue» 
+					«event.type.targetLanguageName» «module»::«scope.interfaceName»::«event.asGetter»() {
+						//TODO: Check if event is not raised
+						return «event.valueAccess»;
+					}
+				«ENDIF»
 			«ENDFOR»
 			
 			«FOR variable : scope.variableDefinitions»
-				«variable.type.targetLanguageName» «variable.asGetter»(«scHandleDecl») {
+				«variable.type.targetLanguageName» «module»::«scope.interfaceName»::«variable.asGetter»() {
 					return «variable.access»;
 				}
 				«IF !variable.readonly »
-				void «variable.asSetter»(«scHandleDecl», «variable.type.targetLanguageName» value) {
+				void «module»::«scope.interfaceName»::«variable.asSetter»(«variable.type.targetLanguageName» value) {
 					«variable.access» = value;
 				}
 				«ENDIF»
@@ -252,7 +268,7 @@ class StatemachineImplementation {
 	
 	def dispatch functionImplementation(Check it) '''
 		«stepComment»
-		sc_boolean «execution_flow.module»::«asCheckFunction»(«scHandleDecl») {
+		sc_boolean «execution_flow.module»::«asCheckFunction»() {
 			return «code»;
 		}
 		
@@ -260,11 +276,9 @@ class StatemachineImplementation {
 	
 	def dispatch functionImplementation(Step it) '''
 		«stepComment»
-		void «execution_flow.module»::«functionName»(«scHandleDecl») {
+		void «execution_flow.module»::«functionName»() {
 			«code»
 		}
 		
 	'''
-	
-	
 }

+ 7 - 6
plugins/org.yakindu.sct.generator.cpp/src/org/yakindu/sct/generator/cpp/IStatemachine.xtend

@@ -15,7 +15,7 @@ import org.eclipse.xtext.generator.IFileSystemAccess
 import com.google.inject.Inject
 import org.yakindu.sct.generator.c.GenmodelEntries
 
-class IStatemachine {
+class StatemachineInterface {
 	
 	@Inject
 	extension Naming
@@ -24,21 +24,22 @@ class IStatemachine {
 	extension GenmodelEntries
 	
 	def generateIStatemachine(ExecutionFlow flow, GeneratorEntry entry, IFileSystemAccess fsa) {
-		fsa.generateFile(iStatemachine.hpp, flow.content(entry) )
+		fsa.generateFile(statemachineInterface.hpp, flow.content(entry) )
 	}
 	
 	def private content(ExecutionFlow it, GeneratorEntry entry) {
 		'''
 		«entry.licenseText»
 		
-		#ifndef «iStatemachine.define»_H_
-		#define «iStatemachine.define»_H_
+		#ifndef «statemachineInterface.define»_H_
+		#define «statemachineInterface.define»_H_
 		
 		/*
 		 * Basic interface for statemachines.
 		 */
-		class IStatemachine {
+		class «statemachineInterface» {
 			public:
+				virtual ~«statemachineInterface»() = 0;
 				/*
 				* Initializes the statemachine. Use to init internal variables etc.
 				*/
@@ -60,7 +61,7 @@ class IStatemachine {
 				virtual void runCycle() = 0;
 		};
 		
-		#endif /* «iStatemachine.define»_H_ */
+		#endif /* «statemachineInterface.define»_H_ */
 		'''
 	}
 }

+ 13 - 10
plugins/org.yakindu.sct.generator.cpp/src/org/yakindu/sct/generator/cpp/ITimedStatemachine.xtend

@@ -15,7 +15,7 @@ import org.eclipse.xtext.generator.IFileSystemAccess
 import com.google.inject.Inject
 import org.yakindu.sct.generator.c.GenmodelEntries
 
-class ITimedStatemachine {
+class TimedStatemachineInterface {
 	
 	@Inject
 	extension Naming
@@ -24,43 +24,46 @@ class ITimedStatemachine {
 	extension GenmodelEntries
 	
 	def generateITimedStatemachine(ExecutionFlow flow, GeneratorEntry entry, IFileSystemAccess fsa) {
-		fsa.generateFile(iTimedStatemachine.hpp, flow.content(entry) )
+		fsa.generateFile(timedStatemachineInterface.hpp, flow.content(entry) )
 	}
 	
 	def private content(ExecutionFlow it, GeneratorEntry entry) {
 		'''
 		«entry.licenseText»
 		
-		#ifndef «iTimedStatemachine.define»_H_
-		#define «iTimedStatemachine.define»_H_
+		#ifndef «timedStatemachineInterface.define»_H_
+		#define «timedStatemachineInterface.define»_H_
 		
 		#include "«typesModule.hpp»"
-		#include "«iTimerService.hpp»"
+		#include "«timerServiceInterface.hpp»"
 		
 		/*
 		* Interface for state machines which use timed event triggers.
 		*/
-		class ITimedStatemachine {
+		class «timedStatemachineInterface» {
 			public:
+			
+				virtual ~«timedStatemachineInterface»() = 0;
+				
 				/*
 				* Set the ITimerService for the state machine. It must be set
 				* externally on a timed state machine before a run cycle can be correct
 				* executed.
 				*/
-				virtual void setTimerService(ITimerService* timerService) = 0;
+				virtual void setTimerService(«timerServiceInterface»* timerService) = 0;
 				
 				/*
 				* Returns the currently used timer service.
 				*/
-				virtual ITimerService* getTimerService() = 0;
+				virtual «timerServiceInterface»* getTimerService() = 0;
 				
 				/*
 				* Callback method if a time event occurred.
 				*/
-				virtual void raiseTimeEvent(sc_eventid event) = 0;
+				virtual void «nameOfRaiseTimeEventFunction»(sc_eventid event) = 0;
 		};
 		
-		#endif /* «iTimedStatemachine.define»_H_ */
+		#endif /* «timedStatemachineInterface.define»_H_ */
 		'''
 	}
 }

+ 12 - 9
plugins/org.yakindu.sct.generator.cpp/src/org/yakindu/sct/generator/cpp/ITimerService.xtend

@@ -15,7 +15,7 @@ import org.eclipse.xtext.generator.IFileSystemAccess
 import com.google.inject.Inject
 import org.yakindu.sct.generator.c.GenmodelEntries
 
-class ITimerService {
+class TimerServiceInterface {
 	
 	@Inject
 	extension Naming
@@ -24,32 +24,35 @@ class ITimerService {
 	extension GenmodelEntries
 	
 	def generateITimerService(ExecutionFlow flow, GeneratorEntry entry, IFileSystemAccess fsa) {
-		fsa.generateFile(iTimerService.hpp, flow.content(entry) )
+		fsa.generateFile(timerServiceInterface.hpp, flow.content(entry) )
 	}
 	
 	def private content(ExecutionFlow it, GeneratorEntry entry) {
 		'''
 		«entry.licenseText»
 		
-		#ifndef «iTimerService.define»_H_
-		#define «iTimerService.define»_H_
+		#ifndef «timerServiceInterface.define»_H_
+		#define «timerServiceInterface.define»_H_
 		
-		#include "«iTimedStatemachine.hpp»"
+		#include "«timedStatemachineInterface.hpp»"
 		
 		/*
 		 * Basic interface for statemachines.
 		 */
-		class ITimerService {
+		class «timerServiceInterface» {
 			public:
+			
+				virtual ~«timerServiceInterface»() = 0;
+			
 				/*
 				 * Starts the timing for a time event.
 				 */ 
-				virtual void setTimer(ITimedStatemachine* statemachine, sc_eventid event, sc_integer time, sc_boolean isPeriodic) = 0;
+				virtual void setTimer(«timedStatemachineInterface»* statemachine, sc_eventid event, sc_integer time, sc_boolean isPeriodic) = 0;
 				
 				/*
 				 * Unsets the given time event.
 				 */
-				virtual void resetTimer(ITimedStatemachine* statemachine, sc_eventid event) = 0;
+				virtual void unsetTimer(«timedStatemachineInterface»* statemachine, sc_eventid event) = 0;
 			
 				/*
 				 * Cancel timer service. Use this to end possible timing threads and free
@@ -58,7 +61,7 @@ class ITimerService {
 				virtual void cancel() = 0;
 		};
 		
-		#endif /* «iTimerService.define»_H_ */
+		#endif /* «timerServiceInterface.define»_H_ */
 		'''
 	}
 }

+ 1 - 0
plugins/org.yakindu.sct.generator.cpp/src/org/yakindu/sct/generator/cpp/Types.xtend

@@ -32,6 +32,7 @@ class Types {
 		#ifndef «typesModule.define»_H_
 		#define «typesModule.define»_H_
 		
+		#include <cstdint>
 		#include <string>
 		
 		typedef unsigned char	sc_ushort;

BIN
plugins/org.yakindu.sct.generator.cpp/xtend-gen/org/yakindu/sct/generator/cpp/.CppGenerator.java._trace


BIN
plugins/org.yakindu.sct.generator.cpp/xtend-gen/org/yakindu/sct/generator/cpp/.IStatemachine.java._trace


BIN
plugins/org.yakindu.sct.generator.cpp/xtend-gen/org/yakindu/sct/generator/cpp/.ITimedStatemachine.java._trace


BIN
plugins/org.yakindu.sct.generator.cpp/xtend-gen/org/yakindu/sct/generator/cpp/.ITimerService.java._trace


BIN
plugins/org.yakindu.sct.generator.cpp/xtend-gen/org/yakindu/sct/generator/cpp/.Naming.java._trace


BIN
plugins/org.yakindu.sct.generator.cpp/xtend-gen/org/yakindu/sct/generator/cpp/.Navigation.java._trace


BIN
plugins/org.yakindu.sct.generator.cpp/xtend-gen/org/yakindu/sct/generator/cpp/.Types.java._trace


+ 4 - 0
plugins/org.yakindu.sct.model.sexec/src/org/yakindu/sct/model/sexec/extensions/SExecExtensions.xtend

@@ -66,6 +66,10 @@ class SExecExtensions {
 		declarations.filter(typeof(EventDefinition)).filter[direction == Direction::IN].fold(new LinkedList<EventDefinition>, [l, ev | l += ev l])
 	}
 	
+	def List<EventDefinition> getLocalEvents(Scope it) {
+		declarations.filter(typeof(EventDefinition)).filter[direction == Direction::LOCAL].fold(new LinkedList<EventDefinition>, [l, ev | l += ev l])
+	}
+	
 	def getInterfaceScopes(ExecutionFlow it) {
 		scopes.filter(typeof(InterfaceScope))
 	}