commit f291130e58193fc42197cab5f277365b9d2ad853
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Tue May 7 23:35:23 2019 +0100

    Progress with DistortedCube.

diff --git a/src/main/java/org/distorted/effect/TransitionEffect.java b/src/main/java/org/distorted/effect/TransitionEffect.java
index 6d8bfff1..1395b154 100644
--- a/src/main/java/org/distorted/effect/TransitionEffect.java
+++ b/src/main/java/org/distorted/effect/TransitionEffect.java
@@ -33,18 +33,12 @@ public abstract class TransitionEffect implements EffectListener
   {
   public enum Type
     {
-    /**
-     * No transition effect at all, just detach the old cube and attach the new one straight away.
-     */
-    EMPTY      (TransitionEffectEmpty.class),
-    /**
-     * Gradually make the old cube more and more transparent until it disappears, then make the new one appear.
-     */
+    EMPTY      (TransitionEffectEmpty.class    ),
     DISAPPEAR  (TransitionEffectDisappear.class),
-    /**
-     * Move the old cube to the right and the new one from the left.
-     */
-    MOVE       (TransitionEffectMove.class);
+    MOVE       (TransitionEffectMove.class     ),
+    ROUND      (TransitionEffectRound.class    ),
+    SCALE      (TransitionEffectScale.class    ),
+    ;
 
     private final Class<? extends TransitionEffect> effectClass;
 
@@ -54,37 +48,76 @@ public abstract class TransitionEffect implements EffectListener
       }
     }
 
-  private final int MOVE_POSITION;
-  private long mDisappearID, mAppearID;
+  private final int FAKE_EFFECT_ID = -1;
+
+  private int mOldCubeEffectNumber  , mNewCubeEffectNumber;
+  private int mOldCubeEffectReturned, mNewCubeEffectReturned;
+
   private EffectListener mListener;
   private DistortedScreen mScreen;
-  private RubikCube mOld, mNew;
+  private RubikCube mOldCube, mNewCube;
 
