Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / effects / fastscramble / FastScrambleEffect.java @ 00057bb1

1 186bc982 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2022 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6 f2abba90 Leszek Koltunski
// Magic Cube is proprietary software licensed under an EULA which you should have received      //
7
// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
8 186bc982 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
9
10
package org.distorted.objectlib.effects.fastscramble;
11
12
import java.lang.reflect.Method;
13 3ad0a514 Leszek Koltunski
import java.util.Random;
14 186bc982 Leszek Koltunski
15
import org.distorted.library.effect.Effect;
16
import org.distorted.library.main.DistortedEffects;
17
import org.distorted.library.message.EffectListener;
18
19
import org.distorted.objectlib.main.ObjectPreRender;
20
import org.distorted.objectlib.main.TwistyObject;
21
22
import org.distorted.objectlib.effects.BaseEffect;
23
import org.distorted.objectlib.main.TwistyObjectNode;
24
25
///////////////////////////////////////////////////////////////////////////////////////////////////
26
27
public abstract class FastScrambleEffect extends BaseEffect implements EffectListener
28
{
29
  public enum Type
30
    {
31
    SPIN   (FastScrambleEffectSpin.class),
32
    ;
33
34
    final Class<? extends FastScrambleEffect> effect;
35
36
    Type(Class<? extends FastScrambleEffect> effect)
37
      {
38
      this.effect = effect;
39
      }
40
    }
41
42
  private static final int NUM_EFFECTS = Type.values().length;
43
  private static final int NUM_PHASES  = 2;
44
  private static final int FAKE_EFFECT_ID = -5;
45
  private static final Type[] types;
46
47
  static
48
    {
49
    int i=0;
50
    types = new Type[NUM_EFFECTS];
51
52
    for(Type type: Type.values())
53
      {
54
      types[i++] = type;
55
      }
56
    }
57
58
  private int mDuration;
59
  private int mEffectReturned;
60
  private final int[] mCubeEffectNumber, mNodeEffectNumber;
61
  private int mPhase;
62 3ad0a514 Leszek Koltunski
  private final Random mRnd;
63
  private final Object mLock;
64
  int mNumScrambles;
65
  int[][] mScrambles;
66 186bc982 Leszek Koltunski
67
  ObjectPreRender mPre;
68
  TwistyObject mObject;
69
  TwistyObjectNode mObjectNode;
70
  Effect[][] mCubeEffects;
71
  int[][] mCubeEffectPosition;
72
  Effect[][] mNodeEffects;
73
  int[][] mNodeEffectPosition;
74
75
///////////////////////////////////////////////////////////////////////////////////////////////////
76
77
  FastScrambleEffect()
78
    {
79 3ad0a514 Leszek Koltunski
    mLock = new Object();
80
    mRnd = new Random( System.currentTimeMillis() );
81
82 186bc982 Leszek Koltunski
    mPhase= 0;
83
84
    mCubeEffectNumber   = new int[NUM_PHASES];
85
    mNodeEffectNumber   = new int[NUM_PHASES];
86
    mCubeEffectPosition = new int[NUM_PHASES][];
87
    mNodeEffectPosition = new int[NUM_PHASES][];
88
    mCubeEffects        = new Effect[NUM_PHASES][];
89
    mNodeEffects        = new Effect[NUM_PHASES][];
90
    }
91
92
///////////////////////////////////////////////////////////////////////////////////////////////////
93
94
  abstract void createEffectsPhase0(int duration);
95
  abstract void createEffectsPhase1(int duration);
96
97 3ad0a514 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
98
99
  private void createScrambles()
100
    {
101
    mScrambles = new int[mNumScrambles][3];
102
103 0cdd9b6c Leszek Koltunski
    if( mObject!=null )
104 3ad0a514 Leszek Koltunski
      {
105 0cdd9b6c Leszek Koltunski
      synchronized(mLock)
106
        {
107
        for(int scramble=0; scramble<mNumScrambles; scramble++)
108
          {
109
          mObject.randomizeNewScramble(mScrambles, mRnd, scramble, mNumScrambles);
110
          }
111
        }
112 3ad0a514 Leszek Koltunski
      }
113
    }
114
115 186bc982 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
116
117
  private void assignEffects(int phase)
118
    {
119
    mCubeEffectNumber[phase] = ( mCubeEffects[phase]!=null ) ? mCubeEffects[phase].length : 0;
120
    mNodeEffectNumber[phase] = ( mNodeEffects[phase]!=null ) ? mNodeEffects[phase].length : 0;
121
122
    if( mCubeEffectNumber[phase]==0 && mNodeEffectNumber[phase]==0 )
123
      {
124
      throw new RuntimeException("Cube and Node Effects ("+phase+" phase) both not created!");
125
      }
126
127
    for(int i=0; i<mCubeEffectNumber[phase]; i++)
128
      {
129 826d293e Leszek Koltunski
      mObject.applyEffect(mCubeEffects[phase][i],mCubeEffectPosition[phase][i]);
130 186bc982 Leszek Koltunski
      mCubeEffects[phase][i].notifyWhenFinished(this);
131
      }
132
133
    DistortedEffects nodeEffects = mObjectNode.getEffects();
134
135
    for(int i=0; i<mNodeEffectNumber[phase]; i++)
136
      {
137
      nodeEffects.apply(mNodeEffects[phase][i],mNodeEffectPosition[phase][i]);
138
      mNodeEffects[phase][i].notifyWhenFinished(this);
139
      }
140
    }
141
142
///////////////////////////////////////////////////////////////////////////////////////////////////
143
144
  private void effectAction(int phase)
145
    {
146
    switch(phase)
147
      {
148
      case 0: mEffectReturned = 0;
149
              mPhase          = 1;
150 3ad0a514 Leszek Koltunski
151
              // do not start initializing the Object until we have finished creating moves!
152
              synchronized(mLock)
153
                {
154 d356eecc Leszek Koltunski
                mPre.applyScrambles(mScrambles);
155 3ad0a514 Leszek Koltunski
                }
156
157 186bc982 Leszek Koltunski
              createEffectsPhase1(mDuration);
158
              assignEffects(mPhase);
159
              break;
160
      case 1: mPre.effectFinished(FAKE_EFFECT_ID);
161
              break;
162
      }
163
    }
164
165
///////////////////////////////////////////////////////////////////////////////////////////////////
166
// PUBLIC API
167
///////////////////////////////////////////////////////////////////////////////////////////////////
168
169
  @SuppressWarnings("unused")
170
  public static String[] getNames()
171
    {
172
    String[] names = new String[NUM_EFFECTS];
173
174
    for( int i=0; i<NUM_EFFECTS; i++)
175
      {
176
      names[i] = types[i].name();
177
      }
178
179
    return names;
180
    }
181
182
///////////////////////////////////////////////////////////////////////////////////////////////////
183
184
  @SuppressWarnings("unused")
185
  public static FastScrambleEffect create(int ordinal) throws InstantiationException, IllegalAccessException
186
    {
187
    return types[ordinal].effect.newInstance();
188
    }
189
190
///////////////////////////////////////////////////////////////////////////////////////////////////
191
192
  public void effectFinished(final long effectID)
193
    {
194
    int total = mCubeEffectNumber[mPhase]+mNodeEffectNumber[mPhase];
195
196
    for(int i=0; i<mCubeEffectNumber[mPhase]; i++)
197
      {
198
      long id = mCubeEffects[mPhase][i].getID();
199
200
      if( effectID == id )
201
        {
202
        if( ++mEffectReturned == total ) effectAction(mPhase);
203 826d293e Leszek Koltunski
        mObject.removeEffect(id);
204 186bc982 Leszek Koltunski
        return;
205
        }
206
      }
207
    for(int i=0; i<mNodeEffectNumber[mPhase]; i++)
208
      {
209
      long id = mNodeEffects[mPhase][i].getID();
210
211
      if( effectID == id )
212
        {
213
        if( ++mEffectReturned == total ) effectAction(mPhase);
214
        mObjectNode.getEffects().abortById(id);
215
        return;
216
        }
217
      }
218
    }
219
220
///////////////////////////////////////////////////////////////////////////////////////////////////
221
222
  @SuppressWarnings("unused")
223
  public long start(int duration, ObjectPreRender pre)
224
    {
225 3ad0a514 Leszek Koltunski
    mObject       = pre.getObject();
226
    mObjectNode   = pre.getObjectNode();
227
    mPre          = pre;
228
    mDuration     = duration;
229 da1e61aa Leszek Koltunski
    mNumScrambles = pre.getNumScrambles();
230 3ad0a514 Leszek Koltunski
231
    Thread thread = new Thread()
232
      {
233
      public void run()
234
        {
235
        createScrambles();
236
        }
237
      };
238
239
    thread.start();
240 186bc982 Leszek Koltunski
241
    createEffectsPhase0(mDuration);
242
    assignEffects(mPhase);
243
244
    return FAKE_EFFECT_ID;
245
    }
246
247
///////////////////////////////////////////////////////////////////////////////////////////////////
248
249
  @SuppressWarnings("unused")
250
  public static void enableEffects()
251
    {
252
    Method method;
253
254
    for(Type type: Type.values())
255
      {
256
      try
257
        {
258
        method = type.effect.getDeclaredMethod("enable"); // enable not public, thus getDeclaredMethod
259
        }
260
      catch(NoSuchMethodException ex)
261
        {
262
        android.util.Log.e("FastScrambleEffect", type.effect.getSimpleName()+": exception getting method: "+ex.getMessage());
263
        method = null;
264
        }
265
266
      try
267
        {
268
        if( method!=null ) method.invoke(null);
269
        }
270
      catch(Exception ex)
271
        {
272
        android.util.Log.e("FastScrambleEffect", type.effect.getSimpleName()+": exception invoking method: "+ex.getMessage());
273
        }
274
      }
275
    }
276
}