commit 7eae2d499a18a770179dbf9605dc99999aaed2c6
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Sat Jun 20 10:58:44 2020 +0100

    On object change, report FPS to Firebase

diff --git a/src/main/java/org/distorted/main/RubikActivity.java b/src/main/java/org/distorted/main/RubikActivity.java
index 2a8b3605..5cfe52d1 100644
--- a/src/main/java/org/distorted/main/RubikActivity.java
+++ b/src/main/java/org/distorted/main/RubikActivity.java
@@ -217,11 +217,46 @@ public class RubikActivity extends AppCompatActivity
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    public void changeObject(RubikObjectList object, int size)
+    public void changeObject(RubikObjectList newObject, int newSize, boolean reportChange)
       {
       RubikSurfaceView view = findViewById(R.id.rubikSurfaceView);
       RubikPreRender pre = view.getPreRender();
-      pre.changeObject(object,size);
+
+      if( reportChange )
+        {
+        RubikObject oldObject = pre.getObject();
+        RubikObjectList oldList = oldObject.getObjectList();
+        int oldSize = oldObject.getSize();
+        float fps = view.getRenderer().getFPS();
+        StringBuilder name = new StringBuilder();
+        name.append(oldList.name());
+        name.append('_');
+        name.append(oldSize);
+        name.append(' ');
+        name.append(fps);
+        name.append(" --> ");
+        name.append(newObject.name());
+        name.append('_');
+        name.append(newSize);
+
+        if( BuildConfig.DEBUG )
+          {
+          android.util.Log.e("rubik", name.toString());
+          }
+        else
+          {
+          FirebaseAnalytics analytics = getAnalytics();
+
+          if( analytics!=null )
+            {
+            Bundle bundle = new Bundle();
+            bundle.putString(FirebaseAnalytics.Param.ITEM_NAME, name.toString());
+            analytics.logEvent(FirebaseAnalytics.Event.SELECT_ITEM, bundle);
+            }
+          }
+        }
+
+      pre.changeObject(newObject,newSize);
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/main/RubikRenderer.java b/src/main/java/org/distorted/main/RubikRenderer.java
index 8c35d975..0399caa5 100644
--- a/src/main/java/org/distorted/main/RubikRenderer.java
+++ b/src/main/java/org/distorted/main/RubikRenderer.java
@@ -40,6 +40,45 @@ public class RubikRenderer implements GLSurfaceView.Renderer, DistortedLibrary.E
 {
    private RubikSurfaceView mView;
    private DistortedScreen mScreen;
+   private Fps mFPS;
+
+   private static class Fps
+     {
+     private static final int NUM_FRAMES  = 100;
+
+     private long lastTime=0;
+     private long[] durations;
+     private int currDuration;
+     private float currFPS;
+
+     Fps()
+       {
+       durations = new long[NUM_FRAMES+1];
+       currDuration = 0;
+
+       for (int i=0; i<NUM_FRAMES+1; i++) durations[i] = 16;
+       durations[NUM_FRAMES] = NUM_FRAMES * 16;
+       }
+
+     void onRender(long time)
+       {
+       if( lastTime==0 ) lastTime = time;
+
+       currDuration++;
+       if (currDuration >= NUM_FRAMES) currDuration = 0;
+       durations[NUM_FRAMES] += ((time - lastTime) - durations[currDuration]);
+       durations[currDuration] = time - lastTime;
+
+       currFPS = ((int)(10000.0f*NUM_FRAMES/durations[NUM_FRAMES]))/10.0f;
+
+       lastTime = time;
+       }
+
+     float getFPS()
+       {
+       return currFPS;
+       }
+     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -48,6 +87,7 @@ public class RubikRenderer implements GLSurfaceView.Renderer, DistortedLibrary.E
      final float BRIGHTNESS = 0.1f;
 
      mView = v;
+     mFPS = new Fps();
      mScreen = new DistortedScreen();
      mScreen.glClearColor(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS, 1.0f);
      }
@@ -59,8 +99,10 @@ public class RubikRenderer implements GLSurfaceView.Renderer, DistortedLibrary.E
    @Override
    public void onDrawFrame(GL10 glUnused)
      {
+     long time = System.currentTimeMillis();
+     mFPS.onRender(time);
      mView.getPreRender().preRender();
-     mScreen.render( System.currentTimeMillis() );
+     mScreen.render(time);
      }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -126,6 +168,13 @@ public class RubikRenderer implements GLSurfaceView.Renderer, DistortedLibrary.E
        }
      }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+   float getFPS()
+     {
+     return mFPS.getFPS();
+     }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
    DistortedScreen getScreen()
diff --git a/src/main/java/org/distorted/states/RubikStatePattern.java b/src/main/java/org/distorted/states/RubikStatePattern.java
index c5d5fe82..8ed85ed8 100644
--- a/src/main/java/org/distorted/states/RubikStatePattern.java
+++ b/src/main/java/org/distorted/states/RubikStatePattern.java
@@ -71,7 +71,7 @@ public class RubikStatePattern extends RubikStateAbstract
       int objectPlay= play.getObject();
       int sizePlay  = play.getSize();
 
-      act.changeObject(RubikObjectList.getObject(objectPlay),sizePlay);
+      act.changeObject(RubikObjectList.getObject(objectPlay),sizePlay, false);
       }
     }
 
diff --git a/src/main/java/org/distorted/states/RubikStatePlay.java b/src/main/java/org/distorted/states/RubikStatePlay.java
index 80459c32..c19b4846 100644
--- a/src/main/java/org/distorted/states/RubikStatePlay.java
+++ b/src/main/java/org/distorted/states/RubikStatePlay.java
@@ -283,19 +283,9 @@ public class RubikStatePlay extends RubikStateAbstract implements AdapterView.On
             {
             if( act.getPreRender().canPlay() && RubikState.getCurrentState()==RubikState.PLAY )
               {
-              FirebaseAnalytics analytics = act.getAnalytics();
-
-              if( analytics!=null )
-                {
-                String name = RubikObjectList.getObject(obj).name()+"_"+sizes[size];
-                Bundle bundle = new Bundle();
-                bundle.putString(FirebaseAnalytics.Param.ITEM_NAME, name);
-                analytics.logEvent(FirebaseAnalytics.Event.SELECT_ITEM, bundle);
-                }
-
               mObject = obj;
               mSize   = sizes[size];
-              act.changeObject(list,sizes[size]);
+              act.changeObject(list,sizes[size], true);
               adjustSpinner(act);
               }
 
