Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / main / ObjectPreRender.java @ 7c111294

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.objectlib.main;
21

    
22
import android.content.SharedPreferences;
23
import android.content.res.Resources;
24

    
25
import org.distorted.objectlib.helpers.ObjectStateActioner;
26
import org.distorted.objectlib.helpers.ObjectSurfaceView;
27
import org.distorted.objectlib.effects.BaseEffect;
28
import org.distorted.objectlib.effects.EffectController;
29
import org.distorted.objectlib.effects.scramble.ScrambleEffect;
30
import org.distorted.objectlib.helpers.BlockController;
31
import org.distorted.objectlib.helpers.MovesFinished;
32

    
33
///////////////////////////////////////////////////////////////////////////////////////////////////
34

    
35
public class ObjectPreRender implements EffectController
36
  {
37
  private final ObjectSurfaceView mView;
38
  private ObjectType mNextObject;
39
  private TwistyObject mOldObject, mNewObject;
40
  private SharedPreferences mPreferences;
41
  private MovesFinished mAddActionListener;
42
  private final BlockController mBlockController;
43
  private final ObjectStateActioner mActioner;
44
  private String mDebug;
45

    
46
  private boolean mFinishRotation, mRemoveRotation, mRemovePatternRotation, mAddRotation,
47
                  mSetQuat, mChangeObject, mSetupObject, mSolveObject, mScrambleObject,
48
                  mInitializeObject, mSetTextureMap, mResetAllTextureMaps, mSolve;
49
  private boolean mUIBlocked, mTouchBlocked, mIsSolved;
50
  private long mRotationFinishedID;
51
  private final long[] mEffectID;
52
  private int mScreenWidth;
53
  private int[][] mNextMoves;
54
  private int mScrambleObjectNum;
55
  private int mAddRotationAxis, mAddRotationRowBitmap, mAddRotationAngle;
56
  private long mAddRotationDuration;
57
  private long mAddRotationID, mRemoveRotationID;
58
  private int mCubit, mFace, mNewColor;
59
  private int mNearestAngle;
60
  private long mDebugStartTime;
61

    
62
///////////////////////////////////////////////////////////////////////////////////////////////////
63

    
64
  public ObjectPreRender(ObjectSurfaceView view, ObjectStateActioner actioner)
65
    {
66
    mView = view;
67
    mActioner = actioner;
68

    
69
    mFinishRotation       = false;
70
    mRemoveRotation       = false;
71
    mRemovePatternRotation= false;
72
    mAddRotation          = false;
73
    mSetQuat              = false;
74
    mChangeObject         = false;
75
    mSetupObject          = false;
76
    mSolveObject          = false;
77
    mSolve                = false;
78
    mScrambleObject       = false;
79

    
80
    mOldObject = null;
81
    mNewObject = null;
82

    
83
    mDebug = "";
84

    
85
    mScreenWidth = 0;
86
    mScrambleObjectNum = 0;
87

    
88
    mEffectID = new long[BaseEffect.Type.LENGTH];
89

    
90
    mBlockController = new BlockController(mView.getActivity());
91
    unblockEverything();
92
    }
93

    
94
///////////////////////////////////////////////////////////////////////////////////////////////////
95

    
96
  private void createObjectNow(ObjectType object, int[][] moves)
97
    {
98
    boolean firstTime = (mNewObject==null);
99

    
100
    if( mOldObject!=null ) mOldObject.releaseResources();
101
    mOldObject = mNewObject;
102
    Resources res = mView.getActivity().getResources();
103

    
104
    mNewObject = object.create(mView.getQuat(), moves, res, mScreenWidth);
105

    
106
    if( mNewObject!=null )
107
      {
108
      mView.setMovement(mNewObject.getMovement());
109
      if( firstTime ) mNewObject.restorePreferences(mPreferences);
110
      mIsSolved = mNewObject.isSolved();
111
      }
112
    }
113

    
114
///////////////////////////////////////////////////////////////////////////////////////////////////
115
// do all 'adjustable' effects (SizeChange, Solve, Scramble)
116

    
117
  private void doEffectNow(BaseEffect.Type type)
118
    {
119
    try
120
      {
121
      int index = type.ordinal();
122
      mEffectID[index] = type.startEffect(mView.getScreen(),this);
123
      }
124
    catch( Exception ex )
125
      {
126
      android.util.Log.e("renderer", "exception starting effect: "+ex.getMessage());
127
      unblockEverything();
128
      }
129
    }
130

    
131
///////////////////////////////////////////////////////////////////////////////////////////////////
132

    
133
  private void removeRotationNow()
134
    {
135
    mRemoveRotation=false;
136
    mNewObject.removeRotationNow();
137

    
138
    boolean solved = mNewObject.isSolved();
139

    
140
    if( solved && !mIsSolved )
141
      {
142
      mActioner.onSolved();
143
      unblockEverything();
144
      doEffectNow( BaseEffect.Type.WIN );
145
      }
146
    else
147
      {
148
      unblockEverything();
149
      }
150

    
151
    mIsSolved = solved;
152
    }
153

    
154
///////////////////////////////////////////////////////////////////////////////////////////////////
155

    
156
  private void removeRotation()
157
    {
158
    mRemoveRotation = true;
159
    }
160

    
161
///////////////////////////////////////////////////////////////////////////////////////////////////
162

    
163
  private void removePatternRotation()
164
    {
165
    mRemovePatternRotation = true;
166
    }
167

    
168
///////////////////////////////////////////////////////////////////////////////////////////////////
169

    
170
  private void removePatternRotationNow()
171
    {
172
    mRemovePatternRotation=false;
173
    mNewObject.removeRotationNow();
174
    mAddActionListener.onActionFinished(mRemoveRotationID);
175
    }
176

    
177
///////////////////////////////////////////////////////////////////////////////////////////////////
178

    
179
  private void addRotationNow()
180
    {
181
    mAddRotation = false;
182
    mAddRotationID = mNewObject.addNewRotation( mAddRotationAxis, mAddRotationRowBitmap,
183
                                                mAddRotationAngle, mAddRotationDuration, this);
184

    
185
    if( mAddRotationID==0 ) // failed to add effect - should never happen
186
      {
187
      unblockEverything();
188
      }
189
    }
190

    
191
///////////////////////////////////////////////////////////////////////////////////////////////////
192

    
193
  private void finishRotationNow()
194
    {
195
    mFinishRotation = false;
196
    blockEverything(BlockController.RUBIK_PLACE_0);
197
    mRotationFinishedID = mNewObject.finishRotationNow(this, mNearestAngle);
198

    
199
    if( mRotationFinishedID==0 ) // failed to add effect - should never happen
200
      {
201
      unblockEverything();
202
      }
203
    }
204

    
205
///////////////////////////////////////////////////////////////////////////////////////////////////
206

    
207
  private void changeObjectNow()
208
    {
209
    mChangeObject = false;
210

    
211
    if ( mNewObject==null || mNewObject.getObjectType()!=mNextObject )
212
      {
213
      blockEverything(BlockController.RUBIK_PLACE_1);
214
      createObjectNow(mNextObject, null);
215
      doEffectNow( BaseEffect.Type.SIZECHANGE );
216
      }
217
    }
218

    
219
///////////////////////////////////////////////////////////////////////////////////////////////////
220

    
221
  private void setupObjectNow()
222
    {
223
    mSetupObject = false;
224

    
225
    if ( mNewObject==null || mNewObject.getObjectType()!=mNextObject)
226
      {
227
      blockEverything(BlockController.RUBIK_PLACE_2);
228
      createObjectNow(mNextObject, mNextMoves);
229
      doEffectNow( BaseEffect.Type.SIZECHANGE );
230
      }
231
    else
232
      {
233
      mNewObject.initializeObject(mNextMoves);
234
      }
235
    }
236

    
237
///////////////////////////////////////////////////////////////////////////////////////////////////
238

    
239
  private void scrambleObjectNow()
240
    {
241
    mScrambleObject = false;
242
    mIsSolved       = false;
243
    blockEverything(BlockController.RUBIK_PLACE_3);
244
    doEffectNow( BaseEffect.Type.SCRAMBLE );
245
    }
246

    
247
///////////////////////////////////////////////////////////////////////////////////////////////////
248

    
249
  private void solveObjectNow()
250
    {
251
    mSolveObject = false;
252
    blockEverything(BlockController.RUBIK_PLACE_4);
253
    doEffectNow( BaseEffect.Type.SOLVE );
254
    }
255

    
256
///////////////////////////////////////////////////////////////////////////////////////////////////
257

    
258
  private void solveNow()
259
    {
260
    mSolve = false;
261
    mNewObject.solve();
262
    }
263

    
264
///////////////////////////////////////////////////////////////////////////////////////////////////
265

    
266
  private void initializeObjectNow()
267
    {
268
    mInitializeObject = false;
269
    mNewObject.initializeObject(mNextMoves);
270
    }
271

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

    
274
  private void setTextureMapNow()
275
    {
276
    mSetTextureMap = false;
277

    
278
    if( mNewObject!=null ) mNewObject.setTextureMap(mCubit,mFace,mNewColor);
279
    }
280

    
281
///////////////////////////////////////////////////////////////////////////////////////////////////
282

    
283
  private void resetAllTextureMapsNow()
284
    {
285
    mResetAllTextureMaps = false;
286
    if( mNewObject!=null ) mNewObject.resetAllTextureMaps();
287
    }
288

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

    
291
  private void setQuatNow()
292
    {
293
    mSetQuat = false;
294
    mView.setQuat();
295
    }
296

    
297
///////////////////////////////////////////////////////////////////////////////////////////////////
298
// PUBLIC API
299
///////////////////////////////////////////////////////////////////////////////////////////////////
300

    
301
  public void rememberMove(int axis, int row, int angle)
302
    {
303
    mDebug += (" (m "+axis+" "+(1<<row)+" "+angle+" "+(System.currentTimeMillis()-mDebugStartTime)+")");
304
    }
305

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

    
308
  public void setScreenSize(int width)
309
    {
310
    if( mNewObject!=null )
311
      {
312
      mNewObject.createTexture();
313
      mNewObject.recomputeScaleFactor(width);
314
      }
315
    mScreenWidth = width;
316
    }
317

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

    
320
  public void savePreferences(SharedPreferences.Editor editor)
321
    {
322
    if( mNewObject!=null )
323
      {
324
      mNewObject.savePreferences(editor);
325
      }
326
    }
327

    
328
///////////////////////////////////////////////////////////////////////////////////////////////////
329

    
330
  public void restorePreferences(SharedPreferences preferences)
331
    {
332
    mPreferences = preferences;
333
    }
334

    
335
///////////////////////////////////////////////////////////////////////////////////////////////////
336

    
337
  public void finishRotation(int nearestAngle)
338
    {
339
    mNearestAngle   = nearestAngle;
340
    mFinishRotation = true;
341
    }
342

    
343
///////////////////////////////////////////////////////////////////////////////////////////////////
344

    
345
  public void changeObject(ObjectType object)
346
    {
347
    mChangeObject = true;
348
    mNextObject = object;
349
    }
350

    
351
///////////////////////////////////////////////////////////////////////////////////////////////////
352

    
353
  public void setupObject(ObjectType object, int[][] moves)
354
    {
355
    mSetupObject= true;
356
    mNextObject = object;
357
    mNextMoves  = moves;
358
    }
359

    
360
///////////////////////////////////////////////////////////////////////////////////////////////////
361

    
362
  public void setTextureMap(int cubit, int face, int newColor)
363
    {
364
    mSetTextureMap = true;
365

    
366
    mCubit    = cubit;
367
    mFace     = face;
368
    mNewColor = newColor;
369
    }
370

    
371
///////////////////////////////////////////////////////////////////////////////////////////////////
372

    
373
  public boolean isTouchBlocked()
374
    {
375
    return mTouchBlocked;
376
    }
377

    
378
///////////////////////////////////////////////////////////////////////////////////////////////////
379

    
380
  public boolean isUINotBlocked()
381
    {
382
    return !mUIBlocked;
383
    }
384

    
385
///////////////////////////////////////////////////////////////////////////////////////////////////
386

    
387
  public void blockEverything(int place)
388
    {
389
    mUIBlocked   = true;
390
    mTouchBlocked= true;
391
    mBlockController.touchBlocked(place);
392
    mBlockController.uiBlocked(place);
393
    }
394

    
395
///////////////////////////////////////////////////////////////////////////////////////////////////
396

    
397
  public void blockTouch(int place)
398
    {
399
    mTouchBlocked= true;
400
    mBlockController.touchBlocked(place);
401
    }
402

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

    
405
  public void unblockEverything()
406
    {
407
    mUIBlocked   = false;
408
    mTouchBlocked= false;
409
    mBlockController.touchUnblocked();
410
    mBlockController.uiUnblocked();
411
    }
412

    
413
///////////////////////////////////////////////////////////////////////////////////////////////////
414

    
415
  public void unblockTouch()
416
    {
417
    mTouchBlocked= false;
418
    mBlockController.touchUnblocked();
419
    }
420

    
421
///////////////////////////////////////////////////////////////////////////////////////////////////
422

    
423
  public void unblockUI()
424
    {
425
    mUIBlocked= false;
426
    mBlockController.uiUnblocked();
427
    }
428

    
429
///////////////////////////////////////////////////////////////////////////////////////////////////
430

    
431
  public void setQuatOnNextRender()
432
    {
433
    mSetQuat = true;
434
    }
435

    
436
///////////////////////////////////////////////////////////////////////////////////////////////////
437

    
438
  public void preRender()
439
    {
440
    if( mSolve                 ) solveNow();
441
    if( mSetQuat               ) setQuatNow();
442
    if( mFinishRotation        ) finishRotationNow();
443
    if( mRemoveRotation        ) removeRotationNow();
444
    if( mRemovePatternRotation ) removePatternRotationNow();
445
    if( mChangeObject          ) changeObjectNow();
446
    if( mSetupObject           ) setupObjectNow();
447
    if( mSolveObject           ) solveObjectNow();
448
    if( mScrambleObject        ) scrambleObjectNow();
449
    if( mAddRotation           ) addRotationNow();
450
    if( mInitializeObject      ) initializeObjectNow();
451
    if( mResetAllTextureMaps   ) resetAllTextureMapsNow();
452
    if( mSetTextureMap         ) setTextureMapNow();
453
    }
454

    
455
///////////////////////////////////////////////////////////////////////////////////////////////////
456

    
457
  public void addRotation(MovesFinished listener, int axis, int rowBitmap, int angle, long duration)
458
    {
459
    mAddRotation = true;
460

    
461
    mAddActionListener    = listener;
462
    mAddRotationAxis      = axis;
463
    mAddRotationRowBitmap = rowBitmap;
464
    mAddRotationAngle     = angle;
465
    mAddRotationDuration  = duration;
466

    
467
    if( listener instanceof ScrambleEffect )
468
      {
469
      mDebug += (" (a "+axis+" "+rowBitmap+" "+angle+" "+(System.currentTimeMillis()-mDebugStartTime)+")");
470
      }
471
    }
472

    
473
///////////////////////////////////////////////////////////////////////////////////////////////////
474

    
475
  public void initializeObject(int[][] moves)
476
    {
477
    mInitializeObject = true;
478
    mNextMoves = moves;
479
    }
480

    
481
///////////////////////////////////////////////////////////////////////////////////////////////////
482

    
483
  public void scrambleObject(int num)
484
    {
485
    if( !mUIBlocked )
486
      {
487
      mScrambleObject = true;
488
      mScrambleObjectNum = num;
489
      mDebug = "";
490
      mDebugStartTime = System.currentTimeMillis();
491
      }
492
    }
493

    
494
///////////////////////////////////////////////////////////////////////////////////////////////////
495
// this starts the Solve Effect
496

    
497
  public void solveObject()
498
    {
499
    if( !mUIBlocked )
500
      {
501
      mSolveObject = true;
502
      }
503
    }
504

    
505
///////////////////////////////////////////////////////////////////////////////////////////////////
506
// this only sets the cubits state to solved
507

    
508
  public void solve()
509
    {
510
    mSolve = true;
511
    }
512

    
513
///////////////////////////////////////////////////////////////////////////////////////////////////
514

    
515
  public void resetAllTextureMaps()
516
    {
517
    mResetAllTextureMaps = true;
518
    }
519

    
520
///////////////////////////////////////////////////////////////////////////////////////////////////
521

    
522
  public TwistyObject getObject()
523
    {
524
    return mNewObject;
525
    }
526

    
527
///////////////////////////////////////////////////////////////////////////////////////////////////
528

    
529
  public TwistyObject getOldObject()
530
    {
531
    return mOldObject;
532
    }
533

    
534
///////////////////////////////////////////////////////////////////////////////////////////////////
535

    
536
  public int getNumScrambles()
537
    {
538
    return mScrambleObjectNum;
539
    }
540

    
541
///////////////////////////////////////////////////////////////////////////////////////////////////
542

    
543
  public void effectFinished(final long effectID)
544
    {
545
    if( effectID == mRotationFinishedID )
546
      {
547
      mRotationFinishedID = 0;
548
      removeRotation();
549
      }
550
    else if( effectID == mAddRotationID )
551
      {
552
      mAddRotationID = 0;
553
      mRemoveRotationID = effectID;
554
      removePatternRotation();
555
      }
556
    else
557
      {
558
      for(int i=0; i<BaseEffect.Type.LENGTH; i++)
559
        {
560
        if( effectID == mEffectID[i] )
561
          {
562
          if( i!=BaseEffect.Type.WIN.ordinal() ) unblockEverything();
563
          if( i==BaseEffect.Type.SCRAMBLE.ordinal() ) mActioner.onScrambleEffectFinished(mView.getActivity());
564
          if( i==BaseEffect.Type.WIN.ordinal()      ) mActioner.onWinEffectFinished(mView.getActivity(),mDebug,mScrambleObjectNum);
565
          break;
566
          }
567
        }
568
      }
569
    }
570
  }
(7-7/14)