Project

General

Profile

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

magiccube / src / main / java / org / distorted / magic / RubikPostRender.java @ d12bb11b

1 8becce57 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
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.magic;
21
22
import android.content.SharedPreferences;
23
import android.os.Bundle;
24
25
import org.distorted.dialog.RubikDialogNewRecord;
26
import org.distorted.dialog.RubikDialogSolved;
27
import org.distorted.effect.BaseEffect;
28
import org.distorted.library.message.EffectListener;
29
import org.distorted.object.RubikObject;
30
import org.distorted.object.RubikObjectList;
31
import org.distorted.scores.RubikScores;
32
import org.distorted.uistate.RubikState;
33
import org.distorted.uistate.RubikStateSolving;
34
35
///////////////////////////////////////////////////////////////////////////////////////////////////
36
37
public class RubikPostRender implements EffectListener
38
  {
39
  public interface ActionFinishedListener
40
    {
41
    void onActionFinished(long effectID);
42
    }
43
44
  private RubikSurfaceView mView;
45 d12bb11b Leszek Koltunski
  private boolean mFinishRotation, mRemoveRotation, mRemovePatternRotation, mAddRotation,
46
                  mSetQuatCurrent, mSetQuatAccumulated;
47 8becce57 Leszek Koltunski
  private boolean mChangeObject, mSolveObject, mScrambleObject;
48
  private boolean mCanRotate, mCanDrag, mCanUI;
49
  private boolean mIsSolved;
50
  private RubikObjectList mNextObject;
51
  private int mNextSize;
52
  private long mRotationFinishedID;
53
  private long[] mEffectID;
54
  private boolean mIsNewRecord;
55
  private long mNewRecord;
56
  private int mScreenWidth, mScreenHeight;
57
  private SharedPreferences mPreferences;
58 a31d25de Leszek Koltunski
  private int[][] mNextMoves;
59 8becce57 Leszek Koltunski
  private RubikObject mOldObject, mNewObject;
60
  private int mScrambleObjectNum;
61
  private int mAddRotationAxis, mAddRotationRowBitmap, mAddRotationAngle;
62
  private long mAddRotationDuration;
63
  private ActionFinishedListener mAddActionListener;
64 d12bb11b Leszek Koltunski
  private long mAddRotationID, mRemoveRotationID;
65
  private boolean mInitializeObject;
66 8becce57 Leszek Koltunski
67
///////////////////////////////////////////////////////////////////////////////////////////////////
68
69
  RubikPostRender(RubikSurfaceView view)
70
    {
71
    mView = view;
72
73 d12bb11b Leszek Koltunski
    mFinishRotation       = false;
74
    mRemoveRotation       = false;
75
    mRemovePatternRotation= false;
76
    mAddRotation          = false;
77
    mSetQuatCurrent       = false;
78
    mSetQuatAccumulated   = false;
79
    mChangeObject         = false;
80
    mSolveObject          = false;
81
    mScrambleObject       = false;
82 8becce57 Leszek Koltunski
83
    mCanRotate   = true;
84
    mCanDrag     = true;
85
    mCanUI       = true;
86
87
    mOldObject = null;
88
    mNewObject = null;
89
90
    mScreenWidth = mScreenHeight = 0;
91
    mScrambleObjectNum = 0;
92
93
    mEffectID = new long[BaseEffect.Type.LENGTH];
94
    }
95
96
///////////////////////////////////////////////////////////////////////////////////////////////////
97
98 a31d25de Leszek Koltunski
  private void createObjectNow(RubikObjectList object, int size, int[][] moves)
99 8becce57 Leszek Koltunski
    {
100
    boolean firstTime = (mNewObject==null);
101
102
    if( mOldObject!=null ) mOldObject.releaseResources();
103
    mOldObject = mNewObject;
104
105
    mNewObject = object.create(size, mView.getQuatCurrent(), mView.getQuatAccumulated(), moves);
106
    mNewObject.createTexture();
107
    mView.setMovement(object.getObjectMovementClass());
108
109
    if( firstTime ) mNewObject.restorePreferences(mPreferences);
110
111
    if( mScreenWidth!=0 )
112
      {
113
      mNewObject.recomputeScaleFactor(mScreenWidth, mScreenHeight);
114
      }
115
116
    mIsSolved = true;
117
    }
118
119
///////////////////////////////////////////////////////////////////////////////////////////////////
120
// do all 'adjustable' effects (SizeChange, Solve, Scramble)
121
122
  private void doEffectNow(BaseEffect.Type type)
123
    {
124
    int index = type.ordinal();
125
126
    try
127
      {
128
      mEffectID[index] = type.startEffect(mView.getRenderer().getScreen(),this);
129
      }
130
    catch( Exception ex )
131
      {
132
      android.util.Log.e("renderer", "exception starting effect: "+ex.getMessage());
133
134
      mCanUI     = true;
135
      mCanRotate = true;
136
      mCanDrag   = true;
137
      }
138
    }
139
140
///////////////////////////////////////////////////////////////////////////////////////////////////
141
142
  private void removeRotationNow()
143
    {
144
    mRemoveRotation=false;
145
    mNewObject.removeRotationNow();
146
147
    boolean solved = mNewObject.isSolved();
148
149
    if( solved && !mIsSolved )
150
      {
151
      if( RubikState.getCurrentState()==RubikState.SOLV )
152
        {
153
        RubikStateSolving solving = (RubikStateSolving)RubikState.SOLV.getStateClass();
154
        mNewRecord = solving.stopCounting((RubikActivity)mView.getContext());
155
156
        if( mNewRecord< 0 )
157
          {
158
          mNewRecord = -mNewRecord;
159
          mIsNewRecord = false;
160
          }
161
        else
162
          {
163
          mIsNewRecord = true;
164
          }
165
        }
166
167
      mCanDrag   = true;
168
      mCanRotate = false;
169
      mCanUI     = false;
170
      doEffectNow( BaseEffect.Type.WIN );
171
      }
172
    else
173
      {
174
      mCanRotate = true;
175
      mCanUI     = true;
176
      }
177
178
    mIsSolved = solved;
179
    }
180
181
///////////////////////////////////////////////////////////////////////////////////////////////////
182
183
  private void removeRotation()
184
    {
185
    mRemoveRotation = true;
186
    }
187
188 d12bb11b Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
189
190
  private void removePatternRotation()
191
    {
192
    mRemovePatternRotation = true;
193
    }
194
195
///////////////////////////////////////////////////////////////////////////////////////////////////
196
197
  private void removePatternRotationNow()
198
    {
199
    mRemovePatternRotation=false;
200
    mNewObject.removeRotationNow();
201
    mAddActionListener.onActionFinished(mRemoveRotationID);
202
    }
203
204 8becce57 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
205
206
  private void addRotationNow()
207
    {
208
    mAddRotation = false;
209
    mAddRotationID = mNewObject.addNewRotation( mAddRotationAxis, mAddRotationRowBitmap,
210
                                                mAddRotationAngle, mAddRotationDuration, this);
211
    }
212
213
///////////////////////////////////////////////////////////////////////////////////////////////////
214
215
  private void finishRotationNow()
216
    {
217
    mFinishRotation = false;
218
    mCanRotate      = false;
219
    mCanUI          = false;
220
    mRotationFinishedID = mNewObject.finishRotationNow(this);
221
222
    if( mRotationFinishedID==0 ) // failed to add effect - should never happen
223
      {
224
      mCanRotate = true;
225
      mCanUI     = true;
226
      }
227
    }
228
229
///////////////////////////////////////////////////////////////////////////////////////////////////
230
231
  private void changeObjectNow()
232
    {
233
    mChangeObject = false;
234
235
    if ( mNewObject==null || mNewObject.getObjectList()!=mNextObject || mNewObject.getSize()!=mNextSize)
236
      {
237
      mCanDrag      = false;
238
      mCanRotate    = false;
239
      mCanUI        = false;
240
      createObjectNow(mNextObject, mNextSize, mNextMoves);
241
      doEffectNow( BaseEffect.Type.SIZECHANGE );
242
      }
243
    else
244
      {
245
      mNewObject.initializeObject(mNextMoves);
246
      }
247
    }
248
249
///////////////////////////////////////////////////////////////////////////////////////////////////
250
251
  private void scrambleObjectNow()
252
    {
253
    mScrambleObject = false;
254
    mCanDrag        = false;
255
    mCanRotate      = false;
256
    mCanUI          = false;
257
    mIsSolved       = false;
258
    RubikScores.getInstance().incrementNumPlays();
259
    doEffectNow( BaseEffect.Type.SCRAMBLE );
260
    }
261
262
///////////////////////////////////////////////////////////////////////////////////////////////////
263
264
  private void solveObjectNow()
265
    {
266
    mSolveObject    = false;
267
    mCanDrag        = false;
268
    mCanRotate      = false;
269
    mCanUI          = false;
270
    doEffectNow( BaseEffect.Type.SOLVE );
271
    }
272
273 d12bb11b Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
274
275
  private void initializeObjectNow()
276
    {
277
    mInitializeObject = false;
278
    mNewObject.initializeObject(mNextMoves);
279
    }
280
281 8becce57 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
282
283
  private void setQuatCurrentNow()
284
    {
285
    mSetQuatCurrent = false;
286
    mView.setQuatCurrent();
287
    }
288
289
///////////////////////////////////////////////////////////////////////////////////////////////////
290
291
  private void setQuatAccumulatedNow()
292
    {
293
    mSetQuatAccumulated = false;
294
    mView.setQuatAccumulated();
295
    }
296
297
///////////////////////////////////////////////////////////////////////////////////////////////////
298
//
299
///////////////////////////////////////////////////////////////////////////////////////////////////
300
301
  void setScreenSize(int width, int height)
302
    {
303
    if( mNewObject!=null )
304
      {
305
      mNewObject.createTexture();
306
      mNewObject.recomputeScaleFactor(width,height);
307
      }
308
309
    mScreenHeight = height;
310
    mScreenWidth  = width;
311
    }
312
313
///////////////////////////////////////////////////////////////////////////////////////////////////
314
315
  void savePreferences(SharedPreferences.Editor editor)
316
    {
317
    if( mNewObject!=null )
318
      {
319
      mNewObject.savePreferences(editor);
320
      }
321
    }
322
323
///////////////////////////////////////////////////////////////////////////////////////////////////
324
325
  void restorePreferences(SharedPreferences preferences)
326
    {
327
    mPreferences = preferences;
328
    }
329
330
///////////////////////////////////////////////////////////////////////////////////////////////////
331
332
  void finishRotation()
333
    {
334
    mFinishRotation = true;
335
    }
336
337
///////////////////////////////////////////////////////////////////////////////////////////////////
338
339 a31d25de Leszek Koltunski
  void changeObject(RubikObjectList object, int size, int[][] moves)
340 8becce57 Leszek Koltunski
    {
341
    if( size>0 )
342
      {
343
      mChangeObject = true;
344
      mNextObject = object;
345
      mNextSize   = size;
346
      mNextMoves  = moves;
347
      }
348
    }
349
350
///////////////////////////////////////////////////////////////////////////////////////////////////
351
352
  void scrambleObject(int num)
353
    {
354
    if( mCanUI )
355
      {
356
      mScrambleObject = true;
357
      mScrambleObjectNum = num;
358
      }
359
    }
360
361
///////////////////////////////////////////////////////////////////////////////////////////////////
362
363
  void solveObject()
364
    {
365
    if( mCanUI )
366
      {
367
      mSolveObject = true;
368
      }
369
    }
370
371
///////////////////////////////////////////////////////////////////////////////////////////////////
372
373
  boolean canRotate()
374
    {
375
    return mCanRotate;
376
    }
377
378
///////////////////////////////////////////////////////////////////////////////////////////////////
379
380
  boolean canDrag()
381
    {
382
    return mCanDrag;
383
    }
384
385
///////////////////////////////////////////////////////////////////////////////////////////////////
386
387
  void setQuatCurrentOnNextRender()
388
    {
389
    mSetQuatCurrent = true;
390
    }
391
392
///////////////////////////////////////////////////////////////////////////////////////////////////
393
394
  void setQuatAccumulatedOnNextRender()
395
    {
396
    mSetQuatAccumulated = true;
397
    }
398
399
///////////////////////////////////////////////////////////////////////////////////////////////////
400
401
  void postRender()
402
    {
403 d12bb11b Leszek Koltunski
    if( mSetQuatCurrent        ) setQuatCurrentNow();
404
    if( mSetQuatAccumulated    ) setQuatAccumulatedNow();
405
    if( mFinishRotation        ) finishRotationNow();
406
    if( mRemoveRotation        ) removeRotationNow();
407
    if( mRemovePatternRotation ) removePatternRotationNow();
408
    if( mChangeObject          ) changeObjectNow();
409
    if( mSolveObject           ) solveObjectNow();
410
    if( mScrambleObject        ) scrambleObjectNow();
411
    if( mAddRotation           ) addRotationNow();
412
    if( mInitializeObject      ) initializeObjectNow();
413 8becce57 Leszek Koltunski
    }
414
415
///////////////////////////////////////////////////////////////////////////////////////////////////
416
// PUBLIC API
417
///////////////////////////////////////////////////////////////////////////////////////////////////
418
419
  public void addRotation(ActionFinishedListener listener, int axis, int rowBitmap, int angle, long duration)
420
    {
421
    mAddRotation = true;
422
423
    mAddActionListener    = listener;
424
    mAddRotationAxis      = axis;
425
    mAddRotationRowBitmap = rowBitmap;
426
    mAddRotationAngle     = angle;
427
    mAddRotationDuration  = duration;
428
    }
429
430 d12bb11b Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
431
432
  public void initializeObject(int[][] moves)
433
    {
434
    mInitializeObject = true;
435
    mNextMoves = moves;
436
    }
437
438 8becce57 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
439
440
  public RubikObject getObject()
441
    {
442
    return mNewObject;
443
    }
444
445
///////////////////////////////////////////////////////////////////////////////////////////////////
446
447
  public RubikObject getOldObject()
448
    {
449
    return mOldObject;
450
    }
451
452
///////////////////////////////////////////////////////////////////////////////////////////////////
453
454
  public int getNumScrambles()
455
    {
456
    return mScrambleObjectNum;
457
    }
458
459
///////////////////////////////////////////////////////////////////////////////////////////////////
460
461
  public void effectFinished(final long effectID)
462
    {
463
    if( effectID == mRotationFinishedID )
464
      {
465
      mRotationFinishedID = 0;
466
      removeRotation();
467
      }
468
    else if( effectID == mAddRotationID )
469
      {
470
      mAddRotationID = 0;
471 d12bb11b Leszek Koltunski
      mRemoveRotationID = effectID;
472
      removePatternRotation();
473 8becce57 Leszek Koltunski
      }
474
    else
475
      {
476
      for(int i=0; i<BaseEffect.Type.LENGTH; i++)
477
        {
478
        if( effectID == mEffectID[i] )
479
          {
480
          mCanRotate   = true;
481
          mCanDrag     = true;
482
          mCanUI       = true;
483
484
          if( i==BaseEffect.Type.SCRAMBLE.ordinal() )
485
            {
486
            final RubikActivity act = (RubikActivity)mView.getContext();
487
488
            act.runOnUiThread(new Runnable()
489
              {
490
              @Override
491
              public void run()
492
                {
493
                RubikState.switchState( act, RubikState.SOLV);
494
                }
495
              });
496
            }
497
498
          if( i==BaseEffect.Type.WIN.ordinal() )
499
            {
500
            if( RubikState.getCurrentState()==RubikState.SOLV )
501
              {
502
              final RubikActivity act = (RubikActivity)mView.getContext();
503
              Bundle bundle = new Bundle();
504
              bundle.putLong("time", mNewRecord );
505
506
              if( mIsNewRecord )
507
                {
508
                RubikDialogNewRecord dialog = new RubikDialogNewRecord();
509
                dialog.setArguments(bundle);
510
                dialog.show( act.getSupportFragmentManager(), null);
511
                }
512
              else
513
                {
514
                RubikDialogSolved dialog = new RubikDialogSolved();
515
                dialog.setArguments(bundle);
516
                dialog.show( act.getSupportFragmentManager(), null);
517
                }
518
              }
519
            }
520
521
          break;
522
          }
523
        }
524
      }
525
    }
526
  }