commit b3fff6fb6a8d6f661c901a763b0e5b3560dfe67e
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Tue Oct 5 15:12:27 2021 +0200

    Remove the concept of a 'TwistyActivity' altogether.

diff --git a/src/main/java/org/distorted/objectlib/automator/ObjectAutomator.java b/src/main/java/org/distorted/objectlib/automator/ObjectAutomator.java
index e0b6fdb2..19bc0f6c 100644
--- a/src/main/java/org/distorted/objectlib/automator/ObjectAutomator.java
+++ b/src/main/java/org/distorted/objectlib/automator/ObjectAutomator.java
@@ -19,27 +19,28 @@
 
 package org.distorted.objectlib.automator;
 
+import java.lang.ref.WeakReference;
+
+import android.app.Activity;
+
 import org.distorted.library.main.DistortedNode;
 import org.distorted.library.main.DistortedScreen;
 import org.distorted.library.message.EffectListener;
-
 import org.distorted.library.type.Static4D;
+
+import org.distorted.objectlib.helpers.ObjectLibInterface;
 import org.distorted.objectlib.main.ObjectControl;
-import org.distorted.objectlib.main.ObjectPreRender;
 import org.distorted.objectlib.helpers.BlockController;
-import org.distorted.objectlib.helpers.TwistyActivity;
 import org.distorted.objectlib.main.TwistyObject;
 
