Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / main / ObjectPreRender.java @ 594bbce0

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 java.io.InputStream;
23
import java.lang.ref.WeakReference;
24

    
25
import android.app.Activity;
26
import android.content.SharedPreferences;
27
import android.content.res.Resources;
28

    
29
import org.distorted.library.message.EffectListener;
30
import org.distorted.library.type.Static3D;
31

    
32
import org.distorted.objectlib.helpers.ObjectLibInterface;
33
import org.distorted.objectlib.effects.BaseEffect;
34
import org.distorted.objectlib.effects.scramble.ScrambleEffect;
35
import org.distorted.objectlib.helpers.BlockController;
36
import org.distorted.objectlib.helpers.MovesFinished;
37

    
38
///////////////////////////////////////////////////////////////////////////////////////////////////
39

    
40
public class ObjectPreRender implements EffectListener
41
  {
42
  private final WeakReference<Activity> mAct;
43
  private final ObjectControl mController;
44
  private ObjectType mNextObject;
45
  private TwistyObject mOldObject, mNewObject;
46
  private SharedPreferences mPreferences;
47
  private MovesFinished mAddActionListener;
48
  private final BlockController mBlockController;
49
  private final ObjectLibInterface mInterface;
50
  private String mDebug;
51
  private float mMoveX, mMoveY;
52

    
53
  private boolean mFinishRotation, mRemoveRotation, mRemovePatternRotation, mAddRotation,
54
                  mSetQuat, mChangeObject, mSolveObject, mScrambleObject, mRecreateObject,
55
                  mInitializeObject, mSetTextureMap, mResetAllTextureMaps, mSolve;
56
  private boolean mUIBlocked, mTouchBlocked, mIsSolved;
57
  private long mRotationFinishedID;
58
  private final long[] mEffectID;
59
  private int[][] mNextMoves;
60
  private int mScrambleObjectNum;
61
  private int mAddRotationAxis, mAddRotationRowBitmap, mAddRotationAngle;
62
  private long mAddRotationDuration;
63
  private long mAddRotationID, mRemoveRotationID;
64
  private int mCubit, mFace, mNewColor;
65
  private int mNearestAngle;
66
  private long mDebugStartTime;
67

    
68
///////////////////////////////////////////////////////////////////////////////////////////////////
69

    
70
  public ObjectPreRender(Activity act, ObjectControl controller, ObjectLibInterface actioner)
71
    {
72
    mAct = new WeakReference<>(act);
73
    mInterface = actioner;
74
    mController = controller;
75

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

    
87
    mOldObject = null;
88
    mNewObject = null;
89

    
90
    mDebug = "";
91
    mScrambleObjectNum = 0;
92

    
93
    mEffectID = new long[BaseEffect.Type.LENGTH];
94

    
95
    mBlockController = new BlockController(act,this);
96
    unblockEverything();
97
    }
98

    
99
///////////////////////////////////////////////////////////////////////////////////////////////////
100

    
101
  private void createObjectNow(ObjectType object)
102
    {
103
    boolean firstTime = (mNewObject==null);
104

    
105
    if( mOldObject!=null ) mOldObject.releaseResources();
106
    mOldObject = mNewObject;
107
    Static3D move = new Static3D(mMoveX,mMoveY,0);
108
    Resources res = mAct.get().getResources();
109

    
110
    long time1 = System.currentTimeMillis();
111

    
112
    int meshID = object.getMeshID();
113
    InputStream meshStream = ( meshID!=0 && ObjectControl.isInDmeshMode() ) ? res.openRawResource(meshID) : null;
114

    
115
    if( !ObjectControl.isInJsonMode() )
116
      {
117
      mNewObject = object.create( mController.getQuat(), move, meshStream);
118
      }
119
    else
120
      {
121
      int jsonID = object.getJsonID();
122
      InputStream jsonStream = jsonID!=0 ? res.openRawResource(jsonID) : null;
123
      mNewObject = new TwistyJson(jsonStream, mController.getQuat(), move, meshStream);
124
      }
125

    
126
    long time2 = System.currentTimeMillis();
127
    mInterface.onObjectCreated(time2-time1);
128

    
129
    if( mNewObject!=null )
130
      {
131
      TwistyObjectNode node = mController.getNode();
132
      if( node!=null ) mNewObject.setObjectRatioNow( 1.0f, node.getScaleFactor() );
133
      mController.setMovement(mNewObject.getMovement());
134
      if( firstTime && mPreferences!=null ) mNewObject.restorePreferences(mPreferences);
135
      mIsSolved = mNewObject.isSolved();
136
      }
137
    }
138

    
139
///////////////////////////////////////////////////////////////////////////////////////////////////
140
// do all 'adjustable' effects (SizeChange, Solve, Scramble)
141

    
142
  private void doEffectNow(BaseEffect.Type type)
143
    {
144
    try
145
      {
146
      int index = type.ordinal();
147
      mEffectID[index] = type.startEffect(this);
148
      }
149
    catch( Exception ex )
150
      {
151
      android.util.Log.e("renderer", "exception starting effect: "+ex.getMessage());
152
      unblockEverything();
153
      }
154
    }
155

    
156
///////////////////////////////////////////////////////////////////////////////////////////////////
157

    
158
  private void removeRotationNow()
159
    {
160
    mRemoveRotation=false;
161
    mNewObject.removeRotationNow();
162

    
163
    boolean solved = mNewObject.isSolved();
164

    
165
    if( solved && !mIsSolved )
166
      {
167
      mInterface.onSolved();
168
      unblockEverything();
169
      doEffectNow( BaseEffect.Type.WIN );
170
      }
171
    else
172
      {
173
      unblockEverything();
174
      }
175

    
176
    mIsSolved = solved;
177
    }
178

    
179
///////////////////////////////////////////////////////////////////////////////////////////////////
180

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

    
186
///////////////////////////////////////////////////////////////////////////////////////////////////
187

    
188
  private void removePatternRotation()
189
    {
190
    mRemovePatternRotation = true;
191
    }
192

    
193
///////////////////////////////////////////////////////////////////////////////////////////////////
194

    
195
  private void removePatternRotationNow()
196
    {
197
    mRemovePatternRotation=false;
198
    mNewObject.removeRotationNow();
199
    mAddActionListener.onActionFinished(mRemoveRotationID);
200
    }
201

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

    
204
  private void addRotationNow()
205
    {
206
    mAddRotation = false;
207
    mAddRotationID = mNewObject.addNewRotation( mAddRotationAxis, mAddRotationRowBitmap,
208
                                                mAddRotationAngle, mAddRotationDuration, this);
209

    
210
    if( mAddRotationID==0 ) // failed to add effect - should never happen
211
      {
212
      unblockEverything();
213
      }
214
    }
215

    
216
///////////////////////////////////////////////////////////////////////////////////////////////////
217

    
218
  private void finishRotationNow()
219
    {
220
    mFinishRotation = false;
221
    blockEverything(BlockController.PLACE_0);
222
    mRotationFinishedID = mNewObject.finishRotationNow(this, mNearestAngle);
223

    
224
    if( mRotationFinishedID==0 ) // failed to add effect - should never happen
225
      {
226
      unblockEverything();
227
      }
228
    }
229

    
230
///////////////////////////////////////////////////////////////////////////////////////////////////
231

    
232
  private void changeObjectNow()
233
    {
234
    mChangeObject = false;
235

    
236
    if ( mNewObject==null || mNewObject.getObjectType()!=mNextObject )
237
      {
238
      blockEverything(BlockController.PLACE_1);
239
      createObjectNow(mNextObject);
240
      doEffectNow( BaseEffect.Type.SIZECHANGE );
241
      }
242
    }
243

    
244
///////////////////////////////////////////////////////////////////////////////////////////////////
245

    
246
  private void recreateObjectNow()
247
    {
248
    mRecreateObject = false;
249

    
250
    if ( mNewObject!=null )
251
      {
252
      blockEverything(BlockController.PLACE_1);
253
      createObjectNow(mNewObject.getObjectType());
254
      doEffectNow( BaseEffect.Type.SIZECHANGE );
255
      }
256
    }
257

    
258
///////////////////////////////////////////////////////////////////////////////////////////////////
259

    
260
  private void scrambleObjectNow()
261
    {
262
    mScrambleObject = false;
263
    mIsSolved       = false;
264
    blockEverything(BlockController.PLACE_3);
265
    doEffectNow( BaseEffect.Type.SCRAMBLE );
266
    }
267

    
268
///////////////////////////////////////////////////////////////////////////////////////////////////
269

    
270
  private void solveObjectNow()
271
    {
272
    mSolveObject = false;
273
    blockEverything(BlockController.PLACE_4);
274
    doEffectNow( BaseEffect.Type.SOLVE );
275
    }
276

    
277
///////////////////////////////////////////////////////////////////////////////////////////////////
278

    
279
  private void solveNow()
280
    {
281
    mSolve = false;
282
    if( mNewObject!=null ) mNewObject.solve();
283
    }
284

    
285
///////////////////////////////////////////////////////////////////////////////////////////////////
286

    
287
  private void initializeObjectNow()
288
    {
289
    mInitializeObject = false;
290
    mNewObject.initializeObject(mNextMoves);
291
    }
292

    
293
///////////////////////////////////////////////////////////////////////////////////////////////////
294

    
295
  private void setTextureMapNow()
296
    {
297
    mSetTextureMap = false;
298

    
299
    if( mNewObject!=null ) mNewObject.setTextureMap(mCubit,mFace,mNewColor);
300
    }
301

    
302
///////////////////////////////////////////////////////////////////////////////////////////////////
303

    
304
  private void resetAllTextureMapsNow()
305
    {
306
    mResetAllTextureMaps = false;
307
    if( mNewObject!=null ) mNewObject.resetAllTextureMaps();
308
    }
309

    
310
///////////////////////////////////////////////////////////////////////////////////////////////////
311

    
312
  private void setQuatNow()
313
    {
314
    mSetQuat = false;
315
    mController.setQuat();
316
    }
317

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

    
320
  void rememberMove(int axis, int row, int angle)
321
    {
322
    mDebug += (" (m "+axis+" "+(1<<row)+" "+angle+" "+(System.currentTimeMillis()-mDebugStartTime)+")");
323
    }
324

    
325
///////////////////////////////////////////////////////////////////////////////////////////////////
326

    
327
  void finishRotation(int nearestAngle)
328
    {
329
    mNearestAngle   = nearestAngle;
330
    mFinishRotation = true;
331
    }
332

    
333
///////////////////////////////////////////////////////////////////////////////////////////////////
334

    
335
  void setTextureMap(int cubit, int face, int newColor)
336
    {
337
    mSetTextureMap = true;
338

    
339
    mCubit    = cubit;
340
    mFace     = face;
341
    mNewColor = newColor;
342
    }
343

    
344
///////////////////////////////////////////////////////////////////////////////////////////////////
345

    
346
  void setQuatOnNextRender()
347
    {
348
    mSetQuat = true;
349
    }
350

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

    
353
  void setMove(float xmove, float ymove)
354
    {
355
    mMoveX = xmove;
356
    mMoveY = ymove;
357
    }
358

    
359
///////////////////////////////////////////////////////////////////////////////////////////////////
360
// INTERNAL API
361
///////////////////////////////////////////////////////////////////////////////////////////////////
362

    
363
  public int getNumScrambles()
364
    {
365
    return mScrambleObjectNum;
366
    }
367

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

    
370
  public TwistyObject getOldObject()
371
    {
372
    return mOldObject;
373
    }
374

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

    
377
  public float getMoveX()
378
    {
379
    return mMoveX;
380
    }
381

    
382
///////////////////////////////////////////////////////////////////////////////////////////////////
383

    
384
  public float getMoveY()
385
    {
386
    return mMoveY;
387
    }
388

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

    
393
  public void setScreenSize()
394
    {
395
    if( mNewObject!=null ) mNewObject.createTexture();
396
    }
397

    
398
///////////////////////////////////////////////////////////////////////////////////////////////////
399

    
400
  public void savePreferences(SharedPreferences.Editor editor)
401
    {
402
    if( mNewObject!=null )
403
      {
404
      mNewObject.savePreferences(editor);
405
      }
406
    }
407

    
408
///////////////////////////////////////////////////////////////////////////////////////////////////
409

    
410
  public void restorePreferences(SharedPreferences preferences)
411
    {
412
    mPreferences = preferences;
413
    }
414

    
415
///////////////////////////////////////////////////////////////////////////////////////////////////
416

    
417
  public void changeObject(ObjectType object)
418
    {
419
    mChangeObject = true;
420
    mNextObject = object;
421
    }
422

    
423
///////////////////////////////////////////////////////////////////////////////////////////////////
424

    
425
  public void recreateObject()
426
    {
427
    mRecreateObject = true;
428
    }
429

    
430
///////////////////////////////////////////////////////////////////////////////////////////////////
431

    
432
  public boolean isTouchBlocked()
433
    {
434
    return mTouchBlocked;
435
    }
436

    
437
///////////////////////////////////////////////////////////////////////////////////////////////////
438

    
439
  public boolean isUINotBlocked()
440
    {
441
    return !mUIBlocked;
442
    }
443

    
444
///////////////////////////////////////////////////////////////////////////////////////////////////
445

    
446
  public void blockEverything(int place)
447
    {
448
    mUIBlocked   = true;
449
    mTouchBlocked= true;
450
    mBlockController.touchBlocked(place);
451
    mBlockController.uiBlocked(place);
452
    }
453

    
454
///////////////////////////////////////////////////////////////////////////////////////////////////
455

    
456
  public void blockTouch(int place)
457
    {
458
    mTouchBlocked= true;
459
    mBlockController.touchBlocked(place);
460
    }
461

    
462
///////////////////////////////////////////////////////////////////////////////////////////////////
463

    
464
  public void unblockEverything()
465
    {
466
    mUIBlocked   = false;
467
    mTouchBlocked= false;
468
    mBlockController.touchUnblocked();
469
    mBlockController.uiUnblocked();
470
    }
471

    
472
///////////////////////////////////////////////////////////////////////////////////////////////////
473

    
474
  public void unblockTouch()
475
    {
476
    mTouchBlocked= false;
477
    mBlockController.touchUnblocked();
478
    }
479

    
480
///////////////////////////////////////////////////////////////////////////////////////////////////
481

    
482
  public void unblockUI()
483
    {
484
    mUIBlocked= false;
485
    mBlockController.uiUnblocked();
486
    }
487

    
488
///////////////////////////////////////////////////////////////////////////////////////////////////
489

    
490
  public void preRender()
491
    {
492
    if( mSolve                 ) solveNow();
493
    if( mSetQuat               ) setQuatNow();
494
    if( mFinishRotation        ) finishRotationNow();
495
    if( mRemoveRotation        ) removeRotationNow();
496
    if( mRemovePatternRotation ) removePatternRotationNow();
497
    if( mChangeObject          ) changeObjectNow();
498
    if( mRecreateObject        ) recreateObjectNow();
499
    if( mSolveObject           ) solveObjectNow();
500
    if( mScrambleObject        ) scrambleObjectNow();
501
    if( mAddRotation           ) addRotationNow();
502
    if( mInitializeObject      ) initializeObjectNow();
503
    if( mResetAllTextureMaps   ) resetAllTextureMapsNow();
504
    if( mSetTextureMap         ) setTextureMapNow();
505
    }
506

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

    
509
  public void addRotation(MovesFinished listener, int axis, int rowBitmap, int bareAngle, int millPreDegree)
510
    {
511
    mAddRotation = true;
512

    
513
    int basicAngle= mNewObject.getBasicAngle()[axis];
514
    int angle     = bareAngle*(360/basicAngle);
515
    int duration  = Math.abs(angle)*millPreDegree;
516

    
517
    mAddActionListener    = listener;
518
    mAddRotationAxis      = axis;
519
    mAddRotationRowBitmap = rowBitmap;
520
    mAddRotationAngle     = angle;
521
    mAddRotationDuration  = duration;
522

    
523
    if( listener instanceof ScrambleEffect )
524
      {
525
      mDebug += (" (a "+axis+" "+rowBitmap+" "+angle+" "+(System.currentTimeMillis()-mDebugStartTime)+")");
526
      }
527
    }
528

    
529
///////////////////////////////////////////////////////////////////////////////////////////////////
530

    
531
  public void initializeObject(int[][] moves)
532
    {
533
    mInitializeObject = true;
534
    mNextMoves = moves;
535
    }
536

    
537
///////////////////////////////////////////////////////////////////////////////////////////////////
538

    
539
  public void scrambleObject(int num)
540
    {
541
    if( !mUIBlocked )
542
      {
543
      mScrambleObject = true;
544
      mScrambleObjectNum = num;
545
      mDebug = "";
546
      mDebugStartTime = System.currentTimeMillis();
547
      }
548
    }
549

    
550
///////////////////////////////////////////////////////////////////////////////////////////////////
551
// this starts the Solve Effect
552

    
553
  public void solveObject()
554
    {
555
    if( !mUIBlocked )
556
      {
557
      mSolveObject = true;
558
      }
559
    }
560

    
561
///////////////////////////////////////////////////////////////////////////////////////////////////
562
// this only sets the cubits state to solved
563

    
564
  public void solveOnly()
565
    {
566
    mSolve = true;
567
    }
568

    
569
///////////////////////////////////////////////////////////////////////////////////////////////////
570

    
571
  public void resetAllTextureMaps()
572
    {
573
    mResetAllTextureMaps = true;
574
    }
575

    
576
///////////////////////////////////////////////////////////////////////////////////////////////////
577

    
578
  public TwistyObject getObject()
579
    {
580
    return mNewObject;
581
    }
582

    
583
///////////////////////////////////////////////////////////////////////////////////////////////////
584

    
585
  public TwistyObjectNode getObjectNode()
586
    {
587
    return mController.getNode();
588
    }
589

    
590
///////////////////////////////////////////////////////////////////////////////////////////////////
591

    
592
  public void effectFinished(final long effectID)
593
    {
594
    if( effectID == mRotationFinishedID )
595
      {
596
      mRotationFinishedID = 0;
597
      removeRotation();
598
      }
599
    else if( effectID == mAddRotationID )
600
      {
601
      mAddRotationID = 0;
602
      mRemoveRotationID = effectID;
603
      removePatternRotation();
604
      }
605
    else
606
      {
607
      for(int i=0; i<BaseEffect.Type.LENGTH; i++)
608
        {
609
        if( effectID == mEffectID[i] )
610
          {
611
          if( i!=BaseEffect.Type.WIN.ordinal() ) unblockEverything();
612
          if( i==BaseEffect.Type.SCRAMBLE.ordinal() ) mInterface.onScrambleEffectFinished();
613
          if( i==BaseEffect.Type.WIN.ordinal()      ) mInterface.onWinEffectFinished(mDebug,mScrambleObjectNum);
614
          break;
615
          }
616
        }
617
      }
618
    }
619
  }
(9-9/18)