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

implemented #1 - Add execution support for local reactions on states

terfloth@itemis.de 14 лет назад
Родитель
Сommit
7c91e5c2eb

+ 4 - 1
plugins/org.yakindu.sct.simulation.runtime/src-gen/org/yakindu/sct/simulation/runtime/sgraph/AbstractStatechart.java

@@ -17,10 +17,13 @@ public abstract class AbstractStatechart {
 	private List<RTRegion> regions = new ArrayList<RTRegion>();
 
 	private List<RTTransition> transitions = new ArrayList<RTTransition>();
+	private List<RTReaction> localReactions = new ArrayList<RTReaction>();
 
 	// used to request time events from environment
 	protected RTTimingService timingService = null;
 
+	protected Set<RTEvent> currentEvents = new HashSet<RTEvent>();
+
 	protected AbstractStatechart(String id) {
 		this.id = id;
 		this.timingService = new RTDefaultTimingService(this);
@@ -65,8 +68,8 @@ public abstract class AbstractStatechart {
 	}
 
 	public void runCycle() {
-		Set<RTEvent> currentEvents = new HashSet<RTEvent>();
 		synchronized (raisedEvents) {
+			currentEvents.clear();
 			currentEvents.addAll(raisedEvents);
 			raisedEvents.clear();
 		}

+ 17 - 0
plugins/org.yakindu.sct.simulation.runtime/src-gen/org/yakindu/sct/simulation/runtime/sgraph/RTReaction.java

@@ -1,5 +1,22 @@
 package org.yakindu.sct.simulation.runtime.sgraph;
 
+
 public class RTReaction {
 
+	protected ITrigger trigger;
+	protected RTAction action;
+
+	public RTReaction(ITrigger trigger, RTAction action) {
+		this.trigger = trigger;
+		this.action = action;
+	}
+
+	public RTAction getAction() {
+		return action;
+	}
+
+	public ITrigger getTrigger() {
+		return trigger;
+	}
+
 }

+ 2 - 6
plugins/org.yakindu.sct.simulation.runtime/src-gen/org/yakindu/sct/simulation/runtime/sgraph/RTSimpleState.java

@@ -18,15 +18,11 @@ public class RTSimpleState extends RTState {
 	}
 
 	protected void reactLocallyOn(Set<RTEvent> events) {
-
-		if (doAction != null) {
-			doAction.execute();
-		}
-
+		performLocalReactions(events);
 	}
 
 	public RTAction getDoAction() {
 		return doAction;
 	}
-
+ 
 }

+ 24 - 0
plugins/org.yakindu.sct.simulation.runtime/src-gen/org/yakindu/sct/simulation/runtime/sgraph/RTState.java

@@ -1,5 +1,7 @@
 package org.yakindu.sct.simulation.runtime.sgraph;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Set;
 
 /**
@@ -16,14 +18,21 @@ public abstract class RTState extends RTNode {
 	private RTAction exitAction;
 	private String name;
 
+	protected List<RTReaction> localReactions = new ArrayList<RTReaction>();
+
 	public RTState(String id, String name, RTRegion owningRegion,
 			RTAction entryAction, RTAction exitAction) {
 		super(id, owningRegion);
 		this.name = name;
 		this.entryAction = entryAction;
 		this.exitAction = exitAction;
+		
 	}
 
+	public void addLocalReaction(RTReaction reaction) {
+		localReactions.add(reaction);
+	}
+	
 	public String getName() {
 		return name;
 	}
@@ -113,4 +122,19 @@ public abstract class RTState extends RTNode {
 		return exitAction;
 	}
 
+	
+	protected void performLocalReactions(Set<RTEvent> events) {
+		perfotmParentReactions(events);
+		for (RTReaction reaction : localReactions) {
+			if (reaction.getTrigger().isEnabled(events)) reaction.getAction().execute();
+		}
+	}
+
+	protected void perfotmParentReactions(Set<RTEvent> events) {
+		RTState state = getOwningRegion().getOwningState();
+		if (state != null) {
+			state.performLocalReactions(events);
+		}
+	}
+
 }

+ 11 - 35
plugins/org.yakindu.sct.simulation.runtime/src-gen/org/yakindu/sct/simulation/runtime/sgraph/RTTransition.java

@@ -11,19 +11,11 @@ import java.util.Set;
  * and may be additionally guarded. In case a transition is taken, its action
  * will be executed.
  */
-public class RTTransition {
+public class RTTransition extends RTReaction {
 
 	private String id;
 	private int priority;
 
-	private ITrigger trigger;
-	
-	
-//	private RTGuard guard;
-//	private Set<RTSignalEvent> signalTriggers = new HashSet<RTSignalEvent>();
-//	private RTTimeEvent timeTrigger;
-	private RTAction action;
-
 	private RTNode sourceNode;
 	private RTNode targetNode;
 
@@ -33,6 +25,9 @@ public class RTTransition {
 
 	public RTTransition(String id, int priority, ITrigger trigger, RTAction action,
 			RTNode sourceNode, RTNode targetNode) {
+
+		super(trigger, action);
+		
 		this.id = id;
 		this.priority = priority;
 
@@ -56,11 +51,7 @@ public class RTTransition {
 
 	protected boolean isTriggeredBy(Set<RTEvent> events) {
 
-		// TODO : implement Null-Trigger
 		return (trigger != null) ? trigger.isEnabled(events) : true ;
-//		return !Collections.disjoint(this.signalTriggers, events)
-//				|| (timeTrigger != null && events.contains(timeTrigger));
-
 	}
 
 	public String getId() {
@@ -71,13 +62,6 @@ public class RTTransition {
 		return priority;
 	}
 
-//	protected boolean isEnabled() {
-//		if (guard == null) {
-//			return true;
-//		} else {
-//			return guard.evaluate();
-//		}
-//	}
 
 	public RTTimeEvent getTimeTrigger() {
 		return trigger.getTimeTrigger();
@@ -89,6 +73,9 @@ public class RTTransition {
 
 	protected void take() {
 
+		// first perform all local reactions of non effected parent states...
+		if (getCommonParentState() != null) getCommonParentState().performLocalReactions(commonAncestorRegion.getStatechart().currentEvents);
+		
 		// leave all enclosing states from the souceNode's container up to
 		// the common ancestor region
 		for (RTCompoundState state : enclosingStatesToLeave) {
@@ -176,20 +163,9 @@ public class RTTransition {
 		return targetNode;
 	}
 
-//	public RTGuard getGuard() {
-//		return guard;
-//	}
-
-	public RTAction getAction() {
-		return action;
-	}
-
-	public ITrigger getTrigger() {
-		return trigger;
+	public RTState getCommonParentState() {
+		return (commonAncestorRegion != null)  
+				? commonAncestorRegion.getOwningState()
+				: null;
 	}
-
-//	public Set<RTSignalEvent> getSignalTriggers() {
-//		return signalTriggers;
-//	}
-
 }

+ 1 - 1
plugins/org.yakindu.sct.simulation.runtime/src/org/yakindu/sct/simulation/runtime/sgraph/RTStatechart.java

@@ -132,7 +132,7 @@ public class RTStatechart extends AbstractStatechart implements ExecutionScope,
 		}
 	}
 
-	protected void transitionFired(RTTransition trans) {
+	protected void transitionFired(RTReaction trans) {
 		for (ISGraphExecutionListener listener : listeners) {
 			listener.transitionFired((Transition) elementToAliasMap.get(trans));
 		}

+ 66 - 21
plugins/org.yakindu.sct.simulation.runtime/src/org/yakindu/sct/simulation/runtime/sgraph/builder/SGraphBuilder.java

@@ -13,6 +13,7 @@ package org.yakindu.sct.simulation.runtime.sgraph.builder;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 
 import org.eclipse.emf.common.util.BasicEList;
@@ -51,6 +52,7 @@ import org.yakindu.sct.simulation.runtime.sgraph.RTFinalState;
 import org.yakindu.sct.simulation.runtime.sgraph.RTGuard;
 import org.yakindu.sct.simulation.runtime.sgraph.RTNode;
 import org.yakindu.sct.simulation.runtime.sgraph.RTPseudostate;
+import org.yakindu.sct.simulation.runtime.sgraph.RTReaction;
 import org.yakindu.sct.simulation.runtime.sgraph.RTRegion;
 import org.yakindu.sct.simulation.runtime.sgraph.RTSignalEvent;
 import org.yakindu.sct.simulation.runtime.sgraph.RTSimpleState;
@@ -174,10 +176,18 @@ public class SGraphBuilder extends Function implements ISGraphExecutionBuilder {
 	public Object build(RTRegion parent, State state) {
 		RTState runtimeState = null;
 		
+		LocalReaction entryReaction = getReactionByTriggerEventType(state, EntryEvent.class);
+		LocalReaction exitReaction = getReactionByTriggerEventType(state, ExitEvent.class);
+
+		List<LocalReaction> localReactions = getLocalReactions(state);
+		if ( entryReaction != null ) localReactions.remove(entryReaction);
+		if ( exitReaction != null) localReactions.remove(exitReaction);
 		
+
 		//Build the transition action
-		RTAction entryAction = buildAction((RTStatechart) parent.getStatechart(),  getReactionByTriggerEventType(state, EntryEvent.class));
-		RTAction exitAction = buildAction((RTStatechart) parent.getStatechart(),  getReactionByTriggerEventType(state, ExitEvent.class));
+		RTAction entryAction = buildAction((RTStatechart) parent.getStatechart(),  entryReaction);
+		RTAction exitAction = buildAction((RTStatechart) parent.getStatechart(),  exitReaction);
+		
 		
 		if (state.getSubRegions().size() > 0) {
 			runtimeState = new RTCompoundState(parent.getId() + "."
@@ -189,6 +199,10 @@ public class SGraphBuilder extends Function implements ISGraphExecutionBuilder {
 					+ state.getName(), state.getName(), parent, entryAction, null, exitAction);
 		}
 		
+		for (LocalReaction reaction : localReactions) {
+			runtimeState.addLocalReaction(buildReaction((RTStatechart)parent.getStatechart(), reaction));
+		}
+		
 		((RTStatechart) parent.getStatechart())
 				.defineAlias(state, runtimeState);
 
@@ -196,6 +210,16 @@ public class SGraphBuilder extends Function implements ISGraphExecutionBuilder {
 	}
 
 	
+	private RTReaction buildReaction(RTStatechart context, LocalReaction reaction) {
+		Trigger trigger = reaction.getTrigger();
+		RTTrigger rtTrigger = buildTrigger(context, trigger);
+		
+		RTAction action = buildAction(context, reaction.getEffect());
+
+		return new RTReaction(rtTrigger, action);
+	}
+
+	
 	protected RTAction buildAction(ExecutionScope scope, LocalReaction entryReaction) {
 		if (entryReaction != null) {
 			Effect effect = entryReaction.getEffect();
@@ -222,6 +246,15 @@ public class SGraphBuilder extends Function implements ISGraphExecutionBuilder {
 		return null;
 	}
 	
+	protected List<LocalReaction> getLocalReactions(State state) {
+	
+		// TODO: derive localReactions from scope. 
+		for (Scope declarationScope : state.getScopes()) {
+			return EcoreUtil2.getAllContentsOfType(declarationScope, LocalReaction.class);
+		}
+		return null;
+	}
+	
 	
 	protected LocalReaction getExitReaction(State state) {
 		return null;
@@ -259,15 +292,40 @@ public class SGraphBuilder extends Function implements ISGraphExecutionBuilder {
 
 		if ( fromNode == null || toNode == null ) return null;  // >>>>>>>>> exit here on false precondition
 		
+		Trigger trigger = transition.getTrigger();
+		RTTrigger rtTrigger = buildTrigger(tParent, trigger);
 		
-		RTTimeEvent timeTrigger = null;
-		Set<RTSignalEvent> signalTriggers = new HashSet<RTSignalEvent>();
-		RTGuard guard = null;
+		RTAction action = buildAction(tParent, transition.getEffect());
+
+		String id= "t@" + transition.getSource().getOutgoingTransitions().indexOf(transition);
+		RTReaction tTrans = new RTTransition(id, transition.getPriority(),
+				rtTrigger, action, fromNode, toNode);
+		tParent.defineAlias(transition, tTrans);
+		
+		return tTrans;
+	}
+
+	
+	protected RTAction buildAction(RTStatechart tParent, Effect effect) {
+		//Build the transition action
 		RTAction action = null;
+		RTStatement statement = (RTStatement) textBuilder.build(effect);
+		if (statement != null) {
+			action = new RTActionStatement(statement, tParent);
+		}
+		return action;
+	}
 
-		Trigger trigger = transition.getTrigger();
+	
+	protected RTTrigger buildTrigger(RTStatechart tParent,
+			 
+			 Trigger trigger ) {
+		
 		RTTrigger rtTrigger = null;
-				
+		RTTimeEvent timeTrigger = null;
+		Set<RTSignalEvent> signalTriggers = new HashSet<RTSignalEvent>();
+		RTGuard guard = null;
+		
 		// // TODO: Das muss hier raus:
 		if (trigger instanceof ReactionTrigger) {
 			EList<EventSpec> triggers = ((ReactionTrigger) trigger)
@@ -306,20 +364,7 @@ public class SGraphBuilder extends Function implements ISGraphExecutionBuilder {
 
 			rtTrigger = new RTTrigger(timeTrigger, signalTriggers, guard);
 		}
-		
-		//Build the transition action
-		Effect effect = transition.getEffect();
-		RTStatement statement = (RTStatement) textBuilder.build(effect);
-		if (statement != null) {
-			action = new RTActionStatement(statement, tParent);
-		}
-
-		String id= "t@" + transition.getSource().getOutgoingTransitions().indexOf(transition);
-		RTTransition tTrans = new RTTransition(id, transition.getPriority(),
-				rtTrigger, action, fromNode, toNode);
-		tParent.defineAlias(transition, tTrans);
-		
-		return tTrans;
+		return rtTrigger;
 	}
 
 	protected void build(Object targetParent, EList<EObject> sourceChildren) {

+ 2 - 1
test-plugins/org.yakindu.sct.simulation.runtime.test/src/org/yakindu/sct/simulation/runtime/sgraph/builder/test/SGraphBuilderTest.java

@@ -47,6 +47,7 @@ import org.yakindu.sct.simulation.runtime.sgraph.RTNode;
 import org.yakindu.sct.simulation.runtime.sgraph.RTPseudostate;
 import org.yakindu.sct.simulation.runtime.sgraph.RTRegion;
 import org.yakindu.sct.simulation.runtime.sgraph.RTSimpleState;
+import org.yakindu.sct.simulation.runtime.sgraph.RTState;
 import org.yakindu.sct.simulation.runtime.sgraph.RTStatechart;
 import org.yakindu.sct.simulation.runtime.sgraph.RTTransition;
 import org.yakindu.sct.simulation.runtime.sgraph.builder.SGraphBuilder;
@@ -218,7 +219,7 @@ public class SGraphBuilderTest {
 		assertEquals(1, regions.get(0).getNodes().size());
 		RTNode node = regions.get(0).getNodes().iterator().next();
 		assertTrue(node instanceof RTSimpleState);
-		RTSimpleState tState = (RTSimpleState) node;
+		RTState tState = (RTState) node;
 		assertEquals(state.getName(), tState.getName());
 		
 		fail("complete me");

+ 8 - 6
test-plugins/org.yakindu.sct.simulation.runtime.test/src/org/yakindu/sct/simulation/runtime/sgraph/test/StatechartTest.java

@@ -21,9 +21,11 @@ import org.yakindu.sct.simulation.runtime.sgraph.RTActionStatement;
 import org.yakindu.sct.simulation.runtime.sgraph.GuardExpression;
 import org.yakindu.sct.simulation.runtime.sgraph.PseudostateKind;
 import org.yakindu.sct.simulation.runtime.sgraph.RTPseudostate;
+import org.yakindu.sct.simulation.runtime.sgraph.RTReaction;
 import org.yakindu.sct.simulation.runtime.sgraph.RTRegion;
 import org.yakindu.sct.simulation.runtime.sgraph.RTSignalEvent;
 import org.yakindu.sct.simulation.runtime.sgraph.RTSimpleState;
+import org.yakindu.sct.simulation.runtime.sgraph.RTState;
 import org.yakindu.sct.simulation.runtime.sgraph.RTStatechart;
 import org.yakindu.sct.simulation.runtime.sgraph.RTTransition;
 import org.yakindu.sct.simulation.runtime.stext.Assign;
@@ -38,8 +40,8 @@ public class StatechartTest {
 	private RTRegion rootRegion;
 	protected RTStatechart statechart;
 	private RTPseudostate initial;
-	private RTSimpleState state1;
-	private RTTransition trans;
+	private RTState state1;
+	private RTReaction trans;
 
 	/**
 	 * The setup creates a basic statechart that consists of a single root
@@ -79,7 +81,7 @@ public class StatechartTest {
 	@Test
 	public void notestTransitionWithoutTrigger() {
 
-		RTSimpleState state2 = new RTSimpleState("s2", "b", rootRegion, null,
+		RTState state2 = new RTSimpleState("s2", "b", rootRegion, null,
 				null, null);
 		new RTTransition("t_s1_s2", 1, null, null, state1, state2);
 
@@ -101,7 +103,7 @@ public class StatechartTest {
 
 		final RTSignalEvent event = new RTSignalEvent("event");
 
-		RTSimpleState state2 = new RTSimpleState("s2", "b", rootRegion, null,
+		RTState state2 = new RTSimpleState("s2", "b", rootRegion, null,
 				null, null);
 		RTTrigger trigger = new RTTrigger(null, new HashSet<RTSignalEvent>() {
 			{
@@ -135,7 +137,7 @@ public class StatechartTest {
 		RTVariable var = new RTVariable("v");
 		statechart.addVariable(var);
 
-		RTSimpleState state2 = new RTSimpleState("s2", "b", rootRegion, null,
+		RTState state2 = new RTSimpleState("s2", "b", rootRegion, null,
 				null, null);
 		
 		RTTrigger trigger = new RTTrigger(null, new HashSet<RTSignalEvent>() {
@@ -173,7 +175,7 @@ public class StatechartTest {
 		RTVariable var = new RTVariable("v");
 		statechart.addVariable(var);
 
-		RTSimpleState state2 = new RTSimpleState("s2", "b", rootRegion, null,
+		RTState state2 = new RTSimpleState("s2", "b", rootRegion, null,
 				null, null);