Project

General

Profile

« Previous | Next » 

Revision 36b9ee93

Added by Leszek Koltunski about 3 years ago

Attempt to programmatically catch the 'cube is sometimes not drawn' bug and report it to my server.

View differences:

src/main/java/org/distorted/effects/objectchange/ObjectChangeEffect.java
50 50
      }
51 51
    }
52 52

  
53
  private static int NUM_EFFECTS = Type.values().length;
53
  private static final int NUM_EFFECTS = Type.values().length;
54 54
  private static final int NUM_PHASES  = 2;
55 55
  private static final int FAKE_EFFECT_ID  = -1;
56 56
  private static final Type[] types;
......
68 68

  
69 69
  private EffectController mController;
70 70
  private int mDuration;
71
  private int[] mEffectReturned;
72
  private int[] mCubeEffectNumber, mNodeEffectNumber;
73
  private int[] mEffectFinished;
74
  private boolean[] mPhaseActive;
71
  private final int[] mEffectReturned;
72
  private final int[] mCubeEffectNumber, mNodeEffectNumber;
73
  private final int[] mEffectFinished;
74
  private final boolean[] mPhaseActive;
75 75

  
76 76
  TwistyObject[] mObject;
77 77
  DistortedScreen mScreen;
src/main/java/org/distorted/effects/scramble/ScrambleEffect.java
49 49
      }
50 50
    }
51 51

  
52
  private static int NUM_EFFECTS = Type.values().length;
52
  private static final int NUM_EFFECTS = Type.values().length;
53 53
  private static final int FAKE_EFFECT_ID  = -3;
54 54
  private static final Type[] types;
55 55

  
......
72 72
  private int mNumDoubleScramblesLeft, mNumScramblesLeft;
73 73
  private int mLastRotAxis, mLastRow;
74 74
  private long mDurationSingleTurn;
75
  private Random mRnd;
75
  private final Random mRnd;
76 76
  private int mBasicAngle;
77 77

  
78 78
  TwistyObject mObject;
src/main/java/org/distorted/main/RubikActivity.java
41 41
import org.distorted.effects.BaseEffect;
42 42
import org.distorted.library.main.DistortedLibrary;
43 43

  
44
import org.distorted.library.message.EffectListener;
44 45
import org.distorted.objects.TwistyObject;
45 46
import org.distorted.scores.RubikScores;
46 47
import org.distorted.scores.RubikScoresDownloader;
......
48 49
import org.distorted.states.StateList;
49 50
import org.distorted.states.RubikStatePlay;
50 51
import org.distorted.tutorial.TutorialActivity;
52
import org.distorted.tutorial.TutorialList;
51 53

  
52 54
import java.util.Locale;
53 55

  
54 56
///////////////////////////////////////////////////////////////////////////////////////////////////
55 57

  
56
public class RubikActivity extends AppCompatActivity
58
public class RubikActivity extends AppCompatActivity implements RubikDebug.ActivityChanger, EffectListener
57 59
{
58 60
    public static final float PADDING             = 0.01f;
59 61
    public static final float MARGIN              = 0.004f;
......
89 91
    private int mCurrentApiVersion;
90 92
    private boolean mIsLocked;
91 93

  
94
    private static int mNumTests=0;
95

  
92 96
///////////////////////////////////////////////////////////////////////////////////////////////////
93 97

  
94 98
    @Override
......
224 228
    protected void onPause() 
225 229
      {
226 230
      super.onPause();
231

  
232
      RubikDebug debug = RubikDebug.getInstance();
233
      debug.onPause();
234

  
227 235
      RubikSurfaceView view = findViewById(R.id.rubikSurfaceView);
228 236
      view.onPause();
229 237
      DistortedLibrary.onPause(0);
......
240 248
      DistortedLibrary.onResume(0);
241 249
      RubikSurfaceView view = findViewById(R.id.rubikSurfaceView);
242 250
      view.onResume();
251

  
252
      RubikDebug debug = RubikDebug.getInstance();
253
      debug.onResume(this);
254

  
243 255
      view.initialize();
244 256
      restorePreferences();
245 257
      StateList.setState(this);
......
252 264
        scores.setCountry(this);
253 265
        }
254 266

  
267
RubikPreRender pre = view.getPreRender();
268
pre.destroyNewObject();
269
RubikDebug.addDebug("RubikActivity: onResume");
270

  
255 271
      boolean success = false;
256 272
      RubikStatePlay play = (RubikStatePlay) StateList.PLAY.getStateClass();
257 273
      int object = play.getObject();
......
572 588
      myIntent.putExtra("siz", size);
573 589
      startActivity(myIntent);
574 590
      }
