Project

General

Profile

Download (24.4 KB) Statistics
| Branch: | Revision:

distorted-objectlib / src / main / java / org / distorted / objectlib / main / ObjectPreRender.java @ 4f629c09

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2020 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is proprietary software licensed under an EULA which you should have received      //
7
// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
8
///////////////////////////////////////////////////////////////////////////////////////////////////
9

    
10
package org.distorted.objectlib.main;
11

    
12
import org.distorted.library.message.EffectListener;
13
import org.distorted.library.type.Static3D;
14

    
15
import org.distorted.library.type.Static4D;
16
import org.distorted.objectlib.helpers.ObjectLibInterface;
17
import org.distorted.objectlib.effects.BaseEffect;
18
import org.distorted.objectlib.effects.scramble.ScrambleEffect;
19
import org.distorted.objectlib.helpers.BlockController;
20
import org.distorted.objectlib.helpers.MovesFinished;
21
import org.distorted.objectlib.helpers.OperatingSystemInterface;
22
import org.distorted.objectlib.shape.ShapeDodecahedron;
23
import org.distorted.objectlib.shape.ShapeHexahedron;
24
import org.distorted.objectlib.shape.ShapeOctahedron;
25
import org.distorted.objectlib.shape.ShapeTetrahedron;
26

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

    
29
public class ObjectPreRender implements EffectListener
30
  {
31
  private static final int MAX_SLOW_SCRAMBLE = 50;
32

    
33
  private final ObjectControl mController;
34
  private InitAssets mAsset;
35
  private int mOrdinal;
36
  private TwistyObject mOldObject, mNewObject;
37
  private OperatingSystemInterface mOS;
38
  private MovesFinished mAddActionListener;
39
  private final BlockController mBlockController;
40
  private final ObjectLibInterface mInterface;
41
  private String mDebug;
42
  private float mMoveX, mMoveY;
43
  private float mScale;
44

    
45
  private boolean mFinishRotation, mRemoveRotation, mRemovePatternRotation, mAddRotation,
46
                  mSetQuat, mChangeObject, mSolveObject, mScrambleObject, mFastScrambleObject,
47
                  mPresentObject,mInitializeObject, mSetTextureMap, mResetAllTextureMaps, mSolve,
48
                  mApplyScrambles, mResetTextureEffect;
49
  private boolean mScramblingAndSolvingBlocked, mRotationBlocked, mIsSolved;
50
  private long mRotationFinishedID;
51
  private final long[] mEffectID;
52
  private int[][] mNextMoves;
53
  private int mScrambleObjectNum, mScrambleObjectDuration;
54
  private int mAddRotationAxis, mAddRotationRowBitmap, mAddRotationAngle;
55
  private long mAddRotationDuration;
56
  private int mPresentDuration, mRestickerDuration;
57
  private long mAddRotationID, mRemoveRotationID;
58
  private int mCubit, mFace, mNewColor;
59
  private int mNearestAngle;
60
  private long mScrambleStartTime, mScrambleEndTime;
61
  private int mMeshState, mIconMode;
62

    
63
  // debugging only
64
  private long mAddRotationTime;
65

    
66
///////////////////////////////////////////////////////////////////////////////////////////////////
67

    
68
  public ObjectPreRender(ObjectControl controller, ObjectLibInterface actioner)
69
    {
70
    mInterface = actioner;
71
    mController = controller;
72

    
73
    mFinishRotation       = false;
74
    mRemoveRotation       = false;
75
    mRemovePatternRotation= false;
76
    mAddRotation          = false;
77
    mSetQuat              = false;
78
    mChangeObject         = false;
79
    mSolveObject          = false;
80
    mSolve                = false;
81
    mScrambleObject       = false;
82
    mFastScrambleObject   = false;
83
    mPresentObject        = false;
84
    mResetTextureEffect   = false;
85

    
86
    mOldObject = null;
87
    mNewObject = null;
88

    
89
    mDebug = "";
90
    mScrambleObjectNum = 0;
91
    mScale = 1.0f;
92

    
93
    mEffectID = new long[BaseEffect.Type.LENGTH];
94

    
95
    mBlockController = new BlockController(this);
96
    unblockEverything();
97
    }
98

    
99
///////////////////////////////////////////////////////////////////////////////////////////////////
100

    
101
  private void createObjectNow(int ordinal, int meshState, int iconMode, InitAssets assets)
102
    {
103
    long time1 = System.currentTimeMillis();
104
    Static3D move = new Static3D(mMoveX,mMoveY,0);
105
    Static4D quat = mController.getQuat();
106
    TwistyObject tmp;
107
    boolean error = false;
108

    
109
    if( assets==null || assets.noJsonStream() )
110
      {
111
      tmp = ObjectType.create( ordinal, meshState, iconMode, quat, move, mScale, assets);
112
      }
113
    else
114
      {
115
      tmp = new TwistyJson( meshState, iconMode, quat, move, mScale, assets);
116
      error = tmp.getError();
117
      }
118

    
119
    if( error )
120
      {
121
      String errorString = tmp.getErrorString();
122
      mInterface.reportJSONError(errorString,ordinal);
123
      }
124
    else
125
      {
126
      if( mOldObject!=null ) mOldObject.releaseResources();
127
      mOldObject = mNewObject;
128
      mNewObject = tmp;
129

    
130
      long time2 = System.currentTimeMillis();
131
      mInterface.onObjectCreated(time2-time1);
132

    
133
      if( mNewObject!=null )
134
        {
135
        mNewObject.setLibInterface(mInterface);
136
        mController.setTouchControl(mNewObject);
137
        mNewObject.setObjectRatioNow(mScale, mController.getScalingSize() );
138

    
139
        if( mOS!=null )
140
          {
141
          mNewObject.restorePreferences(mOS);
142
          mOS = null;
143
          }
144

    
145
        mIsSolved = mNewObject.isSolved();
146
        }
147
      }
148
    }
149

    
150
///////////////////////////////////////////////////////////////////////////////////////////////////
151
// do all 'adjustable' effects (SizeChange, Solve, Scramble)
152

    
153
  private void doEffectNow(BaseEffect.Type type, int duration)
154
    {
155
    try
156
      {
157
      int index = type.ordinal();
158
      mEffectID[index] = type.startEffect(this,duration);
159
      }
160
    catch( Exception ex )
161
      {
162
      android.util.Log.e("renderer", "exception starting effect: "+ex.getMessage());
163
      unblockEverything();
164
      }
165
    }
166

    
167
///////////////////////////////////////////////////////////////////////////////////////////////////
168

    
169
  private void removeRotationNow()
170
    {
171
    mRemoveRotation=false;
172
    mNewObject.removeRotationNow();
173

    
174
    boolean solved = mNewObject.isSolved();
175

    
176
    if( solved && !mIsSolved )
177
      {
178
      mInterface.onSolved();
179
      unblockEverything();
180
      int duration = BaseEffect.Type.WIN.getDuration();
181
      doEffectNow( BaseEffect.Type.WIN, duration );
182
      }
183
    else
184
      {
185
      unblockEverything();
186
      }
187

    
188
    mIsSolved = solved;
189
    }
190

    
191
///////////////////////////////////////////////////////////////////////////////////////////////////
192

    
193
  private void removeRotation()
194
    {
195
    mRemoveRotation = true;
196
    }
197

    
198
///////////////////////////////////////////////////////////////////////////////////////////////////
199

    
200
  private void removePatternRotation()
201
    {
202
    mRemovePatternRotation = true;
203
    }
204

    
205
///////////////////////////////////////////////////////////////////////////////////////////////////
206

    
207
  private void removePatternRotationNow()
208
    {
209
    mRemovePatternRotation=false;
210
    mNewObject.removeRotationNow();
211
    mAddActionListener.onActionFinished(mRemoveRotationID);
212
    }
213

    
214
///////////////////////////////////////////////////////////////////////////////////////////////////
215

    
216
  private void addRotationNow()
217
    {
218
    mAddRotation = false;
219

    
220
    if( mNewObject.getNumAxis() > mAddRotationAxis )
221
      {
222
      mAddRotationID = mNewObject.addNewRotation( mAddRotationAxis, mAddRotationRowBitmap,
223
                                                  mAddRotationAngle, mAddRotationDuration, this);
224

    
225
      // failed to add effect (previous rotation hasn't been removed yet)
226
      if( mAddRotationID==0 )
227
        {
228
        mAddActionListener.onActionFinished(0);
229
        }
230
      // the rotation we have just added has forced a finish() of an ongoing
231
      // manual rotation. So the effect that's going to finish is not the manual
232
      // rotation (we have just removed it) but the rotation we have just added
233
      // here - so set mRotationFinishedID to 0
234
      else if( mAddRotationID<0 )
235
        {
236
        mAddRotationID = -mAddRotationID;
237
        mRotationFinishedID = 0;
238
        }
239
      }
240
    else // should never happen but Firebase says it sometimes does
241
      {
242
      long timeNow = System.currentTimeMillis();
243
      Class<? extends MovesFinished> clazz = mAddActionListener.getClass();
244
      String name = clazz.getSimpleName();
245

    
246
      String error = "time now: "+timeNow+" add time: "+mAddRotationTime+" axis="+mAddRotationAxis+
247
                      "object: "+mNewObject.getShortName()+" "+name;
248

    
249
      mInterface.reportProblem(error,true);
250
      unblockEverything();
251
      }
252
    }
253

    
254
///////////////////////////////////////////////////////////////////////////////////////////////////
255

    
256
  private void finishRotationNow()
257
    {
258
    mFinishRotation = false;
259
    blockEverything(BlockController.PLACE_0);
260
    mRotationFinishedID = mNewObject.finishRotationNow(this, mNearestAngle);
261

    
262
    if( mRotationFinishedID==0 ) // failed to add effect - should never happen
263
      {
264
      unblockEverything();
265
      }
266
    }
267

    
268
///////////////////////////////////////////////////////////////////////////////////////////////////
269

    
270
  private void changeObjectNow()
271
    {
272
    mChangeObject = false;
273
    blockEverything(BlockController.PLACE_1);
274
    createObjectNow(mOrdinal,mMeshState,mIconMode,mAsset);
275
    int duration = BaseEffect.Type.SIZECHANGE.getDuration();
276
    doEffectNow( BaseEffect.Type.SIZECHANGE, duration );
277
    }
278

    
279
///////////////////////////////////////////////////////////////////////////////////////////////////
280

    
281
  private void scrambleObjectNow()
282
    {
283
    mScrambleObject = false;
284
    mIsSolved       = false;
285
    blockEverything(BlockController.PLACE_3);
286

    
287
    if( mScrambleObjectNum<MAX_SLOW_SCRAMBLE )
288
      {
289
      int duration = BaseEffect.Type.SCRAMBLE.getDuration();
290
      doEffectNow( BaseEffect.Type.SCRAMBLE, duration );
291
      }
292
    else
293
      {
294
      int duration = BaseEffect.Type.FAST_SCRAMBLE.getDuration();
295
      doEffectNow( BaseEffect.Type.FAST_SCRAMBLE, duration );
296
      }
297
    }
298

    
299
///////////////////////////////////////////////////////////////////////////////////////////////////
300

    
301
  private void fastScrambleObjectNow()
302
    {
303
    mFastScrambleObject = false;
304
    mIsSolved           = false;
305
    blockEverything(BlockController.PLACE_5);
306
    doEffectNow( BaseEffect.Type.FAST_SCRAMBLE, mScrambleObjectDuration );
307
    }
308

    
309
///////////////////////////////////////////////////////////////////////////////////////////////////
310

    
311
  private void resetTextureNow()
312
    {
313
    mResetTextureEffect = false;
314
    doEffectNow( BaseEffect.Type.RESTICKER, mRestickerDuration );
315
    }
316

    
317
///////////////////////////////////////////////////////////////////////////////////////////////////
318

    
319
  private void presentObjectNow()
320
    {
321
    mPresentObject = false;
322
    doEffectNow( BaseEffect.Type.PRESENT, mPresentDuration );
323
    }
324

    
325
///////////////////////////////////////////////////////////////////////////////////////////////////
326

    
327
  private void solveObjectNow()
328
    {
329
    mSolveObject = false;
330
    blockEverything(BlockController.PLACE_4);
331
    int duration = BaseEffect.Type.SOLVE.getDuration();
332
    doEffectNow( BaseEffect.Type.SOLVE, duration );
333
    }
334

    
335
///////////////////////////////////////////////////////////////////////////////////////////////////
336

    
337
  private void solveNow()
338
    {
339
    mSolve = false;
340
    if( mNewObject!=null ) mNewObject.solve();
341
    }
342

    
343
///////////////////////////////////////////////////////////////////////////////////////////////////
344

    
345
  private void initializeObjectNow()
346
    {
347
    mInitializeObject = false;
348
    mNewObject.initializeObject(mNextMoves);
349
    }
350

    
351
///////////////////////////////////////////////////////////////////////////////////////////////////
352

    
353
  private void applyScramblesNow()
354
    {
355
    mApplyScrambles = false;
356
    mNewObject.applyScrambles(mNextMoves);
357
    }
358

    
359
///////////////////////////////////////////////////////////////////////////////////////////////////
360

    
361
  private void setTextureMapNow()
362
    {
363
    mSetTextureMap = false;
364

    
365
    if( mNewObject!=null ) mNewObject.setTextureMap(mCubit,mFace,mNewColor);
366
    }
367

    
368
///////////////////////////////////////////////////////////////////////////////////////////////////
369

    
370
  private void resetAllTextureMapsNow()
371
    {
372
    mResetAllTextureMaps = false;
373
    if( mNewObject!=null ) mNewObject.resetAllTextureMaps();
374
    }
375

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

    
378
  private void setQuatNow()
379
    {
380
    mSetQuat = false;
381
    mController.setQuat();
382
    }
383

    
384
///////////////////////////////////////////////////////////////////////////////////////////////////
385

    
386
  private int computeRowFromBitmap(int rowBitmap)
387
    {
388
    int index = 0;
389

    
390
    while(index<32)
391
      {
392
      if( (rowBitmap&0x1) != 0 ) return index;
393
      rowBitmap>>=1;
394
      index++;
395
      }
396

    
397
    return 0;
398
    }
399

    
400
///////////////////////////////////////////////////////////////////////////////////////////////////
401

    
402
  private void blockEverything(int place)
403
    {
404
    mScramblingAndSolvingBlocked = true;
405
    mRotationBlocked = true;
406
    mBlockController.rotationBlocked(place);
407
    mBlockController.scramblingAndSolvingBlocked(place);
408
    }
409

    
410
///////////////////////////////////////////////////////////////////////////////////////////////////
411
// called from ObjectControl; this from app when we switch the screen to READ post-scrambling.
412
// The point: we only unblock having completed the screen switch so that it is impossible to
413
// click the solve button then.
414

    
415
  void unblockEverything()
416
    {
417
    mScramblingAndSolvingBlocked = false;
418
    mRotationBlocked = false;
419
    mBlockController.rotationUnblocked();
420
    mBlockController.scramblingAndSolvingUnblocked();
421
    }
422

    
423
///////////////////////////////////////////////////////////////////////////////////////////////////
424

    
425
  void rememberMove(int axis, int row, int angle)
426
    {
427
    mDebug += (mNewObject==null ? "[null]" : mNewObject.reportState() );
428
    mDebug += ("(m "+axis+" "+(1<<row)+" "+angle+" "+(System.currentTimeMillis()-mScrambleEndTime))+")";
429
    }
430

    
431
///////////////////////////////////////////////////////////////////////////////////////////////////
432

    
433
  void finishRotation(int nearestAngle)
434
    {
435
    mNearestAngle   = nearestAngle;
436
    mFinishRotation = true;
437
    }
438

    
439
///////////////////////////////////////////////////////////////////////////////////////////////////
440

    
441
  void setTextureMap(int cubit, int face, int newColor)
442
    {
443
    mSetTextureMap = true;
444

    
445
    mCubit    = cubit;
446
    mFace     = face;
447
    mNewColor = newColor;
448
    }
449

    
450
///////////////////////////////////////////////////////////////////////////////////////////////////
451

    
452
  void setQuatOnNextRender()
453
    {
454
    mSetQuat = true;
455
    }
456

    
457
///////////////////////////////////////////////////////////////////////////////////////////////////
458

    
459
  void setMove(float xmove, float ymove)
460
    {
461
    mMoveX = xmove;
462
    mMoveY = ymove;
463
    }
464

    
465
///////////////////////////////////////////////////////////////////////////////////////////////////
466

    
467
  void setScale(float scale)
468
    {
469
    mScale = scale;
470
    }
471

    
472
///////////////////////////////////////////////////////////////////////////////////////////////////
473
// INTERNAL API
474
///////////////////////////////////////////////////////////////////////////////////////////////////
475

    
476
  public int getNumScrambles()
477
    {
478
    return mScrambleObjectNum;
479
    }
480

    
481
///////////////////////////////////////////////////////////////////////////////////////////////////
482

    
483
  public TwistyObject getOldObject()
484
    {
485
    return mOldObject;
486
    }
487

    
488
///////////////////////////////////////////////////////////////////////////////////////////////////
489

    
490
  public float getMoveX()
491
    {
492
    return mMoveX;
493
    }
494

    
495
///////////////////////////////////////////////////////////////////////////////////////////////////
496

    
497
  public float getMoveY()
498
    {
499
    return mMoveY;
500
    }
501

    
502
///////////////////////////////////////////////////////////////////////////////////////////////////
503

    
504
  public ObjectLibInterface getInterface()
505
    {
506
    return mInterface;
507
    }
508

    
509
///////////////////////////////////////////////////////////////////////////////////////////////////
510
// PUBLIC API
511
///////////////////////////////////////////////////////////////////////////////////////////////////
512

    
513
  public void savePreferences(OperatingSystemInterface os)
514
    {
515
    if( mNewObject!=null )
516
      {
517
      mNewObject.savePreferences(os);
518
      }
519
    }
520

    
521
///////////////////////////////////////////////////////////////////////////////////////////////////
522

    
523
  public void restorePreferences(OperatingSystemInterface os)
524
    {
525
    mOS = os;
526
    }
527

    
528
///////////////////////////////////////////////////////////////////////////////////////////////////
529

    
530
  public void changeObject(int ordinal, int meshState, int iconMode, InitAssets asset)
531
    {
532
    mChangeObject = true;
533
    mOrdinal    = ordinal;
534
    mMeshState  = meshState;
535
    mIconMode   = iconMode;
536
    mAsset      = asset;
537
    }
538

    
539
///////////////////////////////////////////////////////////////////////////////////////////////////
540

    
541
  public void setDefaultRotation(int numFaces)
542
    {
543
    if( mController!=null && mController.getRotateOnCreation() )
544
      {
545
      switch(numFaces)
546
        {
547
        case  4: mController.rotateNow(ShapeTetrahedron.DEFAULT_ROT ); break;
548
        case  6: mController.rotateNow(ShapeHexahedron.DEFAULT_ROT  ); break;
549
        case  8: mController.rotateNow(ShapeOctahedron.DEFAULT_ROT  ); break;
550
        case 12: mController.rotateNow(ShapeDodecahedron.DEFAULT_ROT); break;
551
        }
552
      }
553
    }
554

    
555
///////////////////////////////////////////////////////////////////////////////////////////////////
556

    
557
  public boolean isRotationBlocked()
558
    {
559
    return mRotationBlocked;
560
    }
561

    
562
///////////////////////////////////////////////////////////////////////////////////////////////////
563

    
564
  public boolean isScramblingAndSolvingNotBlocked()
565
    {
566
    return !mScramblingAndSolvingBlocked;
567
    }
568

    
569
///////////////////////////////////////////////////////////////////////////////////////////////////
570

    
571
  public void blockRotation(int place)
572
    {
573
    mRotationBlocked = true;
574
    mBlockController.rotationBlocked(place);
575
    }
576

    
577
///////////////////////////////////////////////////////////////////////////////////////////////////
578

    
579
  public void unblockRotation()
580
    {
581
    mRotationBlocked = false;
582
    mBlockController.rotationUnblocked();
583
    }
584

    
585
///////////////////////////////////////////////////////////////////////////////////////////////////
586

    
587
  public void unblockScramblingAndSolving()
588
    {
589
    mScramblingAndSolvingBlocked = false;
590
    mBlockController.scramblingAndSolvingUnblocked();
591
    }
592

    
593
///////////////////////////////////////////////////////////////////////////////////////////////////
594

    
595
  public void preRender()
596
    {
597
    if( mSolve                 ) solveNow();
598
    if( mSetQuat               ) setQuatNow();
599
    if( mFinishRotation        ) finishRotationNow();
600
    if( mRemoveRotation        ) removeRotationNow();
601
    if( mRemovePatternRotation ) removePatternRotationNow();
602
    if( mChangeObject          ) changeObjectNow();
603
    if( mSolveObject           ) solveObjectNow();
604
    if( mScrambleObject        ) scrambleObjectNow();
605
    if( mFastScrambleObject    ) fastScrambleObjectNow();
606
    if( mPresentObject         ) presentObjectNow();
607
    if( mAddRotation           ) addRotationNow();
608
    if( mInitializeObject      ) initializeObjectNow();
609
    if( mApplyScrambles        ) applyScramblesNow();
610
    if( mResetAllTextureMaps   ) resetAllTextureMapsNow();
611
    if( mSetTextureMap         ) setTextureMapNow();
612
    if( mResetTextureEffect    ) resetTextureNow();
613
    }
614

    
615
///////////////////////////////////////////////////////////////////////////////////////////////////
616

    
617
  public void addRotation(MovesFinished listener, int axis, int rowBitmap, int bareAngle, int millPreDegree)
618
    {
619
    int[][] basicAngles = mNewObject==null ? null : mNewObject.getBasicAngles();
620
    int length = basicAngles==null ? 0 : basicAngles.length;
621

    
622
    if( axis<length )
623
      {
624
      int row = computeRowFromBitmap(rowBitmap);
625

    
626
      if( row<basicAngles[axis].length )
627
        {
628
        int basicAngle= basicAngles[axis][row];
629
        int angle     = bareAngle*(360/basicAngle);
630
        int duration  = Math.abs(angle)*millPreDegree;
631

    
632
        mAddActionListener    = listener;
633
        mAddRotationAxis      = axis;
634
        mAddRotationRowBitmap = rowBitmap;
635
        mAddRotationAngle     = angle;
636
        mAddRotationDuration  = duration;
637
        mAddRotationTime      = System.currentTimeMillis();
638
        mAddRotation          = true;
639

    
640
        if( listener instanceof ScrambleEffect )
641
          {
642
          mDebug += (mNewObject==null ? "null" : mNewObject.reportState() );
643
          mDebug += ("(a "+axis+" "+rowBitmap+" "+angle+" "+(mAddRotationTime-mScrambleStartTime))+")";
644
          }
645
        }
646
      }
647
    }
648

    
649
///////////////////////////////////////////////////////////////////////////////////////////////////
650

    
651
  public void initializeObject(int[][] moves)
652
    {
653
    mInitializeObject = true;
654
    mNextMoves = moves;
655
    }
656

    
657
///////////////////////////////////////////////////////////////////////////////////////////////////
658

    
659
  public void applyScrambles(int[][] moves)
660
    {
661
    mApplyScrambles = true;
662
    mNextMoves = moves;
663
    }
664

    
665
///////////////////////////////////////////////////////////////////////////////////////////////////
666

    
667
  public boolean scrambleObject(int num)
668
    {
669
    if( !mScramblingAndSolvingBlocked )
670
      {
671
      mScrambleObject = true;
672
      mScrambleObjectNum = num;
673
      mDebug = "";
674
      mScrambleStartTime = System.currentTimeMillis();
675
      return true;
676
      }
677
    return false;
678
    }
679

    
680
///////////////////////////////////////////////////////////////////////////////////////////////////
681

    
682
  public boolean fastScrambleObject(int duration, int num)
683
    {
684
    if( !mScramblingAndSolvingBlocked )
685
      {
686
      mFastScrambleObject = true;
687
      mScrambleObjectNum = num;
688
      mScrambleObjectDuration = duration;
689
      mDebug = "";
690
      mScrambleStartTime = System.currentTimeMillis();
691
      return true;
692
      }
693
    return false;
694
    }
695

    
696
///////////////////////////////////////////////////////////////////////////////////////////////////
697

    
698
  public void presentObject(int num, int duration)
699
    {
700
    mScrambleObjectNum = num;
701
    mPresentDuration = duration;
702
    mPresentObject = true;
703
    }
704

    
705
///////////////////////////////////////////////////////////////////////////////////////////////////
706
// this starts the Solve Effect
707

    
708
  public void solveObject()
709
    {
710
    if( !mScramblingAndSolvingBlocked )
711
      {
712
      mSolveObject = true;
713
      }
714
    }
715

    
716
///////////////////////////////////////////////////////////////////////////////////////////////////
717
// this only sets the cubits state to solved
718

    
719
  public void solveOnly()
720
    {
721
    mSolve = true;
722
    }
723

    
724
///////////////////////////////////////////////////////////////////////////////////////////////////
725

    
726
  public void resetTextureMapsEffect(int duration)
727
    {
728
    mRestickerDuration = duration;
729
    mResetTextureEffect = true;
730
    }
731

    
732
///////////////////////////////////////////////////////////////////////////////////////////////////
733

    
734
  public void resetAllTextureMaps()
735
    {
736
    mResetAllTextureMaps = true;
737
    }
738

    
739
///////////////////////////////////////////////////////////////////////////////////////////////////
740

    
741
  public TwistyObject getObject()
742
    {
743
    return mNewObject;
744
    }
745

    
746
///////////////////////////////////////////////////////////////////////////////////////////////////
747

    
748
  public TwistyObjectNode getObjectNode()
749
    {
750
    return mController.getNode();
751
    }
752

    
753
///////////////////////////////////////////////////////////////////////////////////////////////////
754

    
755
  public void effectFinished(final long effectID)
756
    {
757
    if( effectID == mRotationFinishedID )
758
      {
759
      mRotationFinishedID = 0;
760
      removeRotation();
761
      }
762
    else if( effectID == mAddRotationID )
763
      {
764
      mAddRotationID = 0;
765
      mRemoveRotationID = effectID;
766
      removePatternRotation();
767
      }
768
    else
769
      {
770
      for(int i=0; i<BaseEffect.Type.LENGTH; i++)
771
        {
772
        if( effectID == mEffectID[i] )
773
          {
774
          if( i==BaseEffect.Type.SCRAMBLE.ordinal() )
775
            {
776
            mScrambleEndTime = System.currentTimeMillis();
777
            mInterface.onScrambleEffectFinished();
778
            }
779
          else if( i==BaseEffect.Type.FAST_SCRAMBLE.ordinal() )
780
            {
781
            mInterface.onScrambleEffectFinished();
782
            unblockEverything();
783
            }
784
          else if( i==BaseEffect.Type.WIN.ordinal() )
785
            {
786
            mInterface.onWinEffectFinished(mScrambleStartTime,mScrambleEndTime-mScrambleStartTime,mDebug,mScrambleObjectNum);
787
            }
788
          else
789
            {
790
            unblockEverything();
791
            }
792

    
793
          break;
794
          }
795
        }
796
      }
797
    }
798
  }
(4-4/11)