-  Effect mDisappear, mAppear;
+  Effect[] mOldCubeEffects, mNewCubeEffects;
+  int[] mOldCubeEffectPosition, mNewCubeEffectPosition;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  TransitionEffect(int position)
+  TransitionEffect()
     {
-    MOVE_POSITION = position;
+    mOldCubeEffectReturned = 0;
+    mNewCubeEffectReturned = 0;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-// whenever we get the message that the old cube completely disappeared, make the new one appear
-// The calling RubikRenderer will get the message that this (final) transition is over and do whatever
-// it wants to do with this.
 
   public void effectMessage(final EffectMessage em, final long effectID, final long objectID)
     {
-    if( effectID == mDisappearID )
+    //android.util.Log.e("transition", "transition effect "+System.currentTimeMillis());
+
+    for(int i=0; i<mOldCubeEffectNumber; i++)
       {
-      mScreen.detach(mOld);
-      mOld.remove(mDisappearID);
-      mOld.deregisterForMessages(this);
+      long id = mOldCubeEffects[i].getID();
+
+      if( effectID == id )
+        {
+        //android.util.Log.e("transition", i+" old effect "+System.currentTimeMillis());
+
+        mOldCubeEffectReturned++;
+        mOldCube.remove(id);
+
+        if( mOldCubeEffectReturned == mOldCubeEffectNumber )
+          {
+          mScreen.detach(mOldCube);
+          mOldCube.deregisterForMessages(this);
+
+          for(int j=0; j<mOldCubeEffectNumber; j++)
+            {
+            mNewCube.apply(mNewCubeEffects[j],mNewCubeEffectPosition[j]);
+            }
+          mScreen.attach(mNewCube);
+          }
+        break;
+        }
+      }
 
-      mNew.apply(mAppear,MOVE_POSITION);
-      mNew.registerForMessages(mListener);
-      mScreen.attach(mNew);
+    for(int i=0; i<mNewCubeEffectNumber; i++)
+      {
+      long id = mNewCubeEffects[i].getID();
+
+      if( effectID == id )
+        {
+        //android.util.Log.e("transition", i+" new effect "+System.currentTimeMillis());
+
+        mNewCubeEffectReturned++;
+        mNewCube.remove(id);
+
+        if( mNewCubeEffectReturned == mNewCubeEffectNumber )
+          {
+          mNewCube.deregisterForMessages(this);
+          mListener.effectMessage(null, FAKE_EFFECT_ID, 0);
+          }
+        break;
+        }
       }
     }
 
@@ -93,17 +126,37 @@ public abstract class TransitionEffect implements EffectListener
   public long start(DistortedScreen screen, RubikCube oldCube, RubikCube newCube,EffectListener listener)
     {
     mScreen   = screen;
-    mNew      = newCube;
-    mOld      = oldCube;
+    mNewCube  = newCube;
+    mOldCube  = oldCube;
     mListener = listener;
 
-    mDisappearID = mDisappear.getID();
-    mAppearID    = mAppear.getID();
+    if( mOldCubeEffects!=null )
+      {
+      mOldCubeEffectNumber = mOldCubeEffects.length;
+      }
+    else
+      {
+      throw new RuntimeException("Old Cube Effects not created!");
+      }
+
+    if( mNewCubeEffects!=null )
+      {
+      mNewCubeEffectNumber = mNewCubeEffects.length;
+      }
+    else
+      {
+      throw new RuntimeException("New Cube Effects not created!");
+      }
+
+    for(int i=0; i<mOldCubeEffectNumber; i++)
+      {
+      mOldCube.apply(mOldCubeEffects[i],mOldCubeEffectPosition[i]);
+      }
 
-    mOld.apply(mDisappear,MOVE_POSITION);
-    mOld.registerForMessages(this);
+    mOldCube.registerForMessages(this);
+    mNewCube.registerForMessages(this);
 
-    return mAppearID;
+    return FAKE_EFFECT_ID;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/effect/TransitionEffectDisappear.java b/src/main/java/org/distorted/effect/TransitionEffectDisappear.java
index 04401641..1bef51aa 100644
--- a/src/main/java/org/distorted/effect/TransitionEffectDisappear.java
+++ b/src/main/java/org/distorted/effect/TransitionEffectDisappear.java
@@ -19,6 +19,7 @@
 
 package org.distorted.effect;
 
+import org.distorted.library.effect.Effect;
 import org.distorted.library.effect.FragmentEffectAlpha;
 import org.distorted.library.type.Dynamic1D;
 import org.distorted.library.type.Static1D;
@@ -29,19 +30,23 @@ class TransitionEffectDisappear extends TransitionEffect
   {
   TransitionEffectDisappear()
     {
-    super(-1);
-
     final int DURATION_IN_MILLIS = 1000;
 
-    Dynamic1D disappearDyn = new Dynamic1D(DURATION_IN_MILLIS, 0.5f);
-    disappearDyn.add(new Static1D(1.0f));
-    disappearDyn.add(new Static1D(0.0f));
-    mDisappear = new FragmentEffectAlpha(disappearDyn);
+    mOldCubeEffectPosition = new int[] {-1};
+    mOldCubeEffects        = new Effect[mOldCubeEffectPosition.length];
+
+    Dynamic1D oldCube0 = new Dynamic1D(DURATION_IN_MILLIS, 0.5f);
+    oldCube0.add(new Static1D(1.0f));
+    oldCube0.add(new Static1D(0.0f));
+    mOldCubeEffects[0] = new FragmentEffectAlpha(oldCube0);
+
+    mNewCubeEffectPosition = new int[] {-1};
+    mNewCubeEffects        = new Effect[mNewCubeEffectPosition.length];
 
-    Dynamic1D appearDyn = new Dynamic1D(DURATION_IN_MILLIS, 0.5f);
-    appearDyn.add(new Static1D(0.0f));
-    appearDyn.add(new Static1D(1.0f));
-    mAppear = new FragmentEffectAlpha(appearDyn);
+    Dynamic1D newCube0 = new Dynamic1D(DURATION_IN_MILLIS, 0.5f);
+    newCube0.add(new Static1D(0.0f));
+    newCube0.add(new Static1D(1.0f));
+    mNewCubeEffects[0] = new FragmentEffectAlpha(newCube0);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/effect/TransitionEffectEmpty.java b/src/main/java/org/distorted/effect/TransitionEffectEmpty.java
index 6eb5430f..7461d8c1 100644
--- a/src/main/java/org/distorted/effect/TransitionEffectEmpty.java
+++ b/src/main/java/org/distorted/effect/TransitionEffectEmpty.java
@@ -19,6 +19,7 @@
 
 package org.distorted.effect;
 
+import org.distorted.library.effect.Effect;
 import org.distorted.library.effect.MatrixEffectMove;
 import org.distorted.library.type.Dynamic3D;
 import org.distorted.library.type.Static3D;
@@ -29,17 +30,21 @@ class TransitionEffectEmpty extends TransitionEffect
   {
   TransitionEffectEmpty()
     {
-    super(-1);
-
     final int DURATION_IN_MILLIS = 1;
 
-    Dynamic3D disappearDyn = new Dynamic3D(DURATION_IN_MILLIS, 0.5f);
-    disappearDyn.add(new Static3D(0,0,0));
-    mDisappear = new MatrixEffectMove(disappearDyn);
+    mOldCubeEffectPosition = new int[] {-1};
+    mOldCubeEffects        = new Effect[mOldCubeEffectPosition.length];
+
+    Dynamic3D oldCube0 = new Dynamic3D(DURATION_IN_MILLIS, 0.5f);
+    oldCube0.add(new Static3D(0,0,0));
+    mOldCubeEffects[0] = new MatrixEffectMove(oldCube0);
+
+    mNewCubeEffectPosition = new int[] {-1};
+    mNewCubeEffects        = new Effect[mNewCubeEffectPosition.length];
 
-    Dynamic3D appearDyn = new Dynamic3D(DURATION_IN_MILLIS, 0.5f);
-    appearDyn.add(new Static3D(0,0,0));
-    mAppear = new MatrixEffectMove(appearDyn);
+    Dynamic3D newCube0 = new Dynamic3D(DURATION_IN_MILLIS, 0.5f);
+    newCube0.add(new Static3D(0,0,0));
+    mNewCubeEffects[0] = new MatrixEffectMove(newCube0);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/effect/TransitionEffectMove.java b/src/main/java/org/distorted/effect/TransitionEffectMove.java
index 3461c157..835374ed 100644
--- a/src/main/java/org/distorted/effect/TransitionEffectMove.java
+++ b/src/main/java/org/distorted/effect/TransitionEffectMove.java
@@ -19,6 +19,7 @@
 
 package org.distorted.effect;
 
+import org.distorted.library.effect.Effect;
 import org.distorted.library.effect.MatrixEffectMove;
 import org.distorted.library.type.Dynamic3D;
 import org.distorted.library.type.Static3D;
@@ -31,19 +32,23 @@ class TransitionEffectMove extends TransitionEffect
   {
   TransitionEffectMove()
     {
-    super(2);
-
     final int DURATION_IN_MILLIS = 1000;
 
-    Dynamic3D disappearDyn = new Dynamic3D(DURATION_IN_MILLIS, 0.5f);
-    disappearDyn.add(new Static3D(0,0,0));
-    disappearDyn.add(new Static3D(TEXTURE_SIZE,0,0));
-    mDisappear = new MatrixEffectMove(disappearDyn);
+    mOldCubeEffectPosition = new int[] {2};
+    mOldCubeEffects        = new Effect[mOldCubeEffectPosition.length];
+
+    Dynamic3D oldCube0 = new Dynamic3D(DURATION_IN_MILLIS, 0.5f);
+    oldCube0.add(new Static3D(0,0,0));
+    oldCube0.add(new Static3D(TEXTURE_SIZE,0,0));
+    mOldCubeEffects[0] = new MatrixEffectMove(oldCube0);
+
+    mNewCubeEffectPosition = new int[] {2};
+    mNewCubeEffects        = new Effect[mNewCubeEffectPosition.length];
 
-    Dynamic3D appearDyn = new Dynamic3D(DURATION_IN_MILLIS, 0.5f);
-    appearDyn.add(new Static3D(-TEXTURE_SIZE,0,0));
-    appearDyn.add(new Static3D(0,0,0));
-    mAppear = new MatrixEffectMove(appearDyn);
+    Dynamic3D newCube0 = new Dynamic3D(DURATION_IN_MILLIS, 0.5f);
+    newCube0.add(new Static3D(-TEXTURE_SIZE,0,0));
+    newCube0.add(new Static3D(0,0,0));
+    mNewCubeEffects[0] = new MatrixEffectMove(newCube0);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/magic/RubikActivity.java b/src/main/java/org/distorted/magic/RubikActivity.java
index d95b9463..6a03bf77 100644
--- a/src/main/java/org/distorted/magic/RubikActivity.java
+++ b/src/main/java/org/distorted/magic/RubikActivity.java
@@ -106,10 +106,13 @@ public class RubikActivity extends Activity
           break;
           }
 
-      markButton(size);
-
       RubikSurfaceView view = findViewById(R.id.rubikSurfaceView);
-      view.setNewCubeSize(size);
+      boolean success = view.setNewCubeSize(size);
+
+      if( success )
+        {
+        markButton(size);
+        }
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/magic/RubikCube.java b/src/main/java/org/distorted/magic/RubikCube.java
index 0bba5ff2..3be9007d 100644
--- a/src/main/java/org/distorted/magic/RubikCube.java
+++ b/src/main/java/org/distorted/magic/RubikCube.java
@@ -24,6 +24,7 @@ import android.graphics.Canvas;
 import android.graphics.Paint;
 
 import org.distorted.library.effect.Effect;
+import org.distorted.library.effect.EffectType;
 import org.distorted.library.effect.MatrixEffectMove;
 import org.distorted.library.effect.MatrixEffectQuaternion;
 import org.distorted.library.effect.MatrixEffectRotate;
@@ -181,7 +182,7 @@ public class RubikCube extends DistortedNode
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    public void apply(Effect effect)
+    public void apply(Effect effect, int position)
       {
       for(int x=0; x<mSize; x++)
         for(int y=0; y<mSize; y++)
@@ -189,14 +190,14 @@ public class RubikCube extends DistortedNode
             {
             if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 )
               {
-              mEffects[x][y][z].apply(effect);
+              mEffects[x][y][z].apply(effect, position);
               }
             }
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    public void apply(Effect effect, int position)
+    public void remove(long effectID)
       {
       for(int x=0; x<mSize; x++)
         for(int y=0; y<mSize; y++)
@@ -204,24 +205,16 @@ public class RubikCube extends DistortedNode
             {
             if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 )
               {
-              mEffects[x][y][z].apply(effect, position);
+              mEffects[x][y][z].abortById(effectID);
               }
             }
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    public void remove(long effectID)
+    public int getNumEffects(EffectType type)
       {
-      for(int x=0; x<mSize; x++)
-        for(int y=0; y<mSize; y++)
-          for(int z=0; z<mSize; z++)
-            {
-            if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 )
-              {
-              mEffects[x][y][z].abortById(effectID);
-              }
-            }
+      return mEffects[0][0][0].getNumEffects(type);
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/magic/RubikRenderer.java b/src/main/java/org/distorted/magic/RubikRenderer.java
index 0cd09a31..5fba056b 100644
--- a/src/main/java/org/distorted/magic/RubikRenderer.java
+++ b/src/main/java/org/distorted/magic/RubikRenderer.java
@@ -22,6 +22,7 @@ package org.distorted.magic;
 import android.opengl.GLSurfaceView;
 
 import org.distorted.effect.TransitionEffect;
+import org.distorted.library.effect.EffectType;
 import org.distorted.library.effect.VertexEffectSink;
 import org.distorted.library.main.DistortedEffects;
 import org.distorted.library.main.DistortedLibrary;
@@ -131,7 +132,7 @@ public class RubikRenderer implements GLSurfaceView.Renderer, EffectListener
 
         try
           {
-          TransitionEffect effect = TransitionEffect.create(TransitionEffect.Type.EMPTY);
+          TransitionEffect effect = TransitionEffect.create(TransitionEffect.Type.ROUND);
           mTransitionEffectID = effect.start(mScreen,mOldCube,mNewCube,this);
           }
         catch(Exception ex)
@@ -150,14 +151,29 @@ public class RubikRenderer implements GLSurfaceView.Renderer, EffectListener
      {
      if(      effectID == mRotationFinishedID )
        {
+       //android.util.Log.e("renderer", "rotation finished");
+
        mRemoveRotation = true;
        }
      else if( effectID == mTransitionEffectID )
        {
+       /*
+       int nM = mNewCube.getNumEffects(EffectType.MATRIX);
+       int nV = mNewCube.getNumEffects(EffectType.VERTEX);
+       int nF = mNewCube.getNumEffects(EffectType.FRAGMENT);
+       int nP = mNewCube.getNumEffects(EffectType.POSTPROCESS);
+
+       android.util.Log.d("renderer", "transition finished, new cube effects= "+nM+","+nV+","+nF+","+nP);
+
+       int oM = mOldCube.getNumEffects(EffectType.MATRIX);
+       int oV = mOldCube.getNumEffects(EffectType.VERTEX);
+       int oF = mOldCube.getNumEffects(EffectType.FRAGMENT);
+       int oP = mOldCube.getNumEffects(EffectType.POSTPROCESS);
+
+       android.util.Log.d("renderer", "transition finished, old cube effects= "+oM+","+oV+","+oF+","+oP);
+       */
        mCanRotate = true;
        mCanDrag   = true;
-       mNewCube.remove(mTransitionEffectID);
-       mNewCube.deregisterForMessages(this);
        }
      }
 
@@ -218,9 +234,17 @@ public class RubikRenderer implements GLSurfaceView.Renderer, EffectListener
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-   void createCube(int newSize)
+   boolean createCube(int newSize)
      {
-     mNextCubeSize = newSize;
+     if( mCanDrag && mCanRotate )
+       {
+       mNextCubeSize = newSize;
+       return true;
+       }
+
+     android.util.Log.e("renderer", "cannot change, drag="+mCanDrag+" rotate="+mCanRotate);
+
+     return false;
      }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/magic/RubikSurfaceView.java b/src/main/java/org/distorted/magic/RubikSurfaceView.java
index b15825ff..4532c131 100644
--- a/src/main/java/org/distorted/magic/RubikSurfaceView.java
+++ b/src/main/java/org/distorted/magic/RubikSurfaceView.java
@@ -162,9 +162,9 @@ class RubikSurfaceView extends GLSurfaceView
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    void setNewCubeSize(int newCubeSize)
+    boolean setNewCubeSize(int newCubeSize)
       {
-      mRenderer.createCube(newCubeSize);
+      return mRenderer.createCube(newCubeSize);
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
