Explorar o código

Fixes Yakindu/sctpro#1364 where simluation does not get suspended for state local reactions (#1945)

Robert Rudi %!s(int64=7) %!d(string=hai) anos
pai
achega
ce06b525ef

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

@@ -388,8 +388,17 @@ class BehaviorMapping {
 	}
 	
 	def Sequence mapToEffect(LocalReaction lr) {
-		if (lr.effect != null) lr.effect.mapEffect	
+		if (lr.effect !== null) {
+			if (trace.addTraceSteps) {
+				val sequence = lr.effect.mapEffect
+				sequence.steps.add(0, lr.create.newTraceReactionWillFire)
+				sequence.steps.add(lr.create.newTraceReactionFired)
+				return sequence
+			} else
+				return lr.effect.mapEffect
+		}
 	}
+
 	
 	def Sequence mapToEffect(Transition t, Reaction r) {
 		val sequence = sexec.factory.createSequence 

+ 0 - 38
plugins/org.yakindu.sct.model.sexec/src/org/yakindu/sct/model/sexec/transformation/ReactionBuilder.xtend

@@ -200,7 +200,6 @@ class ReactionBuilder {
 
 
 	def Sequence createLocalReactionSequence(ExecutionNode state, Step localStep) {	
-				
 		val localReactions = state.reactions.filter(r | ! r.transition ).toList
 		var localSteps = sexec.factory.createSequence
 		localSteps.steps.addAll(localReactions.map(lr | {
@@ -226,7 +225,6 @@ class ReactionBuilder {
 		if (localStep != null) localSteps.steps += localStep
 		if (localSteps.steps.empty) localSteps = null
 				
-				
 		val transitionReactions = state.reactions.filter(r | r.transition && ! r.unchecked ).toList
 		val transitionStep = transitionReactions.reverseView.fold(localSteps as Step, [s, reaction | {
 				var ifStep = sexec.factory.createIf
@@ -236,48 +234,12 @@ class ReactionBuilder {
 				ifStep as Step
 			}])
 
-	
 		if (transitionStep != null) cycle.steps.add(transitionStep)		
 		else if (localSteps != null) cycle.steps.add(localSteps)
 		
 		return cycle
 	}
 	
-	
-//	def Sequence createReactionSequence(ExecutionNode state, Step localStep) {	
-//		val cycle = sexec.factory.createSequence
-//		cycle.name = "react"
-//		
-//		val localReactions = state.reactions.filter(r | ! r.transition ).toList
-//		var localSteps = sexec.factory.createSequence
-//		localSteps.steps.addAll(localReactions.map(lr | {
-//				var ifStep = sexec.factory.createIf
-//				ifStep.check = lr.check.newRef		
-//				ifStep.thenStep = lr.effect.newCall
-//				ifStep
-//		}))
-//		
-//		if (localStep != null) localSteps.steps += localStep
-//		if (localSteps.steps.empty) localSteps = null
-//				
-//				
-//		val transitionReactions = state.reactions.filter(r | r.transition && ! r.unchecked ).toList
-//		val transitionStep = transitionReactions.reverseView.fold(localSteps as Step, [s, reaction | {
-//				var ifStep = sexec.factory.createIf
-//				ifStep.check = reaction.check.newRef		
-//				ifStep.thenStep = reaction.effect.newCall
-//				ifStep.elseStep = s
-//				ifStep as Step
-//			}])
-//
-//	
-//		if (transitionStep != null) cycle.steps.add(transitionStep)		
-//		else if (localSteps != null) cycle.steps.add(localSteps)
-//		
-//		return cycle
-//	}
-	
-	
 	def ExecutionFlow defineEntryReactions(Statechart statechart, ExecutionFlow r) {
 		statechart.allEntries.forEach(e|e.defineReaction)
 		return r

+ 6 - 0
plugins/org.yakindu.sct.simulation.core.sexec/src/org/yakindu/sct/simulation/core/sexec/interpreter/DefaultExecutionFlowInterpreter.xtend

@@ -48,6 +48,7 @@ import org.yakindu.sct.model.stext.lib.StatechartAnnotations
 import org.yakindu.sct.simulation.core.engine.scheduling.ITimeTaskScheduler
 import org.yakindu.sct.simulation.core.engine.scheduling.ITimeTaskScheduler.TimeTask
 import org.yakindu.sct.simulation.core.util.ExecutionContextExtensions
+import org.yakindu.sct.model.sexec.SexecFactory
 
 /**
  * 
@@ -93,6 +94,9 @@ class DefaultExecutionFlowInterpreter implements IExecutionFlowInterpreter, IEve
 	protected List<Step> executionStack
 	protected int activeStateIndex
 	protected boolean useInternalEventQueue
+	
+	protected static final Trace beginRunCycleTrace = SexecFactory.eINSTANCE.createTraceBeginRunCycle
+	protected static final Trace endRunCycleTrace = SexecFactory.eINSTANCE.createTraceEndRunCycle
 
 	override initialize(ExecutionFlow flow, ExecutionContext context) {
 		initialize(flow, context, false)
@@ -149,6 +153,7 @@ class DefaultExecutionFlowInterpreter implements IExecutionFlowInterpreter, IEve
 	}
 
 	override runCycle() {
+		traceInterpreter.evaluate(beginRunCycleTrace, executionContext)
 		var Event event = null
 		do {
 			// activate an event if there is one
@@ -162,6 +167,7 @@ class DefaultExecutionFlowInterpreter implements IExecutionFlowInterpreter, IEve
 			// get next event if available
 			if(! internalEventQueue.empty) event = internalEventQueue.poll
 		} while (event !== null)
+		traceInterpreter.evaluate(endRunCycleTrace, executionContext)
 	}
 
 	def rtcStep() {

+ 4 - 1
plugins/org.yakindu.sct.simulation.core.sexec/src/org/yakindu/sct/simulation/core/sexec/interpreter/DefaultTraceStepInterpreter.java

@@ -10,6 +10,7 @@
 */
 package org.yakindu.sct.simulation.core.sexec.interpreter;
 
+import org.eclipse.emf.ecore.EObject;
 import org.yakindu.sct.model.sexec.ReactionFired;
 import org.yakindu.sct.model.sexec.Trace;
 import org.yakindu.sct.model.sruntime.ExecutionContext;
@@ -19,7 +20,9 @@ public class DefaultTraceStepInterpreter implements ITraceStepInterpreter {
 	@Override
 	public void evaluate(Trace trace, ExecutionContext context) {
 		if (trace instanceof ReactionFired) {
-			context.getExecutedElements().add(((ReactionFired) trace).getReaction().getSourceElement());
+			EObject sourceElement = ((ReactionFired) trace).getReaction().getSourceElement();
+			if (sourceElement != null)
+				context.getExecutedElements().add(sourceElement);
 		}
 	}
 }