591

  
592
///////////////////////////////////////////////////////////////////////////////////////////////////
593

  
594
  public void change()
595
    {
596
    mNumTests++;
597

  
598
    if( mNumTests<100 )
599
      {
600
      TutorialList list  = TutorialList.getObject(2);
601
      ObjectList objList = list.getObjectList();
602
      int size           = list.getSize();
603
      String url         = list.getTutorialURL(0);
604

  
605
      switchTutorial(url, objList, size);
606
      }
607
    else
608
      {
609
      finish();
610
      }
611
    }
612

  
613
///////////////////////////////////////////////////////////////////////////////////////////////////
614

  
615
  public void assign()
616
    {
617
    RubikSurfaceView view = findViewById(R.id.rubikSurfaceView);
618
    RubikPreRender pre = view.getPreRender();
619
    TwistyObject object = pre.getObject();
620

  
621
    int angle = 360 / object.getBasicAngle();
622

  
623
    object.addNewRotation(1,1,angle,1000,this);
624
    }
625

  
626
///////////////////////////////////////////////////////////////////////////////////////////////////
627

  
628
  public void effectFinished(final long effectID)
629
    {
630
    RubikDebug debug = RubikDebug.getInstance();
631
    debug.onReturned();
632
    }
575 633
}
src/main/java/org/distorted/main/RubikDebug.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2021 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 org.distorted.scores.RubikScoresDownloader;
23

  
24
import java.util.Timer;
25
import java.util.TimerTask;
26

  
27
///////////////////////////////////////////////////////////////////////////////////////////////////
28

  
29
public class RubikDebug
30
  {
31
  private static final int CHECK_INTERVAL = 1000;
32

  
33
  private String mDebug;
34
  private long mResumeTime;
35
  private int mNumReturned;
36
  private ActivityChanger mChanger;
37

  
38
  public static RubikDebug mThis;
39

  
40
  public interface ActivityChanger
41
    {
42
    void change();
43
    void assign();
44
    }
45

  
46
///////////////////////////////////////////////////////////////////////////////////////////////////
47

  
48
  private void initialize()
49
    {
50
    mDebug      = "";
51
    mResumeTime = 0;
52
    mNumReturned= 0;
53
    }
54

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

  
57
  private void report(String debug)
58
    {
59
    android.util.Log.e("debug", "Reporting: "+debug);
60

  
61
    RubikScoresDownloader downloader = RubikScoresDownloader.getInstance();
62
    downloader.error(debug);
63
    }
64

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

  
67
  private void check(int loopNum)
68
    {
69
    if( loopNum==1 )
70
      {
71
      mChanger.assign();
72
      }
73
    if( loopNum==4 )
74
      {
75
      if( mNumReturned!=2 )
76
        {
77
        report(mDebug);
78
        }
79

  
80
      mChanger.change();
81
      }
82
    }
83

  
84
///////////////////////////////////////////////////////////////////////////////////////////////////
85

  
86
  private RubikDebug()
87
    {
88
    initialize();
89
    }
90

  
91
///////////////////////////////////////////////////////////////////////////////////////////////////
92

  
93
  public static RubikDebug getInstance()
94
    {
95
    if( mThis==null ) mThis = new RubikDebug();
96

  
97
    return mThis;
98
    }
99

  
100
///////////////////////////////////////////////////////////////////////////////////////////////////
101

  
102
  public static void addDebug(String debug)
103
    {
104
    if( mThis==null ) mThis = new RubikDebug();
105

  
106
    mThis.mDebug += (debug + "\n");
107
    }
108

  
109
///////////////////////////////////////////////////////////////////////////////////////////////////
110

  
111
  public void onResume(ActivityChanger changer)
112
    {
113
    mChanger = changer;
114
    mResumeTime = System.currentTimeMillis();
115

  
116
    final Timer timer = new Timer();
117

  
118
    timer.scheduleAtFixedRate(new TimerTask()
119
      {
120
      private int mLoopNum = 0;
121

  
122
      @Override
123
      public void run()
124
        {
125
        if( mLoopNum==5 )
126
          {
127
          timer.cancel();
128
          }
129

  
130
        check(mLoopNum++);
131
        }
132
      } ,CHECK_INTERVAL, CHECK_INTERVAL);
133
    }
134

  
135
///////////////////////////////////////////////////////////////////////////////////////////////////
136

  
137
  public void onPause()
138
    {
139
    initialize();
140
    }
141

  
142
///////////////////////////////////////////////////////////////////////////////////////////////////
143

  
144
  public void onReturned()
145
    {
146
    mNumReturned++;
147
    }
148
  }
