Project

General

Profile

Download (15.3 KB) Statistics
| Branch: | Tag: | Revision:

magiccube / src / main / java / org / distorted / main / RubikObjectLibInterface.java @ eb647d5e

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2019 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is free software: you can redistribute it and/or modify                            //
7
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11
// Magic Cube is distributed in the hope that it will be useful,                                 //
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17
// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19

    
20
package org.distorted.main;
21

    
22
import android.os.Bundle;
23

    
24
import androidx.annotation.NonNull;
25

    
26
import com.google.android.play.core.review.ReviewInfo;
27
import com.google.android.play.core.review.ReviewManager;
28
import com.google.android.play.core.review.ReviewManagerFactory;
29
import com.google.android.play.core.tasks.OnCompleteListener;
30
import com.google.android.play.core.tasks.OnFailureListener;
31
import com.google.android.play.core.tasks.Task;
32
import com.google.firebase.analytics.FirebaseAnalytics;
33
import com.google.firebase.crashlytics.FirebaseCrashlytics;
34

    
35
import org.distorted.library.message.EffectMessageSender;
36

    
37
import org.distorted.objectlib.BuildConfig;
38
import org.distorted.objectlib.helpers.BlockController;
39
import org.distorted.objectlib.helpers.ObjectLibInterface;
40
import org.distorted.objectlib.main.ObjectControl;
41
import org.distorted.objectlib.main.ObjectType;
42

    
43
import org.distorted.dialogs.RubikDialogNewRecord;
44
import org.distorted.dialogs.RubikDialogSolved;
45
import org.distorted.network.RubikScores;
46
import org.distorted.screens.RubikScreenPlay;
47
import org.distorted.screens.RubikScreenReady;
48
import org.distorted.screens.RubikScreenSolver;
49
import org.distorted.screens.RubikScreenSolving;
50
import org.distorted.screens.ScreenList;
51
import org.distorted.solvers.SolverMain;
52

    
53
import java.lang.ref.WeakReference;
54

    
55
///////////////////////////////////////////////////////////////////////////////////////////////////
56

    
57
public class RubikObjectLibInterface implements ObjectLibInterface
58
{
59
  private final WeakReference<RubikActivity> mAct;
60
  private boolean mIsNewRecord;
61
  private long mNewRecord;
62
  private int mLastCubitColor, mLastCubit, mLastCubitFace;
63

    
64
///////////////////////////////////////////////////////////////////////////////////////////////////
65

    
66
  RubikObjectLibInterface(RubikActivity act)
67
    {
68
    mAct = new WeakReference<>(act);
69
    mLastCubitColor = -1;
70
    }
71

    
72
///////////////////////////////////////////////////////////////////////////////////////////////////
73

    
74
  private void analyticsReport(RubikActivity act, String message, String name, long timeBegin)
75
    {
76
    long elapsed = System.currentTimeMillis() - timeBegin;
77
    String msg = message+" startTime: "+timeBegin+" elapsed: "+elapsed+" name: "+name;
78

    
79
    if( BuildConfig.DEBUG )
80
       {
81
       android.util.Log.d("pre", msg);
82
       }
83
    else
84
      {
85
      FirebaseAnalytics analytics = act.getAnalytics();
86

    
87
      if( analytics!=null )
88
        {
89
        Bundle bundle = new Bundle();
90
        bundle.putString(FirebaseAnalytics.Param.CONTENT_TYPE, msg);
91
        analytics.logEvent(FirebaseAnalytics.Event.SHARE, bundle);
92
        }
93
      }
94
    }
95

    
96
///////////////////////////////////////////////////////////////////////////////////////////////////
97

    
98
  private void reportRecord(RubikActivity act, String debug, int scrambleNum)
99
    {
100
    RubikScreenPlay play= (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
101
    RubikScores scores  = RubikScores.getInstance();
102
    ObjectType object   = play.getObject();
103
    int level           = play.getLevel();
104
    String name         = scores.getName();
105

    
106
    String record = object.name()+" level "+level+" time "+mNewRecord+" isNew: "+mIsNewRecord+" scrambleNum: "+scrambleNum;
107

    
108
    if( BuildConfig.DEBUG )
109
       {
110
       android.util.Log.e("pre", debug);
111
       android.util.Log.e("pre", name);
112
       android.util.Log.e("pre", record);
113
       }
114
    else
115
      {
116
      FirebaseAnalytics analytics = act.getAnalytics();
117

    
118
      if( analytics!=null )
119
        {
120
        Bundle bundle = new Bundle();
121
        bundle.putString(FirebaseAnalytics.Param.CONTENT_TYPE, debug);
122
        bundle.putString(FirebaseAnalytics.Param.CHARACTER, name);
123
        bundle.putString(FirebaseAnalytics.Param.LEVEL, record);
124
        analytics.logEvent(FirebaseAnalytics.Event.LEVEL_UP, bundle);
125
        }
126
      }
127
    }
128

    
129
///////////////////////////////////////////////////////////////////////////////////////////////////
130

    
131
  private void requestReview(RubikActivity act)
132
    {
133
    final RubikScores scores = RubikScores.getInstance();
134
    int numWins = scores.incrementNumWins();
135

    
136
    if( numWins==7 || numWins==30 || numWins==100 || numWins==200)
137
      {
138
      final long timeBegin = System.currentTimeMillis();
139
      final ReviewManager manager = ReviewManagerFactory.create(act);
140
      Task<ReviewInfo> request = manager.requestReviewFlow();
141

    
142
      request.addOnCompleteListener(new OnCompleteListener<ReviewInfo>()
143
        {
144
        @Override
145
        public void onComplete (@NonNull Task<ReviewInfo> task)
146
          {
147
          if (task.isSuccessful())
148
            {
149
            final String name = scores.getName();
150
            ReviewInfo reviewInfo = task.getResult();
151
            Task<Void> flow = manager.launchReviewFlow(act, reviewInfo);
152

    
153
            flow.addOnFailureListener(new OnFailureListener()
154
              {
155
              @Override
156
              public void onFailure(Exception e)
157
                {
158
                analyticsReport(act,"Failed", name, timeBegin);
159
                }
160
              });
161

    
162
            flow.addOnCompleteListener(new OnCompleteListener<Void>()
163
              {
164
              @Override
165
              public void onComplete(@NonNull Task<Void> task)
166
                {
167
                analyticsReport(act,"Complete", name, timeBegin);
168
                }
169
              });
170
            }
171
          else
172
            {
173
            String name = scores.getName();
174
            analyticsReport(act,"Not Successful", name, timeBegin);
175
            }
176
          }
177
        });
178
      }
179
    }
180

    
181
///////////////////////////////////////////////////////////////////////////////////////////////////
182

    
183
  public void onWinEffectFinished(String debug, int scrambleNum)
184
    {
185
    if( ScreenList.getCurrentScreen()== ScreenList.SOLV )
186
      {
187
      RubikActivity act = mAct.get();
188
      Bundle bundle = new Bundle();
189
      bundle.putLong("time", mNewRecord );
190

    
191
      reportRecord(act,debug,scrambleNum);
192
      requestReview(act);
193

    
194
      if( mIsNewRecord )
195
        {
196
        RubikDialogNewRecord dialog = new RubikDialogNewRecord();
197
        dialog.setArguments(bundle);
198
        dialog.show( act.getSupportFragmentManager(), RubikDialogNewRecord.getDialogTag() );
199
        }
200
      else
201
        {
202
        RubikDialogSolved dialog = new RubikDialogSolved();
203
        dialog.setArguments(bundle);
204
        dialog.show( act.getSupportFragmentManager(), RubikDialogSolved.getDialogTag() );
205
        }
206

    
207
      act.runOnUiThread(new Runnable()
208
        {
209
        @Override
210
        public void run()
211
          {
212
          ScreenList.switchScreen( act, ScreenList.DONE);
213
          }
214
        });
215
      }
216
    }
217

    
218
///////////////////////////////////////////////////////////////////////////////////////////////////
219

    
220
  public void onScrambleEffectFinished()
221
    {
222
    RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
223

    
224
    if( play.shouldReactToEndOfScrambling() )
225
      {
226
      RubikActivity act = mAct.get();
227
      RubikScores.getInstance().incrementNumPlays();
228

    
229
      act.runOnUiThread(new Runnable()
230
        {
231
        @Override
232
        public void run()
233
        {
234
        ScreenList.switchScreen( act, ScreenList.READ);
235
        }
236
        });
237
      }
238
    }
239

    
240
///////////////////////////////////////////////////////////////////////////////////////////////////
241

    
242
  public void onFinishRotation(int axis, int row, int angle)
243
    {
244
    if( ScreenList.getCurrentScreen()== ScreenList.SOLV )
245
      {
246
      RubikScreenSolving solv = (RubikScreenSolving) ScreenList.SOLV.getScreenClass();
247
      solv.addMove(mAct.get(), axis, row, angle);
248
      }
249
    if( ScreenList.getCurrentScreen()== ScreenList.PLAY )
250
      {
251
      RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
252
      play.addMove(mAct.get(), axis, row, angle);
253
      }
254
    }
255

    
256
///////////////////////////////////////////////////////////////////////////////////////////////////
257

    
258
  public void onBeginRotation()
259
    {
260
    if( ScreenList.getCurrentScreen()== ScreenList.READ )
261
      {
262
      RubikScreenSolving solving = (RubikScreenSolving) ScreenList.SOLV.getScreenClass();
263
      solving.resetElapsed();
264
      RubikActivity act = mAct.get();
265

    
266
      act.runOnUiThread(new Runnable()
267
        {
268
        @Override
269
        public void run()
270
          {
271
          ScreenList.switchScreen( act, ScreenList.SOLV);
272
          }
273
        });
274
      }
275
    }
276

    
277
///////////////////////////////////////////////////////////////////////////////////////////////////
278

    
279
  public void failedToDrag()
280
    {
281
    ScreenList curr = ScreenList.getCurrentScreen();
282

    
283
    if( curr==ScreenList.PLAY )
284
      {
285
      RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
286
      play.reddenLock(mAct.get());
287
      }
288
    else if( curr==ScreenList.READ )
289
      {
290
      RubikScreenReady read = (RubikScreenReady) ScreenList.READ.getScreenClass();
291
      read.reddenLock(mAct.get());
292
      }
293
    else if( curr==ScreenList.SOLV )
294
      {
295
      RubikScreenSolving solv = (RubikScreenSolving) ScreenList.SOLV.getScreenClass();
296
      solv.reddenLock(mAct.get());
297
      }
298
    }
299

    
300
///////////////////////////////////////////////////////////////////////////////////////////////////
301

    
302
  public void onSolved()
303
    {
304
    if( ScreenList.getCurrentScreen()== ScreenList.SOLV )
305
      {
306
      RubikScreenSolving solving = (RubikScreenSolving) ScreenList.SOLV.getScreenClass();
307
      mNewRecord = solving.getRecord();
308

    
309
      if( mNewRecord< 0 )
310
        {
311
        mNewRecord = -mNewRecord;
312
        mIsNewRecord = false;
313
        }
314
      else
315
        {
316
        mIsNewRecord = true;
317
        RubikScreenPlay play= (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
318
        play.adjustSolvedIcons();
319
        }
320
      }
321
    }
322

    
323
///////////////////////////////////////////////////////////////////////////////////////////////////
324

    
325
  public void onObjectCreated(long time)
326
    {
327

    
328
    }
329

    
330
///////////////////////////////////////////////////////////////////////////////////////////////////
331

    
332
  public void reportProblem(String problem, boolean recordException)
333
    {
334
    if( BuildConfig.DEBUG )
335
      {
336
      android.util.Log.e("interface", problem);
337
      }
338
    else
339
      {
340
      if( recordException )
341
        {
342
        Exception ex = new Exception(problem);
343
        FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
344
        crashlytics.setCustomKey("problem" , problem);
345
        crashlytics.recordException(ex);
346
        }
347
      else
348
        {
349
        FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
350
        crashlytics.log(problem);
351
        }
352
      }
353
    }
354

    
355
///////////////////////////////////////////////////////////////////////////////////////////////////
356

    
357
  private void reportUIProblem(int place, long pause, long resume, long time)
358
    {
359
    String error = "UI BLOCK "+place+" blocked for "+time;
360

    
361
    if( BuildConfig.DEBUG )
362
       {
363
       android.util.Log.e("D", error);
364
       }
365
    else
366
      {
367
      Exception ex = new Exception(error);
368
      FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
369
      crashlytics.setCustomKey("pause" , pause );
370
      crashlytics.setCustomKey("resume", resume );
371
      crashlytics.recordException(ex);
372
      }
373
    }
374

    
375
///////////////////////////////////////////////////////////////////////////////////////////////////
376

    
377
  private void reportTouchProblem(int place, long pause, long resume, long time)
378
    {
379
    String error = "TOUCH BLOCK "+place+" blocked for "+time;
380

    
381
    if( BuildConfig.DEBUG )
382
       {
383
       android.util.Log.e("D", error);
384
       }
385
    else
386
      {
387
      Exception ex = new Exception(error);
388
      FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
389
      crashlytics.setCustomKey("pause" , pause );
390
      crashlytics.setCustomKey("resume", resume);
391
      crashlytics.recordException(ex);
392
      }
393
    }
394

    
395
///////////////////////////////////////////////////////////////////////////////////////////////////
396

    
397
  private void reportThreadProblem(int place, long pause, long resume, long time)
398
    {
399
    String error = EffectMessageSender.reportState();
400

    
401
    if( BuildConfig.DEBUG )
402
       {
403
       android.util.Log.e("D", error);
404
       }
405
    else
406
      {
407
      Exception ex = new Exception(error);
408
      FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
409
      crashlytics.setCustomKey("pause" , pause  );
410
      crashlytics.setCustomKey("resume", resume );
411
      crashlytics.recordException(ex);
412
      }
413
    }
414

    
415
///////////////////////////////////////////////////////////////////////////////////////////////////
416

    
417
  public void reportBlockProblem(int type, int place, long pause, long resume, long time)
418
    {
419
    switch(type)
420
      {
421
      case BlockController.TYPE_UI    : reportUIProblem(place,pause,resume,time); break;
422
      case BlockController.TYPE_TOUCH : reportTouchProblem(place,pause,resume,time); break;
423
      case BlockController.TYPE_THREAD: reportThreadProblem(place,pause,resume,time); break;
424
      }
425
    }
426

    
427
///////////////////////////////////////////////////////////////////////////////////////////////////
428

    
429
  public void onReplaceModeDown(int cubit, int face)
430
    {
431
    RubikScreenSolver solver = (RubikScreenSolver) ScreenList.SVER.getScreenClass();
432
    int color = solver.getCurrentColor();
433
    RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
434
    ObjectType currObject = play.getObject();
435
    mLastCubitColor = SolverMain.cubitIsLocked(currObject,cubit);
436
    mLastCubit = cubit;
437
    mLastCubitFace = face;
438
    ObjectControl control = mAct.get().getControl();
439
    control.setTextureMap( cubit, face, color );
440
    }
441

    
442
///////////////////////////////////////////////////////////////////////////////////////////////////
443

    
444
  public void onReplaceModeUp()
445
    {
446
    if( mLastCubitColor>=0 )
447
      {
448
      ObjectControl control = mAct.get().getControl();
449
      control.setTextureMap( mLastCubit, mLastCubitFace, mLastCubitColor );
450
      mLastCubitColor = -1;
451
      }
452
    }
453
}
(2-2/4)