Project

General

Profile

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

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

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

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

    
54
import java.lang.ref.WeakReference;
55

    
56
///////////////////////////////////////////////////////////////////////////////////////////////////
57

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

    
65
///////////////////////////////////////////////////////////////////////////////////////////////////
66

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

    
73
///////////////////////////////////////////////////////////////////////////////////////////////////
74

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

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

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

    
97
///////////////////////////////////////////////////////////////////////////////////////////////////
98

    
99
  private void reportRecord(RubikActivity act, String debug, int scrambleNum)
100
    {
101
    RubikScreenPlay play= (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
102
    RubikScores scores  = RubikScores.getInstance();
103
    int object  = RubikObjectList.getCurrObject();
104
    int level   = play.getLevel();
105
    String name = scores.getName();
106
    RubikObject obj = RubikObjectList.getObject(object);
107
    String objName = obj==null ? "NULL" : obj.getName();
108

    
109
    String record = objName+" level "+level+" time "+mNewRecord+" isNew: "+mIsNewRecord+" scrambleNum: "+scrambleNum;
110

    
111
    if( BuildConfig.DEBUG )
112
       {
113
       android.util.Log.e("libInterface", debug);
114
       android.util.Log.e("libInterface", name);
115
       android.util.Log.e("libInterface", record);
116
       }
117
    else
118
      {
119
      FirebaseAnalytics analytics = act.getAnalytics();
120

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

    
132
///////////////////////////////////////////////////////////////////////////////////////////////////
133

    
134
  private void requestReview(RubikActivity act)
135
    {
136
    final RubikScores scores = RubikScores.getInstance();
137
    int numWins = scores.incrementNumWins();
138

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

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

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

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

    
184
///////////////////////////////////////////////////////////////////////////////////////////////////
185

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

    
194
      reportRecord(act,debug,scrambleNum);
195
      requestReview(act);
196

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

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

    
221
///////////////////////////////////////////////////////////////////////////////////////////////////
222

    
223
  public void onScrambleEffectFinished()
224
    {
225
    RubikScreenPlay play = (RubikScreenPlay) ScreenList.PLAY.getScreenClass();
226

    
227
    if( play.shouldReactToEndOfScrambling() )
228
      {
229
      RubikActivity act = mAct.get();
230
      RubikScores.getInstance().incrementNumPlays();
231

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

    
243
///////////////////////////////////////////////////////////////////////////////////////////////////
244

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

    
259
///////////////////////////////////////////////////////////////////////////////////////////////////
260

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

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

    
280
///////////////////////////////////////////////////////////////////////////////////////////////////
281

    
282
  public void failedToDrag()
283
    {
284
    ScreenList curr = ScreenList.getCurrentScreen();
285

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

    
303
///////////////////////////////////////////////////////////////////////////////////////////////////
304

    
305
  public void onSolved()
306
    {
307
    if( ScreenList.getCurrentScreen()== ScreenList.SOLV )
308
      {
309
      RubikScreenSolving solving = (RubikScreenSolving) ScreenList.SOLV.getScreenClass();
310
      mNewRecord = solving.getRecord();
311

    
312
      if( mNewRecord< 0 )
313
        {
314
        mNewRecord = -mNewRecord;
315
        mIsNewRecord = false;
316
        }
317
      else
318
        {
319
        mIsNewRecord = true;
320
        }
321
      }
322
    }
323

    
324
///////////////////////////////////////////////////////////////////////////////////////////////////
325

    
326
  public void onObjectCreated(long time)
327
    {
328

    
329
    }
330

    
331
///////////////////////////////////////////////////////////////////////////////////////////////////
332

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

    
356
///////////////////////////////////////////////////////////////////////////////////////////////////
357

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

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

    
376
///////////////////////////////////////////////////////////////////////////////////////////////////
377

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

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

    
396
///////////////////////////////////////////////////////////////////////////////////////////////////
397

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

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

    
416
///////////////////////////////////////////////////////////////////////////////////////////////////
417

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

    
428
///////////////////////////////////////////////////////////////////////////////////////////////////
429

    
430
  public void onReplaceModeDown(int cubit, int face)
431
    {
432
    RubikScreenSolver solver = (RubikScreenSolver) ScreenList.SVER.getScreenClass();
433
    int color = solver.getCurrentColor();
434
    int currObject = RubikObjectList.getCurrObject();
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)