From: Antti Villberg Date: Wed, 26 Sep 2018 10:10:27 +0000 (+0300) Subject: Merge branch 'change/2080/9' into private/balas X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=commitdiff_plain;h=refs%2Fheads%2Fprivate%2Fbalas;hp=3bf0403ae1537e2130644c4d7d63f6218c80996d;p=simantics%2Fplatform.git Merge branch 'change/2080/9' into private/balas --- diff --git a/bundles/org.simantics.diagram.connection/src/org/simantics/diagram/connection/rendering/StyledRouteGraphRenderer.java b/bundles/org.simantics.diagram.connection/src/org/simantics/diagram/connection/rendering/StyledRouteGraphRenderer.java index b084e5875..dd9473042 100644 --- a/bundles/org.simantics.diagram.connection/src/org/simantics/diagram/connection/rendering/StyledRouteGraphRenderer.java +++ b/bundles/org.simantics.diagram.connection/src/org/simantics/diagram/connection/rendering/StyledRouteGraphRenderer.java @@ -36,9 +36,13 @@ public class StyledRouteGraphRenderer implements IRouteGraphRenderer, Serializab protected final ConnectionStyle style; + private static class Cache { + Path2D path = new Path2D.Double(); + THashSet branchPoints = new THashSet<>(); + } + // Caches to avoid creating new objects all the time during rendering - protected transient Path2D path; - protected transient THashSet branchPoints; + protected static ThreadLocal caches = ThreadLocal.withInitial(() -> new Cache()); public StyledRouteGraphRenderer(ConnectionStyle style) { if (style == null) @@ -52,14 +56,14 @@ public class StyledRouteGraphRenderer implements IRouteGraphRenderer, Serializab @Override public void render(Graphics2D g, RouteGraph rg) { - if (path == null) - path = new Path2D.Double(); + Cache cache = caches.get(); + Path2D path = cache.path; + THashSet branchPoints = cache.branchPoints; + path.reset(); rg.getPath2D(path); style.drawPath(g, path, false); - if (branchPoints == null) - branchPoints = new THashSet(); branchPoints.clear(); for(RouteLine line : rg.getLines()) { renderLine(g, line, false); diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/TypeGroup.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/TypeGroup.java index e025fb2dd..522c0b9d5 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/TypeGroup.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/TypeGroup.java @@ -47,6 +47,31 @@ public class TypeGroup implements Group { 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. * diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/ResourceSCLTextGridStyle.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/ResourceSCLTextGridStyle.java index 3bbbf8081..224e767c2 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/ResourceSCLTextGridStyle.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/ResourceSCLTextGridStyle.java @@ -23,11 +23,10 @@ import org.simantics.utils.datastructures.Pair; */ 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) { @@ -51,7 +50,7 @@ public class ResourceSCLTextGridStyle extends TextGridStyle { @Override protected Object getIdentity(Resource entry) { - return new Pair(style, entry); + return new Pair(getResource(), entry); } @Override @@ -63,7 +62,7 @@ public class ResourceSCLTextGridStyle extends TextGridStyle { 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 function = styleVariable.getPossiblePropertyValue(graph, DIA.ResourceSCLTextGridStyle_texts); Tuple3 result = Simantics.applySCLRead(graph, function, element); @@ -79,7 +78,7 @@ public class ResourceSCLTextGridStyle extends TextGridStyle { @Override public String getNodeName() { - return "" + style.getResourceId(); + return "" + getResource().getResourceId(); } } diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/SCLTextGridStyle.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/SCLTextGridStyle.java index 4401f2213..f084799fd 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/SCLTextGridStyle.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/SCLTextGridStyle.java @@ -25,11 +25,10 @@ import org.simantics.utils.datastructures.Pair; */ 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) { @@ -53,7 +52,7 @@ public class SCLTextGridStyle extends TextGridStyle { @Override protected Object getIdentity(Resource entry) { - return new Pair(style, entry); + return new Pair(getResource(), entry); } @Override @@ -81,7 +80,7 @@ public class SCLTextGridStyle extends TextGridStyle { if (moduleVariable == null) return null; - Variable styleVariable = Variables.getVariable(graph, style); + Variable styleVariable = Variables.getVariable(graph, getResource()); Function1 function = styleVariable.getPossiblePropertyValue(graph, DIA.SCLTextGridStyle_texts); Tuple3 result = Simantics.applySCLRead(graph, function, moduleVariable); @@ -97,7 +96,7 @@ public class SCLTextGridStyle extends TextGridStyle { @Override public String getNodeName() { - return "" + style.getResourceId(); + return "" + getResource().getResourceId(); } } diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/StyleBase.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/StyleBase.java index 21071ba74..28b03a1f6 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/StyleBase.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/StyleBase.java @@ -11,12 +11,7 @@ *******************************************************************************/ 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; @@ -44,8 +39,7 @@ import org.simantics.scenegraph.profile.Style; 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; /** @@ -72,14 +66,48 @@ import org.simantics.utils.datastructures.Pair; */ public abstract class StyleBase implements Style { - protected final Map values = new ConcurrentHashMap(); - -// private Map listeners = new ConcurrentHashMap(); + private Object identity; + + public StyleBase(Object identity) { + this.identity = identity; + } - private Map, ObserverGroupListener> listeners = new HashMap, ObserverGroupListener>(); + public StyleBase() { + this.identity = getClass(); + } + protected 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 removals = new ArrayList(); + @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 @@ -175,9 +203,9 @@ public abstract class StyleBase implements Style { */ 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(); } @@ -283,12 +311,11 @@ public abstract class StyleBase implements Style { 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); + } } @@ -308,7 +335,7 @@ public abstract class StyleBase implements Style { listener = new GroupListener(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); @@ -390,7 +417,7 @@ public abstract class StyleBase implements Style { 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! @@ -425,19 +452,13 @@ public abstract class StyleBase implements Style { 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); } @@ -480,7 +501,7 @@ public abstract class StyleBase implements Style { } private ObserverGroupListener getListener(Resource runtime, Group group) { - return listeners.get(Pair.make(runtime, group)); + return StyleBaseData.getInstance().getListener(new Tuple3(this, runtime, group)); } } diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/StyleBaseData.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/StyleBaseData.java new file mode 100644 index 000000000..5bd51b20b --- /dev/null +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/StyleBaseData.java @@ -0,0 +1,84 @@ +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 values = new ConcurrentHashMap<>(); + + private Map listeners = new HashMap<>(); + + private final Map> 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 getValue(Tuple t) { + return (T)values.get(t); + } + + public synchronized void removeItem(Style s, Resource r) { + List 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 rs = removals.remove(s); + if(rs == null) return; + + DataNodeMap map = evaluationContext.getConstant(ProfileKeys.NODE_MAP); + + for (Resource item : rs) { + s.cleanupStyleForItem(evaluationContext, map, item); + } + + } + +} diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/TextGridStyle.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/TextGridStyle.java index 54972155d..60e8fa6da 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/TextGridStyle.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/TextGridStyle.java @@ -38,17 +38,18 @@ public abstract class TextGridStyle extends StyleBase { 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; } @@ -175,29 +176,33 @@ public abstract class TextGridStyle extends StyleBase { // 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); @@ -361,18 +366,45 @@ public abstract class TextGridStyle extends StyleBase { @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(); + } } diff --git a/bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/handler/impl/PickContextImpl.java b/bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/handler/impl/PickContextImpl.java index a891d62b7..f6fd5fe6d 100644 --- a/bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/handler/impl/PickContextImpl.java +++ b/bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/handler/impl/PickContextImpl.java @@ -1,5 +1,5 @@ /******************************************************************************* - * 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 @@ -8,6 +8,7 @@ * * 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; @@ -51,6 +52,8 @@ import org.slf4j.LoggerFactory; /** * @author Toni Kalajainen + * @author Jani Simomaa + * @author Tuukka Lehtonen */ public class PickContextImpl implements PickContext { @@ -62,6 +65,16 @@ public class PickContextImpl implements PickContext { private static final ThreadLocal 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, @@ -171,11 +184,11 @@ public class PickContextImpl implements PickContext { return shape.getBounds2D(); } - private static List pickElements(IDiagram diagram, PickRequest request) { + private List 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; diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/internal/Activator.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/internal/Activator.java index 3fc0d46fa..b55bed028 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/internal/Activator.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/internal/Activator.java @@ -5,7 +5,7 @@ import java.util.Hashtable; 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 { diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphModuleSourceRepository.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphModuleSourceRepository.java index f3f5b9170..8eed51aca 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphModuleSourceRepository.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphModuleSourceRepository.java @@ -15,6 +15,7 @@ import org.simantics.db.request.Read; 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; diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphEntityType.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/GraphEntityType.java similarity index 98% rename from bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphEntityType.java rename to bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/GraphEntityType.java index d59ea605c..8ea51cfd0 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphEntityType.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/GraphEntityType.java @@ -1,4 +1,4 @@ -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; diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphPropertyRelation.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/GraphPropertyRelation.java similarity index 99% rename from bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphPropertyRelation.java rename to bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/GraphPropertyRelation.java index a4c1c4b2a..3275656bc 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphPropertyRelation.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/GraphPropertyRelation.java @@ -1,4 +1,4 @@ -package org.simantics.modeling.scl; +package org.simantics.modeling.scl.ontologymodule; import org.simantics.db.Resource; import org.simantics.scl.compiler.common.names.Name; diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphRelation.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/GraphRelation.java similarity index 99% rename from bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphRelation.java rename to bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/GraphRelation.java index f1c8a79f8..5a4598ce3 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphRelation.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/GraphRelation.java @@ -1,4 +1,4 @@ -package org.simantics.modeling.scl; +package org.simantics.modeling.scl.ontologymodule; import org.simantics.db.Resource; import org.simantics.scl.compiler.common.names.Name; diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/GraphRequestDuringSCLCompilation.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/GraphRequestDuringSCLCompilation.java new file mode 100644 index 000000000..54533ad29 --- /dev/null +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/GraphRequestDuringSCLCompilation.java @@ -0,0 +1,18 @@ +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(); + } + +} diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/OntologyModule.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/OntologyModule.java similarity index 58% rename from bundles/org.simantics.modeling/src/org/simantics/modeling/scl/OntologyModule.java rename to bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/OntologyModule.java index 39cf2f765..ec698e670 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/OntologyModule.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/OntologyModule.java @@ -1,8 +1,9 @@ -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; @@ -16,29 +17,48 @@ import org.simantics.db.exception.DatabaseException; 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 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; @@ -69,26 +89,55 @@ public class OntologyModule extends LazyModule { 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 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 getLocalMap(Resource parent) { @@ -129,16 +178,116 @@ public class OntologyModule extends LazyModule { } } + @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 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 diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/OntologyModuleSourceRepository.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/OntologyModuleSourceRepository.java similarity index 97% rename from bundles/org.simantics.modeling/src/org/simantics/modeling/scl/OntologyModuleSourceRepository.java rename to bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/OntologyModuleSourceRepository.java index b91e90d61..134b2b3d7 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/OntologyModuleSourceRepository.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/OntologyModuleSourceRepository.java @@ -1,4 +1,4 @@ -package org.simantics.modeling.scl; +package org.simantics.modeling.scl.ontologymodule; import java.util.Collection; diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/SCLRelationInfo.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/SCLRelationInfo.java new file mode 100644 index 000000000..451a83ecf --- /dev/null +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/SCLRelationInfo.java @@ -0,0 +1,13 @@ +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; + } +} diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/SCLRelationInfoRequest.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/SCLRelationInfoRequest.java new file mode 100644 index 000000000..6662463c5 --- /dev/null +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/SCLRelationInfoRequest.java @@ -0,0 +1,79 @@ +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 { + 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 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 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; + } + } + +} diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/SCLReservedWordsEscapingChildMapOfResource.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/SCLReservedWordsEscapingChildMapOfResource.java new file mode 100644 index 000000000..6e674e41c --- /dev/null +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/SCLReservedWordsEscapingChildMapOfResource.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * 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> { + + private static final Logger LOGGER = LoggerFactory.getLogger(SCLReservedWordsEscapingChildMapOfResource.class); + + public SCLReservedWordsEscapingChildMapOfResource(Resource resource) { + super(resource); + } + + @Override + public Map perform(ReadGraph graph) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + Collection objects = graph.getObjects(resource, L0.ConsistsOf); + CollectionSupport cs = graph.getService(CollectionSupport.class); + Map 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; + } + +} diff --git a/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/ConnectionNode.java b/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/ConnectionNode.java index d4543c6d1..9331a1ede 100644 --- a/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/ConnectionNode.java +++ b/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/ConnectionNode.java @@ -16,6 +16,7 @@ import java.awt.Composite; 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; @@ -161,5 +162,17 @@ public class ConnectionNode extends SingleElementNode implements InitValueSuppor 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); + } + } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EConstant.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EConstant.java index eb3f5ca4a..25cc96019 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EConstant.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EConstant.java @@ -16,6 +16,7 @@ import org.simantics.scl.compiler.elaboration.errors.NotPatternException; 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; @@ -125,6 +126,14 @@ public class EConstant extends Expression { 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; } diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/macros/MacroRule.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/macros/MacroRule.java index 60d53acd2..21b836871 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/macros/MacroRule.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/macros/MacroRule.java @@ -7,6 +7,12 @@ import org.simantics.scl.compiler.types.Type; 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; + } } diff --git a/bundles/org.simantics.scl.db/scl/Simantics/DB.scl b/bundles/org.simantics.scl.db/scl/Simantics/DB.scl index a400659ee..2ff2f51ac 100644 --- a/bundles/org.simantics.scl.db/scl/Simantics/DB.scl +++ b/bundles/org.simantics.scl.db/scl/Simantics/DB.scl @@ -108,6 +108,9 @@ importJava "org.simantics.db.ReadGraph" where @JavaName getRelatedValue2 relatedValue2 :: Resource -> Resource -> a + @JavaName getPossibleRelatedValue2 + possibleRelatedValue2 :: Resource -> Resource -> Maybe a + @JavaName getRelatedVariantValue2 relatedVariantValue2 :: Resource -> Resource -> Variant @@ -187,6 +190,9 @@ class Browsable a where valueOf :: Serializable v => a -> v + genericRelatedValue :: a -> Resource -> t + genericPossibleRelatedValue :: a -> Resource -> Maybe t + variantValueOf :: a -> Variant children :: a -> [a] @@ -206,6 +212,9 @@ instance Browsable Resource where 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 diff --git a/bundles/org.simantics.scl.db/scl/Simantics/Variables.scl b/bundles/org.simantics.scl.db/scl/Simantics/Variables.scl index 43be6defb..436e0a173 100644 --- a/bundles/org.simantics.scl.db/scl/Simantics/Variables.scl +++ b/bundles/org.simantics.scl.db/scl/Simantics/Variables.scl @@ -421,6 +421,9 @@ instance Browsable Variable where 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 -> [Variable] propertiesClassified parent classified = do diff --git a/bundles/org.simantics.scl.db/src/org/simantics/scl/db/SCLCompilationRequestProcessor.java b/bundles/org.simantics.scl.db/src/org/simantics/scl/db/SCLCompilationRequestProcessor.java new file mode 100644 index 000000000..b793b2128 --- /dev/null +++ b/bundles/org.simantics.scl.db/src/org/simantics/scl/db/SCLCompilationRequestProcessor.java @@ -0,0 +1,15 @@ +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(); + } +} diff --git a/bundles/pom.xml b/bundles/pom.xml index 04b6311eb..9e409d9df 100644 --- a/bundles/pom.xml +++ b/bundles/pom.xml @@ -153,6 +153,8 @@ org.simantics.issues.ontology org.simantics.issues.ui org.simantics.issues.ui.ontology + org.simantics.jdbc + org.simantics.jdbc.ontology org.simantics.layer0 org.simantics.layer0.utils org.simantics.layer0x.ontology diff --git a/features/org.simantics.jdbc.feature/feature.xml b/features/org.simantics.jdbc.feature/feature.xml index 66b53fac8..1665527b2 100644 --- a/features/org.simantics.jdbc.feature/feature.xml +++ b/features/org.simantics.jdbc.feature/feature.xml @@ -16,14 +16,7 @@ [Enter License Description here.] - - - - + + + org.simantics.image.feature org.simantics.issues.feature org.simantics.issues.ui.feature + org.simantics.jdbc.feature org.simantics.layer0.feature org.simantics.logging.feature org.simantics.logging.ui.feature