Project

General

Profile

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

magiccube / src / main / java / org / distorted / magic / RubikPostRender.java @ 8becce57

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.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
  private boolean mFinishRotation, mRemoveRotation, mAddRotation, mSetQuatCurrent, mSetQuatAccumulated;
46
  private boolean mChangeObject, mSolveObject, mScrambleObject;
47
  private boolean mCanRotate, mCanDrag, mCanUI;
48
  private boolean mIsSolved;
49
  private RubikObjectList mNextObject;
50
  private int mNextSize;
51
  private long mRotationFinishedID;
52
  private long[] mEffectID;
53
  private boolean mIsNewRecord;
54
  private long mNewRecord;
55
  private int mScreenWidth, mScreenHeight;
56
  private SharedPreferences mPreferences;
57
  private String mNextMoves;
58
  private RubikObject mOldObject, mNewObject;
59
  private int mScrambleObjectNum;
60
  private int mAddRotationAxis, mAddRotationRowBitmap, mAddRotationAngle;
61
  private long mAddRotationDuration;
62
  private ActionFinishedListener mAddActionListener;
63
  private long mAddRotationID;
64

    
65
///////////////////////////////////////////////////////////////////////////////////////////////////
66

    
67
  RubikPostRender(RubikSurfaceView view)
68
    {
69
    mView = view;
70

    
71
    mFinishRotation     = false;
72
    mRemoveRotation     = false;
73
    mAddRotation        = false;
74
    mSetQuatCurrent     = false;
75
    mSetQuatAccumulated = false;
76
    mChangeObject       = false;
77
    mSolveObject        = false;
78
    mScrambleObject     = false;
79

    
80
    mCanRotate   = true;
81
    mCanDrag     = true;
82
    mCanUI       = true;
83

    
84
    mOldObject = null;
85
    mNewObject = null;
86

    
87
    mScreenWidth = mScreenHeight = 0;
88
    mScrambleObjectNum = 0;
89

    
90
    mEffectID = new long[BaseEffect.Type.LENGTH];
91
    }
92

    
93
///////////////////////////////////////////////////////////////////////////////////////////////////
94

    
95
  private void createObjectNow(RubikObjectList object, int size, String moves)
96
    {
97
    boolean firstTime = (mNewObject==null);
98

    
99
    if( mOldObject!=null ) mOldObject.releaseResources();
100
    mOldObject = mNewObject;
101

    
102
    mNewObject = object.create(size, mView.getQuatCurrent(), mView.getQuatAccumulated(), moves);
103
    mNewObject.createTexture();
104
    mView.setMovement(object.getObjectMovementClass());
105

    
106
    if( firstTime ) mNewObject.restorePreferences(mPreferences);
107

    
108
    if( mScreenWidth!=0 )
109
      {
110
      mNewObject.recomputeScaleFactor(mScreenWidth, mScreenHeight);
111
      }
112

    
113
    mIsSolved = true;
114
    }
115

    
116
///////////////////////////////////////////////////////////////////////////////////////////////////
117
// do all 'adjustable' effects (SizeChange, Solve, Scramble)
118

    
119
  private void doEffectNow(BaseEffect.Type type)
120
    {
121
    int index = type.ordinal();
122

    
123
    try
124
      {
125
      mEffectID[index] = type.startEffect(mView.getRenderer().getScreen(),this);
126
      }
127
    catch( Exception ex )
128
      {
129
      android.util.Log.e("renderer", "exception starting effect: "+ex.getMessage());
130

    
131
      mCanUI     = true;
132
      mCanRotate = true;
133
      mCanDrag   = 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
android.util.Log.e("post", "1 canDrag true");
165

    
166
      mCanDrag   = true;
167
      mCanRotate = false;
168
      mCanUI     = false;
169
      doEffectNow( BaseEffect.Type.WIN );
170
      }
171
    else
172
      {
173
      mCanRotate = true;
174
      mCanUI     = true;
175
      }
176

    
177
    mIsSolved = solved;
178
    }
179

    
180
///////////////////////////////////////////////////////////////////////////////////////////////////
181

    
182
  private void removeRotation()
183
    {
184
    mRemoveRotation = true;
185
    }
186

    
187
///////////////////////////////////////////////////////////////////////////////////////////////////
188

    
189
  private void addRotationNow()
190
    {
191
    mAddRotation = false;
192

    
193
    mAddRotationID = mNewObject.addNewRotation( mAddRotationAxis, mAddRotationRowBitmap,
194
                                                mAddRotationAngle, mAddRotationDuration, this);
195
    }
