Просмотр исходного кода

refactor: make typesafe and immutable

Riccardo Balbo 2 дней назад
Родитель
Сommit
c42dfdcee0

+ 11 - 19
jme3-effects/src/main/java/com/jme3/vectoreffect/EaseVectorEffect.java

@@ -52,27 +52,30 @@ public final class EaseVectorEffect extends VectorEffect {
 
     private EaseFunction easeFunction = Easing.linear; 
 
-    public EaseVectorEffect(Object vectorToModify) {
+    public EaseVectorEffect(VectorGroup vectorToModify) {
         super(vectorToModify);
     }
     
-    public EaseVectorEffect(Object vectorToModify, Object targetVector, float duration) {
+    public EaseVectorEffect(VectorGroup vectorToModify, VectorGroup targetVector, float duration) {
         this(vectorToModify);
         setEaseToValueOverDuration(duration, targetVector);
     }
     
-    public EaseVectorEffect(Object vectorToModify, Object targetVector, float duration, float delay) {
+    public EaseVectorEffect(VectorGroup vectorToModify, VectorGroup targetVector, float duration,
+            float delay) {
         this(vectorToModify);
         setEaseToValueOverDuration(duration, targetVector);
         setDelayTime(delay);
     }
     
-    public EaseVectorEffect(Object vectorToModify, Object targetVector, float duration, EaseFunction easeFunction) {
+    public EaseVectorEffect(VectorGroup vectorToModify, VectorGroup targetVector, float duration,
+            EaseFunction easeFunction) {
         this(vectorToModify, targetVector, duration);
         setEaseFunction(easeFunction);
     }
     
-    public EaseVectorEffect(Object vectorToModify, Object targetVector, float duration, EaseFunction easeFunction, float delay) {
+    public EaseVectorEffect(VectorGroup vectorToModify, VectorGroup targetVector, float duration,
+            EaseFunction easeFunction, float delay) {
         this(vectorToModify, targetVector, duration);
         setEaseFunction(easeFunction);
         setDelayTime(delay);
@@ -89,12 +92,7 @@ public final class EaseVectorEffect extends VectorEffect {
 
         
         if (startVectors == null) {
-            startVectors = new VectorGroup();
-            
-            for(int v = 0; v < vectorsToModify.getSize(); v++){
-                Vector4f startVector = vectorsToModify.getAsVector4(v).clone();
-                startVectors.addVectorToGroup(startVector);
-            }
+            startVectors = vectorsToModify.clone();
         }
 
         easeTimer += tpf;
@@ -117,14 +115,8 @@ public final class EaseVectorEffect extends VectorEffect {
         }
     }
 
-    public EaseVectorEffect setEaseToValueOverDuration(float dur, Object targetVector) {
-        if(targetVector instanceof VectorGroup){
-            targetVectors = (VectorGroup) targetVector;
-        }
-        else{
-            targetVectors = new VectorGroup(targetVector);
-        }
-        
+    public EaseVectorEffect setEaseToValueOverDuration(float dur, VectorGroup targetVector) {
+        this.targetVectors = targetVector;
         duration = dur;
         startVectors = null;
         return this;

+ 5 - 14
jme3-effects/src/main/java/com/jme3/vectoreffect/NoiseVectorEffect.java

@@ -49,19 +49,15 @@ public class NoiseVectorEffect extends VectorEffect {
     public float speed = 1;
     private float timeAccrued = 0;
     
-    public NoiseVectorEffect(Object vectorObject, Object noiseMagnitude) {
+    public NoiseVectorEffect(VectorGroup vectorObject, VectorGroup noiseMagnitude) {
         this(vectorObject, noiseMagnitude, NoiseType.OpenSimplex2, 0.5f);       
     }
     
-    public NoiseVectorEffect(Object vectorObject, Object noiseMagnitude, NoiseType noiseType, float frequency) {
+    public NoiseVectorEffect(VectorGroup vectorObject, VectorGroup noiseMagnitude, NoiseType noiseType,
+            float frequency) {
         super(vectorObject);
         
-        if(noiseMagnitude instanceof VectorGroup){
-            noiseMagnitudes = (VectorGroup) noiseMagnitude;
-        }else{
-            noiseMagnitudes = new VectorGroup(noiseMagnitude);
-        }        
-        
+        this.noiseMagnitudes = noiseMagnitude;
         noiseGenerator = new FastNoiseLite();
         noiseGenerator.SetFrequency(frequency);
         noiseGenerator.SetNoiseType(noiseType);       
@@ -73,12 +69,7 @@ public class NoiseVectorEffect extends VectorEffect {
         super.update(tpf);
         
         if(originalVectorValues == null){
-            originalVectorValues = new VectorGroup();
-            for(int v = 0; v < vectorsToModify.getSize(); v++){
-                Vector4f startVector = vectorsToModify.getAsVector4(v).clone();
-                originalVectorValues.addVectorToGroup(startVector);
-            }
-
+            originalVectorValues = vectorsToModify.clone();
         }
         
         timeAccrued += tpf;                

+ 2 - 7
jme3-effects/src/main/java/com/jme3/vectoreffect/VectorEffect.java

@@ -52,13 +52,8 @@ public abstract class VectorEffect {
         
     }
     
-    public VectorEffect(Object vectorObj) {
-        
-        if(vectorObj instanceof VectorGroup){
-            vectorsToModify = (VectorGroup) vectorObj;
-        }else{
-            vectorsToModify = new VectorGroup(vectorObj); 
-        }        
+    public VectorEffect(VectorGroup vectorsToModify) {
+        this.vectorsToModify = vectorsToModify;
     }        
     
     public void setIsFinished(boolean isFinished) {        

+ 37 - 75
jme3-effects/src/main/java/com/jme3/vectoreffect/VectorGroup.java

@@ -42,98 +42,60 @@ import java.util.ArrayList;
  *
  * @author yaRnMcDonuts
  */
-public class VectorGroup {
+public class VectorGroup implements Cloneable {
     
-    private final ArrayList vectorList = new ArrayList();    
+    protected final ArrayList<VectorSupplier> vectorSupplier = new ArrayList<>();
         
     public int getSize(){
-        return vectorList.size();
+        return vectorSupplier.size();
     }
     
-    public VectorGroup(Object... vectorObjects) {
-        for(int v = 0; v < vectorObjects.length; v++){
-            addVectorToGroup(vectorObjects[v]);
+    public VectorGroup(VectorSupplier... vectorSuppliers) {
+        for (VectorSupplier vs : vectorSuppliers) {
+            vectorSupplier.add(vs);
         }
     }
-    
-    public final void addVectorToGroup(Object vectorObj){
-        if(isValidVectorObject(vectorObj)){
-            vectorList.add(vectorObj);
-        } else{  
-            throw new IllegalArgumentException(  "VectorGroup must contain valid vector-type objects. This includes: Vector2f, Vector3f, Vector4f, and ColorRGBA/ Incompatible type: " + vectorObj.getClass().getSimpleName());
+
+    public VectorGroup(ColorRGBA... color) {
+        for (ColorRGBA c : color) {
+            this.vectorSupplier.add(VectorSupplier.of(c));
         }
     }
-    
-    
-   //regardless of type, all vectors in a VectorGroup are converted to and from Vector4f when being operated on internally by a VectorEffect.     
-    public Vector4f getAsVector4(int index) {
-        Object vectorObj = vectorList.get(index);
-        if (vectorObj instanceof Vector4f) {
-            Vector4f vec4 = (Vector4f) vectorObj;
-            return vec4.clone();  
-        }
-        else if (vectorObj instanceof Vector3f) {
-            Vector3f vec3 = (Vector3f) vectorObj;
-            return new Vector4f(vec3.x, vec3.y, vec3.z, 1f); 
-        }
-        else if (vectorObj instanceof Vector2f) {
-            Vector2f vec2 = (Vector2f) vectorObj;
-            return new Vector4f(vec2.x, vec2.y, 1f, 1f);  
-        }
-        else if (vectorObj instanceof ColorRGBA) {
-            ColorRGBA color = (ColorRGBA) vectorObj;
-            return color.toVector4f(); 
-        }
-        else {
-            throw new IllegalStateException("VectorEffect supports only Vector2f, Vector3f, Vector4f, or ColorRGBA");
+
+    public VectorGroup(Vector4f... vectors) {
+        for (Vector4f v : vectors) {
+            this.vectorSupplier.add(VectorSupplier.of(v));
         }
     }
 
-    public void updateVectorObject(Vector4f newVal, int index) {
-        Object store = vectorList.get(index);
-        if (store instanceof Vector4f) {
-            ((Vector4f)store).set(newVal);  // set vec4
-        }
-        else if (store instanceof Vector3f) {
-            ((Vector3f)store).set(newVal.x, newVal.y, newVal.z);  
-        }
-        else if (store instanceof Vector2f) {
-            ((Vector2f)store).set(newVal.x, newVal.y);  // drop z,w
+    public VectorGroup(Vector3f... vectors) {
+        for (Vector3f v : vectors) {
+            this.vectorSupplier.add(VectorSupplier.of(v));
         }
-        else if (store instanceof ColorRGBA) {
-            ((ColorRGBA)store).set(newVal.x, newVal.y, newVal.z, newVal.w);  // map xyzw -> rgba
-        }
-        else {
-            throw new IllegalStateException("VectorEffect supports only Vector2f, Vector3f, Vector4f, or ColorRGBA");
+    }
+
+    public VectorGroup(Vector2f... vectors) {
+        for (Vector2f v : vectors) {
+            this.vectorSupplier.add(VectorSupplier.of(v));
         }
     }
-    
-    private boolean isValidVectorObject(Object vectorObj){
-        return (vectorObj instanceof Vector2f || vectorObj instanceof Vector3f || vectorObj instanceof Vector4f || vectorObj instanceof ColorRGBA || vectorObj instanceof VectorGroup);
+
+    protected Vector4f getAsVector4(int index) {
+        return vectorSupplier.get(index).get();
     }
-    
-        
-    public VectorGroup copy() {
-        VectorGroup newCopy = new VectorGroup();
 
-        for (Object vectorObj : vectorList) {
-            if (vectorObj instanceof Vector2f) {
-                Vector2f v2 = (Vector2f) vectorObj;
-                newCopy.addVectorToGroup(v2.clone());
-            } else if (vectorObj instanceof Vector3f) {
-                Vector3f v3 = (Vector3f) vectorObj;
-                newCopy.addVectorToGroup(v3.clone());
-            } else if (vectorObj instanceof Vector4f) {
-                Vector4f v4 = (Vector4f) vectorObj;
-                newCopy.addVectorToGroup(v4.clone());
-            } else if (vectorObj instanceof ColorRGBA) {
-                ColorRGBA c = (ColorRGBA) vectorObj;
-                newCopy.addVectorToGroup(c.clone());
-            } else {
-                throw new IllegalStateException("Unsupported object type: " + vectorObj.getClass());
-            }
+    protected void updateVectorObject(Vector4f newVal, int index) {
+        VectorSupplier store = vectorSupplier.get(index);
+        store.set(newVal);
+    }
+
+    @Override
+    public VectorGroup clone() {
+        VectorGroup clonedGroup = new VectorGroup(new VectorSupplier[0]);
+        for (VectorSupplier supplier : this.vectorSupplier) {
+            clonedGroup.vectorSupplier.add(supplier);
         }
-        return newCopy;
-    }       
+        return clonedGroup;
+    }
 }
 

+ 126 - 0
jme3-effects/src/main/java/com/jme3/vectoreffect/VectorSupplier.java

@@ -0,0 +1,126 @@
+package com.jme3.vectoreffect;
+
+import com.jme3.math.ColorRGBA;
+import com.jme3.math.Vector2f;
+import com.jme3.math.Vector3f;
+import com.jme3.math.Vector4f;
+
+public interface VectorSupplier extends Cloneable {
+    Vector4f get();
+    void set(Vector4f newVal);
+
+
+
+    static class Vector4fSupplier implements VectorSupplier {
+        private final Vector4f vector;
+
+        Vector4fSupplier(Vector4f vector) {
+            this.vector = vector;
+        }
+
+        public Vector4f get() {
+            return vector;
+        }
+
+        public void set(Vector4f newVal) {
+            this.vector.set(newVal);
+        }
+
+        @Override
+        public Vector4fSupplier clone() {
+            return new Vector4fSupplier(vector.clone());
+        }
+      
+    }
+
+    static class Vector3fSupplier implements VectorSupplier {
+        private final Vector3f vector;
+        private final Vector4f store = new Vector4f();
+        Vector3fSupplier(Vector3f vector) {
+            this.vector = vector;
+        }
+
+        public Vector4f get() {
+            store.set(vector.x, vector.y, vector.z, 0);
+            return store;
+        }
+
+        public void set(Vector4f newVal) {
+            this.vector.set(newVal.x, newVal.y, newVal.z);
+            get(); //update store
+        }
+
+        @Override
+        public Vector3fSupplier clone() {
+            return new Vector3fSupplier(vector.clone());
+        }
+    }
+
+    static class ColorRGBASupplier implements VectorSupplier {
+        private ColorRGBA color;
+        private final Vector4f store = new Vector4f();
+
+        ColorRGBASupplier(ColorRGBA color) {
+            this.color = color;
+        }
+
+        public Vector4f get() {
+            store.set(color.r, color.g, color.b, color.a);
+            return store;
+        }
+
+        public void set(Vector4f newVal) {
+            this.color.set(newVal.x, newVal.y, newVal.z, newVal.w);
+            get(); //update store
+        }
+
+        @Override
+        public ColorRGBASupplier clone() {
+            return new ColorRGBASupplier(color.clone());
+        }
+    }
+
+    static class Vector2fSupplier implements VectorSupplier {
+        private final Vector2f vector;
+        private final Vector4f store = new Vector4f();
+
+        Vector2fSupplier(Vector2f vector) {
+            this.vector = vector;
+        }
+
+        public Vector4f get() {
+            store.set(vector.x, vector.y, 0, 0);
+            return store;
+        }
+
+        public void set(Vector4f newVal) {
+            this.vector.set(newVal.x, newVal.y);
+            get(); //update store
+        }
+
+        @Override
+        public Vector2fSupplier clone() {
+            return new Vector2fSupplier(vector.clone());
+        }
+    }
+    
+
+
+    public static VectorSupplier of(Vector4f vector) {
+        return new Vector4fSupplier(vector);
+    }
+
+    public static VectorSupplier of(Vector3f vector) {
+        return new Vector3fSupplier(vector);
+    }
+
+    public static VectorSupplier of(Vector2f vector) {
+        return new Vector2fSupplier(vector);
+    }
+
+    public static VectorSupplier of(ColorRGBA color) {
+        return new ColorRGBASupplier(color);
+    }
+
+
+}

+ 51 - 66
jme3-examples/src/main/java/jme3test/effect/VectorEffectSimpleTest.java

@@ -33,6 +33,7 @@ package jme3test.effect;
 
 import com.jme3.vectoreffect.EaseVectorEffect;
 import com.jme3.vectoreffect.VectorEffectManagerState;
+import com.jme3.vectoreffect.VectorGroup;
 import com.jme3.vectoreffect.SequencedVectorEffect;
 import com.jme3.app.SimpleApplication;
 import com.jme3.light.PointLight;
@@ -46,9 +47,6 @@ import com.jme3.scene.Geometry;
 import com.jme3.scene.shape.Quad;
 import com.jme3.scene.shape.Sphere;
 import com.jme3.system.AppSettings;
-import java.awt.DisplayMode;
-import java.awt.GraphicsDevice;
-import java.awt.GraphicsEnvironment;
 
 /**
  *
@@ -56,10 +54,10 @@ import java.awt.GraphicsEnvironment;
  */
 public class VectorEffectSimpleTest extends SimpleApplication {
 
-    private ColorRGBA colorToShift  = new ColorRGBA(0.0f, 0.0f, 1.0f, 1.0f);
-    
-    private VectorEffectManagerState vectorEffectManagerState;    
-    
+    private ColorRGBA colorToShift = new ColorRGBA(0.0f, 0.0f, 1.0f, 1.0f);
+
+    private VectorEffectManagerState vectorEffectManagerState;
+
     public static void main(String[] args) {
         VectorEffectSimpleTest app = new VectorEffectSimpleTest();
         AppSettings settings = new AppSettings(true);
@@ -67,54 +65,52 @@ public class VectorEffectSimpleTest extends SimpleApplication {
         app.start();
     }
 
-
     @Override
     public void simpleInitApp() {
         restart();
         flyCam.setMoveSpeed(10f);
-        
+
         vectorEffectManagerState = new VectorEffectManagerState();
         stateManager.attach(vectorEffectManagerState);
-        
+
         initBloom();
         initPbrRoom(13);
-        
+
         initLightAndEmissiveSphere();
-    
-     //initiate VectorEffectManagerState    
+
+        // initiate VectorEffectManagerState
         vectorEffectManagerState = new VectorEffectManagerState();
         stateManager.attach(vectorEffectManagerState);
         vectorEffectManagerState.setEnabled(true);
-        
-     //create gradient effect :
+
+        // create gradient effect :
+        VectorGroup vg = new VectorGroup(colorToShift);
         SequencedVectorEffect colorGradientEffect = new SequencedVectorEffect(
-                new EaseVectorEffect(colorToShift, ColorRGBA.Cyan, 0.75f),
-                new EaseVectorEffect(colorToShift, ColorRGBA.Yellow, 0.75f),
-                new EaseVectorEffect(colorToShift, ColorRGBA.Blue, 0.75f ),
-                new EaseVectorEffect(colorToShift, ColorRGBA.Magenta, 0.75f),
-                new EaseVectorEffect(colorToShift, ColorRGBA.Green, 0.75f),
-                new EaseVectorEffect(colorToShift, ColorRGBA.Red, 0.75f)
-        );
-        
-     //create red flashing effect : 
+                new EaseVectorEffect(vg, new VectorGroup(ColorRGBA.Cyan), 0.75f),
+                new EaseVectorEffect(vg, new VectorGroup(ColorRGBA.Yellow), 0.75f),
+                new EaseVectorEffect(vg, new VectorGroup(ColorRGBA.Blue), 0.75f),
+                new EaseVectorEffect(vg, new VectorGroup(ColorRGBA.Magenta), 0.75f),
+                new EaseVectorEffect(vg, new VectorGroup(ColorRGBA.Green), 0.75f),
+                new EaseVectorEffect(vg, new VectorGroup(ColorRGBA.Red), 0.75f));
+
+        // create red flashing effect :
         SequencedVectorEffect blinkEffect = new SequencedVectorEffect(
-                new EaseVectorEffect(colorToShift, ColorRGBA.Black, 0.25f, Easing.inOutQuad),
-                new EaseVectorEffect(colorToShift, ColorRGBA.Red, 0.175f, Easing.outQuart)
-        );  
+                new EaseVectorEffect(vg, new VectorGroup(ColorRGBA.Black), 0.25f, Easing.inOutQuad),
+                new EaseVectorEffect(vg, new VectorGroup(ColorRGBA.Red), 0.175f, Easing.outQuart));
         blinkEffect.setRepeatNumberOfTimes(10);
-        
-        
-    //put both effects into a looping SequencedVectorEffect    
-        SequencedVectorEffect finalLoopingEffect = new SequencedVectorEffect(colorGradientEffect, blinkEffect);        
+
+        // put both effects into a looping SequencedVectorEffect
+        SequencedVectorEffect finalLoopingEffect = new SequencedVectorEffect(colorGradientEffect,
+                blinkEffect);
         finalLoopingEffect.setLooping(true);
-        
-    //register the effect:
+
+        // register the effect:
         vectorEffectManagerState.registerVectorEffect(finalLoopingEffect);
-        
+
     }
-    
+
     private void initBloom() {
-        
+
         FilterPostProcessor fpp = new FilterPostProcessor(assetManager);
         BloomFilter bloom = new BloomFilter(BloomFilter.GlowMode.Scene);
         bloom.setBloomIntensity(5f);
@@ -125,15 +121,14 @@ public class VectorEffectSimpleTest extends SimpleApplication {
         viewPort.addProcessor(fpp);
     }
 
-    private void initLightAndEmissiveSphere(){
-      
+    private void initLightAndEmissiveSphere() {
 
-      //make point light
+        // make point light
         PointLight light = new PointLight();
         light.setRadius(10);
         colorToShift = light.getColor();
-        
-      //make sphere with Emissive color  
+
+        // make sphere with Emissive color
         Sphere sphereMesh = new Sphere(32, 32, 0.5f);
         Geometry glowingSphere = new Geometry("ShakingSphere", sphereMesh);
 
@@ -143,65 +138,55 @@ public class VectorEffectSimpleTest extends SimpleApplication {
         sphereMat.setFloat("Metallic", 0.98f);
         sphereMat.setBoolean("UseVertexColor", false);
         glowingSphere.setMaterial(sphereMat);
-        
-        
-        //assign the same colorToShift vector to both the light and emissive value (important not to clone)
-        light.setColor(colorToShift);        
-        sphereMat.setColor("Emissive", colorToShift);  
-        
-        
-        rootNode.attachChild(glowingSphere);          
+
+        // assign the same colorToShift vector to both the light and emissive value (important not to clone)
+        light.setColor(colorToShift);
+        sphereMat.setColor("Emissive", colorToShift);
+
+        rootNode.attachChild(glowingSphere);
         rootNode.addLight(light);
-        
-        
+
     }
-    
-    public void initPbrRoom(float size) {
 
+    public void initPbrRoom(float size) {
 
         float half = size * 0.5f;
 
-        
         Material wallMat = new Material(assetManager, "Common/MatDefs/Light/PBRLighting.j3md");
 
-        wallMat.setColor("BaseColor", new ColorRGBA(1,1,1, 1f));
+        wallMat.setColor("BaseColor", new ColorRGBA(1, 1, 1, 1f));
         wallMat.setFloat("Roughness", 0.12f);
         wallMat.setFloat("Metallic", 0.02f);
 
         // Floor
-        Geometry floor = new Geometry("Floor",
-                new Quad(size, size));
+        Geometry floor = new Geometry("Floor", new Quad(size, size));
         floor.setMaterial(wallMat);
         floor.rotate(-FastMath.HALF_PI, 0, 0);
         floor.setLocalTranslation(-half, -half, half);
         rootNode.attachChild(floor);
 
         // Ceiling
-        Geometry ceiling = new Geometry("Ceiling",
-                new Quad(size, size));
+        Geometry ceiling = new Geometry("Ceiling", new Quad(size, size));
         ceiling.setMaterial(wallMat);
         ceiling.rotate(FastMath.HALF_PI, 0, 0);
-        ceiling.setLocalTranslation(-half, size-half, -half);
+        ceiling.setLocalTranslation(-half, size - half, -half);
         rootNode.attachChild(ceiling);
 
         // Back wall
-        Geometry backWall = new Geometry("BackWall",
-                new Quad(size, size));
+        Geometry backWall = new Geometry("BackWall", new Quad(size, size));
         backWall.setMaterial(wallMat);
         backWall.setLocalTranslation(-half, -half, -half);
         rootNode.attachChild(backWall);
 
         // Left wall
-        Geometry leftWall = new Geometry("LeftWall",
-                new Quad(size, size));
+        Geometry leftWall = new Geometry("LeftWall", new Quad(size, size));
         leftWall.setMaterial(wallMat);
         leftWall.rotate(0, FastMath.HALF_PI, 0);
         leftWall.setLocalTranslation(-half, -half, half);
         rootNode.attachChild(leftWall);
 
         // Right wall
-        Geometry rightWall = new Geometry("RightWall",
-                new Quad(size, size));
+        Geometry rightWall = new Geometry("RightWall", new Quad(size, size));
         rightWall.setMaterial(wallMat);
         rightWall.rotate(0, -FastMath.HALF_PI, 0);
         rightWall.setLocalTranslation(half, -half, -half);