Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / main / ObjectPreRender.java @ d887aa16

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
      mNewObject.setLibInterface(mInterface);
132
      TwistyObjectNode node = mController.getNode();
133
      if( node!=null ) mNewObject.setObjectRatioNow( 1.0f, node.getScaleFactor() );
134
      mController.setMovement(mNewObject.getMovement());
135
      if( firstTime && mPreferences!=null ) mNewObject.restorePreferences(mPreferences);
136
      mIsSolved = mNewObject.isSolved();
137
      }
138
    }
139

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

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

    
157
///////////////////////////////////////////////////////////////////////////////////////////////////
158

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

    
164
    boolean solved = mNewObject.isSolved();
165

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

    
177
    mIsSolved = solved;
178
    }
179

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

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

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

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

    
194
///////////////////////////////////////////////////////////////////////////////////////////////////
195

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

    
203
///////////////////////////////////////////////////////////////////////////////////////////////////
204

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

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

    
217
///////////////////////////////////////////////////////////////////////////////////////////////////
218

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

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

    
231
///////////////////////////////////////////////////////////////////////////////////////////////////
232

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

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

    
245
///////////////////////////////////////////////////////////////////////////////////////////////////
246

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

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

    
259
///////////////////////////////////////////////////////////////////////////////////////////////////
260

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

    
269
///////////////////////////////////////////////////////////////////////////////////////////////////
270

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

    
278
///////////////////////////////////////////////////////////////////////////////////////////////////
279

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

    
286
///////////////////////////////////////////////////////////////////////////////////////////////////
287

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

    
294
///////////////////////////////////////////////////////////////////////////////////////////////////
295

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

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

    
303
///////////////////////////////////////////////////////////////////////////////////////////////////
304

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

    
311
///////////////////////////////////////////////////////////////////////////////////////////////////
312

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

    
319
///////////////////////////////////////////////////////////////////////////////////////////////////
320

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

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

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

    
334
///////////////////////////////////////////////////////////////////////////////////////////////////
335

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

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

    
345
///////////////////////////////////////////////////////////////////////////////////////////////////
346

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

    
352
///////////////////////////////////////////////////////////////////////////////////////////////////
353

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

    
360
///////////////////////////////////////////////////////////////////////////////////////////////////
361
// INTERNAL API
362
///////////////////////////////////////////////////////////////////////////////////////////////////
363

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

    
369
///////////////////////////////////////////////////////////////////////////////////////////////////
370

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

    
376
///////////////////////////////////////////////////////////////////////////////////////////////////
377

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

    
383
///////////////////////////////////////////////////////////////////////////////////////////////////
384

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

    
390
///////////////////////////////////////////////////////////////////////////////////////////////////
391

    
392
  public ObjectLibInterface getInterface()
393
    {
394
    return mInterface;
395
    }
396

    
397
///////////////////////////////////////////////////////////////////////////////////////////////////
398
// PUBLIC API
399
///////////////////////////////////////////////////////////////////////////////////////////////////
400

    
401
  public void setScreenSize()
402
    {
403
    if( mNewObject!=null ) mNewObject.createTexture();
404
    }
405

    
406
///////////////////////////////////////////////////////////////////////////////////////////////////
407

    
408
  public void savePreferences(SharedPreferences.Editor editor)
409
    {
410
    if( mNewObject!=null )
411
      {
412
      mNewObject.savePreferences(editor);
413
      }
414
    }
415

    
416
///////////////////////////////////////////////////////////////////////////////////////////////////
417

    
418
  public void restorePreferences(SharedPreferences preferences)
419
    {
420
    mPreferences = preferences;
421
    }
422

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

    
425
  public void changeObject(ObjectType object)
426
    {
427
    mChangeObject = true;
428
    mNextObject = object;
429
    }
430

    
431
///////////////////////////////////////////////////////////////////////////////////////////////////
432

    
433
  public void recreateObject()
434
    {
435
    mRecreateObject = true;
436
    }
437

    
438
///////////////////////////////////////////////////////////////////////////////////////////////////
439

    
440
  public boolean isTouchBlocked()
441
    {
442
    return mTouchBlocked;
443
    }
444

    
445
///////////////////////////////////////////////////////////////////////////////////////////////////
446

    
447
  public boolean isUINotBlocked()
448
    {
449
    return !mUIBlocked;
450
    }
451

    
452
///////////////////////////////////////////////////////////////////////////////////////////////////
453

    
454
  public void blockEverything(int place)
