Project

General

Profile

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

magiccube / src / main / java / org / distorted / main / RubikPreRender.java @ ad38d800

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2020 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.content.Context;
23
import android.content.SharedPreferences;
24
import android.content.res.Resources;
25
import android.os.Bundle;
26

    
27
import org.distorted.dialogs.RubikDialogNewRecord;
28
import org.distorted.dialogs.RubikDialogSolved;
29
import org.distorted.effects.BaseEffect;
30
import org.distorted.library.message.EffectListener;
31
import org.distorted.objects.RubikObject;
32
import org.distorted.objects.RubikObjectList;
33
import org.distorted.scores.RubikScores;
34
import org.distorted.states.RubikState;
35
import org.distorted.states.RubikStateSolving;
36

    
37
///////////////////////////////////////////////////////////////////////////////////////////////////
38

    
39
public class RubikPreRender implements EffectListener
40
  {
41
  public interface ActionFinishedListener
42
    {
43
    void onActionFinished(long effectID);
44
    }
45

    
46
  private RubikSurfaceView mView;
47
  private boolean mFinishRotation, mRemoveRotation, mRemovePatternRotation, mAddRotation,
48
                  mSetQuat, mChangeObject, mSetupObject, mSolveObject, mScrambleObject,
49
                  mInitializeObject, mSetTextureMap, mResetAllTextureMaps;
50
  private boolean mCanRotate, mCanPlay;
51
  private boolean mIsSolved;
52
  private RubikObjectList mNextObject;
53
  private int mNextSize;
54
  private long mRotationFinishedID;
55
  private long[] mEffectID;
56
  private boolean mIsNewRecord;
57
  private long mNewRecord;
58
  private int mScreenWidth, mScreenHeight;
59
  private SharedPreferences mPreferences;
60
  private int[][] mNextMoves;
61
  private RubikObject mOldObject, mNewObject;
62
  private int mScrambleObjectNum;
63
  private int mAddRotationAxis, mAddRotationRowBitmap, mAddRotationAngle;
64
  private long mAddRotationDuration;
65
  private ActionFinishedListener mAddActionListener;
66
  private long mAddRotationID, mRemoveRotationID;
67
  private int mCubit, mFace, mNewColor;
68
  private int mNearestAngle;
69

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

    
72
  RubikPreRender(RubikSurfaceView view)
73
    {
74
    mView = view;
75

    
76
    mFinishRotation       = false;
77
    mRemoveRotation       = false;
78
    mRemovePatternRotation= false;
79
    mAddRotation          = false;
80
    mSetQuat              = false;
81
    mChangeObject         = false;
82
    mSetupObject          = false;
83
    mSolveObject          = false;
84
    mScrambleObject       = false;
85

    
86
    mCanRotate = true;
87
    mCanPlay   = true;
88

    
89
    mOldObject = null;
90
    mNewObject = null;
91

    
92
    mScreenWidth = mScreenHeight = 0;
93
    mScrambleObjectNum = 0;
94

    
95
    mEffectID = new long[BaseEffect.Type.LENGTH];
96
    }
97

    
98
///////////////////////////////////////////////////////////////////////////////////////////////////
99

    
100
  private void createObjectNow(RubikObjectList object, int size, int[][] moves)
101
    {
102
    boolean firstTime = (mNewObject==null);
103

    
104
    if( mOldObject!=null ) mOldObject.releaseResources();
105
    mOldObject = mNewObject;
106

    
107
    Context con = mView.getContext();
108
    Resources res = con.getResources();
109

    
110
    mNewObject = object.create(size, mView.getQuat(), moves, res, mScreenWidth);
111

    
112
    if( mNewObject!=null )
113
      {
114
      mNewObject.createTexture();
115
      mView.setMovement(object.getObjectMovementClass());
116

    
117
      if( firstTime ) mNewObject.restorePreferences(mPreferences);
118

    
119
      if( mScreenWidth!=0 )
120
        {
121
        mNewObject.recomputeScaleFactor(mScreenWidth, mScreenHeight);
122
        }
123

    
124
      mIsSolved = mNewObject.isSolved();
125
      }
126
    }
127

    
128
///////////////////////////////////////////////////////////////////////////////////////////////////
129
// do all 'adjustable' effects (SizeChange, Solve, Scramble)
130

    
131
  private void doEffectNow(BaseEffect.Type type)
132
    {
133
    int index = type.ordinal();
134

    
135
    try
136
      {
137
      mEffectID[index] = type.startEffect(mView.getRenderer().getScreen(),this);
138
      }
139
    catch( Exception ex )
140
      {
141
      android.util.Log.e("renderer", "exception starting effect: "+ex.getMessage());
142

    
143
      mCanPlay   = true;
144
      mCanRotate = true;
145
      }
146
    }
147

    
148
///////////////////////////////////////////////////////////////////////////////////////////////////
149

    
150
  private void removeRotationNow()
151
    {
152
    mRemoveRotation=false;
153
    mNewObject.removeRotationNow();
154

    
155
    boolean solved = mNewObject.isSolved();
156

    
157
    if( solved && !mIsSolved )
158
      {
159
      if( RubikState.getCurrentState()==RubikState.SOLV )
160
        {
161
        RubikStateSolving solving = (RubikStateSolving)RubikState.SOLV.getStateClass();
162
        mNewRecord = solving.getRecord();
163

    
164
        if( mNewRecord< 0 )
165
          {
166
          mNewRecord = -mNewRecord;
167
          mIsNewRecord = false;
168
          }
169
        else
170
          {
171
          mIsNewRecord = true;
172
          }
173
        }
174

    
175
      mCanRotate = true;
176
      mCanPlay = false;
177
      doEffectNow( BaseEffect.Type.WIN );
178
      }
179
    else
180
      {
181
      mCanRotate = true;
182
      mCanPlay = true;
183
      }
184

    
185
    mIsSolved = solved;
186
    }
187

    
188
///////////////////////////////////////////////////////////////////////////////////////////////////
189

    
190
  private void removeRotation()
191
    {
192
    mRemoveRotation = true;
193
    }
194

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

    
197
  private void removePatternRotation()
198
    {
199
    mRemovePatternRotation = true;
200
    }
201

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

    
204
  private void removePatternRotationNow()
205
    {
206
    mRemovePatternRotation=false;
207
    mNewObject.removeRotationNow();
208
    mAddActionListener.onActionFinished(mRemoveRotationID);
209
    }
210

    
211
///////////////////////////////////////////////////////////////////////////////////////////////////
212

    
213
  private void addRotationNow()
214
    {
215
    mAddRotation = false;
216
    mAddRotationID = mNewObject.addNewRotation( mAddRotationAxis, mAddRotationRowBitmap,
217
                                                mAddRotationAngle, mAddRotationDuration, this);
218
    }
219

    
220
///////////////////////////////////////////////////////////////////////////////////////////////////
221

    
222
  private void finishRotationNow()
223
    {
224
    mFinishRotation = false;
225
    mCanRotate      = false;
226
    mCanPlay        = false;
227
    mRotationFinishedID = mNewObject.finishRotationNow(this, mNearestAngle);
228

    
229
    if( mRotationFinishedID==0 ) // failed to add effect - should never happen
230
      {
231
      mCanRotate = true;
232
      mCanPlay   = true;
233
      }
234
    }
235

    
236
///////////////////////////////////////////////////////////////////////////////////////////////////
237

    
238
  private void changeObjectNow()
239
    {
240
    mChangeObject = false;
241

    
242
    if ( mNewObject==null || mNewObject.getObjectList()!=mNextObject || mNewObject.getSize()!=mNextSize)
243
      {
244
      mCanRotate= false;
245
      mCanPlay  = false;
246
      createObjectNow(mNextObject, mNextSize, null);
247
      doEffectNow( BaseEffect.Type.SIZECHANGE );
248
      }
249
    }
250

    
251
///////////////////////////////////////////////////////////////////////////////////////////////////
252

    
253
  private void setupObjectNow()
254
    {
255
    mSetupObject = false;
256

    
257
    if ( mNewObject==null || mNewObject.getObjectList()!=mNextObject || mNewObject.getSize()!=mNextSize)
258
      {
259
      mCanRotate= false;
260
      mCanPlay  = false;
261
      createObjectNow(mNextObject, mNextSize, mNextMoves);
262
      doEffectNow( BaseEffect.Type.SIZECHANGE );
263
      }
264
    else
265
      {
266
      mNewObject.initializeObject(mNextMoves);
267
      }
268
    }
269

    
270
///////////////////////////////////////////////////////////////////////////////////////////////////
271

    
272
  private void scrambleObjectNow()
273
    {
274
    mScrambleObject = false;
275
    mCanRotate      = false;
276
    mCanPlay        = false;
277
    mIsSolved       = false;
278
    RubikScores.getInstance().incrementNumPlays();
279
    doEffectNow( BaseEffect.Type.SCRAMBLE );
280
    }
281

    
282
///////////////////////////////////////////////////////////////////////////////////////////////////
283

    
284
  private void solveObjectNow()
285
    {
286
    mSolveObject = false;
287
    mCanRotate   = false;
288
    mCanPlay     = false;
289
    doEffectNow( BaseEffect.Type.SOLVE );
290
    }
291

    
292
///////////////////////////////////////////////////////////////////////////////////////////////////
293

    
294
  private void initializeObjectNow()
295
    {
296
    mInitializeObject = false;
297
    mNewObject.initializeObject(mNextMoves);
298
    }
299

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

    
302
  private void setTextureMapNow()
303
    {
304
    mSetTextureMap = false;
305

    
306
    if( mNewObject!=null ) mNewObject.setTextureMap(mCubit,mFace,mNewColor);
307
    }
308

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

    
311
  private void resetAllTextureMapsNow()
312
    {
313
    mResetAllTextureMaps = false;
314

    
315
    if( mNewObject!=null ) mNewObject.resetAllTextureMaps();
316
    }
317

    
318
///////////////////////////////////////////////////////////////////////////////////////////////////
319

    
320
  private void setQuatNow()
321
    {
322
    mSetQuat = false;
323
    mView.setQuat();
324
    }
325

    
326
///////////////////////////////////////////////////////////////////////////////////////////////////
327
//
328
///////////////////////////////////////////////////////////////////////////////////////////////////
329

    
330
  void setScreenSize(int width, int height)
331
    {
332
    if( mNewObject!=null )
333
      {
334
      mNewObject.createTexture();
335
      mNewObject.recomputeScaleFactor(width,height);
336
      }
337

    
338
    mScreenHeight = height;
339
    mScreenWidth  = width;
340
    }
341

    
342
///////////////////////////////////////////////////////////////////////////////////////////////////
343

    
344
  void savePreferences(SharedPreferences.Editor editor)
345
    {
346
    if( mNewObject!=null )
347
      {
348
      mNewObject.savePreferences(editor);
349
      }
350
    }
351

    
352
///////////////////////////////////////////////////////////////////////////////////////////////////
353

    
354
  void restorePreferences(SharedPreferences preferences)
355
    {
356
    mPreferences = preferences;
357
    }
358

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

    
361
  void finishRotation(int nearestAngle)
362
    {
363
    mNearestAngle   = nearestAngle;
364
    mFinishRotation = true;
365
    }
366

    
367
///////////////////////////////////////////////////////////////////////////////////////////////////
368

    
369
  void changeObject(RubikObjectList object, int size)
370
    {
371
    if( size>0 )
372
      {
373
      mChangeObject = true;
374
      mNextObject = object;
375
      mNextSize   = size;
376
      }
377
    }
378

    
379
///////////////////////////////////////////////////////////////////////////////////////////////////
380

    
381
  void setupObject(RubikObjectList object, int size, int[][] moves)
382
    {
383
    if( size>0 )
384
      {
385
      mSetupObject= true;
386
      mNextObject = object;
387
      mNextSize   = size;
388
      mNextMoves  = moves;
389
      }
390
    }
391

    
392
///////////////////////////////////////////////////////////////////////////////////////////////////
393

    
394
  void setTextureMap(int cubit, int face, int newColor)
395
    {
396
    mSetTextureMap = true;
397

    
398
    mCubit    = cubit;
399
    mFace     = face;
400
    mNewColor = newColor;
401
    }
402

    
403
///////////////////////////////////////////////////////////////////////////////////////////////////
404

    
405
  boolean canRotate()
406
    {
407
    return mCanRotate;
408
    }
409

    
410
///////////////////////////////////////////////////////////////////////////////////////////////////
411

    
412
  public boolean canPlay()
413
    {
414
    return mCanPlay;
415
    }
416

    
417
///////////////////////////////////////////////////////////////////////////////////////////////////
418

    
419
  void setQuatOnNextRender()
420
    {
421
    mSetQuat = true;
422
    }
423

    
424
///////////////////////////////////////////////////////////////////////////////////////////////////
425

    
426
  void preRender()
427
    {
428
    if( mSetQuat               ) setQuatNow();
429
    if( mFinishRotation        ) finishRotationNow();
430
    if( mRemoveRotation        ) removeRotationNow();
431
    if( mRemovePatternRotation ) removePatternRotationNow();
432
    if( mChangeObject          ) changeObjectNow();
433
    if( mSetupObject           ) setupObjectNow();
434
    if( mSolveObject           ) solveObjectNow();
435
    if( mScrambleObject        ) scrambleObjectNow();
436
    if( mAddRotation           ) addRotationNow();
437
    if( mInitializeObject      ) initializeObjectNow();
438
    if( mResetAllTextureMaps   ) resetAllTextureMapsNow();
439
    if( mSetTextureMap         ) setTextureMapNow();
440
    }
441

    
442
///////////////////////////////////////////////////////////////////////////////////////////////////
443
// PUBLIC API
444
///////////////////////////////////////////////////////////////////////////////////////////////////
445

    
446
  public void addRotation(ActionFinishedListener listener, int axis, int rowBitmap, int angle, long duration)
447
    {
448
    mAddRotation = true;
449

    
450
    mAddActionListener    = listener;
451
    mAddRotationAxis      = axis;
452
    mAddRotationRowBitmap = rowBitmap;
453
    mAddRotationAngle     = angle;
454
    mAddRotationDuration  = duration;
455
    }
456

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

    
459
  public void initializeObject(int[][] moves)
460
    {
461
    mInitializeObject = true;
462
    mNextMoves = moves;
463
    }
464

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

    
467
  public void scrambleObject(int num)
468
    {
469
    if( mCanPlay )
470
      {
471
      mScrambleObject = true;
472
      mScrambleObjectNum = num;
473
      }
474
    }
475

    
476
///////////////////////////////////////////////////////////////////////////////////////////////////
477

    
478
  public void solveObject()
479
    {
480
    if( mCanPlay )
481
      {
482
      mSolveObject = true;
483
      }
484
    }
485

    
486
///////////////////////////////////////////////////////////////////////////////////////////////////
487

    
488
  public void resetAllTextureMaps()
489
    {
490
    mResetAllTextureMaps = true;
491
    }
492

    
493
///////////////////////////////////////////////////////////////////////////////////////////////////
494

    
495
  public RubikObject getObject()
496
    {
497
    return mNewObject;
498
    }
499

    
500
///////////////////////////////////////////////////////////////////////////////////////////////////
501

    
502
  public RubikObject getOldObject()
503
    {
504
    return mOldObject;
505
    }
506

    
507
///////////////////////////////////////////////////////////////////////////////////////////////////
508

    
509
  public int getNumScrambles()
510
    {
511
    return mScrambleObjectNum;
512
    }
513

    
514
///////////////////////////////////////////////////////////////////////////////////////////////////
515

    
516
  public void effectFinished(final long effectID)
517
    {
518
    if( effectID == mRotationFinishedID )
519
      {
520
      mRotationFinishedID = 0;
521
      removeRotation();
522
      }
523
    else if( effectID == mAddRotationID )
524
      {
525
      mAddRotationID = 0;
526
      mRemoveRotationID = effectID;
527
      removePatternRotation();
528
      }
529
    else
530
      {
531
      for(int i=0; i<BaseEffect.Type.LENGTH; i++)
532
        {
533
        if( effectID == mEffectID[i] )
534
          {
535
          mCanRotate = true;
536
          mCanPlay   = true;
537

    
538
          if( i==BaseEffect.Type.SCRAMBLE.ordinal() )
539
            {
540
            final RubikActivity act = (RubikActivity)mView.getContext();
541

    
542
            act.runOnUiThread(new Runnable()
543
              {
544
              @Override
545
              public void run()
546
                {
547
                RubikState.switchState( act, RubikState.READ);
548
                }
549
              });
550
            }
551

    
552
          if( i==BaseEffect.Type.WIN.ordinal() )
553
            {
554
            if( RubikState.getCurrentState()==RubikState.SOLV )
555
              {
556
              final RubikActivity act = (RubikActivity)mView.getContext();
557
              Bundle bundle = new Bundle();
558
              bundle.putLong("time", mNewRecord );
559

    
560
              if( mIsNewRecord )
561
                {
562
                RubikDialogNewRecord dialog = new RubikDialogNewRecord();
563
                dialog.setArguments(bundle);
564
                dialog.show( act.getSupportFragmentManager(), null);
565
                }
566
              else
567
                {
568
                RubikDialogSolved dialog = new RubikDialogSolved();
569
                dialog.setArguments(bundle);
570
                dialog.show( act.getSupportFragmentManager(), null);
571
                }
572

    
573
              act.runOnUiThread(new Runnable()
574
                {
575
                @Override
576
                public void run()
577
                  {
578
                  RubikState.switchState( act, RubikState.DONE);
579
                  }
580
                });
581
              }
582
            }
583

    
584
          break;
585
          }
586
        }
587
      }
588
    }
589
  }
(2-2/4)