Explorar o código

Added cycle based and event driven implementations for Simulation

Andreas Mülder %!s(int64=14) %!d(string=hai) anos
pai
achega
2b7811b185

+ 24 - 26
plugins/org.yakindu.sct.simulation.core/src/org/yakindu/sct/simulation/core/debugmodel/SCTDebugTarget.java

@@ -14,8 +14,6 @@ import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
-import java.util.Timer;
-import java.util.TimerTask;
 
 import org.eclipse.core.resources.IMarkerDelta;
 import org.eclipse.core.runtime.CoreException;
@@ -39,8 +37,11 @@ import org.yakindu.sct.simulation.core.extensions.ExecutionFactoryExtensions;
 import org.yakindu.sct.simulation.core.extensions.ExecutionFactoryExtensions.ExecutionFactoryDescriptor;
 import org.yakindu.sct.simulation.core.launch.IStatechartLaunchParameters;
 import org.yakindu.sct.simulation.core.runtime.IExecutionFacade;
+import org.yakindu.sct.simulation.core.runtime.IExecutionFacadeController;
 import org.yakindu.sct.simulation.core.runtime.IExecutionFacadeFactory;
 import org.yakindu.sct.simulation.core.runtime.IExecutionTraceListener;
+import org.yakindu.sct.simulation.core.runtime.impl.CycleBasedExecutionFacadeController;
+import org.yakindu.sct.simulation.core.runtime.impl.EventDrivenExecutionFacadeController;
 
 /**
  * 
@@ -54,8 +55,6 @@ public class SCTDebugTarget extends SCTDebugElement implements IDebugTarget,
 
 	private IExecutionFacade facade;
 
-	private Timer timer;
-
 	private boolean stepping = false;
 	private boolean terminated = false;
 	private boolean suspended = false;
@@ -64,7 +63,7 @@ public class SCTDebugTarget extends SCTDebugElement implements IDebugTarget,
 
 	private List<SCTDebugThread> threads;
 
-	private long cyclePeriod;
+	private IExecutionFacadeController controller;
 
 	public SCTDebugTarget(ILaunch launch, Statechart statechart)
 			throws CoreException {
@@ -72,31 +71,31 @@ public class SCTDebugTarget extends SCTDebugElement implements IDebugTarget,
 		this.launch = launch;
 		this.statechart = statechart;
 		threads = new ArrayList<SCTDebugThread>();
-		timer = new Timer();
 		DebugPlugin.getDefault().getBreakpointManager()
 				.addBreakpointListener(this);
 		createExecutionModel(statechart);
-		cyclePeriod = launch.getLaunchConfiguration().getAttribute(
-				CYCLE_PERIOD, DEFAULT_CYCLE_PERIOD);
-
 	}
 
-	private void createExecutionModel(Statechart statechart) {
+	private void createExecutionModel(Statechart statechart)
+			throws CoreException {
 		IExecutionFacadeFactory factory = getExecutionFacadeFactory(statechart);
 		facade = factory.createExecutionFacade(statechart);
 		facade.addTraceListener(this);
-		facade.enter();
-		scheduleCycle();
-	}
-
-	protected void scheduleCycle() {
-		if (!terminated && !suspended)
-			timer.schedule(new TimerTask() {
-				public void run() {
-					facade.runCycle();
-					scheduleCycle();
-				}
-			}, cyclePeriod);
+		initFacadeController();
+	}
+
+	private void initFacadeController() throws CoreException {
+		boolean isCycleBased = launch.getLaunchConfiguration().getAttribute(
+				IS_CYCLE_BASED, DEFAULT_IS_CYCLE_BASED);
+		if (isCycleBased) {
+			long cyclePeriod = launch.getLaunchConfiguration().getAttribute(
+					CYCLE_PERIOD, DEFAULT_CYCLE_PERIOD);
+			controller = new CycleBasedExecutionFacadeController(facade,
+					cyclePeriod);
+		} else {
+			controller = new EventDrivenExecutionFacadeController(facade);
+		}
+		controller.start();
 	}
 
 	protected IExecutionFacadeFactory getExecutionFacadeFactory(EObject context) {
@@ -172,9 +171,7 @@ public class SCTDebugTarget extends SCTDebugElement implements IDebugTarget,
 		fireEvent(new DebugEvent(getDebugTarget(), DebugEvent.TERMINATE));
 		terminated = true;
 		facade.removeTraceListener(this);
-		facade.tearDown();
-		timer.cancel();
-		timer.purge();
+		controller.terminate();
 	}
 
 	public boolean canResume() {
@@ -193,13 +190,14 @@ public class SCTDebugTarget extends SCTDebugElement implements IDebugTarget,
 		fireEvent(new DebugEvent(this, DebugEvent.RESUME));
 		fireChangeEvent(DebugEvent.CONTENT);
 		suspended = false;
-		scheduleCycle();
+		controller.resume();
 	}
 
 	public void suspend() throws DebugException {
 		fireEvent(new DebugEvent(this, DebugEvent.SUSPEND));
 		fireChangeEvent(DebugEvent.CONTENT);
 		suspended = true;
+		controller.suspend();
 	}
 
 	public void breakpointAdded(IBreakpoint breakpoint) {

+ 33 - 0
plugins/org.yakindu.sct.simulation.core/src/org/yakindu/sct/simulation/core/runtime/IExecutionFacadeController.java

@@ -0,0 +1,33 @@
+/**
+ * Copyright (c) 2012 committers of YAKINDU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * Contributors:
+ * 	committers of YAKINDU - initial API and implementation
+ * 
+ */
+
+package org.yakindu.sct.simulation.core.runtime;
+
+/**
+ * An {@link IExecutionFacadeController} controls the {@link IExecutionFacade}
+ * runCycle method invocation.
+ * 
+ * Possible implementations can be cycle based or event driven controllers.
+ * 
+ * @author andreas muelder - Initial contribution and API
+ * 
+ */
+public interface IExecutionFacadeController {
+
+	public void start();
+
+	public void suspend();
+
+	public void resume();
+
+	public void terminate();
+
+}

