Project

General

Profile

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

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

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 java.io.InputStream;
13

    
14
import android.app.Activity;
15
import android.content.SharedPreferences;
16

    
17
import org.distorted.library.message.EffectListener;
18
import org.distorted.library.type.Static3D;
19

    
20
import org.distorted.library.type.Static4D;
21
import org.distorted.objectlib.helpers.ObjectLibInterface;
22
import org.distorted.objectlib.effects.BaseEffect;
23
import org.distorted.objectlib.effects.scramble.ScrambleEffect;
24
import org.distorted.objectlib.helpers.BlockController;
25
import org.distorted.objectlib.helpers.MovesFinished;
26
import org.distorted.objectlib.shape.ShapeDodecahedron;
27
import org.distorted.objectlib.shape.ShapeHexahedron;
28
import org.distorted.objectlib.shape.ShapeOctahedron;
29
import org.distorted.objectlib.shape.ShapeTetrahedron;
30

    
31
///////////////////////////////////////////////////////////////////////////////////////////////////
32

    
33
public class ObjectPreRender implements EffectListener
34
  {
35
  private static final int MAX_SLOW_SCRAMBLE = 50;
36

    
37
  private final ObjectControl mController;
38
  private InputStream mJsonStream, mMeshStream;
39
  private int mOrdinal;
40
  private TwistyObject mOldObject, mNewObject;
41
  private SharedPreferences mPreferences;
42
  private MovesFinished mAddActionListener;
43
  private final BlockController mBlockController;
44
  private final ObjectLibInterface mInterface;
45
  private String mDebug;
46
  private float mMoveX, mMoveY;
47
  private float mScale;
48

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

    
67
  // debugging only
68
  private long mAddRotationTime;
69

    
70
///////////////////////////////////////////////////////////////////////////////////////////////////
71

    
72
  public ObjectPreRender(Activity act, ObjectControl controller, ObjectLibInterface actioner)
73
    {
74
    mInterface = actioner;
75
    mController = controller;
76

    
77
    mFinishRotation       = false;
78
    mRemoveRotation       = false;
79
    mRemovePatternRotation= false;
80
    mAddRotation          = false;
81
    mSetQuat              = false;
82
    mChangeObject         = false;
83
    mSolveObject          = false;
84
    mSolve                = false;
85
    mScrambleObject       = false;
86
    mFastScrambleObject   = false;
87
    mPresentObject        = false;
88
    mResetTextureEffect   = false;
89

    
90
    mOldObject = null;
91
    mNewObject = null;
92

    
93
    mDebug = "";
94
    mScrambleObjectNum = 0;
95
    mScale = 1.0f;
96

    
97
    mEffectID = new long[BaseEffect.Type.LENGTH];
98

    
99
    mBlockController = new BlockController(act,this);
100
    unblockEverything();
101
    }
102

    
103
///////////////////////////////////////////////////////////////////////////////////////////////////
104

    
105
  private void createObjectNow(int ordinal, int meshState, int iconMode, InputStream jsonStream, InputStream meshStream)
106
    {
107
    long time1 = System.currentTimeMillis();
108
    Static3D move = new Static3D(mMoveX,mMoveY,0);
109
    Static4D quat = mController.getQuat();
110
    TwistyObject tmp;
111
    boolean error = false;
112

    
113
    if( jsonStream==null )
114
      {
115
      tmp = ObjectType.create( ordinal, meshState, iconMode, quat, move, mScale, meshStream);
116
      }
117
    else
118
      {
119
      tmp = new TwistyJson( jsonStream, meshState, iconMode, quat, move, mScale, meshStream);
120
      error = tmp.getError();
121
      }
122

    
123
    if( error )
124
      {
125
      String errorString = tmp.getErrorString();
126
      mInterface.reportJSONError(errorString,ordinal);
127
      }
128
    else
129
      {
130
      if( mOldObject!=null ) mOldObject.releaseResources();
131
      mOldObject = mNewObject;
132
      mNewObject = tmp;
133

    
134
      long time2 = System.currentTimeMillis();
135
      mInterface.onObjectCreated(time2-time1);
136

    
137
      if( mNewObject!=null )
138
        {
139
        mNewObject.setLibInterface(mInterface);
140
        mController.setTouchControl(mNewObject);
141
        mNewObject.setObjectRatioNow(mScale, mController.getScalingSize() );
142

    
143
        if( mPreferences!=null )
144
          {
145
          mNewObject.restorePreferences(mPreferences);
146
          mPreferences = null;
147
          }
148

    
149
        mIsSolved = mNewObject.isSolved();
150
        }
151
      }
152
    }
153

    
154
///////////////////////////////////////////////////////////////////////////////////////////////////
155
// do all 'adjustable' effects (SizeChange, Solve, Scramble)
156

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

    
171
///////////////////////////////////////////////////////////////////////////////////////////////////
172

    
173
  private void removeRotationNow()
174
    {
175
    mRemoveRotation=false;
176
    mNewObject.removeRotationNow();
177

    
178
    boolean solved = mNewObject.isSolved();
179

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

    
192
    mIsSolved = solved;
193
    }
194

    
195
///////////////////////////////////////////////////////////////////////////////////////////////////
196

    
197
  private void removeRotation()
198
    {
199
    mRemoveRotation = true;
200
    }
201

    
202
///////////////////////////////////////////////////////////////////////////////////////////////////
203

    
204
  private void removePatternRotation()
205
    {
206
    mRemovePatternRotation = true;
207
    }
208

    
209
///////////////////////////////////////////////////////////////////////////////////////////////////
210

    
211
  private void removePatternRotationNow()
212
    {
213
    mRemovePatternRotation=false;
214
    mNewObject.removeRotationNow();
215
    mAddActionListener.onActionFinished(mRemoveRotationID);
216
    }
217

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

    
220
  private void addRotationNow()
221
    {
222
    mAddRotation = false;
223

    
224
    if( mNewObject.getNumAxis() > mAddRotationAxis )
225
      {
226
      mAddRotationID = mNewObject.addNewRotation( mAddRotationAxis, mAddRotationRowBitmap,
227
                                                  mAddRotationAngle, mAddRotationDuration, this);
228

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

    
250
      String error = "time now: "+timeNow+" add time: "+mAddRotationTime+" axis="+mAddRotationAxis+
251
                      "object: "+mNewObject.getShortName()+" "+name;
252

    
253
      mInterface.reportProblem(error,true);
254
      unblockEverything();
255
      }
256
    }
257

    
258
///////////////////////////////////////////////////////////////////////////////////////////////////
259

    
260
  private void finishRotationNow()
261
    {
262
    mFinishRotation = false;
263
    blockEverything(BlockController.PLACE_0);
264
    mRotationFinishedID = mNewObject.finishRotationNow(this, mNearestAngle);
265

    
266
    if( mRotationFinishedID==0 ) // failed to add effect - should never happen
267
      {
268
      unblockEverything();
269
      }
270
    }
271

    
272
///////////////////////////////////////////////////////////////////////////////////////////////////
273

    
274
  private void changeObjectNow()
275
    {
276
    mChangeObject = false;
277
    blockEverything(BlockController.PLACE_1);
278
    createObjectNow(mOrdinal,mMeshState,mIconMode,mJsonStream,mMeshStream);
279
    int duration = BaseEffect.Type.SIZECHANGE.getDuration();
280
    doEffectNow( BaseEffect.Type.SIZECHANGE, duration );
281
    }
282

    
283
///////////////////////////////////////////////////////////////////////////////////////////////////
284

    
285
  private void scrambleObjectNow()
286
    {
287
    mScrambleObject = false;
288
    mIsSolved       = false;
289
    blockEverything(BlockController.PLACE_3);
290

    
291
    if( mScrambleObjectNum<MAX_SLOW_SCRAMBLE )
292
      {
293
      int duration = BaseEffect.Type.SCRAMBLE.getDuration();
294
      doEffectNow( BaseEffect.Type.SCRAMBLE, duration );
295
      }
296
    else
297
      {
298
      int duration = BaseEffect.Type.FAST_SCRAMBLE.getDuration();
299
      doEffectNow( BaseEffect.Type.FAST_SCRAMBLE, duration );
300
      }
301
    }
302

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

    
305
  private void fastScrambleObjectNow()
306
    {
307
    mFastScrambleObject = false;
308
    mIsSolved           = false;
309
    blockEverything(BlockController.PLACE_5);
310
    doEffectNow( BaseEffect.Type.FAST_SCRAMBLE, mScrambleObjectDuration );
311
    }
312

    
313
///////////////////////////////////////////////////////////////////////////////////////////////////
314

    
315
  private void resetTextureNow()
316
    {
317
    mResetTextureEffect = false;
318
    doEffectNow( BaseEffect.Type.RESTICKER, mRestickerDuration );
319
    }
320

    
321
///////////////////////////////////////////////////////////////////////////////////////////////////
322

    
323
  private void presentObjectNow()
324
    {
325
    mPresentObject = false;
326
    doEffectNow( BaseEffect.Type.PRESENT, mPresentDuration );
327
    }
328

    
329
///////////////////////////////////////////////////////////////////////////////////////////////////
330

    
331
  private void solveObjectNow()
332
    {
333
    mSolveObject = false;
334
    blockEverything(BlockController.PLACE_4);
335
    int duration = BaseEffect.Type.SOLVE.getDuration();
336
    doEffectNow( BaseEffect.Type.SOLVE, duration );
337
    }
338

    
339
///////////////////////////////////////////////////////////////////////////////////////////////////
340

    
341
  private void solveNow()
342
    {
343
    mSolve = false;
344
    if( mNewObject!=null ) mNewObject.solve();
345
    }
346

    
347
///////////////////////////////////////////////////////////////////////////////////////////////////
348

    
349
  private void initializeObjectNow()
350
    {
351
    mInitializeObject = false;
352
    mNewObject.initializeObject(mNextMoves);
353
    }
354

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

    
357
  private void applyScramblesNow()
358
    {
359
    mApplyScrambles = false;
360
    mNewObject.applyScrambles(mNextMoves);
361
    }
362

    
363
///////////////////////////////////////////////////////////////////////////////////////////////////
364

    
365
  private void setTextureMapNow()
366
    {
367
    mSetTextureMap = false;
368

    
369
    if( mNewObject!=null ) mNewObject.setTextureMap(mCubit,mFace,mNewColor);
370
    }
371

    
372
///////////////////////////////////////////////////////////////////////////////////////////////////
373

    
374
  private void resetAllTextureMapsNow()
375
    {
376
    mResetAllTextureMaps = false;
377
    if( mNewObject!=null ) mNewObject.resetAllTextureMaps();
378
    }
379

    
380
///////////////////////////////////////////////////////////////////////////////////////////////////
381

    
382
  private void setQuatNow()
383
    {
384
    mSetQuat = false;
385
    mController.setQuat();
386
    }
387

    
388
///////////////////////////////////////////////////////////////////////////////////////////////////
389

    
390
  private int computeRowFromBitmap(int rowBitmap)
391
    {
392
    int index = 0;
393

    
394
    while(index<32)
395
      {
396
      if( (rowBitmap&0x1) != 0 ) return index;
397
      rowBitmap>>=1;
398
      index++;
399
      }
400

    
401
    return 0;
402
    }
403

    
404
///////////////////////////////////////////////////////////////////////////////////////////////////
405

    
406
  private void blockEverything(int place)
407
    {
408
    mScramblingAndSolvingBlocked = true;
409
    mRotationBlocked = true;
410
    mBlockController.rotationBlocked(place);
411
    mBlockController.scramblingAndSolvingBlocked(place);
412
    }
413

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

    
419
  void unblockEverything()
420
    {
421
    mScramblingAndSolvingBlocked = false;
422
    mRotationBlocked = false;
423
    mBlockController.rotationUnblocked();
424
    mBlockController.scramblingAndSolvingUnblocked();
425
    }
426

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

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

    
435
///////////////////////////////////////////////////////////////////////////////////////////////////
436

    
437
  void finishRotation(int nearestAngle)
438
    {
439
    mNearestAngle   = nearestAngle;
440
    mFinishRotation = true;
441
    }
442

    
443
///////////////////////////////////////////////////////////////////////////////////////////////////
444

    
445
  void setTextureMap(int cubit, int face, int newColor)
446
    {
447
    mSetTextureMap = true;
448

    
449
    mCubit    = cubit;
450
    mFace     = face;
451
    mNewColor = newColor;
452
    }
453

    
454
///////////////////////////////////////////////////////////////////////////////////////////////////
455

    
456
  void setQuatOnNextRender()
457
    {
458
    mSetQuat = true;
459
    }
460

    
461
///////////////////////////////////////////////////////////////////////////////////////////////////
462

    
463
  void setMove(float xmove, float ymove)
464
    {
465
    mMoveX = xmove;
466
    mMoveY = ymove;
467
    }
468

    
469
///////////////////////////////////////////////////////////////////////////////////////////////////
470

    
471
  void setScale(float scale)
472
    {
473
    mScale = scale;
474
    }
475

    
476
///////////////////////////////////////////////////////////////////////////////////////////////////
477
// INTERNAL API
478
///////////////////////////////////////////////////////////////////////////////////////////////////
479

    
480
  public int getNumScrambles()
481
    {
482
    return mScrambleObjectNum;
483
    }
484

    
485
///////////////////////////////////////////////////////////////////////////////////////////////////
486

    
487
  public TwistyObject getOldObject()
488
    {
489
    return mOldObject;
490
    }
491

    
492
///////////////////////////////////////////////////////////////////////////////////////////////////
493

    
494
  public float getMoveX()
495
    {
496
    return mMoveX;
497
    }
498

    
499
///////////////////////////////////////////////////////////////////////////////////////////////////
500

    
501
  public float getMoveY()
502
    {
503
    return mMoveY;
504
    }
505

    
506
///////////////////////////////////////////////////////////////////////////////////////////////////
507

    
508
  public ObjectLibInterface getInterface()
509
    {
510
    return mInterface;
511
    }
512

    
513
///////////////////////////////////////////////////////////////////////////////////////////////////
514
// PUBLIC API
515
///////////////////////////////////////////////////////////////////////////////////////////////////
516

    
517
  public void savePreferences(SharedPreferences.Editor editor)
518
    {
519
    if( mNewObject!=null )
520
      {
521
      mNewObject.savePreferences(editor);
522
      }
523
    }
524

    
525
///////////////////////////////////////////////////////////////////////////////////////////////////
526

    
527
  public void restorePreferences(SharedPreferences preferences)
528
    {
529
    mPreferences = preferences;
530
    }
531

    
532
///////////////////////////////////////////////////////////////////////////////////////////////////
533

    
534
  public void changeObject(int ordinal, int meshState, int iconMode, InputStream jsonStream, InputStream meshStream)
535
    {
536
    mChangeObject = true;
537
    mOrdinal    = ordinal;
538
    mMeshState  = meshState;
539
    mIconMode   = iconMode;
540
    mJsonStream = jsonStream;
541
    mMeshStream = meshStream;
542
    }
543

    
544
///////////////////////////////////////////////////////////////////////////////////////////////////
545

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

    
560
///////////////////////////////////////////////////////////////////////////////////////////////////
561

    
562
  public boolean isRotationBlocked()
563
    {
564
    return mRotationBlocked;
565
    }
566

    
567
///////////////////////////////////////////////////////////////////////////////////////////////////
568

    
569
  public boolean isScramblingAndSolvingNotBlocked()
570
    {
571
    return !mScramblingAndSolvingBlocked;
572
    }
573

    
574
///////////////////////////////////////////////////////////////////////////////////////////////////
575

    
576
  public void blockRotation(int place)
577
    {
578
    mRotationBlocked = true;
579
    mBlockController.rotationBlocked(place);
580
    }
581

    
582
///////////////////////////////////////////////////////////////////////////////////////////////////
583

    
584
  public void unblockRotation()
585
    {
586
    mRotationBlocked = false;
587
    mBlockController.rotationUnblocked();
588
    }
589

    
590
///////////////////////////////////////////////////////////////////////////////////////////////////
591

    
592
  public void unblockScramblingAndSolving()
593
    {
594
    mScramblingAndSolvingBlocked = false;
595
    mBlockController.scramblingAndSolvingUnblocked();
596
    }
597

    
598
///////////////////////////////////////////////////////////////////////////////////////////////////
599

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

    
620
///////////////////////////////////////////////////////////////////////////////////////////////////
621

    
622
  public void addRotation(MovesFinished listener, int axis, int rowBitmap, int bareAngle, int millPreDegree)
623
    {
624
    int[][] basicAngles = mNewObject==null ? null : mNewObject.getBasicAngles();
625
    int length = basicAngles==null ? 0 : basicAngles.length;
626

    
627
    if( axis<length )
628
      {
629
      int row = computeRowFromBitmap(rowBitmap);
630

    
631
      if( row<basicAngles[axis].length )
632
        {
633
        int basicAngle= basicAngles[axis][row];
634
        int angle     = bareAngle*(360/basicAngle);
635
        int duration  = Math.abs(angle)*millPreDegree;
636

    
637
        mAddActionListener    = listener;
638
        mAddRotationAxis      = axis;
639
        mAddRotationRowBitmap = rowBitmap;
640
        mAddRotationAngle     = angle;
641
        mAddRotationDuration  = duration;
642
        mAddRotationTime      = System.currentTimeMillis();
643
        mAddRotation          = true;
644

    
645
        if( listener instanceof ScrambleEffect )
646
          {
647
          mDebug += (mNewObject==null ? "null" : mNewObject.reportState() );
648
          mDebug += ("(a "+axis+" "+rowBitmap+" "+angle+" "+(mAddRotationTime-mScrambleStartTime))+")";
649
          }
650
        }
651
      }
652
    }
653

    
654
///////////////////////////////////////////////////////////////////////////////////////////////////
655

    
656
  public void initializeObject(int[][] moves)
657
    {
658
    mInitializeObject = true;
659
    mNextMoves = moves;
660
    }
661

    
662
///////////////////////////////////////////////////////////////////////////////////////////////////
663

    
664
  public void applyScrambles(int[][] moves)
665
    {
666
    mApplyScrambles = true;
667
    mNextMoves = moves;
668
    }
669

    
670
///////////////////////////////////////////////////////////////////////////////////////////////////
671

    
672
  public boolean scrambleObject(int num)
673
    {
674
    if( !mScramblingAndSolvingBlocked )
675
      {
676
      mScrambleObject = true;
677
      mScrambleObjectNum = num;
678
      mDebug = "";
679
      mScrambleStartTime = System.currentTimeMillis();
680
      return true;
681
      }
682
    return false;
683
    }
684

    
685
///////////////////////////////////////////////////////////////////////////////////////////////////
686

    
687
  public boolean fastScrambleObject(int duration, int num)
688
    {
689
    if( !mScramblingAndSolvingBlocked )
690
      {
691
      mFastScrambleObject = true;
692
      mScrambleObjectNum = num;
693
      mScrambleObjectDuration = duration;
694
      mDebug = "";
695
      mScrambleStartTime = System.currentTimeMillis();
696
      return true;
697
      }
698
    return false;
699
    }
700

    
701
///////////////////////////////////////////////////////////////////////////////////////////////////
702

    
703
  public void presentObject(int num, int duration)
704
    {
705
    mScrambleObjectNum = num;
706
    mPresentDuration = duration;
707
    mPresentObject = true;
708
    }
709

    
710
///////////////////////////////////////////////////////////////////////////////////////////////////
711
// this starts the Solve Effect
712

    
713
  public void solveObject()
714
    {
715
    if( !mScramblingAndSolvingBlocked )
716
      {
717
      mSolveObject = true;
718
      }
719
    }
720

    
721
///////////////////////////////////////////////////////////////////////////////////////////////////
722
// this only sets the cubits state to solved
723

    
724
  public void solveOnly()
725
    {
726
    mSolve = true;
727
    }
728

    
729
///////////////////////////////////////////////////////////////////////////////////////////////////
730

    
731
  public void resetTextureMapsEffect(int duration)
732
    {
733
    mRestickerDuration = duration;
734
    mResetTextureEffect = true;
735
    }
736

    
737
///////////////////////////////////////////////////////////////////////////////////////////////////
738

    
739
  public void resetAllTextureMaps()
740
    {
741
    mResetAllTextureMaps = true;
742
    }
743

    
744
///////////////////////////////////////////////////////////////////////////////////////////////////
745

    
746
  public TwistyObject getObject()
747
    {
748
    return mNewObject;
749
    }
750

    
751
///////////////////////////////////////////////////////////////////////////////////////////////////
752

    
753
  public TwistyObjectNode getObjectNode()
754
    {
755
    return mController.getNode();
756
    }
757

    
758
///////////////////////////////////////////////////////////////////////////////////////////////////
759

    
760
  public void effectFinished(final long effectID)
761
    {
762
    if( effectID == mRotationFinishedID )
763
      {
764
      mRotationFinishedID = 0;
765
      removeRotation();
766
      }
767
    else if( effectID == mAddRotationID )
768
      {
769
      mAddRotationID = 0;
770
      mRemoveRotationID = effectID;
771
      removePatternRotation();
772
      }
773
    else
774
      {
775
      for(int i=0; i<BaseEffect.Type.LENGTH; i++)
776
        {
777
        if( effectID == mEffectID[i] )
778
          {
779
          if( i==BaseEffect.Type.SCRAMBLE.ordinal() )
780
            {
781
            mScrambleEndTime = System.currentTimeMillis();
782
            mInterface.onScrambleEffectFinished();
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
  }
(3-3/10)