[COMMITTED] changing shaderVariableList type from ArrayList to HashMap

setUniform is callled frequently,

But it searches shader variable by comparing String.equals().

How about using HashMap?



If it is accepted I'll create patch for JOGL either.



Index: src/com/jme/scene/state/lwjgl/LWJGLShaderObjectsState.java
===================================================================
--- src/com/jme/scene/state/lwjgl/LWJGLShaderObjectsState.java   (revision 4107)
+++ src/com/jme/scene/state/lwjgl/LWJGLShaderObjectsState.java   (working copy)
@@ -341,9 +341,7 @@
                                     .updateShaderAttribute(shaderVariable);
                         }
 
-                        for (int i = shaderUniforms.size(); --i >= 0;) {
-                            ShaderVariable shaderVariable =
-                                    shaderUniforms.get(i);
+                        for (ShaderVariable shaderVariable : shaderUniforms.values()) {
                             if (shaderVariable.needsRefresh) {
                                 LWJGLShaderUtil.updateUniformLocation(
                                         shaderVariable, programID);
Index: src/com/jme/util/shader/ShaderVariable.java
===================================================================
--- src/com/jme/util/shader/ShaderVariable.java   (revision 4107)
+++ src/com/jme/util/shader/ShaderVariable.java   (working copy)
@@ -78,4 +78,9 @@
     public Class getClassTag() {
         return this.getClass();
     }
+
+    @Override
+    public int hashCode() {
+        return name.hashCode();
+    }
 }
No newline at end of file
Index: src/com/jme/scene/state/GLSLShaderObjectsState.java
===================================================================
--- src/com/jme/scene/state/GLSLShaderObjectsState.java   (revision 4107)
+++ src/com/jme/scene/state/GLSLShaderObjectsState.java   (working copy)
@@ -44,6 +44,8 @@
 import java.nio.IntBuffer;
 import java.nio.ShortBuffer;
 import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
@@ -54,7 +56,6 @@
 import com.jme.math.Vector3f;
 import com.jme.renderer.ColorRGBA;
 import com.jme.scene.Geometry;
-import com.jme.scene.state.RenderState.StateType;
 import com.jme.util.export.InputCapsule;
 import com.jme.util.export.JMEExporter;
 import com.jme.util.export.JMEImporter;
@@ -88,11 +89,11 @@
             .getLogger(GLSLShaderObjectsState.class.getName());
 
     /** Storage for shader uniform values */
-    protected ArrayList<ShaderVariable> shaderUniforms =
-            new ArrayList<ShaderVariable>();
+    protected HashMap<String, ShaderVariable> shaderUniforms =
+            new HashMap<String, ShaderVariable>();
     /** Storage for shader attribute values */
-    protected ArrayList<ShaderVariable> shaderAttributes =
-            new ArrayList<ShaderVariable>();
+    protected HashMap<String, ShaderVariable> shaderAttributes =
+            new HashMap<String, ShaderVariable>();
     
     /** Optional logic for setting shadervariables based on the current geom */
     protected GLSLShaderDataLogic shaderDataLogic;
@@ -127,8 +128,8 @@
      * Gets all shader uniforms variables.
      * @return
      */
-    public   ArrayList<ShaderVariable>   getShaderUniforms() {
-       return shaderUniforms;
+    public   Collection<ShaderVariable>   getShaderUniforms() {
+       return shaderUniforms.values();
     }
     
     /**
@@ -137,7 +138,7 @@
      * @return
      */
     public   ShaderVariable      getUniformByName(String uniformName) {
-       for(ShaderVariable shaderVar : shaderUniforms) {
+       for(ShaderVariable shaderVar : shaderUniforms.values()) {
           if(shaderVar.name.equals(uniformName)) {
              return shaderVar;
           }
@@ -150,8 +151,8 @@
      * Gets all shader attribute variables.
      * @return
      */
-    public   ArrayList<ShaderVariable>   getShaderAttributes() {
-       return shaderAttributes;
+    public   Collection<ShaderVariable>   getShaderAttributes() {
+       return shaderAttributes.values();
     }
     
     /**
@@ -160,7 +161,7 @@
      * @return
      */
     public   ShaderVariable      getAttributeByName(String attributeName) {
-       for(ShaderVariable shaderVar : shaderAttributes) {
+       for(ShaderVariable shaderVar : shaderAttributes.values()) {
           if(shaderVar.name.equals(attributeName)) {
              return shaderVar;
           }
@@ -729,19 +730,18 @@
      */
     @SuppressWarnings("unchecked")
     private <T extends ShaderVariable> T getShaderVariable(String name,
-            Class<T> classz, ArrayList<ShaderVariable> shaderVariableList) {
-        for (int i = shaderVariableList.size(); --i >= 0;) {
-            ShaderVariable temp = shaderVariableList.get(i);
-            if (name.equals(temp.name)) {
-                temp.needsRefresh = true;
-                return (T) temp;
-            }
+            Class<T> classz, HashMap<String, ShaderVariable> shaderVariableList) {
+       
+       ShaderVariable temp = shaderVariableList.get(name);
+        if (temp != null) {
+            temp.needsRefresh = true;
+            return (T) temp;
         }
 
         try {
             T shaderUniform = classz.newInstance();
             shaderUniform.name = name;
-            shaderVariableList.add(shaderUniform);
+            shaderVariableList.put(name, shaderUniform);
 
             return shaderUniform;
         } catch (InstantiationException e) {
@@ -840,20 +840,18 @@
     public void write(JMEExporter e) throws IOException {
         super.write(e);
         OutputCapsule capsule = e.getCapsule(this);
-        capsule.writeSavableArrayList(shaderUniforms, "shaderUniforms",
-                new ArrayList<ShaderVariable>());
-        capsule.writeSavableArrayList(shaderAttributes, "shaderAttributes",
-                new ArrayList<ShaderVariable>());
+        capsule.writeStringSavableMap(shaderUniforms, "shaderUniforms", null);
+        capsule.writeStringSavableMap(shaderAttributes, "shaderAttributes", null);
     }
 
     @SuppressWarnings ("unchecked")
     public void read(JMEImporter e) throws IOException {
         super.read(e);
         InputCapsule capsule = e.getCapsule(this);
-        shaderUniforms = capsule.readSavableArrayList("shaderUniforms",
-                new ArrayList<ShaderVariable>());
-        shaderAttributes = capsule.readSavableArrayList("shaderAttributes",
-                new ArrayList<ShaderVariable>());
+        shaderUniforms = (HashMap<String, ShaderVariable>) capsule.readStringSavableMap("shaderUniforms",
+                new HashMap<String, ShaderVariable>());
+        shaderAttributes = (HashMap<String, ShaderVariable>) capsule.readStringSavableMap("shaderAttributes",
+                new HashMap<String, ShaderVariable>());
     }
 
     public Class<? extends GLSLShaderObjectsState> getClassTag() {



Looks good to me. My only criticism is to make sure the code formatting is consistent with the rest of jME (looks like you have tabs between the return type and the method name).

yes, you're right nymon.

I changed the eclipse formatter type from tab to spaces.

Thanks for pointing it out.  :slight_smile:

With JOGL patch



Index: src/com/jme/scene/state/lwjgl/LWJGLShaderObjectsState.java
===================================================================
--- src/com/jme/scene/state/lwjgl/LWJGLShaderObjectsState.java   (revision 4107)
+++ src/com/jme/scene/state/lwjgl/LWJGLShaderObjectsState.java   (working copy)
@@ -328,10 +328,8 @@
                 if (isEnabled()) {
                     if (programID != -1) {
                         ARBShaderObjects.glUseProgramObjectARB(programID);
-
-                        for (int i = shaderAttributes.size(); --i >= 0;) {
-                            ShaderVariable shaderVariable =
-                                    shaderAttributes.get(i);
+
+                        for (ShaderVariable shaderVariable : shaderAttributes.values()) {
                             if (shaderVariable.needsRefresh) {                                                          
                                 LWJGLShaderUtil.updateAttributeLocation(
                                         shaderVariable, programID);
@@ -341,9 +339,7 @@
                                     .updateShaderAttribute(shaderVariable);
                         }
 
-                        for (int i = shaderUniforms.size(); --i >= 0;) {
-                            ShaderVariable shaderVariable =
-                                    shaderUniforms.get(i);
+                        for (ShaderVariable shaderVariable : shaderUniforms.values()) {
                             if (shaderVariable.needsRefresh) {
                                 LWJGLShaderUtil.updateUniformLocation(
                                         shaderVariable, programID);
Index: src/com/jme/util/shader/ShaderVariable.java
===================================================================
--- src/com/jme/util/shader/ShaderVariable.java   (revision 4107)
+++ src/com/jme/util/shader/ShaderVariable.java   (working copy)
@@ -78,4 +78,9 @@
     public Class getClassTag() {
         return this.getClass();
     }
+
+    @Override
+    public int hashCode() {
+        return name.hashCode();
+    }
 }
No newline at end of file
Index: src/com/jme/scene/state/GLSLShaderObjectsState.java
===================================================================
--- src/com/jme/scene/state/GLSLShaderObjectsState.java   (revision 4107)
+++ src/com/jme/scene/state/GLSLShaderObjectsState.java   (working copy)
@@ -44,6 +44,8 @@
 import java.nio.IntBuffer;
 import java.nio.ShortBuffer;
 import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
@@ -54,7 +56,6 @@
 import com.jme.math.Vector3f;
 import com.jme.renderer.ColorRGBA;
 import com.jme.scene.Geometry;
-import com.jme.scene.state.RenderState.StateType;
 import com.jme.util.export.InputCapsule;
 import com.jme.util.export.JMEExporter;
 import com.jme.util.export.JMEImporter;
@@ -88,11 +89,11 @@
             .getLogger(GLSLShaderObjectsState.class.getName());
 
     /** Storage for shader uniform values */
-    protected ArrayList<ShaderVariable> shaderUniforms =
-            new ArrayList<ShaderVariable>();
+    protected HashMap<String, ShaderVariable> shaderUniforms =
+            new HashMap<String, ShaderVariable>();
     /** Storage for shader attribute values */
-    protected ArrayList<ShaderVariable> shaderAttributes =
-            new ArrayList<ShaderVariable>();
+    protected HashMap<String, ShaderVariable> shaderAttributes =
+            new HashMap<String, ShaderVariable>();
    
     /** Optional logic for setting shadervariables based on the current geom */
     protected GLSLShaderDataLogic shaderDataLogic;
@@ -127,8 +128,8 @@
      * Gets all shader uniforms variables.
      * @return
      */
-    public   ArrayList<ShaderVariable>   getShaderUniforms() {
-       return shaderUniforms;
+    public   Collection<ShaderVariable>   getShaderUniforms() {
+       return shaderUniforms.values();
     }
    
     /**
@@ -137,21 +138,15 @@
      * @return
      */
     public   ShaderVariable      getUniformByName(String uniformName) {
-       for(ShaderVariable shaderVar : shaderUniforms) {
-          if(shaderVar.name.equals(uniformName)) {
-             return shaderVar;
-          }
-       }
-       
-       return null;
+       return shaderUniforms.get(uniformName);
     }
    
     /**
      * Gets all shader attribute variables.
      * @return
      */
-    public   ArrayList<ShaderVariable>   getShaderAttributes() {
-       return shaderAttributes;
+    public   Collection<ShaderVariable>   getShaderAttributes() {
+       return shaderAttributes.values();
     }
    
     /**
@@ -160,13 +155,7 @@
      * @return
      */
     public   ShaderVariable      getAttributeByName(String attributeName) {
-       for(ShaderVariable shaderVar : shaderAttributes) {
-          if(shaderVar.name.equals(attributeName)) {
-             return shaderVar;
-          }
-       }
-       
-       return null;
+        return shaderAttributes.get(attributeName);
     }
    
     /**
@@ -729,19 +718,18 @@
      */
     @SuppressWarnings("unchecked")
     private <T extends ShaderVariable> T getShaderVariable(String name,
-            Class<T> classz, ArrayList<ShaderVariable> shaderVariableList) {
-        for (int i = shaderVariableList.size(); --i >= 0;) {
-            ShaderVariable temp = shaderVariableList.get(i);
-            if (name.equals(temp.name)) {
-                temp.needsRefresh = true;
-                return (T) temp;
-            }
+            Class<T> classz, HashMap<String, ShaderVariable> shaderVariableList) {
+       
+       ShaderVariable temp = shaderVariableList.get(name);
+        if (temp != null) {
+            temp.needsRefresh = true;
+            return (T) temp;
         }
 
         try {
             T shaderUniform = classz.newInstance();
             shaderUniform.name = name;
-            shaderVariableList.add(shaderUniform);
+            shaderVariableList.put(name, shaderUniform);
 
             return shaderUniform;
         } catch (InstantiationException e) {
@@ -840,20 +828,18 @@
     public void write(JMEExporter e) throws IOException {
         super.write(e);
         OutputCapsule capsule = e.getCapsule(this);
-        capsule.writeSavableArrayList(shaderUniforms, "shaderUniforms",
-                new ArrayList<ShaderVariable>());
-        capsule.writeSavableArrayList(shaderAttributes, "shaderAttributes",
-                new ArrayList<ShaderVariable>());
+        capsule.writeStringSavableMap(shaderUniforms, "shaderUniforms", null);
+        capsule.writeStringSavableMap(shaderAttributes, "shaderAttributes", null);
     }
 
     @SuppressWarnings ("unchecked")
     public void read(JMEImporter e) throws IOException {
         super.read(e);
         InputCapsule capsule = e.getCapsule(this);
-        shaderUniforms = capsule.readSavableArrayList("shaderUniforms",
-                new ArrayList<ShaderVariable>());
-        shaderAttributes = capsule.readSavableArrayList("shaderAttributes",
-                new ArrayList<ShaderVariable>());
+        shaderUniforms = (HashMap<String, ShaderVariable>) capsule.readStringSavableMap("shaderUniforms",
+                new HashMap<String, ShaderVariable>());
+        shaderAttributes = (HashMap<String, ShaderVariable>) capsule.readStringSavableMap("shaderAttributes",
+                new HashMap<String, ShaderVariable>());
     }
 
     public Class<? extends GLSLShaderObjectsState> getClassTag() {
Index: src/com/jme/scene/state/jogl/JOGLShaderObjectsState.java
===================================================================
--- src/com/jme/scene/state/jogl/JOGLShaderObjectsState.java   (revision 4107)
+++ src/com/jme/scene/state/jogl/JOGLShaderObjectsState.java   (working copy)
@@ -327,9 +327,7 @@
                     if (programID != -1) {
                         gl.glUseProgramObjectARB(programID);
 
-                        for (int i = shaderAttributes.size(); --i >= 0;) {
-                            ShaderVariable shaderVariable =
-                                    shaderAttributes.get(i);
+                        for (ShaderVariable shaderVariable : shaderAttributes.values()) {
                             if (shaderVariable.needsRefresh) {
                                 JOGLShaderUtil.updateAttributeLocation(
                                         shaderVariable, programID);
@@ -339,9 +337,7 @@
                                     .updateShaderAttribute(shaderVariable);
                         }
 
-                        for (int i = shaderUniforms.size(); --i >= 0;) {
-                            ShaderVariable shaderVariable =
-                                    shaderUniforms.get(i);
+                        for (ShaderVariable shaderVariable : shaderUniforms.values()) {
                             if (shaderVariable.needsRefresh) {
                                 JOGLShaderUtil.updateUniformLocation(
                                         shaderVariable, programID);