+ 52 - 0
plugins/org.yakindu.sct.simulation.core/src/org/yakindu/sct/simulation/core/runtime/impl/AbstractExecutionFacadeController.java

@@ -0,0 +1,52 @@
+/**
+ * Copyright (c) 2012 committers of YAKINDU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * Contributors:
+ * 	committers of YAKINDU - initial API and implementation
+ * 
+ */
+
+package org.yakindu.sct.simulation.core.runtime.impl;
+
+import org.yakindu.sct.simulation.core.runtime.IExecutionFacade;
+import org.yakindu.sct.simulation.core.runtime.IExecutionFacadeController;
+
+/**
+ * Abstract base implementation for {@link IExecutionFacadeController}s
+ * 
+ * @author andreas muelder - Initial contribution and API
+ * 
+ */
+public abstract class AbstractExecutionFacadeController implements
+		IExecutionFacadeController {
+
+	protected final IExecutionFacade facade;
+
+	protected boolean terminated = false;
+	protected boolean suspended = false;
+
+	public AbstractExecutionFacadeController(IExecutionFacade facade) {
+		this.facade = facade;
+	}
+
+	public void start() {
+		facade.enter();
+	}
+
+	public void suspend() {
+		suspended = true;
+	}
+
+	public void resume() {
+		suspended = false;
+	}
+
+	public void terminate() {
+		terminated = true;
+		facade.tearDown();
+	}
+
+}

+ 67 - 0
plugins/org.yakindu.sct.simulation.core/src/org/yakindu/sct/simulation/core/runtime/impl/CycleBasedExecutionFacadeController.java