196

    
197
///////////////////////////////////////////////////////////////////////////////////////////////////
198

    
199
  private void finishRotationNow()
200
    {
201
    mFinishRotation = false;
202
    mCanRotate      = false;
203
    mCanUI          = false;
204
    mRotationFinishedID = mNewObject.finishRotationNow(this);
205

    
206
    if( mRotationFinishedID==0 ) // failed to add effect - should never happen
207
      {
208
      mCanRotate = true;
209
      mCanUI     = true;
210
      }
211
    }
212

    
213
///////////////////////////////////////////////////////////////////////////////////////////////////
214

    
215
  private void changeObjectNow()
216
    {
217
    mChangeObject = false;
218

    
219
    if ( mNewObject==null || mNewObject.getObjectList()!=mNextObject || mNewObject.getSize()!=mNextSize)
220
      {
221
      mCanDrag      = false;
222
      mCanRotate    = false;
223
      mCanUI        = false;
224
      createObjectNow(mNextObject, mNextSize, mNextMoves);
225
      doEffectNow( BaseEffect.Type.SIZECHANGE );
226
      }
227
    else
228
      {
229
      mNewObject.initializeObject(mNextMoves);
230
      }
231
    }
232

    
233
///////////////////////////////////////////////////////////////////////////////////////////////////
234

    
235
  private void scrambleObjectNow()
236
    {
237
    mScrambleObject = false;
238
    mCanDrag        = false;
239
    mCanRotate      = false;
240
    mCanUI          = false;
241
    mIsSolved       = false;
242
    RubikScores.getInstance().incrementNumPlays();
243
    doEffectNow( BaseEffect.Type.SCRAMBLE );
244
    }
245

    
246
///////////////////////////////////////////////////////////////////////////////////////////////////
247

    
248
  private void solveObjectNow()
249
    {
250
    mSolveObject    = false;
251
    mCanDrag        = false;
252
    mCanRotate      = false;
253
    mCanUI          = false;
254
    doEffectNow( BaseEffect.Type.SOLVE );
255
    }
256

    
257
///////////////////////////////////////////////////////////////////////////////////////////////////
258

    
259
  private void setQuatCurrentNow()
260
    {
261
    mSetQuatCurrent = false;
262
    mView.setQuatCurrent();
263
    }
264

    
265
///////////////////////////////////////////////////////////////////////////////////////////////////
266

    
267
  private void setQuatAccumulatedNow()
268
    {
269
    mSetQuatAccumulated = false;
270
    mView.setQuatAccumulated();
271
    }
272

    
273
///////////////////////////////////////////////////////////////////////////////////////////////////
274
//
275
///////////////////////////////////////////////////////////////////////////////////////////////////
276

    
277
  void setScreenSize(int width, int height)
278
    {
279
    if( mNewObject!=null )
280
      {
281
      mNewObject.createTexture();
282
      mNewObject.recomputeScaleFactor(width,height);
283
      }
284

    
285
    mScreenHeight = height;
286
    mScreenWidth  = width;
287
    }
288

    
289
///////////////////////////////////////////////////////////////////////////////////////////////////
290

    
291
  void savePreferences(SharedPreferences.Editor editor)
292
    {
293
    if( mNewObject!=null )
294
      {
295
      mNewObject.savePreferences(editor);
296
      }
297
    }
298

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

    
301
  void restorePreferences(SharedPreferences preferences)
302
    {
303
    mPreferences = preferences;
304
    }
305

    
306
///////////////////////////////////////////////////////////////////////////////////////////////////
307

    
308
  void finishRotation()
309
    {
310
    mFinishRotation = true;
311
    }
312

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

    
315
  void changeObject(RubikObjectList object, int size, String moves)
316
    {
317
    if( size>0 )
318
      {
319
      mChangeObject = true;
320
      mNextObject = object;
321
      mNextSize   = size;
322
      mNextMoves  = moves;
323
      }
324
    }
325

    
326
///////////////////////////////////////////////////////////////////////////////////////////////////
327

    
328
  void scrambleObject(int num)
329
    {
330
    if( mCanUI )
331
      {
332
      mScrambleObject = true;
333
      mScrambleObjectNum = num;
334
      }
335
    }
336

    
337
///////////////////////////////////////////////////////////////////////////////////////////////////
338

    
339
  void solveObject()
340
    {
341
    if( mCanUI )
342
      {
343
      mSolveObject = true;
344
      }
345
    }