src/main/java/org/distorted/main/RubikPreRender.java
55 55
    void onActionFinished(long effectID);
56 56
    }
57 57

  
58
  private RubikSurfaceView mView;
58
  private final RubikSurfaceView mView;
59 59
  private boolean mFinishRotation, mRemoveRotation, mRemovePatternRotation, mAddRotation,
60 60
                  mSetQuat, mChangeObject, mSetupObject, mSolveObject, mScrambleObject,
61 61
                  mInitializeObject, mSetTextureMap, mResetAllTextureMaps;
......
64 64
  private ObjectList mNextObject;
65 65
  private int mNextSize;
66 66
  private long mRotationFinishedID;
67
  private long[] mEffectID;
67
  private final long[] mEffectID;
68 68
  private boolean mIsNewRecord;
69 69
  private long mNewRecord;
70 70
  private int mScreenWidth;
......
111 111
    mDebug = "";
112 112
    }
113 113

  
114
///////////////////////////////////////////////////////////////////////////////////////////////////
115

  
116
  void destroyNewObject()
117
    {
118
    if( mNewObject!=null )
119
      {
120
      mNewObject.releaseResources();
121
      mNewObject = null;
122
      }
123
    }
124

  
114 125
///////////////////////////////////////////////////////////////////////////////////////////////////
115 126

  
116 127
  private void createObjectNow(ObjectList object, int size, int[][] moves)
src/main/java/org/distorted/objects/TwistyObject.java
47 47
import org.distorted.library.type.Static3D;
48 48
import org.distorted.library.type.Static4D;
49 49
import org.distorted.main.BuildConfig;
50
import org.distorted.main.RubikDebug;
50 51

  
51 52
import java.io.DataInputStream;
52 53
import java.io.IOException;
......
618 619

  
619 620
  public synchronized long addNewRotation( int axis, int rowBitmap, int angle, long durationMillis, EffectListener listener )
620 621
    {
622
    RubikDebug.addDebug("adding new rot: axis="+axis+" rowBmp="+rowBitmap+" angle="+angle+" dur="+durationMillis+" object="+getObjectList().name());
623

  
621 624
    mRotAxis     = axis;
622 625
    mRotRowBitmap= rowBitmap;
623 626

  
src/main/java/org/distorted/scores/RubikScoresDownloader.java
19 19

  
20 20
package org.distorted.scores;
21 21

  
22
import android.app.Activity;
22 23
import android.content.pm.PackageInfo;
23 24
import android.content.pm.PackageManager;
24 25

  
......
50 51

  
51 52
  private static final int DOWNLOAD   = 0;
52 53
  private static final int SUBMIT     = 1;
53
  private static final int IDLE       = 2;
54
  private static final int ERROR      = 2;
55
  private static final int IDLE       = 3;
54 56

  
55 57
  private final String[] hex = {
56 58
    "%00", "%01", "%02", "%03", "%04", "%05", "%06", "%07",
......
99 101
  private static int mMode = IDLE;
100 102
  private static Receiver mReceiver;
101 103
  private static String mVersion;
104
  private static String mError = "";
102 105

  
103 106
///////////////////////////////////////////////////////////////////////////////////////////////////
104 107

  
......
381 384
    return url1 + "?" + url2 + "&h=" + hash;
382 385
    }
383 386

  
387
///////////////////////////////////////////////////////////////////////////////////////////////////
388

  
389
  private String constructErrorURL()
390
    {
391
    return "https://distorted.org/magic/cgi-bin/error.cgi?e="+URLencode(mError);
392
    }
393

  
384 394
///////////////////////////////////////////////////////////////////////////////////////////////////
385 395

  
386 396
  private boolean gottaDownload()
......
411 421
          success = network(constructSubmitURL());
412 422
          }
413 423
        }
424
      if( mMode==ERROR )
425
        {
426
        mRunning = true;
427
        success = network(constructErrorURL());
428
        }
414 429
      }
415 430
    catch( Exception e )
416 431
      {
417
      mReceiver.message("Exception downloading records: "+e.getMessage() );
418
      }
419

  
420
    if( mRunning )
421
      {
422
      success = fillValues();
423
      mRunning = false;
432
      if( mReceiver!=null )
433
        {
434
        mReceiver.message("Exception downloading records: "+e.getMessage() );
435
        }
424 436
      }
425 437

  
426
    if( success )
438
    if( mReceiver!=null )
