Browse Source

SDK mat def editor :
- better handling of errors in the material definition
- the navigator now properly refreshs
- the editor is reloaded when a change occur in the text file


git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@10456 75d07b2b-3a1a-0410-a2c5-0572b91ccdca

rem..om 12 years ago
parent
commit
823bb06ec1

+ 75 - 12
jme3-materialeditor/src/com/jme3/gde/materialdefinition/EditableMatDefFile.java

@@ -5,7 +5,6 @@
 package com.jme3.gde.materialdefinition;
 
 import com.jme3.asset.AssetKey;
-import com.jme3.asset.MaterialKey;
 import com.jme3.gde.core.assets.ProjectAssetManager;
 import com.jme3.gde.core.scene.SceneApplication;
 import com.jme3.gde.materialdefinition.fileStructure.MatDefBlock;
@@ -14,12 +13,14 @@ import com.jme3.gde.materialdefinition.fileStructure.TechniqueBlock;
 import com.jme3.gde.materialdefinition.fileStructure.UberStatement;
 import com.jme3.gde.materialdefinition.fileStructure.leaves.InputMappingBlock;
 import com.jme3.gde.materialdefinition.fileStructure.leaves.LeafStatement;
+import com.jme3.gde.materialdefinition.fileStructure.leaves.MatParamBlock;
 import com.jme3.gde.materialdefinition.fileStructure.leaves.OutputMappingBlock;
 import com.jme3.gde.materialdefinition.navigator.node.MatDefNode;
 import com.jme3.material.MatParam;
 import com.jme3.material.Material;
 import com.jme3.material.MaterialDef;
 import com.jme3.material.plugins.J3MLoader;
+import com.jme3.material.plugins.MatParseException;
 import com.jme3.shader.Glsl100ShaderGenerator;
 import com.jme3.shader.Glsl150ShaderGenerator;
 import com.jme3.shader.Shader;
@@ -30,7 +31,6 @@ import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
 import java.util.logging.Level;
