Commit 6798d6d8 authored by Li's avatar Li
Browse files

parts of modes simulation support.

refs 114
parent 6b113e09
......@@ -211,4 +211,27 @@
</modelConnectionCompositor>
</extension>
<!-- View extension. -->
<extension
point="org.eclipse.ui.views">
<view
allowMultiple="true"
class="org.fortiss.af3.mode.ui.simulator.views.GraphicalModeSimulationView"
id="org.fortiss.af3.mode.ui.simulator.views.GraphicalModeSimulationView:graphical"
name="Mode Automaton Simulation UI"
restorable="false">
</view>
</extension>
<!-- Context menu contribution. -->
<extension
point="org.fortiss.af3.component.ui.simulationContextMenuContribution">
<simulationContextMenuContribution
contributor="org.fortiss.af3.mode.ui.simulator.views.GraphicalModeViewMenuContributor">
<modelElementClass
modelElementClass="org.fortiss.af3.mode.model.ModeAutomaton">
</modelElementClass>
</simulationContextMenuContribution>
</extension>
</plugin>
/*--------------------------------------------------------------------------+
$Id$
| |
| Copyright 2011 ForTISS GmbH |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
+--------------------------------------------------------------------------*/
package org.fortiss.af3.mode.ui.simulator.views;
import org.eclipse.gef.GraphicalViewer;
import org.eclipse.gef.ui.parts.ScrollingGraphicalViewer;
import org.eclipse.swt.widgets.Composite;
import org.fortiss.af3.component.model.Component;
import org.fortiss.af3.component.ui.simulator.views.CustomSimulationViewBase;
import org.fortiss.af3.mode.model.Mode;
import org.fortiss.af3.mode.model.ModeAutomaton;
import org.fortiss.af3.mode.simulator.ExecutableModeAutomatonSpecification;
import org.fortiss.af3.mode.ui.editpart.ModeEditPart;
import org.fortiss.af3.mode.ui.editpart.ModesEditPartFactory;
import org.fortiss.tooling.base.model.element.IModelElementSpecification;
import org.fortiss.tooling.base.ui.editpart.ExtendedLayerRootEditPart;
/**
* The graphical simulation view of mode automaton specification.
*
* @author li
* @author $Author$
* @version $Rev$
* @ConQAT.Rating RED Hash:
*/
public class GraphicalModeSimulationView extends
CustomSimulationViewBase<Component> {
/** Stores the view ID. */
public static final String ID = GraphicalModeSimulationView.class.getName()
+ ":graphical";
/** The graphical viewer is used for displaying the diagram. */
private GraphicalViewer graphicalViewer;
/** The specification displayed in this view. */
private Component modeAutomatonSpecification;
/** Constructor. */
public GraphicalModeSimulationView() {
super(Component.class);
}
/** {@inheritDoc} */
@Override
public void createPartControlInternal(Composite parent) {
graphicalViewer = new ScrollingGraphicalViewer();
graphicalViewer.setRootEditPart(new ExtendedLayerRootEditPart());
graphicalViewer.createControl(parent);
graphicalViewer.getControl().setBackground(parent.getBackground());
graphicalViewer.setEditPartFactory(new ModesEditPartFactory());
}
/** {@inheritDoc} */
@Override
protected void setModelElement(Component spec) {
modeAutomatonSpecification = spec;
for (IModelElementSpecification sp : modeAutomatonSpecification
.getSpecificationsList()) {
if (sp instanceof ModeAutomaton) {
graphicalViewer.setContents(((ModeAutomaton) sp).getRootMode());
break;
}
}
}
/** {@inheritDoc} */
@Override
public void setFocus() {
graphicalViewer.getControl().setFocus();
}
/** {@inheritDoc} */
@Override
protected void updateVisuals(Component spec) {
Mode currentMode = null;
if (executable != null) {
currentMode = ((ExecutableModeAutomatonSpecification) executable)
.getCurrentMode();
}
for (final Object editPart : graphicalViewer.getRootEditPart()
.getContents().getChildren()) {
if (editPart instanceof ModeEditPart) {
final ModeEditPart modeEditPart = (ModeEditPart) editPart;
modeEditPart.setActive(modeEditPart.getModel() == currentMode);
graphicalViewer.getControl().redraw();
}
}
}
}
/*--------------------------------------------------------------------------+
$Id$
| |
| Copyright 2011 ForTISS GmbH |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
+--------------------------------------------------------------------------*/
package org.fortiss.af3.mode.ui.simulator.views;
import org.fortiss.af3.component.ui.simulator.menu.ISimulationContextMenuService;
import org.fortiss.af3.component.ui.simulator.menu.SimulationContextMenuContributorBase;
/**
* Menu contributor for {@link GraphicalModeSimulationView}.
*
* @author li
* @author $Author$
* @version $Rev$
* @ConQAT.Rating RED Hash:
*/
public class GraphicalModeViewMenuContributor extends
SimulationContextMenuContributorBase {
/** {@inheritDoc} */
@Override
public String getMenuSectionID() {
return ISimulationContextMenuService.TOP_MOST_MENU_SECTION_ID;
}
/** {@inheritDoc} */
@Override
public String getViewTitle() {
return "Mode Automaton View";
}
/** {@inheritDoc} */
@Override
public String getViewID() {
return GraphicalModeSimulationView.ID;
}
}
......@@ -14,4 +14,5 @@ Export-Package: org.fortiss.af3.mode,
org.fortiss.af3.mode.model,
org.fortiss.af3.mode.model.impl,
org.fortiss.af3.mode.model.util,
org.fortiss.af3.mode.simulator,
org.fortiss.af3.mode.utils
......@@ -60,6 +60,11 @@
<details key="body" value="return org.fortiss.af3.mode.utils.ModeAutomatonUtils.getIncomingSwitchSegments(this);"/>
</eAnnotations>
</eOperations>
<eOperations name="getSwitchSegmentExitConnectors" upperBound="-1" eType="#//SwitchSegmentExitConnector">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="body" value="return org.fortiss.tooling.kernel.utils.EcoreUtils.pickInstanceOf(&#xA;&#x9;&#x9;org.fortiss.af3.mode.model.SwitchSegmentExitConnector.class,&#xA;&#x9;&#x9;getConnectorsList());"/>
</eAnnotations>
</eOperations>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="SwitchSegmentConnector" abstract="true"
eSuperTypes="platform:/plugin/org.fortiss.tooling.base/model/base.ecore#//base/ConnectorBase">
......
......@@ -28,6 +28,7 @@
<genOperations ecoreOperation="mode.ecore#//Mode/getModeComponentStructureSpecification"/>
<genOperations ecoreOperation="mode.ecore#//Mode/getOutgoingSwitchSegments"/>
<genOperations ecoreOperation="mode.ecore#//Mode/getIncomingSwitchSegment"/>
<genOperations ecoreOperation="mode.ecore#//Mode/getSwitchSegmentExitConnectors"/>
</genClasses>
<genClasses image="false" ecoreClass="mode.ecore#//SwitchSegmentConnector">
<genOperations ecoreOperation="mode.ecore#//SwitchSegmentConnector/getMode"/>
......
......@@ -16,4 +16,22 @@
uri="http://www.fortiss.org/af3/mode">
</package>
</extension>
<!-- transformation provider for mode automaton simulator. -->
<extension
point="org.fortiss.tooling.kernel.transformationProvider">
<transformationProvider
transformationProvider="org.fortiss.af3.mode.simulator.ExecutableModeSpecificationTransformation">
<source>
<objectClass
objectClass="org.fortiss.af3.mode.model.ModeAutomaton">
</objectClass>
</source>
<target>
<objectClass
objectClass="org.fortiss.af3.component.simulator.ExecutableComponent">
</objectClass>
</target>
</transformationProvider>
</extension>
</plugin>
/*--------------------------------------------------------------------------+
$Id$
| |
| Copyright 2011 ForTISS GmbH |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
+--------------------------------------------------------------------------*/
package org.fortiss.af3.mode.simulator;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.fortiss.af3.component.model.OutputPort;
import org.fortiss.af3.component.model.behavior.common.DataStateVariable;
import org.fortiss.af3.component.model.behavior.common.Guard;
import org.fortiss.af3.component.simulator.ExecutableAtomicComponentBase;
import org.fortiss.af3.component.simulator.ExecutableComponent;
import org.fortiss.af3.component.simulator.ExecutionException;
import org.fortiss.af3.expression.language.evaluation.BoolValue;
import org.fortiss.af3.expression.language.evaluation.NoVal;
import org.fortiss.af3.expression.model.terms.Var;
import org.fortiss.af3.mode.model.Mode;
import org.fortiss.af3.mode.model.ModeAutomaton;
import org.fortiss.af3.mode.model.SwitchSegment;
import org.fortiss.af3.mode.model.SwitchSegmentConnector;
import org.fortiss.af3.mode.model.SwitchSegmentExitConnector;
import org.fortiss.af3.mode.model.SwitchSegmentLocalConnector;
import org.fortiss.af3.mode.model.SwitchSegmentSpecification;
import org.fortiss.af3.project.model.typesystem.ITerm;
import org.fortiss.af3.project.services.ITypeSystemService;
import org.fortiss.af3.project.typesystem.IEvaluationContext;
import org.fortiss.af3.project.typesystem.evaluation.Term;
import org.fortiss.tooling.kernel.model.INamedElement;
/**
* {@link ExecutableComponent} for {@link ModeAutomaton}.
*
* @author li
* @author $Author$
* @version $Rev$
* @ConQAT.Rating RED Hash:
*/
public class ExecutableModeAutomatonSpecification extends
ExecutableAtomicComponentBase<ModeAutomaton> {
/** Stores the simulated mode automaton. */
private ModeAutomaton modeAutomaton;
/** Stores the variable to data state variable mapping. */
private final Map<Var, DataStateVariable> dataStateVariables = new HashMap<Var, DataStateVariable>();
/** Stores the scratch paper used for data state variable assignment. */
private final IEvaluationContext scratchPaper;
/** Constructor. */
public ExecutableModeAutomatonSpecification(ModeAutomaton modeAutomaton) {
super(modeAutomaton.getContainerComponent(), modeAutomaton);
this.modeAutomaton = modeAutomaton;
this.scratchPaper = ITypeSystemService.INSTANCE
.createEvaluationContext(modelElement);
}
/** Returns the current mode, which is active in the simulation. */
public Mode getCurrentMode() {
return (Mode) getInternalValue(modeAutomaton);
}
/** Stores the current mode. */
public void setCurrentMode(Mode mode) {
setInternalValue(modeAutomaton, mode);
}
/** {@inheritDoc} */
@Override
public void initialize() {
super.initialize();
setCurrentMode(modeAutomaton.getInitialMode());
for (DataStateVariable dsv : modeAutomaton.getDataStateVariablesList()) {
Term<? extends ITerm> initialValue = typeSystemHandler
.getTermEvaluator().evaluate(dsv.getInitialValue(),
evaluationContext);
setInternalValue(dsv, initialValue);
dataStateVariables.put(dsv.getVariable(), dsv);
}
}
/** {@inheritDoc} */
@SuppressWarnings("unchecked")
@Override
protected void doAtomicStep() {
synchronized (this) { // make it thread safe
for (DataStateVariable dsv : modeAutomaton
.getDataStateVariablesList()) {
evaluationContext.setValue(dsv.getVariable(),
(Term<? extends ITerm>) getInternalValue(dsv));
}
scratchPaper.clear();
// simulate one step.
Mode newMode = simulateInternal(getCurrentMode());
// store current state
setCurrentMode(newMode);
// store evaluation result into outputs
for (OutputPort port : outputPortVariables.keySet()) {
Term<? extends ITerm> value = evaluationContext
.getValue(outputPortVariables.get(port));
if (value == null) {
value = NoVal.NOVAL;
}
setInternalOutputValue(port, value);
}
// store evaluation result from scratch paper in data state
// variable.
for (DataStateVariable dsv : modeAutomaton
.getDataStateVariablesList()) {
Term<? extends ITerm> value = scratchPaper.getValue(dsv
.getVariable());
if (value != null) {
setInternalValue(dsv, value);
}
}
}
}
/**
* Simulates one step in mode automaton using given current mode. Returns
* the new mode that was reached.
*/
protected Mode simulateInternal(Mode startMode) {
final List<List<SwitchSegmentSpecification>> readyToFire = computeReadySwitchs(startMode);
// none switchs are ready.
if (readyToFire.size() == 0) {
return startMode;
}
final List<SwitchSegmentSpecification> fire;
if (readyToFire.size() == 1) {
// execute this transition
fire = readyToFire.get(0);
} else {
// select a choice for non-deterministic case.
final int i = chooseNondeterministically(readyToFire.size());
fire = readyToFire.get(i);
}
return fireSwitch(startMode, fire);
}
/**
* Performs non-deterministic choice. The default implementation uses random
* selection.
*/
protected int chooseNondeterministically(int numChoices) {
return (int) (Math.random() * numChoices);
}
/**
* Computes the collection of all fireable switches (e.g. list of segments).
*/
protected List<List<SwitchSegmentSpecification>> computeReadySwitchs(
Mode start) {
final List<List<SwitchSegmentSpecification>> retColl = new LinkedList<List<SwitchSegmentSpecification>>();
final ArrayList<SwitchSegmentSpecification> singlePath = new ArrayList<SwitchSegmentSpecification>();
System.out.println(start.getName());
for (SwitchSegmentExitConnector exit : start
.getSwitchSegmentExitConnectors()) {
if (exit.getOutgoingLength() > 0) {
findSegmentPath(exit, retColl, singlePath);
singlePath.clear();
}
}
return retColl;
}
/**
* Find all paths starting from the given SwitchSegmentConnector. TODO: must
* check again later
*/
protected void findSegmentPath(SwitchSegmentConnector tp,
List<List<SwitchSegmentSpecification>> pathList,
List<SwitchSegmentSpecification> currentPath) {
// dead-end check
if (tp instanceof SwitchSegmentLocalConnector
&& tp.getOutgoingLength() == 0) {
throw new ExecutionException("Found dead-end local connector "
+ tp.getName() + " in mode " + tp.getMode().getName());
}
// cycle-check
for (SwitchSegmentSpecification sseg : currentPath) {
if (sseg.getSwitchSegment().getSource() == tp) {
throw new ExecutionException("Found cycle connector point "
+ tp.getName() + " in modee " + tp.getMode().getName());
}
}
// non-atomic state check
if (tp.getOutgoingLength() == 0
&& tp.getMode().getSubModes().size() > 0) {
throw new ExecutionException("Found terminating connector point "
+ tp.getName() + " in mode "
+ ((INamedElement) tp.eContainer()).getName()
+ ", but target mode " + tp.getMode().getName()
+ " is not atomic.");
}
// no switches for this connector.
if (tp.getOutgoingLength() == 0) {
pathList.add(currentPath);
return;
}
for (final SwitchSegment ts : tp.getOutgoingSwitchSegment()) {
final SwitchSegmentSpecification spec = canFireSwitchSegment(ts);
if (spec != null) {
final List<SwitchSegmentSpecification> nextPath = new ArrayList<SwitchSegmentSpecification>(
currentPath.size() + 1);
nextPath.addAll(currentPath);
nextPath.add(spec);
findSegmentPath(ts.getTargetConnector(), pathList, nextPath);
}
}
}
/** Checks if the given switch segment can be fired. */
protected SwitchSegmentSpecification canFireSwitchSegment(SwitchSegment ts) {
SwitchSegmentSpecification spec = ts.getSwitchSegmentSpecification();
// evaluate the guard
Guard guard = spec.getGuard();
if (guard == null)
return spec;
Term<? extends ITerm> result = typeSystemHandler.getTermEvaluator()
.evaluate(guard.getExpression(), evaluationContext);
if (result instanceof BoolValue) {
if (result.equals(BoolValue.FALSE)) {
return null;
}
} else {
// never thrown for consistent, type-check models
throw new ExecutionException(guard.getExpression().toString()
+ " evaluated to " + result.toString()
+ "; expected boolean value!");
}
return spec;
}
/** Fires the given switch segment. */
protected void fireTransitionSegment(SwitchSegmentSpecification spec) {
// do nothing, because mode has no actions.
}
/** Fires the given switch. */
protected Mode fireSwitch(Mode currentMode,
List<SwitchSegmentSpecification> switchSpecifications) {
// clearOutputs(); // first reset all outputs
// idle switch does not changed mode, all outputs have been cleared
if (switchSpecifications == null) {
return currentMode;
}
// fire each segment of the transition
for (final SwitchSegmentSpecification spec : switchSpecifications) {
fireTransitionSegment(spec);
}
// return destination point parent state of the last segment
return (switchSpecifications.get(switchSpecifications.size() - 1)
.getSwitchSegment().getTargetConnector()).getMode();
}
}
/*--------------------------------------------------------------------------+
$Id$
| |
| Copyright 2011 ForTISS GmbH |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
+--------------------------------------------------------------------------*/
package org.fortiss.af3.mode.simulator;
import org.fortiss.af3.component.model.Component;
import org.fortiss.af3.component.simulator.transform.ExecutableComponentTransformationBase;
import org.fortiss.af3.mode.model.ModeAutomaton;
import org.fortiss.tooling.kernel.extension.data.ITransformationContext;
/**
* Transformation for a {@link Component} with a {@link ModeAutomaton}
* Specification into an {@link ExecutableModeAutomatonSpecification};
*
* @author li
* @author $Author$
* @version $Rev$
* @ConQAT.Rating RED Hash: