]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/GraphToDiagramSynchronizer.java
Diagram threading and ThreadLogger improvements
[simantics/platform.git] / bundles / org.simantics.diagram / src / org / simantics / diagram / adapter / GraphToDiagramSynchronizer.java
index e2c1521ee45b21c6e63dc166535d645b60e0354e..226f47daa76b62ea90f572d561aa75e6bc830295 100644 (file)
@@ -11,9 +11,6 @@
  *******************************************************************************/
 package org.simantics.diagram.adapter;
 
-import gnu.trove.map.hash.TObjectIntHashMap;
-import gnu.trove.set.hash.THashSet;
-
 import java.awt.geom.AffineTransform;
 import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayDeque;
@@ -158,6 +155,11 @@ import org.simantics.utils.strings.EString;
 import org.simantics.utils.threads.ThreadUtils;
 import org.simantics.utils.threads.logger.ITask;
 import org.simantics.utils.threads.logger.ThreadLogger;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import gnu.trove.map.hash.TObjectIntHashMap;
+import gnu.trove.set.hash.THashSet;
 
 /**
  * This class loads a diagram contained in the graph database into the runtime
@@ -250,6 +252,8 @@ import org.simantics.utils.threads.logger.ThreadLogger;
  */
 public class GraphToDiagramSynchronizer extends AbstractDisposable implements IDiagramLoader, IModifiableSynchronizationContext {
 
+    private static final Logger LOGGER = LoggerFactory.getLogger(GraphToDiagramSynchronizer.class);
+
     /**
      * Controls whether the class adds hint listeners to each diagram element
      * that try to perform basic sanity checks on changes happening in element
@@ -612,6 +616,17 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
      */
     ConcurrentMap<Object, ConnectionEntityImpl> dataConnection = new ConcurrentHashMap<Object, ConnectionEntityImpl>();
 
+
+    void mapElementIfNew(final Object data, final IElement element) {
+        IElement mapped = getMappedElement(data);
+        if(mapped == null) {
+            mapElement(data, element);
+            currentUpdater.addedElements.add(element);
+            currentUpdater.addedElementMap.put(data, element);
+        }
+    }
+
+    
     /**
      * @param data
      * @param element
@@ -1111,7 +1126,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
             }
         } catch (InterruptedException e) {
             // Shouldn't happen.
-            e.printStackTrace();
+            LOGGER.error("Dispose interrupted!", e);
         } finally {
             detachSessionListener();
 
@@ -1343,7 +1358,11 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                     g.getSession().asyncRequest(new AsyncReadRequest() {
                         @Override
                         public void run(AsyncReadGraph graph) {
-                            profileObserver.listen(graph, GraphToDiagramSynchronizer.this);
+                          ProfileObserver po = profileObserver;
+                            if (po != null)
+                                po.listen(graph, GraphToDiagramSynchronizer.this);
+                            else
+                                LOGGER.info("profileObserver has been disposed already!");
                         }
                     });
 
@@ -1630,7 +1649,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
             this.removedRouteGraphConnections.clear();
         }
 
-        void processNodes(ReadGraph graph) throws DatabaseException {
+        void processNodes(AsyncReadGraph graph) throws DatabaseException {
 
             for (Map.Entry<Resource, Change> entry : changes.elements.entrySet()) {
 
@@ -1722,7 +1741,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                                     }
                                 };
 
-                                graph.syncRequest(new ConnectionRequest(canvas, diagram, element, errorHandler, loadListener), new AsyncProcedure<IElement>() {
+                                graph.asyncRequest(new ConnectionRequest(canvas, diagram, element, errorHandler, loadListener), new AsyncProcedure<IElement>() {
                                     @Override
                                     public void execute(AsyncReadGraph graph, final IElement e) {
 
@@ -1736,9 +1755,15 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                                             @Override
                                             public void execute(Resource connectionType) {
                                                 synchronized (GraphToDiagramUpdater.this) {
+                                                    IElement mapped = getMappedElement(element);
+                                                    assert(mapped != null);
+                                                    
+                                                    if (DebugPolicy.DEBUG_CONNECTION_LISTENER)
+                                                        System.out.println("CONNECTION ENTITY CREATED " + e + " " + element);
+
                                                     //System.out.println("new connection entity " + e);
-                                                    ConnectionEntityImpl entity = new ConnectionEntityImpl(element, connectionType, e);
-                                                    e.setHint(ElementHints.KEY_CONNECTION_ENTITY, entity);
+                                                    ConnectionEntityImpl entity = new ConnectionEntityImpl(element, connectionType, mapped);
+                                                    mapped.setHint(ElementHints.KEY_CONNECTION_ENTITY, entity);
                                                     addedConnectionEntities.put(element, entity);
                                                 }
                                             }
@@ -1825,7 +1850,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                                 };
 
                                 //System.out.println("NODE REQUEST: " + element);
-                                graph.syncRequest(new NodeRequest(canvas, diagram, element, loadListener), new AsyncProcedure<IElement>() {
+                                graph.asyncRequest(new NodeRequest(canvas, diagram, element, loadListener), new AsyncProcedure<IElement>() {
                                     @Override
                                     public void execute(AsyncReadGraph graph, IElement e) {
                                     }
@@ -2080,7 +2105,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
             return assertMappedConnection(connection);
         }
 
-        void processBranchPoints(ReadGraph graph) throws DatabaseException {
+        void processBranchPoints(AsyncReadGraph graph) throws DatabaseException {
             for (Map.Entry<Resource, Change> entry : changes.branchPoints.entrySet()) {
 
                 final Resource element = entry.getKey();
@@ -2091,7 +2116,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                         IElement mappedElement = getMappedElement(element);
                         if (mappedElement == null) {
                             if (DebugPolicy.DEBUG_NODE_LOAD)
-                                graph.syncRequest(new ReadRequest() {
+                                graph.asyncRequest(new ReadRequest() {
                                     @Override
                                     public void run(ReadGraph graph) throws DatabaseException {
                                         System.out.println("    EXTERNALLY ADDED BRANCH POINT: "
@@ -2161,7 +2186,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                                 }
                             };
 
-                            graph.syncRequest(new NodeRequest(canvas, diagram, element, loadListener), new AsyncProcedure<IElement>() {
+                            graph.asyncRequest(new NodeRequest(canvas, diagram, element, loadListener), new AsyncProcedure<IElement>() {
                                 @Override
                                 public void execute(AsyncReadGraph graph, IElement e) {
                                 }
@@ -2195,7 +2220,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
             }
         }
 
-        void processConnectionSegments(ReadGraph graph) throws DatabaseException {
+        void processConnectionSegments(AsyncReadGraph graph) throws DatabaseException {
             ConnectionSegmentAdapter adapter = connectionSegmentAdapter;
 
             for (Map.Entry<EdgeResource, Change> entry : changes.connectionSegments.entrySet()) {
@@ -2207,7 +2232,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                         IElement mappedElement = getMappedElement(seg);
                         if (mappedElement == null) {
                             if (DebugPolicy.DEBUG_EDGE_LOAD)
-                                graph.syncRequest(new ReadRequest() {
+                                graph.asyncRequest(new ReadRequest() {
                                     @Override
                                     public void run(ReadGraph graph) throws DatabaseException {
                                         System.out.println("    EXTERNALLY ADDED CONNECTION SEGMENT: " + seg.toString()
@@ -2215,13 +2240,13 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                                     }
                                 });
 
-                            graph.syncRequest(new EdgeRequest(canvas, errorHandler, canvasListenerSupport, diagram, adapter, seg), new AsyncProcedure<IElement>() {
+                            graph.asyncRequest(new EdgeRequest(GraphToDiagramSynchronizer.this, canvas, errorHandler, canvasListenerSupport, diagram, adapter, seg), new AsyncProcedure<IElement>() {
                                 @Override
                                 public void execute(AsyncReadGraph graph, IElement e) {
                                     if (DebugPolicy.DEBUG_EDGE_LOAD)
-                                        System.out.println("ADDED EDGE LOADED: " + e);
+                                        System.out.println("ADDED EDGE LOADED: " + e + " " + seg);
+
                                     if (e != null) {
-                                        mapElement(seg, e);
                                         synchronized (GraphToDiagramUpdater.this) {
                                             addedConnectionSegments.add(e);
                                             addedElementMap.put(seg, e);
@@ -2243,7 +2268,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                     case REMOVED: {
                         final IElement e = getMappedElement(seg);
                         if (DebugPolicy.DEBUG_EDGE_LOAD)
-                            graph.syncRequest(new ReadRequest() {
+                            graph.asyncRequest(new ReadRequest() {
                                 @Override
                                 public void run(ReadGraph graph) throws DatabaseException {
                                     System.out.println("    EXTERNALLY REMOVED CONNECTION SEGMENT: " + seg.toString() + " - "
@@ -2294,13 +2319,15 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
             if (changes.isEmpty())
                 return;
 
+            ITask threadLog = ThreadLogger.task("processNodes");
+            
             // NOTE: This order is important.
             Object task = Timing.BEGIN("processNodesConnections");
             //System.out.println("---- PROCESS NODES & CONNECTIONS BEGIN");
             if (!changes.elements.isEmpty()) {
-                graph.syncRequest(new ReadRequest() {
+                graph.syncRequest(new AsyncReadRequest() {
                     @Override
-                    public void run(ReadGraph graph) throws DatabaseException {
+                    public void run(AsyncReadGraph graph) throws DatabaseException {
                         processNodes(graph);
                     }
                     @Override
@@ -2311,13 +2338,21 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
             }
             //System.out.println("---- PROCESS NODES & CONNECTIONS END");
 
+            threadLog.finish();
+            
+            threadLog = ThreadLogger.task("processConnections");
+
             processConnections();
 
+            threadLog.finish();
+
+            threadLog = ThreadLogger.task("processBranchPoints");
+
             //System.out.println("---- PROCESS BRANCH POINTS BEGIN");
             if (!changes.branchPoints.isEmpty()) {
-                graph.syncRequest(new ReadRequest() {
+                graph.syncRequest(new AsyncReadRequest() {
                     @Override
-                    public void run(ReadGraph graph) throws DatabaseException {
+                    public void run(AsyncReadGraph graph) throws DatabaseException {
                         processBranchPoints(graph);
                     }
                     @Override
@@ -2328,14 +2363,19 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
             }
             //System.out.println("---- PROCESS BRANCH POINTS END");
 
+            threadLog.finish();
+
             Timing.END(task);
+
+            threadLog = ThreadLogger.task("processConnectionSegments");
+
             task = Timing.BEGIN("processConnectionSegments");
 
             //System.out.println("---- PROCESS CONNECTION SEGMENTS BEGIN");
             if (!changes.connectionSegments.isEmpty()) {
-                graph.syncRequest(new ReadRequest() {
+                graph.syncRequest(new AsyncReadRequest() {
                     @Override
-                    public void run(ReadGraph graph) throws DatabaseException {
+                    public void run(AsyncReadGraph graph) throws DatabaseException {
                         processConnectionSegments(graph);
                     }
                     @Override
@@ -2346,8 +2386,12 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
             }
             //System.out.println("---- PROCESS CONNECTION SEGMENTS END");
 
+            threadLog.finish();
+
             Timing.END(task);
 
+            threadLog = ThreadLogger.task("processRouteGraphConnections");
+
             task = Timing.BEGIN("processRouteGraphConnections");
             if (!changes.routeGraphConnections.isEmpty()) {
                 graph.syncRequest(new ReadRequest() {
@@ -2363,6 +2407,8 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
             }
             Timing.END(task);
 
+            threadLog.finish();
+
             //System.out.println("---- AFTER LOADING");
             //for (IElement e : addedElements)
             //    System.out.println("    ADDED ELEMENT: " + e);
@@ -2370,7 +2416,12 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
             //    System.out.println("    ADDED BRANCH POINTS: " + e);
 
             task = Timing.BEGIN("executeDeferredLoaders");
+            threadLog = ThreadLogger.task("executeDeferredLoaders");
+            
             executeDeferredLoaders(graph);
+
+            threadLog.finish();
+
             Timing.END(task);
         }
 
@@ -2420,8 +2471,6 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                     @Override
                     public void execute(IElement loaded) {
                         // Invoked when the element has been loaded.
-                        if (DebugPolicy.DEBUG_EDGE_LISTENER)
-                            System.out.println("EDGE LoadListener for " + loaded);
 
                         if (loaded == null) {
                             disposeListener();
@@ -2429,6 +2478,10 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                         }
 
                         Object data = loaded.getHint(ElementHints.KEY_OBJECT);
+
+                        if (DebugPolicy.DEBUG_EDGE_LISTENER)
+                            System.out.println("EDGE LoadListener for " + loaded + " " + data);
+
                         if (addedElementMap.containsKey(data)) {
                             // This element was just loaded, in
                             // which case its hints need to
@@ -3456,7 +3509,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                 Resource resource = ElementUtils.adapt(ec, Resource.class);
                 if (resource == null) {
                     pass = false;
-                    new Exception("Attempted to add an element to the diagram that is not adaptable to Resource: " + e + ", class: " + ec).printStackTrace();
+                    LOGGER.error("", new Exception("Attempted to add an element to the diagram that is not adaptable to Resource: " + e + ", class: " + ec));
                 }
 
                 // Sanity check connection hints