Browse Source

fixes #335 properly. better sorting and sorting on new mapping

Conflicts:
	jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/ShaderNodeBlock.java
	jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/ShaderNodesBlock.java
rickard 3 years ago
parent
commit
605cc17ea0

+ 0 - 3
jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/InputMappingsBlock.java

@@ -4,10 +4,7 @@
  */
 package com.jme3.gde.materialdefinition.fileStructure;
 
-import com.jme3.gde.materialdefinition.fileStructure.*;
 import com.jme3.gde.materialdefinition.fileStructure.leaves.InputMappingBlock;
-import com.jme3.gde.materialdefinition.fileStructure.leaves.MatParamBlock;
-import com.jme3.gde.materialdefinition.fileStructure.leaves.OutputMappingBlock;
 import com.jme3.util.blockparser.Statement;
 import java.util.List;
 

+ 4 - 15
jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/ShaderNodeBlock.java

@@ -16,16 +16,18 @@ import java.util.ArrayList;
 import java.util.List;
 
 /**
- *
+ * A ShaderNodeBlock is a shader node in the MatDef file.
+ * 
  * @author Nehon
  */
-public class ShaderNodeBlock extends UberStatement implements Comparable<ShaderNodeBlock>, PropertyChangeListener {
+public class ShaderNodeBlock extends UberStatement implements PropertyChangeListener {
 
     public final static String POSITION = "position";
     public final static String INPUT = "input";
     public final static String OUTPUT = "output";
     public static final String ADD_MAPPING = "addMapping";
     public static final String REMOVE_MAPPING = "removeMapping";
+    public static final String VALUE = "defaultValue";
     protected String name;
     //built up data for fast sorting 
     protected int spatialOrder;
@@ -192,19 +194,6 @@ public class ShaderNodeBlock extends UberStatement implements Comparable<ShaderN
         fire(REMOVE_MAPPING, mapping, null);
     }
 
-    public int compareTo(ShaderNodeBlock o) {
-        if (inputNodes.contains(o.getName())) {
-            return 1;
-        }
-        if (o.inputNodes.contains(name)) {
-            return -1;
-        }
-        if ((globalInput && o.globalOutput) || (o.globalInput && globalOutput)) {
-            return (int) Math.signum(spatialOrder - o.spatialOrder);
-        }
-        return 0;
-    }
-
     public void propertyChange(PropertyChangeEvent evt) {
         if (evt.getPropertyName().equals(POSITION)) {
             spatialOrder = (Integer) evt.getNewValue();

+ 53 - 14
jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/ShaderNodesBlock.java

@@ -13,14 +13,15 @@ import java.util.List;
 import org.openide.util.WeakListeners;
 
 /**
- * A ShaderNodeBlock is a shader node in the MatDef file.
- *
+ * A ShaderNodesBlock is a set of shader nodes in the MatDef file, for example all frag shader nodes.
+ * 
  * @author Nehon
  */
 public class ShaderNodesBlock extends UberStatement implements PropertyChangeListener {
-
+        
     protected ShaderNodesBlock(int lineNumber, String line) {
         super(lineNumber, line);
+        
     }
 
     public ShaderNodesBlock(Statement sta) {
@@ -47,14 +48,20 @@ public class ShaderNodesBlock extends UberStatement implements PropertyChangeLis
 
     @Override
     public void propertyChange(PropertyChangeEvent evt) {
-        if (evt.getPropertyName().equals("order")) {
+        if (evt.getPropertyName().equals(ShaderNodeBlock.ADD_MAPPING) || evt.getPropertyName().equals("order")) {
             sort();
         }
     }
 
     public void sort() {
         List<ShaderNodeBlock> list = getShaderNodes();
-        Collections.sort(list, new NodeComparator());
+        int passes = 0;
+        NodeComparator nodeComparator = new NodeComparator(list);
+        while (nodeComparator.changes != 0 && passes < 10) {
+            nodeComparator.changes = 0;
+            Collections.sort(list, nodeComparator);
+            passes++;
+        }
         contents.clear();
         contents.addAll(list);
         fire("reorder", null, null);
@@ -62,26 +69,58 @@ public class ShaderNodesBlock extends UberStatement implements PropertyChangeLis
 
     /**
      * Sorts nodes so that they are initialized after their input dependencies.
+     * Will look higher up in hierarchy and move node incrementally. This may require several passes
      */
-    private class NodeComparator implements Comparator<ShaderNodeBlock> {
+    private final class NodeComparator implements Comparator<ShaderNodeBlock> {
+
+        private final List<ShaderNodeBlock> list;
+        private int changes = -1;
+
+        public NodeComparator(List<ShaderNodeBlock> list) {
+            this.list = list;
+        }
 
         @Override
         public int compare(ShaderNodeBlock o1, ShaderNodeBlock o2) {
             if (o1.name.equals(o2.name)) {
                 return 0;
             }
-            for (String s : o1.inputNodes) {
-                if (s.contains(o2.name)) {
-                    return 1;
-                }
+            if (hasInputConnection(o2.name, o1)) {
+                changes++;
+                return 1;
             }
-            for (String s : o2.inputNodes) {
-                if (s.contains(o1.name)) {
-                    return -1;
-                }
+            if (hasInputConnection(o1.name, o2)) {
+                changes++;
+                return -1;
+            }
+
+            if ((o1.globalInput && o2.globalOutput) || (o2.globalInput && o1.globalOutput)) {
+                changes++;
+                return (int) Math.signum(o1.spatialOrder - o2.spatialOrder);
             }
             return 0;
         }
 
+        private ShaderNodeBlock findAncestorNode(String name) {
+            for (ShaderNodeBlock node : list) {
+                if (node.name.equals(name)) {
+                    return node;
+                }
+            }
+            return null;
+        }
+
+        private boolean hasInputConnection(String name, ShaderNodeBlock node) {
+            for (String s : node.inputNodes) {
+                if (s.equals(name)) {
+                    return true;
+                }
+                ShaderNodeBlock ancestor = findAncestorNode(s);
+                if (ancestor != null && hasInputConnection(name, ancestor)) {
+                    return true;
+                }
+            }
+            return false;
+        }
     }
 }