@@ -0,0 +1,67 @@
+/**
+ * Copyright (c) 2012 committers of YAKINDU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * Contributors:
+ * 	committers of YAKINDU - initial API and implementation
+ * 
+ */
+package org.yakindu.sct.simulation.core.runtime.impl;
+
+import java.util.Timer;
+import java.util.TimerTask;
+
+import org.yakindu.sct.simulation.core.runtime.IExecutionFacade;
+import org.yakindu.sct.simulation.core.runtime.IExecutionFacadeController;
+
+/**
+ * Cycle based implementation of {@link IExecutionFacadeController}.
+ * 
+ * runCycle is called on {@link IExecutionFacade} periodically, depending on the
+ * cyclePeriod value.
+ * 
+ * @author andreas muelder - Initial contribution and API
+ * 
+ */
+public class CycleBasedExecutionFacadeController extends
+		AbstractExecutionFacadeController {
+
+	private Timer timer;
+	
+	private long cyclePeriod;
+
+	public CycleBasedExecutionFacadeController(IExecutionFacade facade,
+			long cyclePeriod) {
+		super(facade);
+		this.cyclePeriod = cyclePeriod;
+	}
+
+	protected void scheduleCycle() {
+		if (!terminated && !suspended)
+			timer.schedule(new TimerTask() {
+				public void run() {
+					facade.runCycle();
+					scheduleCycle();
+				}
+			}, cyclePeriod);
+	}
+
+	public void start() {
+		super.start();
+		scheduleCycle();
+	}
+
+	public void resume() {
+		super.resume();
+		scheduleCycle();
+	}
+
+	public void terminate() {
+		super.terminate();
+		timer.cancel();
+		timer.purge();
+	}
+
+}

+ 83 - 0
plugins/org.yakindu.sct.simulation.core/src/org/yakindu/sct/simulation/core/runtime/impl/EventDrivenExecutionFacadeController.java

@@ -0,0 +1,83 @@
+/**
+ * Copyright (c) 2012 committers of YAKINDU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * Contributors:
+ * 	committers of YAKINDU - initial API and implementation
+ * 
+ */
+
+package org.yakindu.sct.simulation.core.runtime.impl;
+
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+
+import org.yakindu.sct.simulation.core.runtime.IExecutionContextListener;
+import org.yakindu.sct.simulation.core.runtime.IExecutionFacade;
+import org.yakindu.sct.simulation.core.runtime.IExecutionFacadeController;
+
+/**
+ * Event Driven implementation of the {@link IExecutionFacadeController}.
+ * 
+ * RunCycle is invoked on the {@link IExecutionFacade} each time a event is
+ * raised.
+ * 
+ * @author andreas muelder - Initial contribution and API
+ * 
+ */
+public class EventDrivenExecutionFacadeController extends
+		AbstractExecutionFacadeController implements IExecutionContextListener {
+
+	private Thread cycleRunner;
+
+	private BlockingQueue<ExecutionEvent> events;
+
+	public EventDrivenExecutionFacadeController(IExecutionFacade facade) {
+		super(facade);
+		facade.getExecutionContext().addExecutionContextListener(this);
+		events = new LinkedBlockingQueue<ExecutionEvent>();
+	}
+
+	public void start() {
+		super.start();
+		cycleRunner = new Thread(new CycleRunner());
+		cycleRunner.start();
+	}
+
+	public void suspend() {
+		super.suspend();
+	}
+
+	public void resume() {
+		super.resume();
+		cycleRunner = new Thread(new CycleRunner());
+		cycleRunner.start();
+	}
+
+	public void terminate() {
+		super.terminate();
+	}
+
+	public void eventRaised(ExecutionEvent event) {
+		events.add(event);
+	}
+
+	public void variableValueChanged(ExecutionVariable variable) {
+		// Nothing to do
+	}
+
+	private final class CycleRunner implements Runnable {
+		public void run() {
+			try {
+				while (!terminated && !suspended) {
+					events.take();
+					facade.runCycle();
+				}
+			} catch (InterruptedException e) {
+				e.printStackTrace();
+			}
+		}
+	}
+}