]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scenegraph.profile/src/org/simantics/scenegraph/profile/common/ProfileObserver.java
Preliminary implementation to update only changed profile entries
[simantics/platform.git] / bundles / org.simantics.scenegraph.profile / src / org / simantics / scenegraph / profile / common / ProfileObserver.java
index efac19055944c8a2ab3bc713dd3100647755d9f8..9d379c890b9bd952a3ac2b6db941b3c71acc07c6 100644 (file)
  *******************************************************************************/
 package org.simantics.scenegraph.profile.common;
 
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.concurrent.TimeUnit;
 
@@ -28,9 +30,11 @@ import org.simantics.scenegraph.INode;
 import org.simantics.scenegraph.g2d.G2DSceneGraph;
 import org.simantics.scenegraph.profile.EvaluationContext;
 import org.simantics.scenegraph.profile.ProfileEntry;
+import org.simantics.scenegraph.profile.Style;
 import org.simantics.scenegraph.profile.impl.DebugPolicy;
 import org.simantics.scenegraph.profile.impl.ProfileActivationListener;
 import org.simantics.scenegraph.profile.request.RuntimeProfileActiveEntries;
+import org.simantics.utils.datastructures.Pair;
 import org.simantics.utils.datastructures.disposable.IDisposable;
 import org.simantics.utils.threads.IThreadWorkQueue;
 import org.simantics.utils.threads.ThreadUtils;
@@ -51,9 +55,12 @@ public class ProfileObserver implements EvaluationContext {
     private final Runnable                    notification;
     private final G2DSceneGraph               sceneGraph;
 
-    private boolean                           dirty               = true;
-    private boolean                           disposed            = false;
+    private volatile boolean                  dirty               = true;
+    private volatile boolean                  disposed            = false;
 
+    private List<Pair<Style, Object>>         updates             = new ArrayList<>();
+    private boolean                           updateAll;
+    
     private ProfileActivationListener         activationListener;
 
     private Map<String, Object>               constants           = new HashMap<String, Object>();
@@ -129,12 +136,20 @@ public class ProfileObserver implements EvaluationContext {
     }
 
     @Override
-    public void update() {
+    public void update(Style style, Object item) {
         if (DebugPolicy.DEBUG_PROFILE_OBSERVER_UPDATE)
             System.out.println("Profile observer marked dirty.");
+        
+        updates.add(Pair.make(style, item));
+        //updateAll = true;
         dirty = true;
     }
 
+    public void update() {
+        updateAll = true;
+        dirty = true;
+    }
+    
     private void perform() {
         dirty = false;
         if (DebugPolicy.DEBUG_PROFILE_OBSERVER_UPDATE)
@@ -148,39 +163,39 @@ public class ProfileObserver implements EvaluationContext {
                     return;
 
                 ThreadUtils.asyncExec(thread, new Runnable() {
-                    
-//                    private void init(INode node) {
-//                        //ProfileVariables.init(node, ProfileObserver.this);
-////                        NodeUtil.forChildren(node, new NodeProcedure<Object>() {
-////                            @Override
-////                            public Object execute(INode node, String id) {
-////                                init(node);
-////                                return null;
-////                            }
-////                        }, null);
-//                    }
-
                     @Override
                     public void run() {
-
                         if (isDisposed())
                             return;
 
                         temporaryProperties.clear();
 
-//                        init(sceneGraph);
-
-//                        for(IElement e : diagram.getElements()) {
-//                            Node node = NodeUtils.
-//                            Variables.init(e, ProfileObserver.this);
-//                        }
-
-                        for(ProfileEntry e : entries) {
-                            if (DebugPolicy.DEBUG_PROFILE_OBSERVER_PERFORM)
-                                System.out.println("Apply profile entry: " + e);
-                            e.apply(ProfileObserver.this);
+                        long t0 = DebugPolicy.DEBUG_PROFILE_OBSERVER_PERFORM ? System.nanoTime() : 0L;
+                        
+                        if (updateAll) {
+                            for(ProfileEntry e : entries) {
+                                if (DebugPolicy.DEBUG_PROFILE_OBSERVER_PERFORM)
+                                    System.out.println("Apply profile entry: " + e);
+                                e.apply(ProfileObserver.this);
+                            }
+                            updateAll = false;
+                            updates.clear();
+                        } else {
+                            List<Pair<Style, Object>> updatesCopy = new ArrayList<>(updates);
+                            updates.clear();
+                            for (Pair<Style, Object> update : updatesCopy) {
+                                Style style = update.first;
+                                Object item = update.second;
+                                
+                                style.apply2(item, ProfileObserver.this);
+                            }
                         }
 
+                        if (DebugPolicy.DEBUG_PROFILE_OBSERVER_PERFORM) {
+                            long t1 = System.nanoTime();
+                            System.out.println((t1-t0) / 1e6);
+                        }
+                        
                         if(dirty) {
                                sceneGraph.setPending(ProfileObserver.this);
 //                             System.err.println("setPending, dirty=true");
@@ -194,21 +209,12 @@ public class ProfileObserver implements EvaluationContext {
 //                        canvas.getContentContext().setDirty();
                         
                         // Something is underway, schedule update
-                        if(dirty) {
-                               Simantics.async(new Runnable() {
-
-                                                               @Override
-                                                               public void run() {
-
-                                                           if (isDisposed()) return;
-                                                           
-                                                                       if(dirty) perform();
-                                                                       
-                                                               }
-                                       
-                               }, 100, TimeUnit.MILLISECONDS);
+                        if (dirty) {
+                            Simantics.async(() -> {
+                                if (isDisposed()) return;
+                                if (dirty) perform();
+                            }, 100, TimeUnit.MILLISECONDS);
                         }
-
                     }
                 });
             }