@@ -68,29 +68,52 @@ public class EditableMatDefFile {
     private final static String GLSL100 = "GLSL100";
     private final static String GLSL150 = "GLSL150";
     private Lookup lookup;
+    private boolean loaded = false;
+    private boolean dirty = false;
 
     public EditableMatDefFile(Lookup lookup) {
         obj = lookup.lookup(MatDefDataObject.class);
+        load(lookup);
 
+    }
+
+    public final void load(Lookup lookup) {
         this.matDefFile = obj.getPrimaryFile();
         this.assetManager = lookup.lookup(ProjectAssetManager.class);
         this.glsl100 = new Glsl100ShaderGenerator(assetManager);
         this.glsl150 = new Glsl150ShaderGenerator(assetManager);
         this.lookup = lookup;
 
-        materialDef = null;
-        matDefStructure = null;
+        if (matDefStructure != null) {
+            obj.getLookupContents().remove(matDefStructure);
+            matDefStructure = null;
+        }
+        if (materialDef != null) {
+            obj.getLookupContents().remove(materialDef);
+            materialDef = null;
+        }
         FileLock lock = null;
-
         try {
             lock = matDefFile.lock();
             List<Statement> sta = BlockLanguageParser.parse(obj.getPrimaryFile().getInputStream());
             matDefStructure = new MatDefBlock(sta.get(0));
-            //  System.err.println(block.toString());
+            AssetKey matDefKey = new AssetKey(assetManager.getRelativeAssetPath(assetManager.getRelativeAssetPath(matDefFile.getPath())));
+            assetManager.deleteFromCache(matDefKey);
             materialDef = (MaterialDef) assetManager.loadAsset(assetManager.getRelativeAssetPath(matDefFile.getPath()));
             lock.releaseLock();
         } catch (Exception ex) {
-            Exceptions.printStackTrace(ex);
+            Throwable t = ex.getCause();
+            boolean matParseError = false;
+            while (t != null) {
+                if (t instanceof MatParseException) {
+                    Logger.getLogger(EditableMatDefFile.class.getName()).log(Level.SEVERE, t.getMessage());
+                    matParseError = true;
+                }
+                t = t.getCause();
+            }
+            if (!matParseError) {
+                Exceptions.printStackTrace(ex);
+            }
         } finally {
             if (lock != null) {
                 lock.releaseLock();
@@ -99,10 +122,11 @@ public class EditableMatDefFile {
         if (materialDef != null) {
             currentTechnique = matDefStructure.getTechniques().get(0);
             registerListener(matDefStructure);
+
             obj.getLookupContents().add(matDefStructure);
             updateLookupWithMaterialData(obj);
+            loaded = true;
         }
-
     }
 
     private void registerListener(Statement sta) {
@@ -130,7 +154,7 @@ public class EditableMatDefFile {
     public String getShaderCode(String version, Shader.ShaderType type) {
         try {
             material.selectTechnique("Default", SceneApplication.getApplication().getRenderManager());
-            Shader s = null;
+            Shader s;
             if (version.equals(GLSL100)) {
                 s = glsl100.generateShader(material.getActiveTechnique());
             } else {
@@ -186,6 +210,22 @@ public class EditableMatDefFile {
         }
     }
 
+    public boolean isLoaded() {
+        return loaded;
+    }
+
+    public boolean isDirty() {
+        return dirty;
+    }
+
+    public void setDirty(boolean dirty) {
+        this.dirty = dirty;
+    }
+
+    public void setLoaded(boolean loaded) {
+        this.loaded = loaded;
+    }
+
     private class MatStructChangeListener implements PropertyChangeListener {
 
         public void propertyChange(PropertyChangeEvent evt) {
@@ -214,6 +254,32 @@ public class EditableMatDefFile {
                     }
                 }
             }
+            if (evt.getPropertyName().equals(MatDefBlock.REMOVE_MAT_PARAM)) {
+                MatParamBlock oldValue = (MatParamBlock) evt.getOldValue();
+
+                for (ShaderNodeBlock shaderNodeBlock : currentTechnique.getShaderNodes()) {
+
+                    if (shaderNodeBlock.getCondition() != null && shaderNodeBlock.getCondition().contains(oldValue.getName())) {
+                        shaderNodeBlock.setCondition(shaderNodeBlock.getCondition().replaceAll(oldValue.getName(), "").trim());                      
+                    }
+                    List<InputMappingBlock> lin = shaderNodeBlock.getInputs();
+                    if (lin != null) {
+                        for (InputMappingBlock inputMappingBlock : shaderNodeBlock.getInputs()) {
+                            if (inputMappingBlock.getCondition() != null && inputMappingBlock.getCondition().contains(oldValue.getName())) {
+                                inputMappingBlock.setCondition(inputMappingBlock.getCondition().replaceAll(oldValue.getName(), "").trim());                               
+                            }
+                        }
+                    }
+                    List<OutputMappingBlock> l = shaderNodeBlock.getOutputs();
+                    if (l != null) {
+                        for (OutputMappingBlock outputMappingBlock : l) {
+                            if (outputMappingBlock.getCondition() != null && outputMappingBlock.getCondition().contains(oldValue.getName())) {
+                                outputMappingBlock.setCondition(outputMappingBlock.getCondition().replaceAll(oldValue.getName(), "").trim());                             
+                            }
+                        }
+                    }
+                }
+            }
             if (evt.getPropertyName().equals(MatDefBlock.ADD_MAT_PARAM)
                     || evt.getPropertyName().equals(TechniqueBlock.ADD_SHADER_NODE)
                     || evt.getPropertyName().equals(ShaderNodeBlock.ADD_MAPPING)) {
@@ -257,8 +323,5 @@ public class EditableMatDefFile {
             Logger.getLogger(EditableMatDefFile.class.getName()).log(Level.SEVERE, ex.getMessage());
         }
         updateLookupWithMaterialData(obj);
-        AssetKey matDefKey = new AssetKey(assetManager.getRelativeAssetPath(assetManager.getRelativeAssetPath(matDefFile.getPath())));
-        assetManager.deleteFromCache(matDefKey);
-
     }
 }

+ 34 - 9
jme3-materialeditor/src/com/jme3/gde/materialdefinition/MatDefDataObject.java

@@ -33,6 +33,8 @@ package com.jme3.gde.materialdefinition;
 
 import com.jme3.gde.core.assets.ProjectAssetManager;
 import com.jme3.gde.materialdefinition.navigator.MatDefNavigatorPanel;
+import java.awt.event.KeyEvent;
+import java.awt.event.KeyListener;
 import java.io.IOException;
 import org.netbeans.api.project.Project;
 import org.netbeans.api.project.ProjectManager;
@@ -41,9 +43,7 @@ import org.netbeans.core.spi.multiview.text.MultiViewEditorElement;
 import org.openide.awt.ActionID;
 import org.openide.awt.ActionReference;
 import org.openide.awt.ActionReferences;
-import org.openide.cookies.SaveCookie;
 import org.openide.filesystems.FileChangeAdapter;
-import org.openide.filesystems.FileChangeListener;
 import org.openide.filesystems.FileEvent;
 import org.openide.filesystems.FileObject;
 import org.openide.filesystems.MIMEResolver;
@@ -140,14 +140,16 @@ public class MatDefDataObject extends MultiDataObject {
         findAssetManager();
         final MatDefMetaData metaData = new MatDefMetaData(this);
         lookupContents.add(metaData);
-        pf.addFileChangeListener(new FileChangeAdapter(){
-
+        pf.addFileChangeListener(new FileChangeAdapter() {
             @Override
             public void fileChanged(FileEvent fe) {
                 super.fileChanged(fe);
                 metaData.save();
+                if (file.isDirty()) {
+                    file.setLoaded(false);
+                    file.setDirty(false);
+                }
             }
-            
         });
 
     }
@@ -202,6 +204,33 @@ public class MatDefDataObject extends MultiDataObject {
             nav.updateData(obj);
         }
         MultiViewEditorElement ed = new MultiViewEditorElement(lkp) {
+            KeyListener listener = new KeyListener() {
+                public void keyTyped(KeyEvent e) {
+                }
+
+                public void keyPressed(KeyEvent e) {
+                    EditableMatDefFile f = obj.getEditableFile();
+                    if (f != null) {
+                        f.setDirty(true);
+                    }
+                }
+
+                public void keyReleased(KeyEvent e) {                   
+                }
+            };
+
+            @Override
+            public void componentActivated() {
+                super.componentActivated();
+                getEditorPane().addKeyListener(listener);
+            }
+
+            @Override
+            public void componentDeactivated() {
+                super.componentDeactivated();
+                getEditorPane().removeKeyListener(listener);
+            }
+
             @Override
             public void componentClosed() {
                 super.componentClosed();
@@ -247,11 +276,7 @@ public class MatDefDataObject extends MultiDataObject {
         metaData.duplicate(df, name);
         return super.handleCopyRename(df, name, ext);
     }
-    
-    
 
-    
-    
     public EditableMatDefFile getEditableFile() {
         if (file == null) {
             file = new EditableMatDefFile(getLookup());

+ 7 - 5
jme3-materialeditor/src/com/jme3/gde/materialdefinition/MatDefMetaData.java

@@ -126,7 +126,7 @@ public class MatDefMetaData {
                 if (prop == null) {
                     return defaultProps.getProperty(key);
                 }
-                return prop;                
+                return prop;
             }
         });
     }
@@ -139,7 +139,7 @@ public class MatDefMetaData {
                 return ret;
             }
         });
-       // writeProperties();
+        // writeProperties();
         notifyListeners(key, ret, value);
         return ret;
     }
@@ -308,10 +308,12 @@ public class MatDefMetaData {
 
     }
 
-    public void save(){
-        writeProperties();
+    public void save() {
+        if (!props.isEmpty()) {
+            writeProperties();
+        }
     }
-    
+
     private void writeProperties() {
         //writeAccess because we write lastMod date, not because we write to the file
         //the mutex protects the properties object, not the file

+ 8 - 0
jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/Diagram.java

@@ -380,6 +380,14 @@ public class Diagram extends JPanel implements MouseListener, MouseMotionListene
         return item;
     }
 
+    
+    public void clear(){
+        removeAll();
+        outBuses.clear();
+        connections.clear();
+        nodes.clear();
+    }
+    
     private void createPopupMenu() {
         contextMenu.setFont(new Font("Tahoma", 1, 10)); // NOI18N
         contextMenu.setOpaque(true);

+ 45 - 7
jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/MatDefEditorlElement.java

@@ -50,14 +50,19 @@ import com.jme3.shader.Shader;
 import com.jme3.shader.ShaderNodeDefinition;
 import com.jme3.shader.ShaderNodeVariable;
 import com.jme3.shader.ShaderUtils;
+import java.awt.Color;
 import java.awt.Dimension;
 import java.awt.Point;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
 import java.beans.PropertyVetoException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 import javax.swing.Action;
+import javax.swing.JButton;
 import javax.swing.JComponent;
+import javax.swing.JLabel;
 import javax.swing.JPanel;
 import javax.swing.JToolBar;
 import org.netbeans.core.spi.multiview.CloseOperationState;
@@ -91,12 +96,17 @@ public final class MatDefEditorlElement extends JPanel implements MultiViewEleme
     Selectable prevNode;
     MatDefMetaData metaData;
 
-    public MatDefEditorlElement(Lookup lkp) {
+    public MatDefEditorlElement(final Lookup lkp) {
+        initComponents();
         obj = lkp.lookup(MatDefDataObject.class);
         metaData = lkp.lookup(MatDefMetaData.class);
         assert obj != null;
-        EditableMatDefFile file = obj.getEditableFile();
-        initComponents();
+        final EditableMatDefFile file = obj.getEditableFile();
+        reload(file, lkp);
+    }
+
+    private void initDiagram(Lookup lkp) throws NumberFormatException {
+        diagram1.clear();
         diagram1.setParent(this);
 
         Material mat = lkp.lookup(Material.class);
@@ -223,9 +233,6 @@ public final class MatDefEditorlElement extends JPanel implements MultiViewEleme
                 }
             });
         }
-
-
-
     }
 
     @Override
@@ -353,6 +360,10 @@ public final class MatDefEditorlElement extends JPanel implements MultiViewEleme
 
     @Override
     public void componentActivated() {
+        if (!obj.getEditableFile().isLoaded()) {
+            obj.getEditableFile().load(obj.getLookup());
+            reload(obj.getEditableFile(), obj.getLookup());
+        }
     }
 
     @Override
@@ -542,7 +553,6 @@ public final class MatDefEditorlElement extends JPanel implements MultiViewEleme
 
     private TechniqueBlock getTechnique(MatDefBlock matDef) {
         TechniqueBlock technique = matDef.getTechniques().get(0);
-
         return technique;
     }
 
@@ -563,4 +573,32 @@ public final class MatDefEditorlElement extends JPanel implements MultiViewEleme
         metaData.setProperty(diagram1.getCurrentTechniqueName() + "/" + key, x + "," + y);
 
     }
+
+    private void reload(final EditableMatDefFile file, final Lookup lkp) throws NumberFormatException {
+        if (file.isLoaded()) {
+            initDiagram(lkp);
+            MatDefNavigatorPanel nav = obj.getLookup().lookup(MatDefNavigatorPanel.class);
+            if (nav != null) {
+                nav.updateData(obj);
+            }
+        } else {
+            diagram1.clear();
+            JLabel error = new JLabel("Cannot load material definition.");
+            error.setForeground(Color.RED);
+            error.setBounds(0, 0, 200, 20);
+            diagram1.add(error);
+            JButton btn = new JButton("retry");
+            btn.addActionListener(new ActionListener() {
+                public void actionPerformed(ActionEvent e) {
+                    file.load(lkp);
+                    if (file.isLoaded()) {
+                        initDiagram(lkp);
+                    }
+                }
+            });
+            btn.setBounds(0, 25, 150, 20);
+            diagram1.add(btn);
+
+        }
+    }
 }

+ 1 - 1
jme3-materialeditor/src/com/jme3/gde/materialdefinition/fileStructure/MatDefBlock.java

@@ -80,7 +80,7 @@ public class MatDefBlock extends UberStatement {
             techniqueBlock.cleanMappings(vblock, "MatParam", matParam.getName());
             techniqueBlock.cleanMappings(fblock, "MatParam", matParam.getName());
         }
-        fire(REMOVE_MAT_PARAM, null, matParam);
+        fire(REMOVE_MAT_PARAM, matParam, null);
     }
 
     public List<TechniqueBlock> getTechniques() {

+ 0 - 13
jme3-materialeditor/src/com/jme3/gde/materialdefinition/navigator/MatDefNavigatorPanel.java

@@ -166,17 +166,4 @@ public class MatDefNavigatorPanel extends JPanel implements NavigatorPanel, Expl
     private javax.swing.JScrollPane jScrollPane1;
     // End of variables declaration//GEN-END:variables
 
-    /**
-     * Gets default instance. Do not use directly: reserved for *.settings files
-     * only, i.e. deserialization routines; otherwise you could get a
-     * non-deserialized instance. To obtain the singleton instance, use
-     * {@link #findInstance}.
-     */
-    public static synchronized MatDefNavigatorPanel getDefault() {
-        if (instance == null) {
-            instance = new MatDefNavigatorPanel();
-        }
-        return instance;
-    }
-    private static MatDefNavigatorPanel instance;
 }