/**
* 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.sexec.container;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IStatusHandler;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.emf.common.util.WrappedException;
import org.yakindu.base.types.validation.IValidationIssueAcceptor.ListBasedValidationIssueAcceptor;
import org.yakindu.base.types.validation.IValidationIssueAcceptor.ValidationIssue.Severity;
import org.yakindu.sct.model.sexec.ExecutionFlow;
import org.yakindu.sct.model.sexec.transformation.IModelSequencer;
import org.yakindu.sct.model.sgraph.Statechart;
import org.yakindu.sct.simulation.core.SimulationCoreActivator;
import org.yakindu.sct.simulation.core.engine.IExecutionControl;
import org.yakindu.sct.simulation.core.engine.ISimulationEngine;
import org.yakindu.sct.simulation.core.sexec.interpreter.IExecutionFlowInterpreter;
import org.yakindu.sct.simulation.core.sruntime.ExecutionContext;
import com.google.inject.Inject;
/**
* Abstract implementation if the {@link ISimulationEngine} interface.
* transforms a {@link Statechart} to an {@link ExecutionFlow} and holds an
* {@link ExecutionContext}
*
* @author andreas muelder - Initial contribution and API
*
*/
public abstract class AbstractExecutionFlowSimulationEngine implements ISimulationEngine, IExecutionControl {
private static final String ERROR_MSG = "An unexpected error ocurred during simulation.";
public static final int ERROR_DURING_SIMULATION = 765;
@Inject
protected ExecutionContext context;
@Inject
private IModelSequencer sequencer;
@Inject
protected IExecutionFlowInterpreter interpreter;
@Inject
private IExecutionContextInitializer contextInitializer;
protected boolean terminated = false;
protected boolean suspended = false;
private Statechart statechart;
public AbstractExecutionFlowSimulationEngine(Statechart statechart) {
this.statechart = statechart;
}
protected void runCycle() {
try {
interpreter.runCycle();
} catch (Exception e) {
e.printStackTrace();
handleException(e);
}
}
protected void handleException(Throwable t) {
if (t instanceof WrappedException) {
t = ((WrappedException) t).getCause();
}
String statusMessage = t.getMessage() == null ? ERROR_MSG : t.getMessage();
Status errorStatus = new Status(Status.ERROR, SimulationCoreActivator.PLUGIN_ID, ERROR_DURING_SIMULATION,
statusMessage, t);
SimulationCoreActivator.getDefault().getLog().log(errorStatus);
IStatusHandler statusHandler = DebugPlugin.getDefault().getStatusHandler(errorStatus);
try {
statusHandler.handleStatus(errorStatus, getDebugTarget());
} catch (CoreException e) {
e.printStackTrace();
} finally {
interpreter.suspend();
terminate();
}
}
protected Object getDebugTarget() {
IDebugTarget[] debugTargets = DebugPlugin.getDefault().getLaunchManager().getDebugTargets();
for (IDebugTarget iDebugTarget : debugTargets) {
if (iDebugTarget.isTerminated())
continue;
if (iDebugTarget.getAdapter(ISimulationEngine.class) == this)
return iDebugTarget;
}
return null;
}
@Override
public void init() {
ListBasedValidationIssueAcceptor acceptor = new ListBasedValidationIssueAcceptor();
ExecutionFlow flow = sequencer.transform(statechart, acceptor);
if (acceptor.getTraces(Severity.ERROR).size() > 0) {
Status errorStatus = new Status(Status.ERROR, SimulationCoreActivator.PLUGIN_ID, ERROR_DURING_SIMULATION,
acceptor.getTraces(Severity.ERROR).iterator().next().toString(), null);
IStatusHandler statusHandler = DebugPlugin.getDefault().getStatusHandler(errorStatus);
try {
statusHandler.handleStatus(errorStatus, getDebugTarget());
} catch (CoreException e) {
e.printStackTrace();
}
}
if (!context.isSnapshot()) {
contextInitializer.initialize(context, flow);
}
interpreter.initialize(flow, context);
}
public void start() {
try {
interpreter.enter();
} catch (Exception ex) {
handleException(ex);
}
}
public void suspend() {
suspended = true;
interpreter.suspend();
}
public void resume() {
try {
suspended = false;
interpreter.resume();
} catch (Exception ex) {
handleException(ex);
}
}
public void terminate() {
terminated = true;
interpreter.tearDown();
}
public void stepForward() {
try {
interpreter.resume();
interpreter.runCycle();
interpreter.suspend();
} catch (Exception ex) {
handleException(ex);
}
}
public void stepBackward() {
}
@Override
public ExecutionContext getExecutionContext() {
return context;
}
public void setExecutionContext(ExecutionContext context) {
this.context = context;
}
@Override
public IExecutionControl getExecutionControl() {
return this;
}
}