346

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

    
349
  boolean canRotate()
350
    {
351
    return mCanRotate;
352
    }
353

    
354
///////////////////////////////////////////////////////////////////////////////////////////////////
355

    
356
  boolean canDrag()
357
    {
358
    return mCanDrag;
359
    }
360

    
361
///////////////////////////////////////////////////////////////////////////////////////////////////
362

    
363
  void setQuatCurrentOnNextRender()
364
    {
365
    mSetQuatCurrent = true;
366
    }
367

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

    
370
  void setQuatAccumulatedOnNextRender()
371
    {
372
    mSetQuatAccumulated = true;
373
    }
374

    
375
///////////////////////////////////////////////////////////////////////////////////////////////////
376

    
377
  void postRender()
378
    {
379
    if( mSetQuatCurrent     ) setQuatCurrentNow();
380
    if( mSetQuatAccumulated ) setQuatAccumulatedNow();
381
    if( mFinishRotation     ) finishRotationNow();
382
    if( mRemoveRotation     ) removeRotationNow();
383
    if( mChangeObject       ) changeObjectNow();
384
    if( mSolveObject        ) solveObjectNow();
385
    if( mScrambleObject     ) scrambleObjectNow();
386
    if( mAddRotation        ) addRotationNow();
387
    }
388

    
389
///////////////////////////////////////////////////////////////////////////////////////////////////
390
// PUBLIC API
391
///////////////////////////////////////////////////////////////////////////////////////////////////
392

    
393
  public void addRotation(ActionFinishedListener listener, int axis, int rowBitmap, int angle, long duration)
394
    {
395
    mAddRotation = true;
396

    
397
    mAddActionListener    = listener;
398
    mAddRotationAxis      = axis;
399
    mAddRotationRowBitmap = rowBitmap;
400
    mAddRotationAngle     = angle;
401
    mAddRotationDuration  = duration;
402
    }
403

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

    
406
  public RubikObject getObject()
407
    {
408
    return mNewObject;
409
    }
410

    
411
///////////////////////////////////////////////////////////////////////////////////////////////////
412

    
413
  public RubikObject getOldObject()
414
    {
415
    return mOldObject;
416
    }
417

    
418
///////////////////////////////////////////////////////////////////////////////////////////////////
419

    
420
  public int getNumScrambles()
421
    {
422
    return mScrambleObjectNum;
423
    }
424

    
425
///////////////////////////////////////////////////////////////////////////////////////////////////
426

    
427
  public void effectFinished(final long effectID)
428
    {
429
    if( effectID == mRotationFinishedID )
430
      {
431
      mRotationFinishedID = 0;
432
      removeRotation();
433
      }
434
    else if( effectID == mAddRotationID )
435
      {
436
      mAddRotationID = 0;
437
      mAddActionListener.onActionFinished(effectID);
438
      }
439
    else
440
      {
441
      for(int i=0; i<BaseEffect.Type.LENGTH; i++)
442
        {
443
        if( effectID == mEffectID[i] )
444
          {
445
          mCanRotate   = true;
446
          mCanDrag     = true;
447
          mCanUI       = true;
448

    
449
          if( i==BaseEffect.Type.SCRAMBLE.ordinal() )
450
            {
451
            final RubikActivity act = (RubikActivity)mView.getContext();
452

    
453
            act.runOnUiThread(new Runnable()
454
              {
455
              @Override
456
              public void run()
457
                {
458
                RubikState.switchState( act, RubikState.SOLV);
459
                }
460
              });
461
            }
462

    
463
          if( i==BaseEffect.Type.WIN.ordinal() )
464
            {
465
            if( RubikState.getCurrentState()==RubikState.SOLV )
466
              {
467
              final RubikActivity act = (RubikActivity)mView.getContext();
468
              Bundle bundle = new Bundle();
469
              bundle.putLong("time", mNewRecord );
470

    
471
              if( mIsNewRecord )
472
                {
473
                RubikDialogNewRecord dialog = new RubikDialogNewRecord();
474
                dialog.setArguments(bundle);
475
                dialog.show( act.getSupportFragmentManager(), null);
476
                }
477
              else
478
                {
479
                RubikDialogSolved dialog = new RubikDialogSolved();
480
                dialog.setArguments(bundle);
481
                dialog.show( act.getSupportFragmentManager(), null);
482
                }
483
              }
484
            }
485

    
486
          break;
487
          }
488
        }
489
      }
490
    }
491
  }
(2-2/4)