package org.simantics.district.network.profile; import java.util.Map; import java.util.Set; import org.simantics.databoard.Bindings; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener; import org.simantics.db.common.procedure.adapter.TransientCacheListener; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.variable.Variable; import org.simantics.db.layer0.variable.Variables; import org.simantics.district.network.ontology.DistrictNetworkResource; import org.simantics.district.network.visualisations.DynamicVisualisationsContributions.DynamicArrowObject; import org.simantics.district.network.visualisations.model.DynamicArrowContribution; import org.simantics.district.network.visualisations.model.DynamicVisualisation; import org.simantics.layer0.Layer0; import org.simantics.modeling.ModelingResources; import org.simantics.scenegraph.INode; import org.simantics.scenegraph.g2d.G2DSceneGraph; import org.simantics.scenegraph.g2d.nodes.ConnectionNode; import org.simantics.scenegraph.profile.EvaluationContext; import org.simantics.scenegraph.profile.common.ProfileVariables; import org.simantics.scl.runtime.SCLContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class ArrowLengthStyle extends ThrottledStyleBase { private static final Logger LOGGER = LoggerFactory.getLogger(ArrowLengthStyle.class); private static final Double PENDING = Double.NaN; @Override public Double calculateThrottledStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource groupItem) throws DatabaseException { Resource diagram = graph.getSingleObject(groupItem, Layer0.getInstance(graph).PartOf); Set edgesToUse = graph.syncRequest(new MidBranchEdgeSetRequest(diagram), TransientCacheListener.instance()); if (!edgesToUse.contains(groupItem)) return null; DynamicVisualisation dv = graph.syncRequest(new RuntimeDynamicVisualisationsRequest(runtimeDiagram), TransientCacheAsyncListener.instance()); // Prevent PendingVariableExceptions from coming through boolean wasSynchronous = graph.setSynchronous(true); try { if (dv != null) { Layer0 L0 = Layer0.getInstance(graph); DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph); ModelingResources MOD = ModelingResources.getInstance(graph); Resource mapping = graph.getSingleObject(groupItem, DN.HasMapping); Map arrowContributions = dv.getArrowContributions(); String mappingName = graph.getRelatedValue(mapping, L0.HasName); DynamicArrowContribution dac = arrowContributions.get(mappingName); if (dac != null && dac.isUsed()) { Resource mappedComponent = graph.getPossibleObject(groupItem, DN.MappedComponent); if (mappedComponent != null) { Resource component = graph.getSingleObject(mappedComponent, MOD.ElementToComponent); Variable variable = Variables.getVariable(graph, component); Variable possibleActiveVariable = Variables.possibleActiveVariable(graph, variable); if (possibleActiveVariable != null) { Variable module = possibleActiveVariable.getPossibleChild(graph, dac.getModuleName()); if (module != null) { Variable attribute = module.getPossibleProperty(graph, dac.getAttributeName()); if (attribute != null) { Double possibleValue = attribute.getPossibleValue(graph, Bindings.DOUBLE); if (possibleValue != null) { double biasValue; double gainValue; if (dac.isUseDefault()) { DynamicArrowObject dynamicArrowObject = dv.getDefaultArrowContributions().get(mappingName); // This is required if ontology module needs to be compiled Object currentGraph = SCLContext.getCurrent().get("graph"); try { SCLContext.getCurrent().put("graph", graph); DynamicArrowContribution ddcc = dynamicArrowObject.getArrowContributions().get(dac.getLabel()); biasValue = ddcc.getDefaultBias(); gainValue = ddcc.getDefaultGain(); } finally { SCLContext.getCurrent().put("graph", currentGraph); } } else { biasValue = dac.getDefaultBias(); gainValue = dac.getDefaultGain(); } // here we do the adjusting according to spec in #15038 return possibleValue.doubleValue() * gainValue + biasValue; } else { LOGGER.warn("No value for {}", attribute.getURI(graph)); } } else { LOGGER.warn("Wrong attribute name {} for {} !!", dac.getAttributeName(), module.getURI(graph)); } } else { LOGGER.warn("Wrong modulename {} for {} !!", dac.getModuleName(), possibleActiveVariable.getURI(graph)); } } else { LOGGER.debug("No active experiment for {}", variable.getURI(graph)); } } else { LOGGER.debug("No mapped component for {} to calculate dynamic color style", groupItem); } } } } finally { graph.setSynchronous(wasSynchronous); } return null; } @Override public void applyThrottledStyleForNode(EvaluationContext observer, INode node, Double value) { // System.out.println("apply: " + node + " : " + value); ConnectionNode n = (ConnectionNode) node; if (value == PENDING) { ((G2DSceneGraph)node.getRootNode()).setPending(node); } else { ((G2DSceneGraph)node.getRootNode()).clearPending(node); } for (INode nn : n.getNodes()) ProfileVariables.claimNodeProperty(nn, "arrowLength", value, observer); } @Override protected void cleanupStyleForNode(EvaluationContext evaluationContext, INode node) { ((G2DSceneGraph)node.getRootNode()).clearPending(node); ConnectionNode n = (ConnectionNode) node; for (INode nn : n.getNodes()) ProfileVariables.claimNodeProperty(nn, "arrowLength", null, evaluationContext); } }