455
    {
456
    mUIBlocked   = true;
457
    mTouchBlocked= true;
458
    mBlockController.touchBlocked(place);
459
    mBlockController.uiBlocked(place);
460
    }
461

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

    
464
  public void blockTouch(int place)
465
    {
466
    mTouchBlocked= true;
467
    mBlockController.touchBlocked(place);
468
    }
469

    
470
///////////////////////////////////////////////////////////////////////////////////////////////////
471

    
472
  public void unblockEverything()
473
    {
474
    mUIBlocked   = false;
475
    mTouchBlocked= false;
476
    mBlockController.touchUnblocked();
477
    mBlockController.uiUnblocked();
478
    }
479

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

    
482
  public void unblockTouch()
483
    {
484
    mTouchBlocked= false;
485
    mBlockController.touchUnblocked();
486
    }
487

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

    
490
  public void unblockUI()
491
    {
492
    mUIBlocked= false;
493
    mBlockController.uiUnblocked();
494
    }
495

    
496
///////////////////////////////////////////////////////////////////////////////////////////////////
497

    
498
  public void preRender()
499
    {
500
    if( mSolve                 ) solveNow();
501
    if( mSetQuat               ) setQuatNow();
502
    if( mFinishRotation        ) finishRotationNow();
503
    if( mRemoveRotation        ) removeRotationNow();
504
    if( mRemovePatternRotation ) removePatternRotationNow();
505
    if( mChangeObject          ) changeObjectNow();
506
    if( mRecreateObject        ) recreateObjectNow();
507
    if( mSolveObject           ) solveObjectNow();
508
    if( mScrambleObject        ) scrambleObjectNow();
509
    if( mAddRotation           ) addRotationNow();
510
    if( mInitializeObject      ) initializeObjectNow();
511
    if( mResetAllTextureMaps   ) resetAllTextureMapsNow();
512
    if( mSetTextureMap         ) setTextureMapNow();
513
    }
514

    
515
///////////////////////////////////////////////////////////////////////////////////////////////////
516

    
517
  public void addRotation(MovesFinished listener, int axis, int rowBitmap, int bareAngle, int millPreDegree)
518
    {
519
    mAddRotation = true;
520

    
521
    int basicAngle= mNewObject.getBasicAngle()[axis];
522
    int angle     = bareAngle*(360/basicAngle);
523
    int duration  = Math.abs(angle)*millPreDegree;
524

    
525
    mAddActionListener    = listener;
526
    mAddRotationAxis      = axis;
527
    mAddRotationRowBitmap = rowBitmap;
528
    mAddRotationAngle     = angle;
529
    mAddRotationDuration  = duration;
530

    
531
    if( listener instanceof ScrambleEffect )
532
      {
533
      mDebug += (" (a "+axis+" "+rowBitmap+" "+angle+" "+(System.currentTimeMillis()-mDebugStartTime)+")");
534
      }
535
    }
536

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

    
539
  public void initializeObject(int[][] moves)
540
    {
541
    mInitializeObject = true;
542
    mNextMoves = moves;
543
    }
544

    
545
///////////////////////////////////////////////////////////////////////////////////////////////////
546

    
547
  public void scrambleObject(int num)
548
    {
549
    if( !mUIBlocked )
550
      {
551
      mScrambleObject = true;
552
      mScrambleObjectNum = num;
553
      mDebug = "";
554
      mDebugStartTime = System.currentTimeMillis();
555
      }
556
    }
557

    
558
///////////////////////////////////////////////////////////////////////////////////////////////////
559
// this starts the Solve Effect
560

    
561
  public void solveObject()
562
    {
563
    if( !mUIBlocked )
564
      {
565
      mSolveObject = true;
566
      }
567
    }
568

    
569
///////////////////////////////////////////////////////////////////////////////////////////////////
570
// this only sets the cubits state to solved
571

    
572
  public void solveOnly()
573
    {
574
    mSolve = true;
575
    }
576

    
577
///////////////////////////////////////////////////////////////////////////////////////////////////
578

    
579
  public void resetAllTextureMaps()
580
    {
581
    mResetAllTextureMaps = true;
582
    }
583

    
584
///////////////////////////////////////////////////////////////////////////////////////////////////
585

    
586
  public TwistyObject getObject()
587
    {
588
    return mNewObject;
589
    }
590

    
591
///////////////////////////////////////////////////////////////////////////////////////////////////
592

    
593
  public TwistyObjectNode getObjectNode()
594
    {
595
    return mController.getNode();
596
    }
597

    
598
///////////////////////////////////////////////////////////////////////////////////////////////////
599

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