Project

General

Profile

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

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

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