Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / effects / objectchange / ObjectChangeEffect.java @ 1eafa9c6

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2019 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// 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
///////////////////////////////////////////////////////////////////////////////////////////////////
9

    
10
package org.distorted.objectlib.effects.objectchange;
11

    
12
import java.lang.reflect.Method;
13

    
14
import org.distorted.library.effect.Effect;
15
import org.distorted.library.main.DistortedEffects;
16
import org.distorted.library.message.EffectListener;
17

    
18
import org.distorted.objectlib.main.ObjectPreRender;
19
import org.distorted.objectlib.main.TwistyObject;
20
import org.distorted.objectlib.effects.BaseEffect;
21
import org.distorted.objectlib.main.TwistyObjectNode;
22

    
23
///////////////////////////////////////////////////////////////////////////////////////////////////
24

    
25
public abstract class ObjectChangeEffect extends BaseEffect implements EffectListener
26
{
27
  public enum Type
28
    {
29
    NONE         (ObjectChangeEffectNone.class        ),
30
    TRANSPARENCY (ObjectChangeEffectTransparency.class),
31
    MOVE         (ObjectChangeEffectMove.class        ),
32
    ROUND        (ObjectChangeEffectRound.class       ),
33
    SCALE        (ObjectChangeEffectScale.class       ),
34
    ;
35

    
36
    final Class<? extends ObjectChangeEffect> effect;
37

    
38
    Type(Class<? extends ObjectChangeEffect> effect)
39
      {
40
      this.effect= effect;
41
      }
42
    }
43

    
44
  private static final int NUM_EFFECTS = Type.values().length;
45
  private static final int NUM_PHASES  = 2;
46
  private static final int FAKE_EFFECT_ID  = -1;
47
  private static final Type[] types;
48

    
49
  static
50
    {
51
    int i=0;
52
    types = new Type[NUM_EFFECTS];
53

    
54
    for(Type type: Type.values())
55
      {
56
      types[i++] = type;
57
      }
58
    }
59

    
60
  private int mDuration;
61
  private final int[] mEffectReturned;
62
  private final int[] mCubeEffectNumber, mNodeEffectNumber;
63
  private final int[] mEffectFinished;
64
  private final boolean[] mPhaseActive;
65

    
66
  ObjectPreRender mPre;
67
  TwistyObject[] mObject;
68
  TwistyObjectNode mObjectNode;
69
  Effect[][] mCubeEffects;
70
  int[][] mCubeEffectPosition;
71
  Effect[][] mNodeEffects;
72
  int[][] mNodeEffectPosition;
73

    
74
///////////////////////////////////////////////////////////////////////////////////////////////////
75

    
76
  ObjectChangeEffect()
77
    {
78
    mPhaseActive        = new boolean[NUM_PHASES];
79
    mEffectReturned     = new int[NUM_PHASES];
80
    mCubeEffectNumber   = new int[NUM_PHASES];
81
    mNodeEffectNumber   = new int[NUM_PHASES];
82
    mEffectFinished     = new int[NUM_PHASES];
83
    mCubeEffectPosition = new int[NUM_PHASES][];
84
    mNodeEffectPosition = new int[NUM_PHASES][];
85
    mCubeEffects        = new Effect[NUM_PHASES][];
86
    mNodeEffects        = new Effect[NUM_PHASES][];
87
    mObject             = new TwistyObject[NUM_PHASES];
88
    }
89

    
90
///////////////////////////////////////////////////////////////////////////////////////////////////
91

    
92
  abstract int createEffectsPhase0(int duration);
93
  abstract int createEffectsPhase1(int duration);
94

    
95
///////////////////////////////////////////////////////////////////////////////////////////////////
96

    
97
  private void effectFinishedPhase(final long effectID, int phase)
98
    {
99
    for(int i=0; i<mCubeEffectNumber[phase]; i++)
100
      {
101
      long id = mCubeEffects[phase][i].getID();
102

    
103
      if( effectID == id )
104
        {
105
        effectReturned(phase);
106
        mObject[phase].removeEffect(id);
107
        return;
108
        }
109
      }
110
    for(int i=0; i<mNodeEffectNumber[phase]; i++)
111
      {
112
      long id = mNodeEffects[phase][i].getID();
113

    
114
      if( effectID == id )
115
        {
116
        effectReturned(phase);
117
        mObjectNode.getEffects().abortById(id);
118
        return;
119
        }
120
      }
121
    }
122

    
123
///////////////////////////////////////////////////////////////////////////////////////////////////
124

    
125
  private void phase0finished()
126
    {
127
    mPhaseActive[1] = true;
128
    mEffectFinished[1] = createEffectsPhase1(mDuration);
129
    assignEffects(1);
130

    
131
    if( mPre!=null )
132
      {
133
      int numFaces = mObject[1].getNumPuzzleFaces();
134
      mPre.setDefaultRotation(numFaces);
135
      }
136

    
137
    mObjectNode.attach(mObject[1].getNode());
138
    mObjectNode.setFOV(mObject[1].getFOV());
139
    }
140

    
141
///////////////////////////////////////////////////////////////////////////////////////////////////
142

    
143
  private void effectReturned(int phase)
144
    {
145
    mEffectReturned[phase]++;
146

    
147
    if( mEffectReturned[phase] == mEffectFinished[phase] )
148
      {
149
      switch(phase)
150
        {
151
        case 0: phase0finished();
152
                break;
153
        case 1: mPre.effectFinished(FAKE_EFFECT_ID);
154
                break;
155
        }
156
      }
157
    if( mEffectReturned[phase] == mCubeEffectNumber[phase]+mNodeEffectNumber[phase] )
158
      {
159
      switch(phase)
160
        {
161
        case 0: mPhaseActive[0] = false;
162
                mObjectNode.detach(mObject[0].getNode());
163
                break;
164
        case 1: mPhaseActive[1] = false;
165
                break;
166
        }
167
      }
168
    }
169

    
170
///////////////////////////////////////////////////////////////////////////////////////////////////
171

    
172
  private void assignEffects(int phase)
173
    {
174
    mCubeEffectNumber[phase] = ( mCubeEffects[phase]!=null ) ? mCubeEffects[phase].length : 0;
175
    mNodeEffectNumber[phase] = ( mNodeEffects[phase]!=null ) ? mNodeEffects[phase].length : 0;
176

    
177
    if( mCubeEffectNumber[phase]==0 && mNodeEffectNumber[phase]==0 )
178
      {
179
      throw new RuntimeException("Cube and Node Effects ("+phase+" phase) both not created!");
180
      }
181

    
182
    for(int i=0; i<mCubeEffectNumber[phase]; i++)
183
      {
184
      mObject[phase].applyEffect(mCubeEffects[phase][i],mCubeEffectPosition[phase][i]);
185
      mCubeEffects[phase][i].notifyWhenFinished(this);
186
      }
187

    
188
    DistortedEffects nodeEffects = mObjectNode.getEffects();
189

    
190
    for(int i=0; i<mNodeEffectNumber[phase]; i++)
191
      {
192
      nodeEffects.apply(mNodeEffects[phase][i],mNodeEffectPosition[phase][i]);
193
      mNodeEffects[phase][i].notifyWhenFinished(this);
194
      }
195
    }
196

    
197
///////////////////////////////////////////////////////////////////////////////////////////////////
198
// PUBLIC API
199
///////////////////////////////////////////////////////////////////////////////////////////////////
200

    
201
  public void effectFinished(final long effectID)
202
    {
203
    if( mPhaseActive[0] ) effectFinishedPhase(effectID,0);
204
    if( mPhaseActive[1] ) effectFinishedPhase(effectID,1);
205
    }
206

    
207
///////////////////////////////////////////////////////////////////////////////////////////////////
208

    
209
  @SuppressWarnings("unused")
210
  public static String[] getNames()
211
    {
212
    String[] names = new String[NUM_EFFECTS];
213

    
214
    for( int i=0; i<NUM_EFFECTS; i++)
215
      {
216
      names[i] = types[i].name();
217
      }
218

    
219
    return names;
220
    }
221

    
222
///////////////////////////////////////////////////////////////////////////////////////////////////
223

    
224
  @SuppressWarnings("unused")
225
  public static ObjectChangeEffect create(int ordinal) throws InstantiationException, IllegalAccessException
226
    {
227
    return types[ordinal].effect.newInstance();
228
    }
229

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

    
232
  @SuppressWarnings("unused")
233
  public long start(int duration, ObjectPreRender pre)
234
    {
235
    mObject[0] = pre.getOldObject();
236
    mObject[1] = pre.getObject();
237
    mObjectNode= pre.getObjectNode();
238
    mPre       = pre;
239
    mDuration  = duration;
240

    
241
    if( mObject[0]!=null )
242
      {
243
      mPhaseActive[0] = true;
244
      mEffectFinished[0] = createEffectsPhase0(mDuration);
245
      assignEffects(0);
246
      }
247
    else phase0finished();
248

    
249
    return FAKE_EFFECT_ID;
250
    }
251

    
252
///////////////////////////////////////////////////////////////////////////////////////////////////
253

    
254
  @SuppressWarnings("unused")
255
  public static void enableEffects()
256
    {
257
    Method method;
258

    
259
    for(Type type: Type.values())
260
      {
261
      try
262
        {
263
        method = type.effect.getDeclaredMethod("enable");  // enable not public, thus getDeclaredMethod
264
        }
265
      catch(NoSuchMethodException ex)
266
        {
267
        android.util.Log.e("SizeChangeEffect", type.effect.getSimpleName()+": exception getting method: "+ex.getMessage());
268
        method = null;
269
        }
270

    
271
      try
272
        {
273
        if( method!=null ) method.invoke(null);
274
        }
275
      catch(Exception ex)
276
        {
277
        android.util.Log.e("SizeChangeEffect", type.effect.getSimpleName()+": exception invoking method: "+ex.getMessage());
278
        }
279
      }
280
    }
281
}
(1-1/6)