427 439
      {
428
      mReceiver.receive(mCountry, mName, mTime);
440
      if( mRunning )
441
        {
442
        success = fillValues();
443
        mRunning = false;
444
        }
429 445

  
430
      if( mMode==SUBMIT )
446
      if( success )
431 447
        {
432
        RubikScores.getInstance().successfulSubmit();
448
        mReceiver.receive(mCountry, mName, mTime);
449

  
450
        if( mMode==SUBMIT )
451
          {
452
          RubikScores.getInstance().successfulSubmit();
453
          }
433 454
        }
434 455
      }
435 456
    }
......
464 485

  
465 486
///////////////////////////////////////////////////////////////////////////////////////////////////
466 487

  
467
  private void start(Receiver receiver, FragmentActivity act, int mode)
488
  private void start(Receiver receiver, Activity act, int mode)
468 489
    {
469 490
    mReceiver = receiver;
470 491
    mMode     = mode;
471 492

  
472 493
    try
473 494
      {
474
      PackageInfo pInfo = act.getPackageManager().getPackageInfo( act.getPackageName(), 0);
475
      mVersion = pInfo.versionName;
495
      if( act!=null )
496
        {
497
        PackageInfo pInfo = act.getPackageManager().getPackageInfo( act.getPackageName(), 0);
498
        mVersion = pInfo.versionName;
499
        }
476 500
      }
477 501
    catch (PackageManager.NameNotFoundException e)
478 502
      {
......
483 507
    networkThrd.start();
484 508
    }
485 509

  
510
///////////////////////////////////////////////////////////////////////////////////////////////////
511

  
512
  public void error(String error)
513
    {
514
    mError = error;
515
    start(null, null, ERROR);
516
    }
517

  
486 518
///////////////////////////////////////////////////////////////////////////////////////////////////
487 519

  
488 520
  public void download(Receiver receiver, FragmentActivity act)
src/main/java/org/distorted/states/RubikStateSolving.java
43 43
  private Timer mTimer;
44 44
  private long mStartTime;
45 45
  private boolean mRunning;
46
  private RubikScores mScores;
46
  private final RubikScores mScores;
47 47
  private long mElapsed;
48 48
  private ImageButton mBackButton;
49 49

  
src/main/java/org/distorted/tutorial/TutorialActivity.java
30 30

  
31 31
import androidx.appcompat.app.AppCompatActivity;
32 32

  
33
import com.google.firebase.analytics.FirebaseAnalytics;
34

  
35 33
import org.distorted.dialogs.RubikDialogError;
36 34
import org.distorted.library.main.DistortedLibrary;
35
import org.distorted.library.message.EffectListener;
37 36
import org.distorted.main.R;
37
import org.distorted.main.RubikDebug;
38 38
import org.distorted.objects.ObjectList;
39 39
import org.distorted.objects.TwistyObject;
40 40
import org.distorted.states.StateList;
......
43 43

  
44 44
///////////////////////////////////////////////////////////////////////////////////////////////////
45 45

  
46
public class TutorialActivity extends AppCompatActivity
46
public class TutorialActivity extends AppCompatActivity implements RubikDebug.ActivityChanger, EffectListener
47 47
{
48 48
    private static final String URL = "https://www.youtube.com/embed/";
49 49

  
......
56 56
                                   | View.SYSTEM_UI_FLAG_FULLSCREEN
57 57
                                   | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
58 58

  
59
    public static final int FLAGS2=  View.SYSTEM_UI_FLAG_LAYOUT_STABLE
60
                                   | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
61

  
62 59
    private boolean mIsLocked;
63
    private FirebaseAnalytics mFirebaseAnalytics;
64 60
    private static int mScreenWidth, mScreenHeight;
65 61
    private int mCurrentApiVersion;
66 62
    private TutorialState mState;
......
88 84
        }
89 85

  
90 86
      mIsLocked = false;
91
      mFirebaseAnalytics = FirebaseAnalytics.getInstance(this);
92 87

  
93 88
      DisplayMetrics displaymetrics = new DisplayMetrics();
94 89
      getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
......
189 184
      super.onPause();
190 185
      TutorialSurfaceView view = findViewById(R.id.tutorialSurfaceView);
191 186
      view.onPause();
187
      RubikDebug debug = RubikDebug.getInstance();
188
      debug.onPause();
192 189

  
193 190
      if( mWebView!=null ) mWebView.onPause();
194 191

  
......
201 198
    protected void onResume() 
202 199
      {
203 200
      super.onResume();
201
      RubikDebug debug = RubikDebug.getInstance();
202
      debug.onResume(this);
203
      RubikDebug.addDebug("RubikActivity: onResume");
204

  
204 205
      DistortedLibrary.onResume(1);
205 206
      TutorialSurfaceView view = findViewById(R.id.tutorialSurfaceView);
206 207
      view.onResume();
......
247 248

  
248 249
///////////////////////////////////////////////////////////////////////////////////////////////////
249 250
// PUBLIC API
250
///////////////////////////////////////////////////////////////////////////////////////////////////
251

  
252
    public FirebaseAnalytics getAnalytics()
253
      {
254
      return mFirebaseAnalytics;
255
      }
256

  
257 251
///////////////////////////////////////////////////////////////////////////////////////////////////
258 252

  
259 253
    public TwistyObject getObject()
......
270 264
      return mScreenWidth;
271 265
      }
272 266

  
273
///////////////////////////////////////////////////////////////////////////////////////////////////
274

  
275
    public int getScreenHeightInPixels()
276
      {
277
      return mScreenHeight;
278
      }
279

  
280 267
///////////////////////////////////////////////////////////////////////////////////////////////////
281 268

  
282 269
    public TutorialPreRender getPreRender()
......
355 342
      {
356 343
      return mIsLocked;
357 344
      }
345

  
346
///////////////////////////////////////////////////////////////////////////////////////////////////
347

  
348
  public void change()
349
    {
350
    finish();
351
    }
352

  
353
///////////////////////////////////////////////////////////////////////////////////////////////////
354

  
355
  public void assign()
356
    {
357
    TutorialSurfaceView view = findViewById(R.id.tutorialSurfaceView);
358
    TutorialPreRender pre = view.getPreRender();
359
    TwistyObject object = pre.getObject();
360

  
361
    int angle = 360 / object.getBasicAngle();
362

  
363
    object.addNewRotation(1,1,angle,1000,this);
364
    }
365

  
366
///////////////////////////////////////////////////////////////////////////////////////////////////
367

  
368
  public void effectFinished(final long effectID)
369
    {
370
    RubikDebug debug = RubikDebug.getInstance();
371
    debug.onReturned();
372
    }
358 373
}
src/main/java/org/distorted/tutorial/TutorialPreRender.java
34 34
public class TutorialPreRender implements EffectController
35 35
  {
36 36
  private ActionFinishedListener mAddActionListener;
37
  private TutorialSurfaceView mView;
37
  private final TutorialSurfaceView mView;
38 38
  private boolean mFinishRotation, mRemoveRotation, mAddRotation,
39 39
                  mSetQuat, mChangeObject, mSetupObject, mSolveObject, mScrambleObject,
40 40
                  mInitializeObject, mResetAllTextureMaps, mRemovePatternRotation;
......
335 335
    mAddRotationDuration  = duration;
336 336
    }
