]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/utils/NodeUtil.java
Merge branch 'feature/funcwrite'
[simantics/platform.git] / bundles / org.simantics.scenegraph / src / org / simantics / scenegraph / utils / NodeUtil.java
index 80b9a8a52c288207c5eb56f1c9ffc5989d0ddd5e..615899a59eef25676ff17b0cbdcb69ca0d62d1b8 100644 (file)
@@ -32,6 +32,7 @@ import java.util.concurrent.TimeUnit;
 import java.util.concurrent.locks.Condition;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
+import java.util.function.Function;
 
 import org.simantics.scenegraph.IDynamicSelectionPainterNode;
 import org.simantics.scenegraph.ILookupService;
@@ -276,6 +277,7 @@ public final class NodeUtil {
         printSceneGraph(System.out, 0, node);
     }
 
+    @FunctionalInterface
     public static interface NodeProcedure<T> {
         T execute(INode node, String id);
     }
@@ -324,6 +326,47 @@ public final class NodeUtil {
         return result;
     }
 
+    /**
+     * Recursively iterates through all child nodes of the specified node and
+     * for those nodes that are of class <code>ofClass</code>, invokes
+     * <code>consumer</code>.
+     * 
+     * @param node
+     * @param ofClass
+     * @param consumer
+     */
+    @SuppressWarnings("unchecked")
+    public static <T extends INode> INode forChildrenDeep(INode node, Class<T> ofClass, Function<T, INode> func) {
+        return forChildrenDeep(node, n -> ofClass.isInstance(n) ? func.apply((T) n) : null);
+    }
+
+    public static <T extends INode> INode forChildrenDeep(INode node, Function<INode, INode> func) {
+        INode ret = func.apply(node);
+        if (ret != null)
+            return ret;
+
+        if (node instanceof ParentNode<?>) {
+            if (node instanceof G2DParentNode) {
+                G2DParentNode g2dpn = (G2DParentNode) node;
+                for (IG2DNode n : g2dpn.getSortedNodes()) {
+                    INode r = forChildrenDeep(n, func);
+                    if (r != null) {
+                        return r;
+                    }
+                }
+            } else {
+                for (INode n : ((ParentNode<?>) node).getNodes()) {
+                    INode r = forChildrenDeep(n, func);
+                    if (r != null) {
+                        return r;
+                    }
+                }
+            }
+        }
+
+        return null;
+    }
+
     public static final int countTreeNodes(INode node) {
         int result = 1;
         if (node instanceof ParentNode<?>) {
@@ -336,11 +379,12 @@ public final class NodeUtil {
         return result;
     }
 
-    public static final void printTreeNodes(INode node, StringBuilder builder) {
+    public static final StringBuilder printTreeNodes(INode node, StringBuilder builder) {
         printTreeNodes(node, 0, builder);
+        return builder;
     }
 
-    public static final void printTreeNodes(INode node, int indent, StringBuilder builder) {
+    public static final StringBuilder printTreeNodes(INode node, int indent, StringBuilder builder) {
         for (int i = 0; i < indent; i++)
             builder.append(" ");
         builder.append(node.toString() + "\n");
@@ -351,6 +395,7 @@ public final class NodeUtil {
                 printTreeNodes(n, indent+2, builder);
             }
         }
+        return builder;
     }
 
     public static final <T extends INode> Set<T> collectNodes(INode node, Class<T> clazz) {