From 8958c9b265fc6a842c76714b60f0d99740434243 Mon Sep 17 00:00:00 2001 From: jsimomaa Date: Tue, 19 Feb 2019 13:25:51 +0200 Subject: [PATCH] First version of throttled profile results - configure via proeprty view gitlab #30 Change-Id: Ie99ee4b3b83911646072d44757570b07f20c450d --- .../DistrictNetworkDiagramSettings.pgraph | 4 + .../ontology/DistrictNetworkResource.java | 6 + .../network/profile/DNElementColorStyle.java | 6 +- .../network/profile/EdgeThicknessStyle.java | 7 +- .../network/profile/ThrottledStyleBase.java | 117 ++++++++++++++++++ .../network/profile/VertexSizeStyle.java | 7 +- .../network/profile/VertexSymbolStyle.java | 7 +- 7 files changed, 139 insertions(+), 15 deletions(-) create mode 100644 org.simantics.district.network/src/org/simantics/district/network/profile/ThrottledStyleBase.java diff --git a/org.simantics.district.network.ontology/graph/DistrictNetworkDiagramSettings.pgraph b/org.simantics.district.network.ontology/graph/DistrictNetworkDiagramSettings.pgraph index 334adbed..8abc05de 100644 --- a/org.simantics.district.network.ontology/graph/DistrictNetworkDiagramSettings.pgraph +++ b/org.simantics.district.network.ontology/graph/DistrictNetworkDiagramSettings.pgraph @@ -83,6 +83,8 @@ DN.Diagram L0.HasLabel "Diagram Background Color" >-- DN.Diagram.drawMapEnabled ==> "Boolean" -- DN.Diagram.profileUpdateInterval ==> "Long" { +public class DNElementColorStyle extends ThrottledStyleBase { private static final boolean DEBUG = false; @Override - public Color calculateStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource groupItem) throws DatabaseException { + public Color calculateThrottledStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource groupItem) throws DatabaseException { DiagramSettings ds = graph.syncRequest(new DiagramSettingsRequest(runtimeDiagram), TransientCacheAsyncListener.instance()); if (ds.elementColoringFunction.isPresent()) { if (DEBUG) @@ -40,7 +40,7 @@ public class DNElementColorStyle extends StyleBase { } @Override - public void applyStyleForNode(EvaluationContext observer, INode node, Color color) { + public void applyThrottledStyleForNode(EvaluationContext observer, INode node, Color color) { SingleElementNode n = (SingleElementNode) node; for (INode nn : n.getNodes()) ProfileVariables.claimNodeProperty(nn, "dynamicColor", color, observer); diff --git a/org.simantics.district.network/src/org/simantics/district/network/profile/EdgeThicknessStyle.java b/org.simantics.district.network/src/org/simantics/district/network/profile/EdgeThicknessStyle.java index 45b55549..06dcdf3f 100644 --- a/org.simantics.district.network/src/org/simantics/district/network/profile/EdgeThicknessStyle.java +++ b/org.simantics.district.network/src/org/simantics/district/network/profile/EdgeThicknessStyle.java @@ -5,20 +5,19 @@ import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener; import org.simantics.db.exception.DatabaseException; -import org.simantics.diagram.profile.StyleBase; 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; -public class EdgeThicknessStyle extends StyleBase { +public class EdgeThicknessStyle extends ThrottledStyleBase { private static final Double PENDING = Double.NaN; private static final Double ONE = 1.0; @Override - public Double calculateStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource groupItem) throws DatabaseException { + public Double calculateThrottledStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource groupItem) throws DatabaseException { DiagramSettings ds = graph.syncRequest(new DiagramSettingsRequest(runtimeDiagram), TransientCacheAsyncListener.instance()); Double thickness = ONE; if (ds.edgeThicknessProperty.isPresent()) { @@ -34,7 +33,7 @@ public class EdgeThicknessStyle extends StyleBase { } @Override - public void applyStyleForNode(EvaluationContext observer, INode node, Double value) { + public void applyThrottledStyleForNode(EvaluationContext observer, INode node, Double value) { // System.out.println("apply: " + node + " : " + value); ConnectionNode n = (ConnectionNode) node; if (value == PENDING) { diff --git a/org.simantics.district.network/src/org/simantics/district/network/profile/ThrottledStyleBase.java b/org.simantics.district.network/src/org/simantics/district/network/profile/ThrottledStyleBase.java new file mode 100644 index 00000000..f8b817ae --- /dev/null +++ b/org.simantics.district.network/src/org/simantics/district/network/profile/ThrottledStyleBase.java @@ -0,0 +1,117 @@ +/******************************************************************************* + * Copyright (c) 2007, 2019 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: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.district.network.profile; + +import java.util.Optional; +import java.util.concurrent.atomic.AtomicLong; + +import org.simantics.Simantics; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.request.UnaryRead; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.procedure.Listener; +import org.simantics.db.request.Read; +import org.simantics.diagram.profile.StyleBase; +import org.simantics.diagram.stubs.DiagramResource; +import org.simantics.district.network.ontology.DistrictNetworkResource; +import org.simantics.scenegraph.INode; +import org.simantics.scenegraph.profile.EvaluationContext; +import org.simantics.scenegraph.profile.Group; +import org.simantics.scenegraph.profile.Observer; +import org.simantics.scenegraph.profile.common.ObserverGroupListener; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class ThrottledStyleBase extends StyleBase> { + + private static final Logger LOGGER = LoggerFactory.getLogger(ThrottledStyleBase.class); + private static final long DEFAULT_INTERVAL = 2000; + + private long lastCalculateTimestamp = 0; + private AtomicLong interval = new AtomicLong(DEFAULT_INTERVAL); + private Listener> resultListener; + + @Override + protected Read> getStyleCalculationRequest(Resource runtimeDiagram, Resource entry, Resource item) { + Simantics.getSession().asyncRequest(new ProfileUpdateIntervalRead(runtimeDiagram), new Listener() { + + @Override + public void execute(Long result) { + interval.set(result); + } + + @Override + public void exception(Throwable t) { + LOGGER.error("Could not listen interval from runtime diagram {}", runtimeDiagram, t); + } + + @Override + public boolean isDisposed() { + return resultListener.isDisposed(); + } + }); + return super.getStyleCalculationRequest(runtimeDiagram, entry, item); + } + + @Override + protected Listener> getStyleResultListener(ObserverGroupListener groupListener, Resource item, + Group group, Observer observer, Resource runtimeDiagram) { + resultListener = super.getStyleResultListener(groupListener, item, group, observer, runtimeDiagram); + return resultListener; + } + + @Override + public final Optional calculateStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, + Resource groupItem) throws DatabaseException { + long currentTimestamp = System.currentTimeMillis(); + if (lastCalculateTimestamp > (currentTimestamp - interval.get())) { + LOGGER.debug("Throttling result calculation for {} {} {} {}", runtimeDiagram, entry, groupItem, interval.get()); + return Optional.empty(); + } + lastCalculateTimestamp = currentTimestamp; + // let's calculate + return Optional.ofNullable(calculateThrottledStyle(graph, runtimeDiagram, entry, groupItem)); + } + + public abstract Result calculateThrottledStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource groupItem) throws DatabaseException; + + @Override + public final void applyStyleForNode(EvaluationContext evaluationContext, INode node, Optional result) { + if (!result.equals(Optional.empty())) { + applyThrottledStyleForNode(evaluationContext, node, result.get()); + } else { + LOGGER.debug("Do not apply as results are unchanged for {} {} {}", evaluationContext, node, result); + } + } + + public abstract void applyThrottledStyleForNode(EvaluationContext evaluationContext, INode node, Result result); + + private static class ProfileUpdateIntervalRead extends UnaryRead { + + public ProfileUpdateIntervalRead(Resource parameter) { + super(parameter); + } + + @Override + public Long perform(ReadGraph graph) throws DatabaseException { + Resource configuration = graph.getPossibleObject(parameter, DiagramResource.getInstance(graph).RuntimeDiagram_HasConfiguration); + DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph); + Long interval = DEFAULT_INTERVAL; + if (configuration != null) { + interval = graph.getPossibleRelatedValue(configuration, DN.Diagram_profileUpdateInterval, Bindings.LONG); + } + return interval != null ? interval : DEFAULT_INTERVAL; + } + } +} diff --git a/org.simantics.district.network/src/org/simantics/district/network/profile/VertexSizeStyle.java b/org.simantics.district.network/src/org/simantics/district/network/profile/VertexSizeStyle.java index b33cd1c0..d536bc04 100644 --- a/org.simantics.district.network/src/org/simantics/district/network/profile/VertexSizeStyle.java +++ b/org.simantics.district.network/src/org/simantics/district/network/profile/VertexSizeStyle.java @@ -5,20 +5,19 @@ import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener; import org.simantics.db.exception.DatabaseException; -import org.simantics.diagram.profile.StyleBase; import org.simantics.scenegraph.INode; import org.simantics.scenegraph.g2d.G2DSceneGraph; import org.simantics.scenegraph.g2d.nodes.SingleElementNode; import org.simantics.scenegraph.profile.EvaluationContext; import org.simantics.scenegraph.profile.common.ProfileVariables; -public class VertexSizeStyle extends StyleBase { +public class VertexSizeStyle extends ThrottledStyleBase { private static final Double PENDING = Double.NaN; private static final Double ONE = 1.0; @Override - public Double calculateStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource groupItem) throws DatabaseException { + public Double calculateThrottledStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource groupItem) throws DatabaseException { DiagramSettings ds = graph.syncRequest(new DiagramSettingsRequest(runtimeDiagram), TransientCacheAsyncListener.instance()); Double scaling = ONE; if (ds.vertexScaleProperty.isPresent()) { @@ -35,7 +34,7 @@ public class VertexSizeStyle extends StyleBase { } @Override - public void applyStyleForNode(EvaluationContext observer, INode node, Double value) { + public void applyThrottledStyleForNode(EvaluationContext observer, INode node, Double value) { //System.out.println("apply: " + node + " : " + value); SingleElementNode n = (SingleElementNode) node; if (value == PENDING) { diff --git a/org.simantics.district.network/src/org/simantics/district/network/profile/VertexSymbolStyle.java b/org.simantics.district.network/src/org/simantics/district/network/profile/VertexSymbolStyle.java index 65304502..98078f82 100644 --- a/org.simantics.district.network/src/org/simantics/district/network/profile/VertexSymbolStyle.java +++ b/org.simantics.district.network/src/org/simantics/district/network/profile/VertexSymbolStyle.java @@ -3,7 +3,6 @@ package org.simantics.district.network.profile; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.exception.DatabaseException; -import org.simantics.diagram.profile.StyleBase; import org.simantics.district.network.ontology.DistrictNetworkResource; import org.simantics.scenegraph.INode; import org.simantics.scenegraph.g2d.G2DSceneGraph; @@ -12,11 +11,11 @@ import org.simantics.scenegraph.profile.EvaluationContext; import org.simantics.scenegraph.profile.common.ProfileVariables; import org.simantics.scl.runtime.function.Function; -public class VertexSymbolStyle extends StyleBase { +public class VertexSymbolStyle extends ThrottledStyleBase { @SuppressWarnings({ "rawtypes", "unchecked" }) @Override - public String calculateStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource groupItem) throws DatabaseException { + public String calculateThrottledStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource groupItem) throws DatabaseException { DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph); Resource symbolFunctionResource = graph.getPossibleObject(entry, DN.HasSymbolFunction); if (symbolFunctionResource == null) @@ -30,7 +29,7 @@ public class VertexSymbolStyle extends StyleBase { } @Override - public void applyStyleForNode(EvaluationContext observer, INode node, String value) { + public void applyThrottledStyleForNode(EvaluationContext observer, INode node, String value) { SingleElementNode n = (SingleElementNode) node; for (INode nn : n.getNodes()) ProfileVariables.claimNodeProperty(nn, "SVG", value, observer); -- 2.47.0