Michael Ludwig avatar Michael Ludwig committed 22ae7af

Update expression and type APIs to pass around accumulator, auto-include structs when referenced (just like functions)

Comments (0)

Files changed (10)

ferox-renderer/ferox-renderer-api/src/main/java/com/ferox/resource/shader/ArrayType.java

 package com.ferox.resource.shader;
 
-public interface ArrayType extends Type {
-    public Type getComponentType();
+public class ArrayType implements Type {
+    private final Type componentType;
+    private final int length;
+
+    public ArrayType(Type componentType, int length) {
+        this.componentType = componentType;
+        this.length = length;
+    }
+
+    public Type getComponentType() {
+        return componentType;
+    }
+
+    public int getLength() {
+        return length;
+    }
+
+    @Override
+    public String getTypeIdentifier(ShaderAccumulator accumulator, String varIdentifier) {
+        if (length < 0) {
+            return componentType.getTypeIdentifier(accumulator, varIdentifier) + "[]";
+        } else {
+            return componentType.getTypeIdentifier(accumulator, varIdentifier) + "[" + length + "]";
+        }
+    }
 }

ferox-renderer/ferox-renderer-api/src/main/java/com/ferox/resource/shader/Environment.java

     private final Environment parent;
     private final Map<String, Type> variables;
 
-    public Environment() {
-        this(new HashMap<String, Type>());
+    private final boolean inLoop;
+    private final boolean inFragmentShader;
+    private final Type requiredReturnType;
+
+    public Environment(boolean inFragmentShader) {
+        this(inFragmentShader, new HashMap<String, Type>());
     }
 
-    public Environment(Map<String, Type> initialState) {
+    public Environment(boolean inFragmentShader, Map<String, Type> initialState) {
         this.parent = null;
+        this.inFragmentShader = inFragmentShader;
+        requiredReturnType = PrimitiveType.VOID;
+        inLoop = false;
         variables = new HashMap<String, Type>(initialState);
     }
 
-    private Environment(Environment parent, Map<String, Type> newState) {
+    private Environment(Environment parent, boolean inFragmentShader, boolean inLoop,
+                        Type requiredReturnType, Map<String, Type> newState) {
         this.parent = parent;
+        this.inFragmentShader = inFragmentShader;
+        this.requiredReturnType = requiredReturnType;
+        this.inLoop = inLoop;
         variables = newState;
     }
 
+    public boolean inLoop() {
+        return inLoop;
+    }
+
+    public Type getRequiredReturnType() {
+        return requiredReturnType;
+    }
+
+    public boolean inFragmentShader() {
+        return inFragmentShader;
+    }
+
     public Type getVariable(String name) {
         Type inScope = variables.get(name);
         if (inScope == null && parent != null) {
         return parent;
     }
 
-    public Environment declare(Type type, String name) {
-        Map<String, Type> newState = new HashMap<String, Type>(variables);
-        newState.put(name, type);
-        return new Environment(this, newState);
+    public Environment getRoot() {
+        Environment p = this;
+        while (p.parent != null) {
+            p = p.parent;
+        }
+        return p;
     }
 
-    public Environment newScope() {
-        Map<String, Type> newState = new HashMap<String, Type>(variables);
-        return new Environment(this, newState);
+    public Environment declare(Type type, String name) {
+        Map<String, Type> newState = new HashMap<String, Type>();
+        newState.put(name, type);
+        return new Environment(this,
+                               inFragmentShader,
+                               inLoop,
+                               requiredReturnType,
+                               newState);
+    }
+
+    public Environment functionScope(Type returnType, Map<String, Type> variables) {
+        return new Environment(getRoot(),
+                               inFragmentShader,
+                               false,
+                               returnType,
+                               new HashMap<String, Type>(variables));
+    }
+
+    public Environment newScope(boolean forLoop) {
+        Map<String, Type> newState = new HashMap<String, Type>();
+        return new Environment(this,
+                               inFragmentShader,
+                               forLoop || inLoop,
+                               requiredReturnType,
+                               newState);
     }
 }

ferox-renderer/ferox-renderer-api/src/main/java/com/ferox/resource/shader/Expression.java

 
     public LValue array(Expression index);
 
+    public LValue x();
+
+    public LValue y();
+
+    public LValue z();
+
+    public LValue xy();
+
+    public LValue xyz();
+
+    public LValue m(int col, int row);
+
     public Type getType(Environment env);
+
+    public String emitExpression(ShaderAccumulator accumulator);
+
+    public boolean containsDeclaration();
+
+    public int getPrecedence();
 }

ferox-renderer/ferox-renderer-api/src/main/java/com/ferox/resource/shader/Function.java

 
 import java.util.Map;
 
-public interface Function {
+public interface Function extends GlslElement {
     public Expression call(Expression... parameters);
 
     public String getName();
 
     public Map<String, Type> getParameters();
 
+    public Type[] getParameterTypes();
+
     public Type getReturnType();
 }

ferox-renderer/ferox-renderer-api/src/main/java/com/ferox/resource/shader/LValue.java

 package com.ferox.resource.shader;
 
 public interface LValue extends Expression {
-    public Statement setTo(Expression value);
+    public Expression setTo(Expression value);
 }

ferox-renderer/ferox-renderer-api/src/main/java/com/ferox/resource/shader/PrimitiveType.java

     SAMPLER2DSHADOW;
 
     @Override
-    public String getTypeIdentifier() {
-        return name().toLowerCase();
+    public String getTypeIdentifier(ShaderAccumulator accumulator, String varIdentifier) {
+        return name().toLowerCase() + " " + varIdentifier;
     }
 }

ferox-renderer/ferox-renderer-api/src/main/java/com/ferox/resource/shader/ShaderAccumulator.java

 public interface ShaderAccumulator {
     public void addLine(String code);
 
-    public ShaderAccumulator indent();
+    public void pushIndent();
+
+    public void popIndent();
 
     public void accumulateFunction(Function f);
+
+    public void accumulateStruct(Struct s);
 }

ferox-renderer/ferox-renderer-api/src/main/java/com/ferox/resource/shader/Struct.java

 
 public interface Struct extends Type, GlslElement {
     public Map<String, Type> getFields();
+
+    public String[] getOrderedFields();
 }

ferox-renderer/ferox-renderer-api/src/main/java/com/ferox/resource/shader/Type.java

 package com.ferox.resource.shader;
 
 public interface Type {
-    public String getTypeIdentifier();
+    public String getTypeIdentifier(ShaderAccumulator accumulator, String varIdentifier);
 }

ferox-renderer/ferox-renderer-api/src/main/java/com/ferox/resource/shader/VertexShaderBuilder.java

 package com.ferox.resource.shader;
 
-import java.sql.Struct;
 
 public interface VertexShaderBuilder {
     public VertexShaderBuilder uniform(Type type, String name);
 
     public VertexShaderBuilder constant(Type type, String name);
 
-    public VertexShaderBuilder struct(Struct type);
-
     public VertexShaderBuilder in(Type type, String name);
 
     public VertexShaderBuilder out(Type type, String name);
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.