Project

General

Profile

Download (7.91 KB) Statistics
| Branch: | Tag: | Revision:

magiccube / src / main / java / org / distorted / effect / UnscrambleEffect.java @ a8cbefce

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2019 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Distorted.                                                               //
5
//                                                                                               //
6
// Distorted 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
// Distorted 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 Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19

    
20
package org.distorted.effect;
21

    
22
///////////////////////////////////////////////////////////////////////////////////////////////////
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
import org.distorted.magic.RubikCube;
29

    
30
import java.lang.reflect.Method;
31

    
32
public abstract class UnscrambleEffect implements EffectListener
33
{
34
  public enum Type
35
    {
36
    NONE   (UnscrambleEffectNone.class),
37
    SPIN   (UnscrambleEffectSpin.class),
38
    ;
39

    
40
    final Class<? extends UnscrambleEffect> effect;
41

    
42
    Type(Class<? extends UnscrambleEffect> effect)
43
      {
44
      this.effect = effect;
45
      }
46
    }
47

    
48
  private static final int NUM_EFFECTS = Type.values().length;
49
  private static final int NUM_PHASES  = 2;
50
  private static final int FAKE_EFFECT_ID = -2;
51
  private static final Type[] types;
52

    
53
  static
54
    {
55
    int i=0;
56
    types = new Type[NUM_EFFECTS];
57

    
58
    for(Type type: Type.values())
59
      {
60
      types[i++] = type;
61
      }
62
    }
63

    
64
  private EffectListener mListener;
65
  private int mDuration;
66
  private int mEffectReturned;
67
  private int[] mCubeEffectNumber, mNodeEffectNumber;
68
  private int mPhase;
69

    
70
  RubikCube mCube;
71
  DistortedScreen mScreen;
72
  Effect[][] mCubeEffects;
73
  int[][] mCubeEffectPosition;
74
  Effect[][] mNodeEffects;
75
  int[][] mNodeEffectPosition;
76

    
77
///////////////////////////////////////////////////////////////////////////////////////////////////
78

    
79
  UnscrambleEffect()
80
    {
81
    mPhase        =  0;
82

    
83
    mCubeEffectNumber   = new int[NUM_PHASES];
84
    mNodeEffectNumber   = new int[NUM_PHASES];
85
    mCubeEffectPosition = new int[NUM_PHASES][];
86
    mNodeEffectPosition = new int[NUM_PHASES][];
87
    mCubeEffects        = new Effect[NUM_PHASES][];
88
    mNodeEffects        = new Effect[NUM_PHASES][];
89
    }
90

    
91
///////////////////////////////////////////////////////////////////////////////////////////////////
92

    
93
  public static Type getType(int ordinal)
94
    {
95
    return types[ordinal];
96
    }
97

    
98
///////////////////////////////////////////////////////////////////////////////////////////////////
99

    
100
  public static String[] getNames()
101
    {
102
    String[] names = new String[NUM_EFFECTS];
103

    
104
    for( int i=0; i<NUM_EFFECTS; i++)
105
      {
106
      names[i] = types[i].name();
107
      }
108

    
109
    return names;
110
    }
111

    
112
///////////////////////////////////////////////////////////////////////////////////////////////////
113

    
114
  public static UnscrambleEffect create(Type type) throws InstantiationException, IllegalAccessException
115
    {
116
    return type.effect.newInstance();
117
    }
118

    
119
///////////////////////////////////////////////////////////////////////////////////////////////////
120

    
121
  abstract void createEffectsPhase0(int duration);
122
  abstract void createEffectsPhase1(int duration);
123

    
124
///////////////////////////////////////////////////////////////////////////////////////////////////
125

    
126
  public void effectFinished(final long effectID)
127
    {
128
    int total = mCubeEffectNumber[mPhase]+mNodeEffectNumber[mPhase];
129

    
130
    for(int i=0; i<mCubeEffectNumber[mPhase]; i++)
131
      {
132
      long id = mCubeEffects[mPhase][i].getID();
133

    
134
      if( effectID == id )
135
        {
136
        if( ++mEffectReturned == total ) effectAction(mPhase);
137
        mCube.remove(id);
138
        return;
139
        }
140
      }
141
    for(int i=0; i<mNodeEffectNumber[mPhase]; i++)
142
      {
143
      long id = mNodeEffects[mPhase][i].getID();
144

    
145
      if( effectID == id )
146
        {
147
        if( ++mEffectReturned == total ) effectAction(mPhase);
148
        mCube.getEffects().abortById(id);
149
        return;
150
        }
151
      }
152
    }
153

    
154
///////////////////////////////////////////////////////////////////////////////////////////////////
155

    
156
  private void effectAction(int phase)
157
    {
158
    switch(phase)
159
      {
160
      case 0: mEffectReturned = 0;
161
              mPhase          = 1;
162
              mCube.unscramble();
163
              createEffectsPhase1(mDuration);
164
              assignEffects(mPhase);
165
              break;
166
      case 1: mListener.effectFinished(FAKE_EFFECT_ID);
167
              break;
168
      }
169
    }
170

    
171
///////////////////////////////////////////////////////////////////////////////////////////////////
172

    
173
  public long start(int duration, DistortedScreen screen, RubikCube cube, EffectListener listener)
174
    {
175
    mScreen   = screen;
176
    mCube     = cube;
177
    mListener = listener;
178
    mDuration = duration;
179

    
180
    createEffectsPhase0(mDuration);
181
    assignEffects(mPhase);
182

    
183
    return FAKE_EFFECT_ID;
184
    }
185

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

    
188
  private void assignEffects(int phase)
189
    {
190
    mCubeEffectNumber[phase] = ( mCubeEffects[phase]!=null ) ? mCubeEffects[phase].length : 0;
191
    mNodeEffectNumber[phase] = ( mNodeEffects[phase]!=null ) ? mNodeEffects[phase].length : 0;
192

    
193
    if( mCubeEffectNumber[phase]==0 && mNodeEffectNumber[phase]==0 )
194
      {
195
      throw new RuntimeException("Cube and Node Effects ("+phase+" phase) both not created!");
196
      }
197

    
198
    for(int i=0; i<mCubeEffectNumber[phase]; i++)
199
      {
200
      mCube.apply(mCubeEffects[phase][i],mCubeEffectPosition[phase][i]);
201
      mCubeEffects[phase][i].notifyWhenFinished(this);
202
      }
203

    
204
    DistortedEffects nodeEffects = mCube.getEffects();
205

    
206
    for(int i=0; i<mNodeEffectNumber[phase]; i++)
207
      {
208
      nodeEffects.apply(mNodeEffects[phase][i],mNodeEffectPosition[phase][i]);
209
      mNodeEffects[phase][i].notifyWhenFinished(this);
210
      }
211
    }
212

    
213
///////////////////////////////////////////////////////////////////////////////////////////////////
214

    
215
  @SuppressWarnings("unused")
216
  public static void enableEffects()
217
    {
218
    Method method;
219

    
220
    for(Type type: Type.values())
221
      {
222
      try
223
        {
224
        method = type.effect.getDeclaredMethod("enable"); // enable not public, thus getDeclaredMethod
225
        }
226
      catch(NoSuchMethodException ex)
227
        {
228
        android.util.Log.e("UnscrambleEffect", type.effect.getSimpleName()+": exception getting method: "+ex.getMessage());
229
        method = null;
230
        }
231

    
232
      try
233
        {
234
        if( method!=null ) method.invoke(null);
235
        }
236
      catch(Exception ex)
237
        {
238
        android.util.Log.e("UnscrambleEffect", type.effect.getSimpleName()+": exception invoking method: "+ex.getMessage());
239
        }
240
      }
241
    }
242
}
(7-7/9)