Pārlūkot izejas kodu

Merge pull request #1829 from Yakindu/issue_1828

Fixes #1828. Fixes invalid code generation for statecharts with C/C++…
Rene Beckmann 7 gadi atpakaļ
vecāks
revīzija
4e9339831f

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

@@ -63,7 +63,6 @@ class Types implements IContentTemplate {
 		
 		#define bool_true true
 		#define bool_false false
-		#define sc_invalid_event_value 0
 		
 		#endif /* «typesModule.define»_H_ */
 	'''

+ 4 - 1
plugins/org.yakindu.sct.generator.c/src/org/yakindu/sct/generator/c/eventdriven/StatechartEventsHeader.xtend

@@ -36,6 +36,9 @@ class StatechartEventsHeader {
 		#ifndef «bufferSize»
 		#define «bufferSize» «BUFFER_SIZE»
 		#endif
+		#ifndef SC_INVALID_EVENT_VALUE
+		#define SC_INVALID_EVENT_VALUE 0
+		#endif
 		
 		«generateEventsEnum»
 		
@@ -57,7 +60,7 @@ class StatechartEventsHeader {
 		 * Enum of event names in the statechart.
 		 */
 		typedef enum  {
-			«invalidEventEnumName(it)» = sc_invalid_event_value,
+			«invalidEventEnumName(it)» = SC_INVALID_EVENT_VALUE,
 			«FOR e : getAllEvents SEPARATOR ","»
 				«eventEnumMemberName(e)»
 			«ENDFOR»

+ 55 - 42
plugins/org.yakindu.sct.generator.cpp/src/org/yakindu/sct/generator/cpp/eventdriven/EventDrivenStatemachineImplementation.xtend

@@ -18,6 +18,9 @@ import org.yakindu.sct.model.sexec.ExecutionFlow
 import org.yakindu.sct.model.sgraph.Scope
 import org.yakindu.sct.model.stext.stext.EventDefinition
 import org.yakindu.sct.model.stext.stext.StatechartScope
+import org.yakindu.sct.model.stext.stext.ImportScope
+import org.yakindu.sct.model.stext.stext.InterfaceScope
+import org.yakindu.sct.model.stext.stext.InternalScope
 
 /*
  * To restore the event queue for in events, revert commit 235659d
@@ -121,56 +124,66 @@ class EventDrivenStatemachineImplementation extends StatemachineImplementation {
 		«ENDFOR»
 		'''
 	}
-	
-	def generateInterfaceDispatchFunction(ExecutionFlow it, Scope s) {
+
+	def dispatch generateInterfaceDispatchFunction(ExecutionFlow it, ImportScope s) {}
+
+	def dispatch generateInterfaceDispatchFunction(ExecutionFlow it, Scope s) {
 		'''
-		void «module»::«s.interfaceName»::dispatch_event(SctEvent * event)
-		{
-			switch(event->name)
-			{
-				«FOR e: s.declarations.filter(EventDefinition).filter[direction == Direction::LOCAL]»
-					case «e.eventEnumMemberName»:
+			«val localEvents = s.declarations.filter(EventDefinition).filter[direction == Direction::LOCAL]»
+			«IF localEvents.size > 0»
+				void «module»::«s.interfaceName»::dispatch_event(SctEvent * event)
+				{
+					switch(event->name)
 					{
-						«IF e.hasValue»
-						«e.eventClassName» * e = dynamic_cast<«e.eventClassName»*>(event);
-						if(e != 0) {
-							internal_«e.asRaiser»(e->value);
+						«FOR e : localEvents»
+							case «e.eventEnumMemberName»:
+							{
+								«IF e.hasValue»
+									«e.eventClassName» * e = dynamic_cast<«e.eventClassName»*>(event);
+									if(e != 0) {
+										internal_«e.asRaiser»(e->value);
+									}
+								«ELSE»
+									internal_«e.asRaiser»();
+								«ENDIF»
+								break;
+							}
+						«ENDFOR»
+						default:
+							break;
 						}
-						«ELSE»
-						internal_«e.asRaiser»();
-						«ENDIF»
-						break;
 					}
-				«ENDFOR»
-				default:
-					break;
-			}
-		}
-		'''
+				«ENDIF»
+			'''
 	}
-	
+
 	def generateInternalDispatchEventFunction(ExecutionFlow it) {
-		'''
-		void «module»::dispatch_event(SctEvent * event)
-		{
-			if(event == 0) {
-				return;
-			}
-			switch(event->name)
+		'''	
+			void «module»::dispatch_event(SctEvent * event)
 			{
-				«FOR s : scopes.filter(StatechartScope)»
-					«FOR e : s.declarations.filter(EventDefinition).filter[direction == Direction::LOCAL]»
-						case «e.eventEnumMemberName»:
+				if(event == 0) {
+					return;
+				}
+				switch(event->name)
+				{
+					«FOR s : scopes.filter(StatechartScope)»
+						«IF !(s instanceof ImportScope)»
+							«val localEvents = s.declarations.filter(EventDefinition).filter[direction == Direction.LOCAL]»
+							«IF localEvents.size > 0»
+								«FOR e : localEvents»
+									case «e.eventEnumMemberName»:
+								«ENDFOR»
+								{
+									«s.instance».dispatch_event(event);
+									break;
+								}
+							«ENDIF»
+						«ENDIF»
 					«ENDFOR»
-					{
-							«s.instance».dispatch_event(event);
-							break;
-					}
-				«ENDFOR»
-				default:
-					break;
+					default:
+						break;
+				}
 			}
-		}
 		'''
 	}
-}
+}

+ 4 - 0
plugins/org.yakindu.sct.generator.cpp/src/org/yakindu/sct/generator/cpp/eventdriven/EventNaming.xtend

@@ -25,6 +25,10 @@ class EventNaming {
 	@Inject extension Navigation
 	@Inject extension INamingService
 	
+	def invalidEventEnumName(ExecutionFlow it) {
+		'''«module»_invalid_event'''.toString.toLowerCase
+	}
+	
 	def eventEnumMemberName(Event it) {
 		'''«scope.interfaceName»_«name.asIdentifier»'''
 	}

+ 5 - 0
plugins/org.yakindu.sct.generator.cpp/src/org/yakindu/sct/generator/cpp/eventdriven/StatechartEvents.xtend

@@ -40,6 +40,9 @@ class StatechartEvents {
 		'''
 		#ifndef «generateHeaderDefineGuard»
 		#define «generateHeaderDefineGuard»
+		#ifndef SC_INVALID_EVENT_VALUE
+		#define SC_INVALID_EVENT_VALUE 0
+		#endif
 		
 		namespace «eventNamespaceName»
 		{
@@ -64,8 +67,10 @@ class StatechartEvents {
 		if(timed) {
 			enumMembers.add(timeEventEnumName)
 		}
+		
 		'''
 		typedef enum  {
+			«invalidEventEnumName(it)» = SC_INVALID_EVENT_VALUE,
 			«FOR e : enumMembers SEPARATOR ","»
 				«e»
 			«ENDFOR»