1 package org.simantics.district.network.ui.styles;
3 import java.awt.geom.Point2D;
6 import org.simantics.Simantics;
7 import org.simantics.db.ReadGraph;
8 import org.simantics.db.Resource;
9 import org.simantics.db.common.procedure.adapter.TransientCacheListener;
10 import org.simantics.db.common.request.ResourceRead;
11 import org.simantics.db.exception.DatabaseException;
12 import org.simantics.db.layer0.exception.MissingVariableException;
13 import org.simantics.db.layer0.exception.MissingVariableValueException;
14 import org.simantics.db.layer0.exception.PendingVariableException;
15 import org.simantics.db.layer0.util.Layer0Utils;
16 import org.simantics.db.layer0.variable.Variable;
17 import org.simantics.db.layer0.variable.Variables;
18 import org.simantics.diagram.profile.StyleBase;
19 import org.simantics.diagram.stubs.DiagramResource;
20 import org.simantics.district.network.DistrictNetworkUtil;
21 import org.simantics.district.network.ontology.DistrictNetworkResource;
22 import org.simantics.district.network.profile.MidBranchEdgeSetRequest;
23 import org.simantics.district.network.ui.nodes.DeferredRenderingNode;
24 import org.simantics.district.network.ui.nodes.DistrictNetworkNodeUtils;
25 import org.simantics.district.network.ui.nodes.DistrictNetworkStaticInfoNode;
26 import org.simantics.layer0.Layer0;
27 import org.simantics.scenegraph.INode;
28 import org.simantics.scenegraph.ParentNode;
29 import org.simantics.scenegraph.g2d.nodes.spatial.RTreeNode;
30 import org.simantics.scenegraph.profile.EvaluationContext;
31 import org.simantics.scenegraph.profile.common.ProfileVariables;
32 import org.simantics.scenegraph.utils.NodeUtil;
33 import org.simantics.scl.compiler.top.ValueNotFound;
34 import org.simantics.scl.osgi.SCLOsgi;
35 import org.simantics.scl.runtime.SCLContext;
36 import org.simantics.scl.runtime.function.Function1;
37 import org.simantics.structural.stubs.StructuralResource2;
38 import org.slf4j.LoggerFactory;
39 import org.slf4j.Logger;
41 public class DistrictNetworkStaticInfoStyle extends StyleBase<DistrictNetworkStaticInfoStyle.StyleResult> {
43 private static final Logger LOGGER = LoggerFactory.getLogger(DistrictNetworkStaticInfoStyle.class);
45 private static final String ACTIONS_MODULE = "Actions";
46 private static final String PIPELINE_INFO = "pipelineInfo";
48 public static final String STATIC_INFO_DEFERRED = "staticInfo";
50 public static class StyleResult {
51 public StyleResult(Point2D p1, Point2D p2, String info) {
62 public DistrictNetworkStaticInfoStyle(Resource style) {
67 public StyleResult calculateStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource mapElement)
68 throws DatabaseException {
69 DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
71 boolean isEdge = graph.isInstanceOf(mapElement, DN.Edge);
72 boolean isVertex = graph.isInstanceOf(mapElement, DN.Vertex);
73 if (!isEdge && !isVertex)
77 Resource diagram = graph.getSingleObject(mapElement, Layer0.getInstance(graph).PartOf);
78 Set<Resource> edgesToUse = graph.syncRequest(new MidBranchEdgeSetRequest(diagram), TransientCacheListener.instance());
79 if (!edgesToUse.contains(mapElement))
83 DiagramResource DIA = DiagramResource.getInstance(graph);
84 StructuralResource2 STR = StructuralResource2.getInstance(graph);
86 Resource module = DistrictNetworkUtil.getMappedComponentCached(graph, mapElement);
90 Resource moduleType = graph.getPossibleType(module, STR.Component);
91 if (moduleType == null)
94 Function1<Variable, String> function = getUCPipelineInfoFunctionCached(graph, moduleType);
100 Variable variable = Variables.getVariable(graph, module);
101 Variable moduleVariable = Variables.possibleActiveVariable(graph, variable);
102 if (moduleVariable == null)
103 moduleVariable = variable;
105 result = Simantics.applySCLRead(graph, function, moduleVariable);
106 } catch (PendingVariableException | MissingVariableValueException e) {
108 } catch (MissingVariableException e) {
109 // the requested variable is missing from the UC
110 String message = e.getMessage();
111 LOGGER.warn("Missing variable for calculating style with function {} {}", function, message);
112 result = "<" + message + ">";
116 double[] coords = graph.getRelatedValue(mapElement, DIA.HasLocation);
117 Point2D p = DistrictNetworkNodeUtils.calculatePoint2D(new Point2D.Double(coords[0], coords[1]), null);
118 return new StyleResult(p, p, result);
121 Resource v1 = graph.getSingleObject(mapElement, DN.HasStartVertex);
122 double[] coords1 = graph.getRelatedValue(v1, DIA.HasLocation);
123 Resource v2 = graph.getSingleObject(mapElement, DN.HasEndVertex);
124 double[] coords2 = graph.getRelatedValue(v2, DIA.HasLocation);
125 Point2D p1 = DistrictNetworkNodeUtils.calculatePoint2D(new Point2D.Double(coords1[0], coords1[1]), null);
126 Point2D p2 = DistrictNetworkNodeUtils.calculatePoint2D(new Point2D.Double(coords2[0], coords2[1]), null);
128 return new StyleResult(p1, p2, result);
135 public void applyStyleForNode(EvaluationContext evaluationContext, INode parent, StyleResult result) {
136 if (result == null) {
137 cleanupStyleForNode(evaluationContext, parent);
141 ParentNode<?> root = (ParentNode<?>) NodeUtil.getNearestParentOfType(parent, RTreeNode.class);
143 DeferredRenderingNode deferred = ProfileVariables.claimChild(root, "", STATIC_INFO_DEFERRED, DeferredRenderingNode.class, evaluationContext);
144 deferred.setZIndex(Integer.MAX_VALUE-1);
147 DistrictNetworkStaticInfoNode node = ProfileVariables.claimChild(parent, "*", DistrictNetworkStaticInfoNode.NODE_KEY, DistrictNetworkStaticInfoNode.class, evaluationContext);
151 Point2D p1 = result.p1;
152 Point2D p2 = result.p2;
155 node.setLocation(p1, new Point2D.Double(1.0, 0.0));
158 double sign = Math.signum(p1.getX() - p2.getX());
159 Point2D.Double origin = new Point2D.Double(0.5 * (p1.getX() + p2.getX()), 0.5 * (p1.getY() + p2.getY()));
160 Point2D direction = new Point2D.Double(0.5 * sign * (p1.getX() - p2.getX()), 0.5 * sign * (p1.getY() - p2.getY()));
162 node.setLocation(origin, direction);
165 node.setInfo(result.info);
168 private static Function1<Variable, String> getUCPipelineInfoFunctionCached(ReadGraph graph, Resource componentType)
169 throws DatabaseException {
170 return graph.syncRequest(new UCPipelineInfoRequest(componentType), TransientCacheListener.instance());
173 private static final class UCPipelineInfoRequest extends ResourceRead<Function1<Variable, String>> {
174 public UCPipelineInfoRequest(Resource resource) {
178 @SuppressWarnings("unchecked")
180 public Function1<Variable, String> perform(ReadGraph graph) throws DatabaseException {
181 Resource actionsModule = Layer0Utils.getPossibleChild(graph, resource, ACTIONS_MODULE);
182 if (actionsModule == null || !graph.isInstanceOf(actionsModule, Layer0.getInstance(graph).SCLModule))
185 String uri = graph.getURI(actionsModule);
186 SCLContext sclContext = SCLContext.getCurrent();
187 Object oldGraph = sclContext.get("graph");
189 sclContext.put("graph", graph);
190 return (Function1<Variable, String>) SCLOsgi.MODULE_REPOSITORY.getValue(uri, PIPELINE_INFO);
191 } catch (ValueNotFound e1) {
194 sclContext.put("graph", oldGraph);
200 protected void cleanupStyleForNode(EvaluationContext evaluationContext, INode node) {
201 ProfileVariables.denyChild(node, "*", DistrictNetworkStaticInfoNode.NODE_KEY);