Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / effects / objectchange / ObjectChangeEffect.java @ 02d80fe6

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2019 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.effects.objectchange;
21

    
22
import java.lang.reflect.Method;
23

    
24
import org.distorted.library.effect.Effect;
25
import org.distorted.library.main.DistortedEffects;
26
import org.distorted.library.main.DistortedScreen;
27
import org.distorted.library.message.EffectListener;
28

    
29
import org.distorted.objectlib.main.ObjectPreRender;
30
import org.distorted.objectlib.main.TwistyObject;
31
import org.distorted.objectlib.effects.BaseEffect;
32

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

    
35
public abstract class ObjectChangeEffect extends BaseEffect implements EffectListener
36
{
37
  public enum Type
38
    {
39
    NONE         (ObjectChangeEffectNone.class        ),
40
    TRANSPARENCY (ObjectChangeEffectTransparency.class),
41
    MOVE         (ObjectChangeEffectMove.class        ),
42
    ROUND        (ObjectChangeEffectRound.class       ),
43
    SCALE        (ObjectChangeEffectScale.class       ),
44
    ;
45

    
46
    final Class<? extends ObjectChangeEffect> effect;
47

    
48
    Type(Class<? extends ObjectChangeEffect> effect)
49
      {
50
      this.effect= effect;
51
      }
52
    }
53

    
54
  private static final int NUM_EFFECTS = Type.values().length;
55
  private static final int NUM_PHASES  = 2;
56
  private static final int FAKE_EFFECT_ID  = -1;
57
  private static final Type[] types;
58

    
59
  static
60
    {
61
    int i=0;
62
    types = new Type[NUM_EFFECTS];
63

    
64
    for(Type type: Type.values())
65
      {
66
      types[i++] = type;
67
      }
68
    }
69

    
70
  private int mDuration;
71
  private final int[] mEffectReturned;
72
  private final int[] mCubeEffectNumber, mNodeEffectNumber;
73
  private final int[] mEffectFinished;
74
  private final boolean[] mPhaseActive;
75

    
76
  ObjectPreRender mPre;
77
  TwistyObject[] mObject;
78
  DistortedScreen mScreen;
79
  Effect[][] mCubeEffects;
80
  int[][] mCubeEffectPosition;
81
  Effect[][] mNodeEffects;
82
  int[][] mNodeEffectPosition;
83

    
84
///////////////////////////////////////////////////////////////////////////////////////////////////
85

    
86
  ObjectChangeEffect()
87
    {
88
    mPhaseActive        = new boolean[NUM_PHASES];
89
    mEffectReturned     = new int[NUM_PHASES];
90
    mCubeEffectNumber   = new int[NUM_PHASES];
91
    mNodeEffectNumber   = new int[NUM_PHASES];
92
    mEffectFinished     = new int[NUM_PHASES];
93
    mCubeEffectPosition = new int[NUM_PHASES][];
94
    mNodeEffectPosition = new int[NUM_PHASES][];
95
    mCubeEffects        = new Effect[NUM_PHASES][];
96
    mNodeEffects        = new Effect[NUM_PHASES][];
97
    mObject             = new TwistyObject[NUM_PHASES];
98
    }
99

    
100
///////////////////////////////////////////////////////////////////////////////////////////////////
101

    
102
  abstract int createEffectsPhase0(int duration);
103
  abstract int createEffectsPhase1(int duration);
104

    
105
///////////////////////////////////////////////////////////////////////////////////////////////////
106

    
107
  private void effectFinishedPhase(final long effectID, int phase)
108
    {
109
    for(int i=0; i<mCubeEffectNumber[phase]; i++)
110
      {
111
      long id = mCubeEffects[phase][i].getID();
112

    
113
      if( effectID == id )
114
        {
115
        effectReturned(phase);
116
        mObject[phase].remove(id);
117
        return;
118
        }
119
      }
120
    for(int i=0; i<mNodeEffectNumber[phase]; i++)
121
      {
122
      long id = mNodeEffects[phase][i].getID();
123

    
124
      if( effectID == id )
125
        {
126
        effectReturned(phase);
127
        mObject[phase].getEffects().abortById(id);
128
        return;
129
        }
130
      }
131
    }
132

    
133
///////////////////////////////////////////////////////////////////////////////////////////////////
134

    
135
  private void effectReturned(int phase)
136
    {
137
    mEffectReturned[phase]++;
138

    
139
    if( mEffectReturned[phase] == mEffectFinished[phase] )
140
      {
141
      switch(phase)
142
        {
143
        case 0: mPhaseActive[1] = true;
144
                mEffectFinished[1] = createEffectsPhase1(mDuration);
145
                assignEffects(1);
146
                mScreen.attach(mObject[1]);
147
                break;
148
        case 1: mPre.effectFinished(FAKE_EFFECT_ID);
149
                break;
150
        }
151
      }
152
    if( mEffectReturned[phase] == mCubeEffectNumber[phase]+mNodeEffectNumber[phase] )
153
      {
154
      switch(phase)
155
        {
156
        case 0: mPhaseActive[0] = false;
157
                mScreen.detach(mObject[0]);
158
                break;
159
        case 1: mPhaseActive[1] = false;
160
                break;
161
        }
162
      }
163
    }
164

    
165
///////////////////////////////////////////////////////////////////////////////////////////////////
166

    
167
  private void assignEffects(int phase)
168
    {
169
    mCubeEffectNumber[phase] = ( mCubeEffects[phase]!=null ) ? mCubeEffects[phase].length : 0;
170
    mNodeEffectNumber[phase] = ( mNodeEffects[phase]!=null ) ? mNodeEffects[phase].length : 0;
171

    
172
    if( mCubeEffectNumber[phase]==0 && mNodeEffectNumber[phase]==0 )
173
      {
174
      throw new RuntimeException("Cube and Node Effects ("+phase+" phase) both not created!");
175
      }
176

    
177
    for(int i=0; i<mCubeEffectNumber[phase]; i++)
178
      {
179
      mObject[phase].apply(mCubeEffects[phase][i],mCubeEffectPosition[phase][i]);
180
      mCubeEffects[phase][i].notifyWhenFinished(this);
181
      }
182

    
183
    DistortedEffects nodeEffects = mObject[phase].getEffects();
184

    
185
    for(int i=0; i<mNodeEffectNumber[phase]; i++)
186
      {
187
      nodeEffects.apply(mNodeEffects[phase][i],mNodeEffectPosition[phase][i]);
188
      mNodeEffects[phase][i].notifyWhenFinished(this);
189
      }
190
    }
191

    
192
///////////////////////////////////////////////////////////////////////////////////////////////////
193
// PUBLIC API
194
///////////////////////////////////////////////////////////////////////////////////////////////////
195

    
196
  public void effectFinished(final long effectID)
197
    {
198
    if( mPhaseActive[0] ) effectFinishedPhase(effectID,0);
199
    if( mPhaseActive[1] ) effectFinishedPhase(effectID,1);
200
    }
201

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

    
204
  @SuppressWarnings("unused")
205
  public static String[] getNames()
206
    {
207
    String[] names = new String[NUM_EFFECTS];
208

    
209
    for( int i=0; i<NUM_EFFECTS; i++)
210
      {
211
      names[i] = types[i].name();
212
      }
213

    
214
    return names;
215
    }
216

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

    
219
  @SuppressWarnings("unused")
220
  public static ObjectChangeEffect create(int ordinal) throws InstantiationException, IllegalAccessException
221
    {
222
    return types[ordinal].effect.newInstance();
223
    }
224

    
225
///////////////////////////////////////////////////////////////////////////////////////////////////
226

    
227
  @SuppressWarnings("unused")
228
  public long start(int duration, DistortedScreen screen, ObjectPreRender pre)
229
    {
230
    mScreen    = screen;
231
    mObject[0] = pre.getOldObject();
232
    mObject[1] = pre.getObject();
233
    mPre       = pre;
234
    mDuration  = duration;
235

    
236
    if( mObject[0]!=null )
237
      {
238
      mPhaseActive[0] = true;
239
      mEffectFinished[0] = createEffectsPhase0(mDuration);
240
      assignEffects(0);
241
      }
242
    else
243
      {
244
      mPhaseActive[1] = true;
245
      mEffectFinished[1] = createEffectsPhase1(mDuration);
246
      assignEffects(1);
247
      mScreen.attach(mObject[1]);
248
      }
249

    
250
    return FAKE_EFFECT_ID;
251
    }
252

    
253
///////////////////////////////////////////////////////////////////////////////////////////////////
254

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

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

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