]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/GraphToDiagramSynchronizer.java
Multiple readers in db client
[simantics/platform.git] / bundles / org.simantics.diagram / src / org / simantics / diagram / adapter / GraphToDiagramSynchronizer.java
index 226f47daa76b62ea90f572d561aa75e6bc830295..37471eb3a1186fa8dc1c993e7d0f267f178a5f91 100644 (file)
@@ -138,6 +138,7 @@ import org.simantics.scenegraph.INode;
 import org.simantics.scenegraph.profile.DataNodeConstants;
 import org.simantics.scenegraph.profile.DataNodeMap;
 import org.simantics.scenegraph.profile.common.ProfileObserver;
+import org.simantics.scl.runtime.tuple.Tuple3;
 import org.simantics.structural2.modelingRules.IModelingRules;
 import org.simantics.utils.datastructures.ArrayMap;
 import org.simantics.utils.datastructures.MapSet;
@@ -1649,6 +1650,90 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
             this.removedRouteGraphConnections.clear();
         }
 
+        class LoadNodeListener extends DisposableListener<IElement> {
+
+            final Resource element;
+            public IElement lastLoaded;
+
+            public LoadNodeListener(ListenerSupport support, Resource element) {
+                super(support);
+                this.element = element;
+            }
+
+            @Override
+            public String toString() {
+                return "Node load listener for " + element;
+            }
+
+            public void applyFirst(IElement loaded) {
+
+                Object data = loaded.getHint(ElementHints.KEY_OBJECT);
+
+                if (addedElementMap.containsKey(data)) {
+                    // This element was just loaded, in
+                    // which case its hints need to
+                    // uploaded to the real mapped
+                    // element immediately.
+                    IElement mappedElement = getMappedElement(data);
+                    if (DebugPolicy.DEBUG_NODE_LISTENER)
+                        System.out.println("LOADED ADDED ELEMENT, currently mapped element: " + mappedElement);
+                    if (mappedElement != null && (mappedElement instanceof Element)) {
+                        if (DebugPolicy.DEBUG_NODE_LISTENER) {
+                            System.out.println("  mapped hints: " + mappedElement.getHints());
+                            System.out.println("  loaded hints: " + loaded.getHints());
+                        }
+                        updateMappedElement((Element) mappedElement, loaded);
+                    }
+                }
+
+            }
+
+            @Override
+            public void execute(IElement loaded) {
+
+                // Invoked when the element has been loaded.
+                if (DebugPolicy.DEBUG_NODE_LISTENER)
+                    System.out.println("NODE LoadListener for " + loaded);
+
+                if (loaded == null) {
+                    disposeListener();
+                    return;
+                }
+
+
+                boolean first = lastLoaded == null;
+
+                lastLoaded = loaded;
+
+                /*
+                 * The first invocation is postponed
+                 */
+                if(first) {
+                    applyFirst(loaded);
+                    return;
+                }
+
+                Object data = loaded.getHint(ElementHints.KEY_OBJECT);
+
+                // Logic for disposing listener
+                if (!previousContent.nodeSet.contains(data)) {
+                    if (DebugPolicy.DEBUG_NODE_LISTENER)
+                        System.out.println("NODE LoadListener, node not in current content: " + data + ". Disposing.");
+                    disposeListener();
+                    return;
+                }
+
+                // This element was already loaded.
+                // Just schedule an update some time
+                // in the future.
+                if (DebugPolicy.DEBUG_NODE_LISTENER)
+                    System.out.println("PREVIOUSLY LOADED NODE UPDATED, scheduling update into the future");
+                offerGraphUpdate( nodeUpdater(element, loaded) );
+
+            }
+
+        }
+
         void processNodes(AsyncReadGraph graph) throws DatabaseException {
 
             for (Map.Entry<Resource, Change> entry : changes.elements.entrySet()) {
@@ -1745,6 +1830,13 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                                     @Override
                                     public void execute(AsyncReadGraph graph, final IElement e) {
 
+                                        mapElement(element, e);
+                                        synchronized (GraphToDiagramUpdater.this) {
+                                            addedElements.add(e);
+                                            addedElementMap.put(element, e);
+                                            addedConnectionMap.put(element, e);
+                                        }
+
                                         // Read connection type
                                         graph.forSingleType(element, br.DIA.Connection, new Procedure<Resource>() {
                                             @Override
@@ -1778,87 +1870,33 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                                 });
                             } else if (content.nodeSet.contains(element)) {
 
-                                Listener<IElement> loadListener = new DisposableListener<IElement>(canvasListenerSupport) {
-
-                                    boolean firstTime = true;
+                                graph.asyncRequest(new ReadRequest() {
 
                                     @Override
-                                    public String toString() {
-                                        return "Node load listener for " + element;
-                                    }
-                                    @Override
-                                    public void execute(IElement loaded) {
-                                        // Invoked when the element has been loaded.
-                                        if (DebugPolicy.DEBUG_NODE_LISTENER)
-                                            System.out.println("NODE LoadListener for " + loaded);
-
-                                        if (loaded == null) {
-                                            disposeListener();
-                                            return;
-                                        }
-
-                                        if (firstTime) {
-
-                                            // This is invoked before the element is actually loaded.
-                                            //System.out.println("NodeRequestProcedure " + e);
-                                            if (DebugPolicy.DEBUG_NODE_LOAD)
-                                                System.out.println("MAPPING ADDED NODE: " + element + " -> " + loaded);
-                                            mapElement(element, loaded);
-                                            synchronized (GraphToDiagramUpdater.this) {
-                                                addedElements.add(loaded);
-                                                addedElementMap.put(element, loaded);
-                                            }
-
-                                            firstTime = false;
-
-                                        }
-
-                                        Object data = loaded.getHint(ElementHints.KEY_OBJECT);
+                                    public void run(ReadGraph graph) throws DatabaseException {
 
-                                        // Logic for disposing listener
-                                        if (!previousContent.nodeSet.contains(data)) {
-                                            if (DebugPolicy.DEBUG_NODE_LISTENER)
-                                                System.out.println("NODE LoadListener, node not in current content: " + data + ". Disposing.");
-                                            disposeListener();
+                                        LoadNodeListener loadListener = new LoadNodeListener(canvasListenerSupport, element);
+                                        Tuple3 t = graph.syncRequest(new NodeRequest2(canvas, diagram, element));
+                                        IElement e = (IElement)t.c0;
+                                        ElementClass ec = (ElementClass)t.c1;
+                                        org.simantics.diagram.adapter.ElementFactory ef = (org.simantics.diagram.adapter.ElementFactory)t.c2;
+                                        if (e == null)
                                             return;
+                                        
+                                        // This is invoked before the element is actually loaded.
+                                        //System.out.println("NodeRequestProcedure " + e);
+                                        if (DebugPolicy.DEBUG_NODE_LOAD)
+                                            System.out.println("MAPPING ADDED NODE: " + element + " -> " + e);
+                                        mapElement(element, e);
+                                        synchronized (GraphToDiagramUpdater.this) {
+                                            addedElements.add(e);
+                                            addedElementMap.put(element, e);
                                         }
 
-                                        if (addedElementMap.containsKey(data)) {
-                                            // This element was just loaded, in
-                                            // which case its hints need to
-                                            // uploaded to the real mapped
-                                            // element immediately.
-                                            IElement mappedElement = getMappedElement(data);
-                                            if (DebugPolicy.DEBUG_NODE_LISTENER)
-                                                System.out.println("LOADED ADDED ELEMENT, currently mapped element: " + mappedElement);
-                                            if (mappedElement != null && (mappedElement instanceof Element)) {
-                                                if (DebugPolicy.DEBUG_NODE_LISTENER) {
-                                                    System.out.println("  mapped hints: " + mappedElement.getHints());
-                                                    System.out.println("  loaded hints: " + loaded.getHints());
-                                                }
-                                                updateMappedElement((Element) mappedElement, loaded);
-                                            }
-                                        } else {
-                                            // This element was already loaded.
-                                            // Just schedule an update some time
-                                            // in the future.
-                                            if (DebugPolicy.DEBUG_NODE_LISTENER)
-                                                System.out.println("PREVIOUSLY LOADED NODE UPDATED, scheduling update into the future");
-                                            offerGraphUpdate( nodeUpdater(element, loaded) );
-                                        }
-                                    }
-                                };
-
-                                //System.out.println("NODE REQUEST: " + element);
-                                graph.asyncRequest(new NodeRequest(canvas, diagram, element, loadListener), new AsyncProcedure<IElement>() {
-                                    @Override
-                                    public void execute(AsyncReadGraph graph, IElement e) {
-                                    }
-
-                                    @Override
-                                    public void exception(AsyncReadGraph graph, Throwable throwable) {
-                                        error(throwable);
+                                        graph.syncRequest(new LoadRequest(canvas, diagram, ef, ec, element), loadListener);
+                                        
                                     }
+                                    
                                 });
 
                             } else {
@@ -1980,8 +2018,121 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                 }
             }
         }
+        
+        class LoadRouteGraphConnectionListener extends DisposableListener<IElement> {
+            
+            final Resource connection;
+            public IElement lastLoaded;
+
+            public LoadRouteGraphConnectionListener(ListenerSupport support, Resource connection) {
+                super(support);
+                this.connection = connection;
+            }
+
+            @Override
+            public String toString() {
+                return "processRouteGraphConnections " + connection;
+            }
+            
+            public void applyFirst(IElement loaded) {
+                
+                Object data = loaded.getHint(ElementHints.KEY_OBJECT);
+                if (addedElementMap.containsKey(data)) {
+                    // This element was just loaded, in
+                    // which case its hints need to
+                    // uploaded to the real mapped
+                    // element immediately.
+                    IElement mappedElement = getMappedElement(data);
+                    if (DebugPolicy.DEBUG_CONNECTION_LISTENER)
+                        System.out.println("LOADED ADDED ROUTE GRAPH CONNECTION, currently mapped connection: " + mappedElement);
+                    if (mappedElement instanceof Element) {
+                        if (DebugPolicy.DEBUG_CONNECTION_LISTENER) {
+                            System.out.println("  mapped hints: " + mappedElement.getHints());
+                            System.out.println("  loaded hints: " + loaded.getHints());
+                        }
+                        updateMappedElement((Element) mappedElement, loaded);
+                    }
+                }
+                
+            }
+            
+            @Override
+            public void execute(IElement loaded) {
+                
+                // Invoked when the element has been loaded.
+                if (DebugPolicy.DEBUG_CONNECTION_LISTENER)
+                    System.out.println("ROUTE GRAPH CONNECTION LoadListener for " + loaded);
+
+                if (loaded == null) {
+                    disposeListener();
+                    return;
+                }
+
+                boolean first = lastLoaded == null;
+
+                lastLoaded = loaded;
+                
+                /*
+                 * The first invocation is postponed
+                 */
+                if(first) {
+                    applyFirst(loaded);
+                    return;
+                }
+
+                Object data = loaded.getHint(ElementHints.KEY_OBJECT);
+
+                // Logic for disposing listener
+                if (!previousContent.routeGraphConnectionSet.contains(data)) {
+                    if (DebugPolicy.DEBUG_CONNECTION_LISTENER)
+                        System.out.println("ROUTE GRAPH CONNECTION LoadListener, connection not in current content: " + data + ". Disposing.");
+                    disposeListener();
+                    return;
+                }
+
+                if (addedElementMap.containsKey(data)) {
+                    // This element was just loaded, in
+                    // which case its hints need to
+                    // uploaded to the real mapped
+                    // element immediately.
+                    IElement mappedElement = getMappedElement(data);
+                    if (DebugPolicy.DEBUG_CONNECTION_LISTENER)
+                        System.out.println("LOADED ADDED ROUTE GRAPH CONNECTION, currently mapped connection: " + mappedElement);
+                    if (mappedElement instanceof Element) {
+                        if (DebugPolicy.DEBUG_CONNECTION_LISTENER) {
+                            System.out.println("  mapped hints: " + mappedElement.getHints());
+                            System.out.println("  loaded hints: " + loaded.getHints());
+                        }
+                        updateMappedElement((Element) mappedElement, loaded);
+                    }
+                } else {
+                    // This element was already loaded.
+                    // Just schedule an update some time
+                    // in the future.
+                    if (DebugPolicy.DEBUG_CONNECTION_LISTENER)
+                        System.out.println("PREVIOUSLY LOADED ROUTE GRAPH CONNECTION UPDATED, scheduling update into the future: " + connection);
+
+                    Set<Object> dirtyNodes = new THashSet<Object>(4);
+                    IElement mappedElement = getMappedElement(connection);
+                    ConnectionEntity ce = mappedElement.getHint(ElementHints.KEY_CONNECTION_ENTITY);
+                    if (ce != null) {
+                        for (Connection conn : ce.getTerminalConnections(null)) {
+                            Object o = conn.node.getHint(ElementHints.KEY_OBJECT);
+                            if (o != null) {
+                                dirtyNodes.add(o);
+                                if (DebugPolicy.DEBUG_CONNECTION_LISTENER)
+                                    System.out.println("Marked connectivity dirty for node: " + conn.node);
+                            }
+                        }
+                    }
+
+                    offerGraphUpdate( routeGraphConnectionUpdater(connection, loaded, dirtyNodes) );
+                }
+            }
+        };
 
-        void processRouteGraphConnections(ReadGraph graph) throws DatabaseException {
+
+        void processRouteGraphConnections(AsyncReadGraph graph) throws DatabaseException {
             for (Map.Entry<Resource, Change> entry : changes.routeGraphConnections.entrySet()) {
                 final Resource connection = entry.getKey();
 
@@ -1992,97 +2143,39 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                         if (mappedElement != null)
                             continue;
 
-                        Listener<IElement> loadListener = new DisposableListener<IElement>(canvasListenerSupport) {
-
-                            boolean firstTime = true;
+                        
+                        graph.asyncRequest(new ReadRequest() {
 
                             @Override
-                            public String toString() {
-                                return "processRouteGraphConnections " + connection;
-                            }
-                            @Override
-                            public void execute(IElement loaded) {
-                                // Invoked when the element has been loaded.
-                                if (DebugPolicy.DEBUG_CONNECTION_LISTENER)
-                                    System.out.println("ROUTE GRAPH CONNECTION LoadListener for " + loaded);
+                            public void run(ReadGraph graph) throws DatabaseException {
 
-                                if (loaded == null) {
-                                    disposeListener();
-                                    return;
-                                }
-
-                                if(firstTime) {
-                                    if (DebugPolicy.DEBUG_NODE_LOAD)
-                                        System.out.println("MAPPING ADDED ROUTE GRAPH CONNECTION: " + connection + " -> " + loaded);
-                                    mapElement(connection, loaded);
-                                    synchronized (GraphToDiagramUpdater.this) {
-                                        addedElements.add(loaded);
-                                        addedElementMap.put(connection, loaded);
-                                        addedRouteGraphConnectionMap.put(connection, loaded);
-                                    }
-                                    firstTime = false;
-                                }
+                                LoadRouteGraphConnectionListener loadListener = new LoadRouteGraphConnectionListener(canvasListenerSupport, connection);
 
-                                Object data = loaded.getHint(ElementHints.KEY_OBJECT);
+                                Tuple3 t = graph.syncRequest(new ConnectionRequest2(canvas, diagram, connection, errorHandler));
+                                IElement e = (IElement)t.c0;
+                                ElementClass ec = (ElementClass)t.c1;
+                                org.simantics.diagram.adapter.ElementFactory ef = (org.simantics.diagram.adapter.ElementFactory)t.c2;
 
-                                // Logic for disposing listener
-                                if (!previousContent.routeGraphConnectionSet.contains(data)) {
-                                    if (DebugPolicy.DEBUG_CONNECTION_LISTENER)
-                                        System.out.println("ROUTE GRAPH CONNECTION LoadListener, connection not in current content: " + data + ". Disposing.");
-                                    disposeListener();
+                                if (e == null)
                                     return;
+
+                                //System.out.println("ConnectionRequestProcedure " + e);
+                                if (DebugPolicy.DEBUG_NODE_LOAD)
+                                    System.out.println("MAPPING ADDED ROUTE GRAPH CONNECTION: " + connection + " -> " + e);
+                                mapElement(connection, e);
+                                synchronized (GraphToDiagramUpdater.this) {
+                                    addedElements.add(e);
+                                    addedElementMap.put(connection, e);
+                                    addedRouteGraphConnectionMap.put(connection, e);
                                 }
 
-                                if (addedElementMap.containsKey(data)) {
-                                    // This element was just loaded, in
-                                    // which case its hints need to
-                                    // uploaded to the real mapped
-                                    // element immediately.
-                                    IElement mappedElement = getMappedElement(data);
-                                    if (DebugPolicy.DEBUG_CONNECTION_LISTENER)
-                                        System.out.println("LOADED ADDED ROUTE GRAPH CONNECTION, currently mapped connection: " + mappedElement);
-                                    if (mappedElement instanceof Element) {
-                                        if (DebugPolicy.DEBUG_CONNECTION_LISTENER) {
-                                            System.out.println("  mapped hints: " + mappedElement.getHints());
-                                            System.out.println("  loaded hints: " + loaded.getHints());
-                                        }
-                                        updateMappedElement((Element) mappedElement, loaded);
-                                    }
-                                } else {
-                                    // This element was already loaded.
-                                    // Just schedule an update some time
-                                    // in the future.
-                                    if (DebugPolicy.DEBUG_CONNECTION_LISTENER)
-                                        System.out.println("PREVIOUSLY LOADED ROUTE GRAPH CONNECTION UPDATED, scheduling update into the future: " + connection);
-
-                                    Set<Object> dirtyNodes = new THashSet<Object>(4);
-                                    IElement mappedElement = getMappedElement(connection);
-                                    ConnectionEntity ce = mappedElement.getHint(ElementHints.KEY_CONNECTION_ENTITY);
-                                    if (ce != null) {
-                                        for (Connection conn : ce.getTerminalConnections(null)) {
-                                            Object o = conn.node.getHint(ElementHints.KEY_OBJECT);
-                                            if (o != null) {
-                                                dirtyNodes.add(o);
-                                                if (DebugPolicy.DEBUG_CONNECTION_LISTENER)
-                                                    System.out.println("Marked connectivity dirty for node: " + conn.node);
-                                            }
-                                        }
-                                    }
+                                graph.syncRequest(new LoadRequest(canvas, diagram, ef, ec, connection), loadListener);
 
-                                    offerGraphUpdate( routeGraphConnectionUpdater(connection, loaded, dirtyNodes) );
-                                }
                             }
-                        };
 
-                        graph.syncRequest(new ConnectionRequest(canvas, diagram, connection, errorHandler, loadListener), new Procedure<IElement>() {
-                            @Override
-                            public void execute(final IElement e) {
-                            }
-                            @Override
-                            public void exception(Throwable throwable) {
-                                error(throwable);
-                            }
                         });
+
+
                         break;
                     }
                     case REMOVED: {
@@ -2127,8 +2220,6 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
 
                             Listener<IElement> loadListener = new DisposableListener<IElement>(canvasListenerSupport) {
 
-                                boolean firstTime = true;
-
                                 @Override
                                 public String toString() {
                                     return "processBranchPoints for " + element;
@@ -2144,21 +2235,6 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                                         return;
                                     }
 
-                                    if (firstTime) {
-
-                                        mapElement(element, loaded);
-                                        synchronized (GraphToDiagramUpdater.this) {
-                                            addedBranchPoints.add(loaded);
-                                            addedElementMap.put(element, loaded);
-                                            ConnectionEntityImpl ce = getConnectionEntity(element);
-                                            loaded.setHint(ElementHints.KEY_CONNECTION_ENTITY, ce);
-                                            loaded.setHint(ElementHints.KEY_PARENT_ELEMENT, ce.getConnectionElement());
-                                        }
-
-                                        firstTime = false;
-
-                                    }
-
                                     Object data = loaded.getHint(ElementHints.KEY_OBJECT);
                                     if (addedElementMap.containsKey(data)) {
                                         // This element was just loaded, in
@@ -2360,6 +2436,7 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
                         return "processBranchPoints";
                     }
                 });
+
             }
             //System.out.println("---- PROCESS BRANCH POINTS END");
 
@@ -2394,9 +2471,9 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
 
             task = Timing.BEGIN("processRouteGraphConnections");
             if (!changes.routeGraphConnections.isEmpty()) {
-                graph.syncRequest(new ReadRequest() {
+                graph.syncRequest(new AsyncReadRequest() {
                     @Override
-                    public void run(ReadGraph graph) throws DatabaseException {
+                    public void run(AsyncReadGraph graph) throws DatabaseException {
                         processRouteGraphConnections(graph);
                     }
                     @Override
@@ -2724,8 +2801,11 @@ public class GraphToDiagramSynchronizer extends AbstractDisposable implements ID
 
                 diagramUpdateLock.lock();
                 try {
-                    if (DebugPolicy.DEBUG_DIAGRAM_UPDATE)
+                    if (DebugPolicy.DEBUG_DIAGRAM_UPDATE) {
                         System.out.println("In diagramGraphUpdater:");
+                        System.out.println("-content = " + content);
+                        System.out.println("-previousContent = " + previousContent);
+                    }
 
                     // Find out what has changed since the last query.
                     Object task = Timing.BEGIN("diagramContentDifference");