]> gerrit.simantics Code Review - simantics/district.git/blobdiff - org.simantics.district.network.ui/src/org/simantics/district/network/ui/participants/DynamicVisualisationContributionsParticipant.java
Improve HoverInfoStyle performance for district network diagrams
[simantics/district.git] / org.simantics.district.network.ui / src / org / simantics / district / network / ui / participants / DynamicVisualisationContributionsParticipant.java
index 690860620059dc9c7802b2bf7bfa0468c840692b..0e0bace92245003ed5b7fec4f22745a4c9a5ede5 100644 (file)
@@ -1,17 +1,34 @@
 package org.simantics.district.network.ui.participants;
 
 import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
 import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
 
+import org.simantics.Simantics;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.common.request.ReadRequest;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.district.network.ontology.DistrictNetworkResource;
+import org.simantics.district.network.profile.RuntimeDynamicVisualisationsRequest;
 import org.simantics.district.network.ui.DistrictDiagramViewer;
+import org.simantics.district.network.ui.nodes.DistrictNetworkHoverInfoNode;
 import org.simantics.district.network.ui.nodes.DynamicVisualisationContributionsNode;
+import org.simantics.district.network.ui.styles.DistrictNetworkHoverInfoStyle;
+import org.simantics.district.network.ui.styles.DistrictNetworkHoverInfoStyle.StyleResult;
 import org.simantics.district.network.visualisations.model.ColorBarOptions;
 import org.simantics.district.network.visualisations.model.DynamicColorContribution;
 import org.simantics.district.network.visualisations.model.DynamicSizeContribution;
+import org.simantics.district.network.visualisations.model.DynamicVisualisation;
 import org.simantics.district.network.visualisations.model.SizeBarOptions;
 import org.simantics.g2d.canvas.ICanvasContext;
 import org.simantics.g2d.canvas.impl.AbstractCanvasParticipant;
 import org.simantics.g2d.canvas.impl.SGNodeReflection.SGInit;
+import org.simantics.layer0.Layer0;
 import org.simantics.scenegraph.g2d.G2DParentNode;
 import org.simantics.scenegraph.g2d.events.EventHandlerReflection.EventHandler;
 import org.simantics.scenegraph.g2d.events.command.CommandEvent;
@@ -19,9 +36,15 @@ import org.simantics.utils.datastructures.hints.HintListenerAdapter;
 import org.simantics.utils.datastructures.hints.IHintContext.Key;
 import org.simantics.utils.datastructures.hints.IHintListener;
 import org.simantics.utils.datastructures.hints.IHintObservable;
+import org.simantics.utils.threads.IThreadWorkQueue;
+import org.simantics.utils.threads.ThreadUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class DynamicVisualisationContributionsParticipant extends AbstractCanvasParticipant {
 
+    private static final Logger LOGGER = LoggerFactory.getLogger(DynamicVisualisationContributionsParticipant.class);
+
     IHintListener hintListener = new HintListenerAdapter() {
         public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) {
             ICanvasContext cc = getContext();
@@ -34,7 +57,9 @@ public class DynamicVisualisationContributionsParticipant extends AbstractCanvas
     
     private DynamicVisualisationContributionsNode node;
     private AffineTransform transform;
-    
+
+    private DistrictNetworkHoverInfoNode hoverInfoNode;
+
     public DynamicVisualisationContributionsParticipant(AffineTransform tr) {
         this.transform = tr;
     }
@@ -63,6 +88,11 @@ public class DynamicVisualisationContributionsParticipant extends AbstractCanvas
         node.setTransform(transform);
         node.setEnabled(true);
         node.setZIndex(1000);
+        
+        hoverInfoNode = parent.addNode("districtNetworkHoverInfoNode", DistrictNetworkHoverInfoNode.class);
+        hoverInfoNode.setLookupId("districtNetworkHoverInfoNode");
+        hoverInfoNode.setTransform(transform);
+        hoverInfoNode.setZIndex(Integer.MAX_VALUE - 500);
     }
     
     @EventHandler(priority = 0)
@@ -113,4 +143,80 @@ public class DynamicVisualisationContributionsParticipant extends AbstractCanvas
         SizeBarOptions options = getHint(DistrictDiagramViewer.KEY_MAP_SIZE_BAR_OPTIONS);
         return options;
     }
+
+    private ScheduledFuture<?> hoverUpdateSchedule;
+    
+    public void hoverNode(Resource runtimeDiagram, Resource mapElement, G2DParentNode hoveredNode) {
+        IThreadWorkQueue thread = getThread();
+        Simantics.getSession().asyncRequest(new ReadRequest() {
+
+            @Override
+            public void run(ReadGraph graph) throws DatabaseException {
+                DynamicVisualisation visualisation = graph.syncRequest(new RuntimeDynamicVisualisationsRequest(runtimeDiagram));
+                if (visualisation == null)
+                    return;
+                if (hoverUpdateSchedule != null && !hoverUpdateSchedule.isDone()) {
+                    hoverUpdateSchedule.cancel(false);
+                }
+                hoverUpdateSchedule = ThreadUtils.getNonBlockingWorkExecutor().scheduleWithFixedDelay(() -> {
+                    
+                    CompletableFuture<Object> future = new CompletableFuture<>();
+                    try {
+                        Simantics.getSession().syncRequest(new ReadRequest() {
+
+                            @Override
+                            public void run(ReadGraph graph) throws DatabaseException {
+                                boolean keyVariablesVertexHover = visualisation.isKeyVariablesVertexHover();
+                                boolean keyVariablesEdgesHover = visualisation.isKeyVariablesEdgesHover();
+                                
+                                Resource mapElementInstanceOf = graph.getSingleObject(mapElement, Layer0.getInstance(graph).InstanceOf);
+                                DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+                                
+                                boolean doHover = true;
+                                if (mapElementInstanceOf.equals(DN.Vertex) && !keyVariablesVertexHover) {
+                                    doHover = false;
+                                } else if (mapElementInstanceOf.equals(DN.Edge) && !keyVariablesEdgesHover) {
+                                    doHover = false;
+                                }
+                                final boolean finalDoHover = doHover;
+                                
+                                StyleResult results = DistrictNetworkHoverInfoStyle.doCalculateStyleResult(graph, runtimeDiagram, mapElement);
+                                if (results != null) {
+                                    Point2D location = DistrictNetworkHoverInfoStyle.calculatePoint(graph, mapElement);
+                                    thread.asyncExec(() -> {
+                                        if (isRemoved())
+                                            return;
+                                        if (finalDoHover) {
+                                            hoverInfoNode.setLabels(results.getLabels());
+                                            hoverInfoNode.setOrigin(results.getOrigin());
+                                            
+                                            hoverInfoNode.setMousePosition(location);
+                                            hoverInfoNode.hover2(hoveredNode);
+                                        } else {
+                                            hoverInfoNode.hover2(null);
+                                        }
+                                        future.complete(new Object());
+                                    });
+                                } else {
+                                    future.complete(new Object());
+                                }
+                            }
+                        });
+                    } catch (DatabaseException e) {
+                        future.completeExceptionally(e);
+                    }
+                    // this waits until everything is done
+                    try {
+                        future.get();
+                    } catch (InterruptedException | ExecutionException e) {
+                        LOGGER.debug("Interrupted hovering", e);
+                    }
+                }, 0, visualisation.getInterval(), TimeUnit.MILLISECONDS);
+            }
+        });
+    }
+
+    public boolean doHover(boolean hover, boolean isConnectionTool) {
+        return hoverInfoNode.hover(hover, isConnectionTool);
+    }
 }