protected final ConnectionStyle style;
+ private static class Cache {
+ Path2D path = new Path2D.Double();
+ THashSet<RoutePoint> branchPoints = new THashSet<>();
+ }
+
// Caches to avoid creating new objects all the time during rendering
- protected transient Path2D path;
- protected transient THashSet<RoutePoint> branchPoints;
+ protected static ThreadLocal<Cache> caches = ThreadLocal.withInitial(() -> new Cache());
public StyledRouteGraphRenderer(ConnectionStyle style) {
if (style == null)
@Override
public void render(Graphics2D g, RouteGraph rg) {
- if (path == null)
- path = new Path2D.Double();
+ Cache cache = caches.get();
+ Path2D path = cache.path;
+ THashSet<RoutePoint> branchPoints = cache.branchPoints;
+
path.reset();
rg.getPath2D(path);
style.drawPath(g, path, false);
- if (branchPoints == null)
- branchPoints = new THashSet<RoutePoint>();
branchPoints.clear();
for(RouteLine line : rg.getLines()) {
renderLine(g, line, false);
this.name = name;
}
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((types == null) ? 0 : types.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ TypeGroup other = (TypeGroup) obj;
+ if (types == null) {
+ if (other.types != null)
+ return false;
+ } else if (!types.equals(other.types))
+ return false;
+ return true;
+ }
+
/**
* Initialize TypeGroup from a DIAGRAM.Group instance.
*
*/
public class ResourceSCLTextGridStyle extends TextGridStyle {
- final Resource style;
final Font font;
public ResourceSCLTextGridStyle(ReadGraph graph, Resource style) throws DatabaseException {
- this.style = style;
+ super(style);
G2DResource G2D = G2DResource.getInstance(graph);
Resource fontR = graph.getPossibleObject(style, G2D.HasFont);
if(fontR != null) {
@Override
protected Object getIdentity(Resource entry) {
- return new Pair<Resource, Resource>(style, entry);
+ return new Pair<Resource, Resource>(getResource(), entry);
}
@Override
public MonitorTextGridResult calculateStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource element, Variable configuration) throws DatabaseException {
DiagramResource DIA = DiagramResource.getInstance(graph);
- Variable styleVariable = Variables.getVariable(graph, style);
+ Variable styleVariable = Variables.getVariable(graph, getResource());
Function1<Resource,Tuple3> function = styleVariable.getPossiblePropertyValue(graph, DIA.ResourceSCLTextGridStyle_texts);
Tuple3 result = Simantics.applySCLRead(graph, function, element);
@Override
public String getNodeName() {
- return "" + style.getResourceId();
+ return "" + getResource().getResourceId();
}
}
*/
public class SCLTextGridStyle extends TextGridStyle {
- final Resource style;
final Font font;
public SCLTextGridStyle(ReadGraph graph, Resource style) throws DatabaseException {
- this.style = style;
+ super(style);
G2DResource G2D = G2DResource.getInstance(graph);
Resource fontR = graph.getPossibleObject(style, G2D.HasFont);
if(fontR != null) {
@Override
protected Object getIdentity(Resource entry) {
- return new Pair<Resource, Resource>(style, entry);
+ return new Pair<Resource, Resource>(getResource(), entry);
}
@Override
if (moduleVariable == null)
return null;
- Variable styleVariable = Variables.getVariable(graph, style);
+ Variable styleVariable = Variables.getVariable(graph, getResource());
Function1<Variable,Tuple3> function = styleVariable.getPossiblePropertyValue(graph, DIA.SCLTextGridStyle_texts);
Tuple3 result = Simantics.applySCLRead(graph, function, moduleVariable);
@Override
public String getNodeName() {
- return "" + style.getResourceId();
+ return "" + getResource().getResourceId();
}
}
*******************************************************************************/
package org.simantics.diagram.profile;
-import java.util.ArrayList;
import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
import org.simantics.databoard.Bindings;
import org.simantics.db.ReadGraph;
import org.simantics.scenegraph.profile.common.ObserverGroupListener;
import org.simantics.scenegraph.profile.common.ObserverGroupValueListener;
import org.simantics.scenegraph.profile.impl.DebugPolicy;
-import org.simantics.scl.runtime.tuple.Tuple;
-import org.simantics.scl.runtime.tuple.Tuple2;
+import org.simantics.scl.runtime.tuple.Tuple3;
import org.simantics.utils.datastructures.Pair;
/**
*/
public abstract class StyleBase<Result> implements Style {
- protected final Map<Tuple, Result> values = new ConcurrentHashMap<Tuple, Result>();
-
-// private Map<Resource,ObserverGroupListener> listeners = new ConcurrentHashMap<Resource, ObserverGroupListener>();
+ private Object identity;
+
+ public StyleBase(Object identity) {
+ this.identity = identity;
+ }
- private Map<Pair<Resource, Group>, ObserverGroupListener> listeners = new HashMap<Pair<Resource, Group>, ObserverGroupListener>();
+ public StyleBase() {
+ this.identity = getClass();
+ }
+ protected <T> T getIdentity() {
+ return (T)identity;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((identity == null) ? 0 : identity.hashCode());
+ return result;
+ }
- private final List<Resource> removals = new ArrayList<Resource>();
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ StyleBase other = (StyleBase) obj;
+ if (identity == null) {
+ if (other.identity != null)
+ return false;
+ } else if (!identity.equals(other.identity))
+ return false;
+ return true;
+ }
+
+ protected Resource getResource() {
+ return getIdentity();
+ }
/**
* For caching this simple base request that is done in every
*/
public void styleResultChanged(Observer observer, Resource runtimeDiagram, Resource object, Result result) {
if (result == null)
- values.remove(new Tuple2(runtimeDiagram, object));
+ StyleBaseData.getInstance().removeValue(new Tuple3(this, runtimeDiagram, object));
else
- values.put(new Tuple2(runtimeDiagram, object), result);
+ StyleBaseData.getInstance().putValue(new Tuple3(this, runtimeDiagram, object), result);
observer.update();
}
if (DebugPolicy.DEBUG_PROFILE_STYLE_GROUP_TRACKING)
System.out.println(style + ": removed from group " + group + ": " + item);
- synchronized (style.removals) {
- style.removals.add(item);
- }
+ StyleBaseData.getInstance().removeItem(style, item);
// TODO: do something here to dispose of ObserverGroupValueListeners?
super.remove(item);
+
}
}
listener = new GroupListener<Result>(backend.getSession(), runtimeDiagram, entry, this, group, observer);
- listeners.put(Pair.make(runtimeDiagram, group), listener);
+ StyleBaseData.getInstance().putListener(new Tuple3(this, runtimeDiagram, group), listener);
group.trackItems(backend, runtimeDiagram, listener);
listener.removeEntry(entry);
if (!listener.hasEntries()) {
listener.dispose();
- listeners.remove(Pair.make(runtimeDiagram, group));
+ StyleBaseData.getInstance().removeListener(new Tuple3(this, runtimeDiagram, group));
}
// This was too eager when multiple groups were tracked!
if (DebugPolicy.DEBUG_PROFILE_STYLE_APPLICATION)
System.out.println(StyleBase.this + ": applying style for items: " + listener.getItems());
- if (!removals.isEmpty()) {
- Resource[] removed;
- synchronized (removals) {
- removed = removals.toArray(Resource.NONE);
- removals.clear();
- }
- for (Resource item : removed) {
- cleanupStyleForItem(evaluationContext, map, item);
- }
- }
+
+ StyleBaseData data = StyleBaseData.getInstance();
+
+ data.applyRemovals(evaluationContext, this);
for (Object item : listener.getItems()) {
- Result value = values.get(new Tuple2(evaluationContext.getResource(), item));
+ Result value = data.getValue(new Tuple3(this, evaluationContext.getResource(), item));
applyStyleForItem(evaluationContext, map, item, value);
}
}
private ObserverGroupListener getListener(Resource runtime, Group group) {
- return listeners.get(Pair.make(runtime, group));
+ return StyleBaseData.getInstance().getListener(new Tuple3(this, runtime, group));
}
}
--- /dev/null
+package org.simantics.diagram.profile;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.simantics.db.Resource;
+import org.simantics.scenegraph.profile.DataNodeMap;
+import org.simantics.scenegraph.profile.EvaluationContext;
+import org.simantics.scenegraph.profile.Style;
+import org.simantics.scenegraph.profile.common.ObserverGroupListener;
+import org.simantics.scl.runtime.tuple.Tuple;
+import org.simantics.scl.runtime.tuple.Tuple3;
+
+public class StyleBaseData {
+
+ protected final Map<Tuple, Object> values = new ConcurrentHashMap<>();
+
+ private Map<Tuple3, ObserverGroupListener> listeners = new HashMap<>();
+
+ private final Map<Style, List<Resource>> removals = new HashMap<>();
+
+ private StyleBaseData() {
+
+ }
+
+ private static StyleBaseData INSTANCE;
+
+ public static StyleBaseData getInstance() {
+ if(INSTANCE == null) {
+ INSTANCE = new StyleBaseData();
+ }
+ return INSTANCE;
+ }
+
+ public void removeValue(Tuple t) {
+ values.remove(t);
+ }
+
+ public void putValue(Tuple t, Object o) {
+ values.put(t, o);
+ }
+
+ public <T> T getValue(Tuple t) {
+ return (T)values.get(t);
+ }
+
+ public synchronized void removeItem(Style s, Resource r) {
+ List<Resource> l = removals.get(s);
+ if(l == null) {
+ l = new ArrayList<>();
+ removals.put(s, l);
+ }
+ l.add(r);
+ }
+
+ public void putListener(Tuple3 key, ObserverGroupListener listener) {
+ listeners.put(key, listener);
+ }
+
+ public void removeListener(Tuple3 key) {
+ listeners.remove(key);
+ }
+
+ public ObserverGroupListener getListener(Tuple3 key) {
+ return listeners.get(key);
+ }
+
+ public synchronized void applyRemovals(EvaluationContext evaluationContext, StyleBase s) {
+
+ List<Resource> rs = removals.remove(s);
+ if(rs == null) return;
+
+ DataNodeMap map = evaluationContext.getConstant(ProfileKeys.NODE_MAP);
+
+ for (Resource item : rs) {
+ s.cleanupStyleForItem(evaluationContext, map, item);
+ }
+
+ }
+
+}
private final Color BACKGROUND_COLOR = new Color(255, 255, 255, 192);
private static final Rectangle2D EMPTY_BOUNDS = new Rectangle2D.Double(0, 0, 0, 0);
- // NOTE: this is a hack
- String id;
+// // NOTE: this is a hack
+// String id;
protected double xOffset;
protected double yOffset;
- public TextGridStyle() {
- this(0.0, 2.1);
+ public TextGridStyle(Resource r) {
+ this(r, 0.0, 2.1);
}
- public TextGridStyle(double xOffset, double yOffset) {
+ public TextGridStyle(Resource r, double xOffset, double yOffset) {
+ super(r);
this.xOffset = xOffset;
this.yOffset = yOffset;
}
// This assumes that this TextGridStyle instance will be devoted to
// this row ID until the end of its life.
- String id = result.getRowId();
- //System.out.println(this + " ID: " + id);
- if (!id.equals(this.id)) {
- //System.out.println(this + " SET ID: " + this.id + " -> " + id);
- this.id = id;
- }
+// String id = result.getRowId();
+// System.out.println(this + " ID: " + id);
+// if (!id.equals(this.id)) {
+// System.out.println(this + " SET ID: " + this.id + " -> " + id);
+// this.id = id;
+// }
+
Integer newRow = observer.getTemporaryProperty(_node, "location");
if (newRow == null)
newRow = 1;
- // Remove from existing row to add to another row if necessary.
- Integer row = observer.getProperty(_node, id);
+ // Remove from existing row to add to another row if necessary.
+ Integer row = getCurrentRowNumber(observer, _node);
if (row != null && row != newRow) {
String actualId = node.getRowId(row);
+ String id = observer.getProperty(_node, rowIdKey());
if (id.equals(actualId)) {
node.removeRow(row);
}
}
row = newRow;
- node.setRowId(row, id);
- observer.setProperty(_node, id, row);
+ node.setRowId(row, result.getRowId());
+
+ setCurrentRowNumber(observer, _node, result.getRowId(), row);
+
observer.setTemporaryProperty(_node, "location", row + 1);
node.setText(2, row, value2);
@Override
protected void cleanupStyleForNode(EvaluationContext observer, INode _node) {
- Integer row = observer.getProperty(_node, id);
+ Integer row = getCurrentRowNumber(observer, _node);
//System.out.println(this + " cleanup(" + id + ", " + row + ")");
//System.out.println(element);
if (row == null)
return;
- observer.setProperty(_node, id, null);
+ clearCurrentRowNumber(observer, _node);
TextGridNode node = ProfileVariables.browseChild(_node, "TextGridStyle");
if (node != null)
node.removeRow(row);
}
+
+ private Integer getCurrentRowNumber(EvaluationContext observer, INode _node) {
+ String rowId = observer.getProperty(_node, rowIdKey());
+ return observer.getProperty(_node, rowId);
+ }
+
+ private void setCurrentRowNumber(EvaluationContext observer, INode _node, String rowId, int row) {
+ // Mapping style identity -> rowId (resourceId)
+ observer.setProperty(_node, rowIdKey(), rowId);
+ // Mapping rowId (resourceId) -> row number
+ observer.setProperty(_node, rowId, row);
+ }
+
+ private void clearCurrentRowNumber(EvaluationContext observer, INode _node) {
+ String rowId = observer.getProperty(_node, rowIdKey());
+ if(rowId != null) {
+ observer.setProperty(_node, rowIdKey(), null);
+ Integer row = observer.getProperty(_node, rowId);
+ if(row != null) {
+ observer.setProperty(_node, rowId, null);
+ }
+ }
+ }
protected void postProcessNode(TextGridNode node, int row) {
}
+
+ private String rowIdKey() {
+ return "style" + getIdentity().toString();
+ }
}
/*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 Association for Decentralized Information Management
* in Industry THTH ry.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
*
* Contributors:
* VTT Technical Research Centre of Finland - initial API and implementation
+ * Semantum Oy - gitlab #66 - parallel/spatial optimization
*******************************************************************************/
package org.simantics.g2d.diagram.handler.impl;
/**
* @author Toni Kalajainen
+ * @author Jani Simomaa
+ * @author Tuukka Lehtonen
*/
public class PickContextImpl implements PickContext {
private static final ThreadLocal<Rectangle2D> perThreadElementBounds = ThreadLocal.withInitial(() -> new Rectangle2D.Double());
+ private boolean useRTree;
+
+ public PickContextImpl() {
+ this(false);
+ }
+
+ public PickContextImpl(boolean useRTree) {
+ this.useRTree = useRTree;
+ }
+
@Override
public void pick(
IDiagram diagram,
return shape.getBounds2D();
}
- private static List<IElement> pickElements(IDiagram diagram, PickRequest request) {
+ private List<IElement> pickElements(IDiagram diagram, PickRequest request) {
ILayers layers = diagram.getHint(DiagramHints.KEY_LAYERS);
// Get the scene graph nodes that intersect the pick-requests pick shape
- INode spatialRoot = request.pickContext != null
+ INode spatialRoot = useRTree && request.pickContext != null
? request.pickContext.getSceneGraph().lookupNode(SceneGraphConstants.SPATIAL_ROOT_NODE_ID)
: null;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.simantics.modeling.scl.GraphModuleSourceRepository;
-import org.simantics.modeling.scl.OntologyModuleSourceRepository;
+import org.simantics.modeling.scl.ontologymodule.OntologyModuleSourceRepository;
import org.simantics.scl.compiler.source.repository.ModuleSourceRepository;
public class Activator implements BundleActivator {
import org.simantics.layer0.Layer0;
import org.simantics.modeling.ModelingUtils;
import org.simantics.modeling.internal.Activator;
+import org.simantics.modeling.scl.ontologymodule.OntologyModuleSourceRepository;
import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidatorFactory;
import org.simantics.scl.compiler.module.repository.UpdateListener;
import org.simantics.scl.compiler.module.repository.UpdateListener.Observable;
-package org.simantics.modeling.scl;
+package org.simantics.modeling.scl.ontologymodule;
import static org.simantics.scl.compiler.elaboration.expressions.Expressions.externalConstant;
import gnu.trove.map.hash.THashMap;
-package org.simantics.modeling.scl;
+package org.simantics.modeling.scl.ontologymodule;
import org.simantics.db.Resource;
import org.simantics.scl.compiler.common.names.Name;
-package org.simantics.modeling.scl;
+package org.simantics.modeling.scl.ontologymodule;
import org.simantics.db.Resource;
import org.simantics.scl.compiler.common.names.Name;
--- /dev/null
+package org.simantics.modeling.scl.ontologymodule;
+
+import org.simantics.Simantics;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.RequestProcessor;
+import org.simantics.scl.runtime.SCLContext;
+
+public class GraphRequestDuringSCLCompilation {
+
+ public static RequestProcessor getRequestProcessor() {
+ ReadGraph graph = (ReadGraph)SCLContext.getCurrent().get("graph");
+ if(graph != null)
+ return graph;
+ else
+ return Simantics.getSession();
+ }
+
+}
-package org.simantics.modeling.scl;
+package org.simantics.modeling.scl.ontologymodule;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import org.simantics.db.request.Read;
import org.simantics.layer0.Layer0;
import org.simantics.scl.compiler.common.names.Name;
+import org.simantics.scl.compiler.constants.StringConstant;
+import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
+import org.simantics.scl.compiler.elaboration.expressions.EApply;
import org.simantics.scl.compiler.elaboration.expressions.EExternalConstant;
+import org.simantics.scl.compiler.elaboration.expressions.ELiteral;
+import org.simantics.scl.compiler.elaboration.expressions.ESimpleLambda;
+import org.simantics.scl.compiler.elaboration.expressions.EVariable;
+import org.simantics.scl.compiler.elaboration.expressions.Expression;
+import org.simantics.scl.compiler.elaboration.expressions.Variable;
+import org.simantics.scl.compiler.elaboration.macros.MacroRule;
import org.simantics.scl.compiler.elaboration.modules.SCLValue;
import org.simantics.scl.compiler.elaboration.relations.SCLEntityType;
import org.simantics.scl.compiler.elaboration.relations.SCLRelation;
import org.simantics.scl.compiler.environment.filter.NamespaceFilter;
+import org.simantics.scl.compiler.errors.Locations;
import org.simantics.scl.compiler.module.ImportDeclaration;
import org.simantics.scl.compiler.module.LazyModule;
import org.simantics.scl.compiler.types.TCon;
+import org.simantics.scl.compiler.types.TVar;
import org.simantics.scl.compiler.types.Type;
import org.simantics.scl.compiler.types.Types;
import org.simantics.scl.compiler.types.exceptions.SCLTypeParseException;
+import org.simantics.scl.compiler.types.kinds.Kinds;
import org.simantics.scl.runtime.SCLContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import gnu.trove.map.hash.THashMap;
import gnu.trove.procedure.TObjectProcedure;
public class OntologyModule extends LazyModule {
-
+ private static final Logger LOGGER = LoggerFactory.getLogger(OntologyModule.class);
+
private static final String DB_MODULE = "Simantics/DB";
+ private static final String VARIABLE_MODULE = "Simantics/Variable";
private static final Collection<ImportDeclaration> DEPENDENCIES = Arrays.asList(
- new ImportDeclaration(DB_MODULE, null)
+ new ImportDeclaration(DB_MODULE, null),
+ new ImportDeclaration(VARIABLE_MODULE, null)
);
private static final TCon RESOURCE = Types.con(DB_MODULE, "Resource");
+ private static final TCon BROWSABLE = Types.con(DB_MODULE, "Browsable");
+ private static final TCon VARIABLE = Types.con(VARIABLE_MODULE, "Variable");
Resource ontology;
String defaultLocalName;
return Collections.emptyList();
}
- private Resource getResource(String name) {
+ private static interface ResourceSearchResult {}
+ private static class JustResource implements ResourceSearchResult {
+ public final Resource resource;
+ public JustResource(Resource resource) {
+ this.resource = resource;
+ }
+ }
+ private static class ResourceAndSuffix implements ResourceSearchResult {
+ public final Resource resource;
+ public final String suffix;
+ public ResourceAndSuffix(Resource resource, String suffix) {
+ this.resource = resource;
+ this.suffix = suffix;
+ }
+ }
+
+ private ResourceSearchResult getResourceOrSuffixedResource(String name) {
Map<String,Resource> localMap = childMaps.get(ontology);
if(localMap == null)
return null;
+ Resource parent = ontology;
while(true) {
int p = name.indexOf('.');
if(p < 0)
break;
String localName = name.substring(0, p);
- Resource newParent = localMap.get(localName);
- if(newParent == null)
+ parent = localMap.get(localName);
+ if(parent == null)
return null;
name = name.substring(p+1);
// Get new local map
- localMap = getLocalMap(newParent);
+ localMap = getLocalMap(parent);
if(localMap == null)
return null;
}
- return localMap.get(name);
+ Resource child = localMap.get(name);
+ if(child != null)
+ return new JustResource(child);
+ else
+ return new ResourceAndSuffix(parent, name);
+ }
+
+ private Resource getResource(String name) {
+ ResourceSearchResult searchResult = getResourceOrSuffixedResource(name);
+ if(searchResult instanceof JustResource)
+ return ((JustResource)searchResult).resource;
+ else
+ return null;
}
private Map<String, Resource> getLocalMap(Resource parent) {
}
}
+ @FunctionalInterface
+ private static interface ResourceFunctionGenerator {
+ SCLValue createValue(Name name, Resource resource);
+ }
+
+ private static class RelatedValueMacroRule implements MacroRule {
+ private final Resource relation;
+ private final SCLRelationInfo relationInfo;
+ private final boolean optionalValue;
+
+ public RelatedValueMacroRule(Resource relation, SCLRelationInfo relationInfo, boolean optionalValue) {
+ this.relation = relation;
+ this.relationInfo = relationInfo;
+ this.optionalValue = optionalValue;
+ }
+
+ private Expression applyWithSubject(SimplificationContext context, Type subjectType, Expression evidence, Expression subject) {
+ if(Types.equals(subjectType, RESOURCE))
+ return new EApply(
+ Locations.NO_LOCATION,
+ Types.READ_GRAPH,
+ context.getConstant(Name.create(DB_MODULE, optionalValue ? "possibleRelatedValue2" : "relatedValue2"), relationInfo.rangeType),
+ subject,
+ new EExternalConstant(relation, RESOURCE));
+ else if(Types.equals(subjectType, VARIABLE))
+ return new EApply(
+ Locations.NO_LOCATION,
+ Types.READ_GRAPH,
+ context.getConstant(Name.create(DB_MODULE, optionalValue ? "untypedPossiblePropertyValue" : "untypedPropertyValue"), relationInfo.rangeType),
+ subject,
+ new ELiteral(new StringConstant(relationInfo.name)));
+ else
+ return new EApply(
+ Locations.NO_LOCATION,
+ Types.READ_GRAPH,
+ context.getConstant(Name.create(DB_MODULE, optionalValue ? "genericPossibleRelatedValue" : "genericRelatedValue"), subjectType, relationInfo.rangeType),
+ evidence,
+ subject,
+ new EExternalConstant(relation, RESOURCE));
+ }
+
+ @Override
+ public Expression apply(SimplificationContext context, Type[] typeParameters, EApply apply) {
+ Type subjectType = typeParameters[0];
+ if(apply.parameters.length == 1) {
+ Variable subject = new Variable("subject", subjectType);
+ return new ESimpleLambda(subject, applyWithSubject(context, subjectType, apply.parameters[0], new EVariable(subject)));
+ }
+ else if(apply.parameters.length >= 2) {
+ Expression valueReplacement = applyWithSubject(context, subjectType, apply.parameters[0], apply.parameters[1]);
+ if(apply.parameters.length == 2)
+ return valueReplacement;
+ else {
+ apply.set(valueReplacement, Arrays.copyOfRange(apply.parameters, 2, apply.parameters.length));
+ return apply;
+ }
+ }
+ else {
+ LOGGER.error("Application of relation following functions should have at least one parameter (the evidence of Browsable).");
+ return null;
+ }
+ }
+ }
+
+ private final static HashMap<String, ResourceFunctionGenerator> VALUE_GENERATOR_MAP = new HashMap<>();
+ static {
+ TVar A = Types.var(Kinds.STAR);
+ VALUE_GENERATOR_MAP.put("value", (name, resource) -> {
+ SCLRelationInfo relationInfo = SCLRelationInfoRequest.getRelationInfo(resource);
+ if(relationInfo == null)
+ return null;
+
+ SCLValue value = new SCLValue(name);
+ value.setType(Types.forAll(A, Types.function(Types.pred(BROWSABLE, A), Types.functionE(A, Types.READ_GRAPH, relationInfo.rangeType))));
+ value.setMacroRule(new RelatedValueMacroRule(resource, relationInfo, false));
+ return value;
+ });
+ VALUE_GENERATOR_MAP.put("possibleValue", (name, resource) -> {
+ SCLRelationInfo relationInfo = SCLRelationInfoRequest.getRelationInfo(resource);
+ if(relationInfo == null)
+ return null;
+
+ SCLValue value = new SCLValue(name);
+ value.setType(Types.forAll(A, Types.function(Types.pred(BROWSABLE, A), Types.functionE(A, Types.READ_GRAPH, Types.apply(Types.MAYBE, relationInfo.rangeType)))));
+ value.setMacroRule(new RelatedValueMacroRule(resource, relationInfo, true));
+ return value;
+ });
+ }
+
@Override
protected SCLValue createValue(String name) {
- Resource resource = getResource(name);
- if(resource == null)
- return null;
- SCLValue value = new SCLValue(Name.create(getName(), name));
- value.setType(RESOURCE);
- value.setExpression(new EExternalConstant(resource, RESOURCE));
- value.setInlineInSimplification(true);
- return value;
+ ResourceSearchResult searchResult = getResourceOrSuffixedResource(name);
+ if(searchResult instanceof JustResource) {
+ Resource resource = ((JustResource)searchResult).resource;
+ SCLValue value = new SCLValue(Name.create(getName(), name));
+ value.setType(RESOURCE);
+ value.setExpression(new EExternalConstant(resource, RESOURCE));
+ value.setInlineInSimplification(true);
+ return value;
+ }
+ else if(searchResult instanceof ResourceAndSuffix){
+ ResourceAndSuffix resourceAndSuffix = (ResourceAndSuffix)searchResult;
+ ResourceFunctionGenerator generator = VALUE_GENERATOR_MAP.get(resourceAndSuffix.suffix);
+ if(generator == null)
+ return null;
+ else
+ return generator.createValue(Name.create(getName(), name), resourceAndSuffix.resource);
+ }
+ else
+ return null;
}
@Override
-package org.simantics.modeling.scl;
+package org.simantics.modeling.scl.ontologymodule;
import java.util.Collection;
--- /dev/null
+package org.simantics.modeling.scl.ontologymodule;
+
+import org.simantics.scl.compiler.types.Type;
+
+public class SCLRelationInfo {
+ public final Type rangeType;
+ public final String name;
+
+ public SCLRelationInfo(Type rangeType, String name) {
+ this.rangeType = rangeType;
+ this.name = name;
+ }
+}
--- /dev/null
+package org.simantics.modeling.scl.ontologymodule;
+
+import java.util.Collection;
+
+import org.simantics.databoard.Bindings;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.common.procedure.adapter.TransientCacheListener;
+import org.simantics.db.common.request.UnaryRead;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.layer0.Layer0;
+import org.simantics.scl.compiler.types.Type;
+import org.simantics.scl.compiler.types.Types;
+import org.simantics.scl.compiler.types.exceptions.SCLTypeParseException;
+import org.simantics.scl.db.SCLCompilationRequestProcessor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SCLRelationInfoRequest extends UnaryRead<Resource,SCLRelationInfo> {
+ private static final Logger LOGGER = LoggerFactory.getLogger(SCLRelationInfoRequest.class);
+
+ private SCLRelationInfoRequest(Resource resource) {
+ super(resource);
+ }
+
+ @Override
+ public SCLRelationInfo perform(ReadGraph graph) throws DatabaseException {
+ Layer0 L0 = Layer0.getInstance(graph);
+ if(!graph.isSubrelationOf(parameter, L0.HasProperty))
+ return null;
+
+ String name = graph.getPossibleRelatedValue(parameter, L0.HasName);
+ if(name == null)
+ return null;
+
+ String valueType = graph.getPossibleRelatedValue(parameter, L0.RequiresValueType);
+ if(valueType == null) {
+ Collection<Resource> rangeTypes = graph.getObjects(parameter, L0.HasRange);
+ if(rangeTypes.size() != 1) {
+ LOGGER.warn("Couldn't find SCLtype for {} because it has multiple range types.", graph.getURI(parameter));
+ return null;
+ }
+
+ Resource range = rangeTypes.iterator().next();
+ Collection<Resource> assertedValueTypes = graph.getAssertedObjects(range, L0.HasValueType);
+ if(assertedValueTypes.size() != 1) {
+ LOGGER.warn("Couldn't find SCL type for {} because its range {} has multiple asserted value types.", graph.getURI(parameter), graph.getURI(range));
+ return null;
+ }
+
+ Resource assertedValueType = assertedValueTypes.iterator().next();
+ valueType = graph.getPossibleValue(assertedValueType, Bindings.STRING);
+ if(valueType == null) {
+ LOGGER.warn("Couldn't find SCL type for {} because value type assertion of {} is missing a value.", graph.getURI(parameter), graph.getURI(range));
+ return null;
+ }
+ }
+
+ Type type;
+ try {
+ type = Types.parseType(valueType);
+ } catch (SCLTypeParseException e) {
+ LOGGER.warn("Couldn't parse the value type of relation {}. Definition was '{}'.", graph.getURI(parameter), valueType);
+ return null;
+ }
+
+ return new SCLRelationInfo(type, name);
+ }
+
+ public static SCLRelationInfo getRelationInfo(Resource resource) {
+ try {
+ return SCLCompilationRequestProcessor.getRequestProcessor().syncRequest(new SCLRelationInfoRequest(resource), TransientCacheListener.instance());
+ } catch(DatabaseException e) {
+ LOGGER.error("SCLRelationInfoRequest failed.", e);
+ return null;
+ }
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * 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:
+ * VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.modeling.scl.ontologymodule;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.simantics.databoard.Bindings;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.common.request.ResourceRead;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.service.CollectionSupport;
+import org.simantics.layer0.Layer0;
+import org.simantics.scl.compiler.common.names.SCLReservedWords;
+import org.simantics.utils.Development;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SCLReservedWordsEscapingChildMapOfResource extends ResourceRead<Map<String, Resource>> {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(SCLReservedWordsEscapingChildMapOfResource.class);
+
+ public SCLReservedWordsEscapingChildMapOfResource(Resource resource) {
+ super(resource);
+ }
+
+ @Override
+ public Map<String, Resource> perform(ReadGraph graph) throws DatabaseException {
+ Layer0 L0 = Layer0.getInstance(graph);
+ Collection<Resource> objects = graph.getObjects(resource, L0.ConsistsOf);
+ CollectionSupport cs = graph.getService(CollectionSupport.class);
+ Map<String,Resource> result = cs.createObjectResourceMap(String.class, objects.size());
+ for(Resource r : objects) {
+ String name = graph.getPossibleRelatedValue(r, L0.HasName, Bindings.STRING);
+ if(name != null) {
+ if(SCLReservedWords.RESERVED_WORDS_SET.contains(name))
+ name = name + "_";
+ Resource old = result.put(name, r);
+ if (old != null)
+ LOGGER.error("The database contains siblings with the same name " + name + " (resource=$" + resource.getResourceId() + ", child=$" + r.getResourceId() + ", previous child=$" + old.getResourceId() + ").");
+ } else {
+ if(Development.DEVELOPMENT)
+ LOGGER.error("The database contains a child with no unique name (resource=$" + resource.getResourceId() + ", child=$" + r.getResourceId() + ").");
+ }
+ }
+ return result;
+ }
+
+}
import java.awt.Graphics2D;
import java.awt.Stroke;
import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
import org.simantics.diagram.connection.RouteGraph;
import org.simantics.scenegraph.INode;
public void afterRender(Graphics2D g) {
g.setRenderingHint(G2DRenderingHints.KEY_END_ELEMENT, "connection");
}
-
+
+ @Override
+ public Rectangle2D getBoundsInLocal() {
+ // #134: Route graph connections render their own selection.
+ // ElementPainter will place an empty G2DParentNode
+ // called "selection" under this ConnectionNode which
+ // should be ignored in bounds calculations.
+ // Otherwise this node will not support being inserted
+ // into a spatial search structure and further selections
+ // will fail.
+ return super.getBoundsInLocal(true);
+ }
+
}
import org.simantics.scl.compiler.elaboration.expressions.lhstype.LhsType;
import org.simantics.scl.compiler.elaboration.expressions.lhstype.PatternMatchingLhs;
import org.simantics.scl.compiler.elaboration.java.DynamicConstructor;
+import org.simantics.scl.compiler.elaboration.macros.MacroRule;
import org.simantics.scl.compiler.elaboration.modules.SCLValue;
import org.simantics.scl.compiler.errors.Locations;
import org.simantics.scl.compiler.internal.codegen.references.IVal;
else
return value.getExpression().copy().simplify(context);
}
+ else {
+ MacroRule macroRule = value.getMacroRule();
+ if(macroRule != null) {
+ Expression newExpression = macroRule.inline(context, typeParameters);
+ if(newExpression != null)
+ return newExpression;
+ }
+ }
return this;
}
public interface MacroRule {
- Expression apply(SimplificationContext context, Type[] typeParameters, EApply apply);
+ default Expression apply(SimplificationContext context, Type[] typeParameters, EApply apply) {
+ return null;
+ }
+
+ default Expression inline(SimplificationContext context, Type[] typeParameters) {
+ return null;
+ }
}
@JavaName getRelatedValue2
relatedValue2 :: Resource -> Resource -> <ReadGraph> a
+ @JavaName getPossibleRelatedValue2
+ possibleRelatedValue2 :: Resource -> Resource -> <ReadGraph> Maybe a
+
@JavaName getRelatedVariantValue2
relatedVariantValue2 :: Resource -> Resource -> <ReadGraph> Variant
valueOf :: Serializable v => a -> <ReadGraph> v
+ genericRelatedValue :: a -> Resource -> <ReadGraph> t
+ genericPossibleRelatedValue :: a -> Resource -> <ReadGraph> Maybe t
+
variantValueOf :: a -> <ReadGraph> Variant
children :: a -> <ReadGraph> [a]
valueOf r = valueOf_ r binding
variantValueOf = variantValueOf_
+ genericRelatedValue = relatedValue2
+ genericPossibleRelatedValue = possibleRelatedValue2
+
children r = r # L0.ConsistsOf
parent r = singleObject r L0.PartOf
possibleParent r = possibleObject r L0.PartOf
variantValueOf v = createVariant (datatype v) (untypedValue v :: Dynamic)
child = child_
possibleChild = possibleChild_
+
+ genericRelatedValue v rel = untypedPropertyValue v (nameOf rel)
+ genericPossibleRelatedValue v rel = untypedPossiblePropertyValue v (nameOf rel)
propertiesClassified :: Variable -> Resource -> <ReadGraph> [Variable]
propertiesClassified parent classified = do
--- /dev/null
+package org.simantics.scl.db;
+
+import org.simantics.Simantics;
+import org.simantics.db.RequestProcessor;
+import org.simantics.scl.runtime.SCLContext;
+
+public class SCLCompilationRequestProcessor {
+ public static RequestProcessor getRequestProcessor() {
+ Object graph = SCLContext.getCurrent().get("graph");
+ if(graph != null)
+ return (RequestProcessor)graph;
+ else
+ return Simantics.getSession();
+ }
+}
<module>org.simantics.issues.ontology</module>
<module>org.simantics.issues.ui</module>
<module>org.simantics.issues.ui.ontology</module>
+ <module>org.simantics.jdbc</module>
+ <module>org.simantics.jdbc.ontology</module>
<module>org.simantics.layer0</module>
<module>org.simantics.layer0.utils</module>
<module>org.simantics.layer0x.ontology</module>
[Enter License Description here.]
</license>
- <plugin
- id="org.simantics.jdbc"
- download-size="0"
- install-size="0"
- version="0.0.0"
- unpack="false"/>
-
- <plugin
+ <plugin
id="org.simantics.simulator.toolkit"
download-size="0"
install-size="0"
unpack="false"/>
<plugin
- id="org.simantics.jdbc.ontology"
+ id="org.simantics.jdbc"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
-
+
<plugin
- id="org.simantics.jdbc.simupedia.sharedlibrary"
+ id="org.simantics.jdbc.ontology"
download-size="0"
install-size="0"
version="0.0.0"
id="org.simantics.logging.ui.feature"
version="0.0.0"/>
+ <includes
+ id="org.simantics.jdbc.feature"
+ version="0.0.0"/>
+
<plugin
id="org.simantics.fileimport"
download-size="0"
<module>org.simantics.image.feature</module>
<module>org.simantics.issues.feature</module>
<module>org.simantics.issues.ui.feature</module>
+ <module>org.simantics.jdbc.feature</module>
<module>org.simantics.layer0.feature</module>
<module>org.simantics.logging.feature</module>
<module>org.simantics.logging.ui.feature</module>