337 337

  
338
///////////////////////////////////////////////////////////////////////////////////////////////////
339

  
340
  public void initializeObject(int[][] moves)
341
    {
342
    mInitializeObject = true;
343
    mNextMoves = moves;
344
    }
345

  
346 338
///////////////////////////////////////////////////////////////////////////////////////////////////
347 339

  
348 340
  public int getNumScrambles()
......
371 363
      }
372 364
    }
373 365

  
374
///////////////////////////////////////////////////////////////////////////////////////////////////
375

  
376
  public void resetAllTextureMaps()
377
    {
378
    mResetAllTextureMaps = true;
379
    }
380

  
381 366
///////////////////////////////////////////////////////////////////////////////////////////////////
382 367

  
383 368
  public TwistyObject getObject()
src/main/java/org/distorted/tutorial/TutorialState.java
46 46

  
47 47
  private static class Move
48 48
    {
49
    private int mAxis, mRow, mAngle;
49
    private final int mAxis, mRow, mAngle;
50 50

  
51 51
    Move(int axis, int row, int angle)
52 52
      {
src/main/java/org/distorted/tutorial/TutorialSurfaceView.java
70 70
    private int mFirstIndex, mLastIndex;
71 71
    private int mDensity;
72 72

  
73
    private static Static4D mQuat= new Static4D(-0.25189602f,0.3546389f,0.009657208f,0.90038127f);
74
    private static Static4D mTemp= new Static4D(0,0,0,1);
73
    private static final Static4D mQuat= new Static4D(-0.25189602f,0.3546389f,0.009657208f,0.90038127f);
74
    private static final Static4D mTemp= new Static4D(0,0,0,1);
75 75

  
76 76
///////////////////////////////////////////////////////////////////////////////////////////////////
77 77

  

Also available in: Unified diff