-import java.lang.ref.WeakReference;
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 public class ObjectAutomator implements EffectListener
   {
   private static ObjectAutomator mControl;
-  private ObjectControl mObjectControl;
+  private final ObjectControl mObjectControl;
 
-  WeakReference<TwistyActivity> mRefAct;
+  WeakReference<Activity> mRefAct;
   boolean mWholeReturned, mRotateReturned;
 
   ObjectAutomatorWhole mWhole;
@@ -49,8 +50,8 @@ public class ObjectAutomator implements EffectListener
 
   DistortedScreen getScreen()
     {
-    TwistyActivity act = mRefAct.get();
-    return act!=null ? act.getScreen() : null;
+    ObjectLibInterface inter = mObjectControl.getInterface();
+    return inter.getScreen();
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -64,17 +65,14 @@ public class ObjectAutomator implements EffectListener
 
   Static4D getQuat()
     {
-    ObjectControl control = getObjectControl();
-    return control.getQuat();
+    return mObjectControl.getQuat();
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   TwistyObject getObject()
     {
-    ObjectControl control = getObjectControl();
-    ObjectPreRender pre =  control.getPreRender();
-    return pre.getObject();
+    return mObjectControl.getObject();
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -115,9 +113,7 @@ public class ObjectAutomator implements EffectListener
       for (DistortedNode node : screenNodes) screen.attach(node);
       }
 
-    ObjectControl control = getObjectControl();
-    ObjectPreRender pre =  control.getPreRender();
-    DistortedNode object = pre.getObject();
+    DistortedNode object = mObjectControl.getObject();
     DistortedNode[] objectNodes = mRotate.getObjectNodes();
 
     if( object!=null && objectNodes!=null )
@@ -138,9 +134,7 @@ public class ObjectAutomator implements EffectListener
       for (DistortedNode node : screenNodes) screen.detach(node);
       }
 
-    ObjectControl control = getObjectControl();
-    ObjectPreRender pre =  control.getPreRender();
-    DistortedNode object = pre.getObject();
+    DistortedNode object = mObjectControl.getObject();
     DistortedNode[] objectNodes = mRotate.returnObjectNodes();
 
     if( object!=null && objectNodes!=null )
@@ -154,9 +148,7 @@ public class ObjectAutomator implements EffectListener
   private void finishWhole()
     {
     removeWholeObjects();
-
     mWholeReturned = true;
-
     if( !mRotateReturned ) addRotateObjects();
     }
 
@@ -166,12 +158,12 @@ public class ObjectAutomator implements EffectListener
     {
     removeRotateObjects();
     mRotateReturned= true;
-    mObjectControl.getPreRender().unblockEverything();
+    mObjectControl.unblockEverything();
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  TwistyActivity getActivity()
+  Activity getActivity()
     {
     return mRefAct.get();
     }
@@ -213,9 +205,9 @@ public class ObjectAutomator implements EffectListener
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public void animateAll(TwistyActivity act)
+  public void animateAll(Activity act)
     {
-    mObjectControl.getPreRender().blockEverything(BlockController.CONTROL_PLACE_0);
+    mObjectControl.blockEverything(BlockController.CONTROL_PLACE_0);
     mRefAct = new WeakReference<>(act);
 
     mWholeReturned = false;
@@ -226,9 +218,9 @@ public class ObjectAutomator implements EffectListener
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public void animateRotate(TwistyActivity act)
+  public void animateRotate(Activity act)
     {
-    mObjectControl.getPreRender().blockEverything(BlockController.CONTROL_PLACE_1);
+    mObjectControl.blockEverything(BlockController.CONTROL_PLACE_1);
     mRefAct = new WeakReference<>(act);
 
     mWholeReturned = true;
diff --git a/src/main/java/org/distorted/objectlib/automator/ObjectAutomatorRotate.java b/src/main/java/org/distorted/objectlib/automator/ObjectAutomatorRotate.java
index 90d284f7..1aceceb7 100644
--- a/src/main/java/org/distorted/objectlib/automator/ObjectAutomatorRotate.java
+++ b/src/main/java/org/distorted/objectlib/automator/ObjectAutomatorRotate.java
@@ -22,6 +22,7 @@ package org.distorted.objectlib.automator;
 import java.io.IOException;
 import java.io.InputStream;
 
+import android.app.Activity;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 
@@ -41,7 +42,6 @@ import org.distorted.library.type.Static4D;
 import org.distorted.library.main.QuatHelper;
 
 import org.distorted.objectlib.R;
-import org.distorted.objectlib.helpers.TwistyActivity;
 import org.distorted.objectlib.main.TwistyObject;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -67,7 +67,7 @@ class ObjectAutomatorRotate implements EffectListener
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-   private Bitmap openBitmap(TwistyActivity act, int resource)
+   private Bitmap openBitmap(Activity act, int resource)
      {
      try( InputStream is = act.getResources().openRawResource(resource) )
        {
@@ -278,7 +278,7 @@ android.util.Log.e("D", "ax: "+ax.get0()+" "+ax.get1()+" "+ax.get2());
       mObjectQuad = new MeshQuad();
       }
 
-    TwistyActivity act = mControl.getActivity();
+    Activity act = mControl.getActivity();
 
     if( act!=null )
       {
diff --git a/src/main/java/org/distorted/objectlib/automator/ObjectAutomatorWhole.java b/src/main/java/org/distorted/objectlib/automator/ObjectAutomatorWhole.java
index c2671f14..3aa17cb0 100644
--- a/src/main/java/org/distorted/objectlib/automator/ObjectAutomatorWhole.java
+++ b/src/main/java/org/distorted/objectlib/automator/ObjectAutomatorWhole.java
@@ -22,6 +22,7 @@ package org.distorted.objectlib.automator;
 import java.io.IOException;
 import java.io.InputStream;
 
+import android.app.Activity;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 
@@ -35,8 +36,8 @@ import org.distorted.library.mesh.MeshQuad;
 import org.distorted.library.type.Dynamic;
 import org.distorted.library.type.Dynamic3D;
 import org.distorted.library.type.Static3D;
+
 import org.distorted.objectlib.R;
-import org.distorted.objectlib.helpers.TwistyActivity;
 import org.distorted.objectlib.main.ObjectControl;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -79,14 +80,14 @@ class ObjectAutomatorWhole
 
    private void setPostFrame(boolean on)
      {
-     TwistyActivity act = mControl.getActivity();
+     Activity act = mControl.getActivity();
   //   act.setControlState(on);
      mLastTime = -1;
      }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-   private Bitmap openBitmap(TwistyActivity act, int resource)
+   private Bitmap openBitmap(Activity act, int resource)
      {
      try( InputStream is = act.getResources().openRawResource(resource) )
        {
@@ -825,7 +826,7 @@ class ObjectAutomatorWhole
       mQuad  = new MeshQuad();
       }
 
-    TwistyActivity act = mControl.getActivity();
+    Activity act = mControl.getActivity();
 
     if( act!=null )
       {
diff --git a/src/main/java/org/distorted/objectlib/helpers/BlockController.java b/src/main/java/org/distorted/objectlib/helpers/BlockController.java
index bc2bfb49..032278c1 100644
--- a/src/main/java/org/distorted/objectlib/helpers/BlockController.java
+++ b/src/main/java/org/distorted/objectlib/helpers/BlockController.java
@@ -19,6 +19,8 @@
 
 package org.distorted.objectlib.helpers;
 
+import android.app.Activity;
+
 import com.google.firebase.crashlytics.FirebaseCrashlytics;
 
 import java.util.Timer;
@@ -69,7 +71,7 @@ public class BlockController
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public BlockController(TwistyActivity act, ObjectPreRender pre)
+  public BlockController(Activity act, ObjectPreRender pre)
     {
     mPre = pre;
 
diff --git a/src/main/java/org/distorted/objectlib/helpers/ObjectLibInterface.java b/src/main/java/org/distorted/objectlib/helpers/ObjectLibInterface.java
new file mode 100644
index 00000000..ea64ae85
--- /dev/null
+++ b/src/main/java/org/distorted/objectlib/helpers/ObjectLibInterface.java
@@ -0,0 +1,43 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2021 Leszek Koltunski                                                               //
+//                                                                                               //
+// This file is part of Magic Cube.                                                              //
+//                                                                                               //
+// Magic Cube is free software: you can redistribute it and/or modify                            //
+// it under the terms of the GNU General Public License as published by                          //
+// the Free Software Foundation, either version 2 of the License, or                             //
+// (at your option) any later version.                                                           //
+//                                                                                               //
+// Magic Cube is distributed in the hope that it will be useful,                                 //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
+// GNU General Public License for more details.                                                  //
+//                                                                                               //
+// You should have received a copy of the GNU General Public License                             //
+// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+package org.distorted.objectlib.helpers;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+import org.distorted.library.main.DistortedScreen;
+import org.distorted.objectlib.main.ObjectControl;
+import org.distorted.objectlib.main.ObjectType;
+
+public interface ObjectLibInterface
+  {
+  // objectlib calls those in reaction to object state changing, app has to respond
+  void onWinEffectFinished(String debug, int scrambleNum);
+  void onScrambleEffectFinished();
+  void onBeginRotation();
+  void onFinishRotation(int axis, int row, int angle);
+  void failedToDrag();
+  void onSolved();
+
+  // objectlib calls those to figure out app's state
+  int getCurrentColor();
+  int cubitIsLocked(ObjectType type, int cubit);
+  ObjectControl getControl();
+  DistortedScreen getScreen();
+  }
diff --git a/src/main/java/org/distorted/objectlib/helpers/ObjectStateActioner.java b/src/main/java/org/distorted/objectlib/helpers/ObjectStateActioner.java
deleted file mode 100644
index d5033ab4..00000000
--- a/src/main/java/org/distorted/objectlib/helpers/ObjectStateActioner.java
+++ /dev/null
@@ -1,36 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2021 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is free software: you can redistribute it and/or modify                            //
-// it under the terms of the GNU General Public License as published by                          //
-// the Free Software Foundation, either version 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Magic Cube is distributed in the hope that it will be useful,                                 //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
-// GNU General Public License for more details.                                                  //
-//                                                                                               //
-// You should have received a copy of the GNU General Public License                             //
-// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.objectlib.helpers;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-import org.distorted.objectlib.main.ObjectType;
-
-public interface ObjectStateActioner
-  {
-  void onWinEffectFinished(TwistyActivity act, String debug, int scrambleNum);
-  void onScrambleEffectFinished(TwistyActivity act);
-  void onBeginRotation(TwistyActivity act);
-  void onFinishRotation(TwistyActivity act, int axis, int row, int angle);
-  void failedToDrag(TwistyActivity act);
-  int getCurrentColor();
-  int cubitIsLocked(ObjectType type, int cubit);
-  void onSolved();
-  }
diff --git a/src/main/java/org/distorted/objectlib/helpers/TwistyActivity.java b/src/main/java/org/distorted/objectlib/helpers/TwistyActivity.java
deleted file mode 100644
index 77b21e0d..00000000
--- a/src/main/java/org/distorted/objectlib/helpers/TwistyActivity.java
+++ /dev/null
@@ -1,33 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2021 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Magic Cube.                                                              //
-//                                                                                               //
-// Magic Cube is free software: you can redistribute it and/or modify                            //
-// it under the terms of the GNU General Public License as published by                          //
-// the Free Software Foundation, either version 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Magic Cube is distributed in the hope that it will be useful,                                 //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
-// GNU General Public License for more details.                                                  //
-//                                                                                               //
-// You should have received a copy of the GNU General Public License                             //
-// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.objectlib.helpers;
-
-import androidx.appcompat.app.AppCompatActivity;
-
-import org.distorted.library.main.DistortedScreen;
-import org.distorted.objectlib.main.ObjectControl;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-abstract public class TwistyActivity extends AppCompatActivity
-  {
-  public abstract ObjectControl getControl();
-  public abstract DistortedScreen getScreen();
-  }
diff --git a/src/main/java/org/distorted/objectlib/main/ObjectControl.java b/src/main/java/org/distorted/objectlib/main/ObjectControl.java
index b29f3ad5..7ea5acd1 100644
--- a/src/main/java/org/distorted/objectlib/main/ObjectControl.java
+++ b/src/main/java/org/distorted/objectlib/main/ObjectControl.java
@@ -19,8 +19,7 @@
 
 package org.distorted.objectlib.main;
 
-import java.lang.ref.WeakReference;
-
+import android.app.Activity;
 import android.content.SharedPreferences;
 import android.util.DisplayMetrics;
 import android.view.MotionEvent;
@@ -30,8 +29,7 @@ import org.distorted.library.type.Static2D;
 import org.distorted.library.type.Static4D;
 
 import org.distorted.objectlib.helpers.MovesFinished;
-import org.distorted.objectlib.helpers.ObjectStateActioner;
-import org.distorted.objectlib.helpers.TwistyActivity;
+import org.distorted.objectlib.helpers.ObjectLibInterface;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -52,8 +50,7 @@ public class ObjectControl
 
     private final Static4D CAMERA_POINT = new Static4D(0, 0, 0, 0);
 
-    private final WeakReference<TwistyActivity> mAct;
-    private final ObjectStateActioner mActioner;
+    private final ObjectLibInterface mInterface;
     private final ObjectPreRender mPreRender;
     private Movement mMovement;
     private boolean mDragging, mBeginningRotation, mContinuingRotation;
@@ -189,22 +186,21 @@ public class ObjectControl
 
             if( down )
               {
-              int color = mActioner.getCurrentColor();
+              int color = mInterface.getCurrentColor();
               mLastCubitFace = mMovement.getTouchedFace();
               float[] point = mMovement.getTouchedPoint3D();
               mLastCubit = object.getCubit(point);
               mPreRender.setTextureMap( mLastCubit, mLastCubitFace, color );
-              mLastCubitColor = mActioner.cubitIsLocked(object.getObjectType(),mLastCubit);
+              mLastCubitColor = mInterface.cubitIsLocked(object.getObjectType(),mLastCubit);
               }
             }
           }
         else
           {
-          final TwistyActivity act = mAct.get();
           mDragging           = (!mIsLocked || mIsAutomatic);
           mBeginningRotation  = false;
           mContinuingRotation = false;
-          if( !mDragging ) mActioner.failedToDrag(act);
+          if( !mDragging ) mInterface.failedToDrag();
           }
         }
       }
@@ -257,12 +253,9 @@ public class ObjectControl
 
       if( angle!=0 )
         {
-        TwistyActivity act = mAct.get();
-
         int basicAngle= object.getBasicAngle()[mCurrentAxis];
         int realAngle = (angle*basicAngle)/360;
-
-        mActioner.onFinishRotation(act,mCurrentAxis,mCurrentRow,realAngle);
+        mInterface.onFinishRotation(mCurrentAxis,mCurrentRow,realAngle);
         }
 
       mContinuingRotation = false;
@@ -314,8 +307,7 @@ public class ObjectControl
 
       object.beginNewRotation( mCurrentAxis, mCurrentRow );
 
-      TwistyActivity act = mAct.get();
-      mActioner.onBeginRotation(act);
+      mInterface.onBeginRotation();
 
       addSpeedProbe(x,y);
 
@@ -504,11 +496,18 @@ public class ObjectControl
       return mPreRender;
       }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+    public ObjectLibInterface getInterface()
+      {
+      return mInterface;
+      }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // PUBLIC API
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    public ObjectControl(TwistyActivity act, ObjectStateActioner actioner)
+    public ObjectControl(Activity act, ObjectLibInterface actioner)
       {
       mIsAutomatic = false;
 
@@ -527,8 +526,7 @@ public class ObjectControl
       mDensity = dm.densityDpi;
 
       mPreRender = new ObjectPreRender(act,this,actioner);
-      mAct = new WeakReference<>(act);
-      mActioner = actioner;
+      mInterface = actioner;
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objectlib/main/ObjectPreRender.java b/src/main/java/org/distorted/objectlib/main/ObjectPreRender.java
index 2a678bb8..1a2f7664 100644
--- a/src/main/java/org/distorted/objectlib/main/ObjectPreRender.java
+++ b/src/main/java/org/distorted/objectlib/main/ObjectPreRender.java
@@ -19,16 +19,17 @@
 
 package org.distorted.objectlib.main;
 
+import android.app.Activity;
 import android.content.SharedPreferences;
 import android.content.res.Resources;
 
-import org.distorted.objectlib.helpers.ObjectStateActioner;
+import org.distorted.library.main.DistortedScreen;
+import org.distorted.objectlib.helpers.ObjectLibInterface;
 import org.distorted.objectlib.effects.BaseEffect;
 import org.distorted.objectlib.effects.EffectController;
 import org.distorted.objectlib.effects.scramble.ScrambleEffect;
 import org.distorted.objectlib.helpers.BlockController;
 import org.distorted.objectlib.helpers.MovesFinished;
-import org.distorted.objectlib.helpers.TwistyActivity;
 
 import java.lang.ref.WeakReference;
 
@@ -36,14 +37,14 @@ import java.lang.ref.WeakReference;
 
 public class ObjectPreRender implements EffectController
   {
-  private final WeakReference<TwistyActivity> mAct;
+  private final WeakReference<Activity> mAct;
   private final ObjectControl mController;
   private ObjectType mNextObject;
   private TwistyObject mOldObject, mNewObject;
   private SharedPreferences mPreferences;
   private MovesFinished mAddActionListener;
   private final BlockController mBlockController;
-  private final ObjectStateActioner mActioner;
+  private final ObjectLibInterface mInterface;
   private String mDebug;
 
   private boolean mFinishRotation, mRemoveRotation, mRemovePatternRotation, mAddRotation,
@@ -64,10 +65,10 @@ public class ObjectPreRender implements EffectController
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public ObjectPreRender(TwistyActivity act, ObjectControl controller, ObjectStateActioner actioner)
+  public ObjectPreRender(Activity act, ObjectControl controller, ObjectLibInterface actioner)
     {
     mAct = new WeakReference<>(act);
-    mActioner = actioner;
+    mInterface = actioner;
     mController = controller;
 
     mFinishRotation       = false;
@@ -104,8 +105,7 @@ public class ObjectPreRender implements EffectController
     if( mOldObject!=null ) mOldObject.releaseResources();
     mOldObject = mNewObject;
 
-    TwistyActivity tact = mAct.get();
-
+    Activity tact = mAct.get();
     Resources res = tact.getResources();
 
     mNewObject = object.create( mController.getQuat(), moves, res, mScreenWidth);
@@ -126,7 +126,8 @@ public class ObjectPreRender implements EffectController
     try
       {
       int index = type.ordinal();
-      mEffectID[index] = type.startEffect(mAct.get().getScreen(),this);
+      DistortedScreen screen = mController.getInterface().getScreen();
+      mEffectID[index] = type.startEffect(screen,this);
       }
     catch( Exception ex )
       {
@@ -146,7 +147,7 @@ public class ObjectPreRender implements EffectController
 
     if( solved && !mIsSolved )
       {
-      mActioner.onSolved();
+      mInterface.onSolved();
       unblockEverything();
       doEffectNow( BaseEffect.Type.WIN );
       }
@@ -573,8 +574,8 @@ public class ObjectPreRender implements EffectController
         if( effectID == mEffectID[i] )
           {
           if( i!=BaseEffect.Type.WIN.ordinal() ) unblockEverything();
-          if( i==BaseEffect.Type.SCRAMBLE.ordinal() ) mActioner.onScrambleEffectFinished(mAct.get());
-          if( i==BaseEffect.Type.WIN.ordinal()      ) mActioner.onWinEffectFinished(mAct.get(),mDebug,mScrambleObjectNum);
+          if( i==BaseEffect.Type.SCRAMBLE.ordinal() ) mInterface.onScrambleEffectFinished();
+          if( i==BaseEffect.Type.WIN.ordinal()      ) mInterface.onWinEffectFinished(mDebug,mScrambleObjectNum);
           break;
           }
         }
