Project

General

Profile

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

library / src / main / java / org / distorted / library / effect / Effect.java @ 8c57d77b

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2017 Leszek Koltunski  leszek@koltunski.pl                                          //
3
//                                                                                               //
4
// This file is part of Distorted.                                                               //
5
//                                                                                               //
6
// This library is free software; you can redistribute it and/or                                 //
7
// modify it under the terms of the GNU Lesser General Public                                    //
8
// License as published by the Free Software Foundation; either                                  //
9
// version 2.1 of the License, or (at your option) any later version.                            //
10
//                                                                                               //
11
// This library 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 GNU                             //
14
// Lesser General Public License for more details.                                               //
15
//                                                                                               //
16
// You should have received a copy of the GNU Lesser General Public                              //
17
// License along with this library; if not, write to the Free Software                           //
18
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA                //
19
///////////////////////////////////////////////////////////////////////////////////////////////////
20

    
21
package org.distorted.library.effect;
22

    
23
import org.distorted.library.effectqueue.EffectQueue;
24
import org.distorted.library.main.DistortedLibrary;
25
import org.distorted.library.main.InternalStackFrameList;
26
import org.distorted.library.message.EffectListener;
27

    
28
import java.lang.reflect.Method;
29
import java.util.ArrayList;
30

    
31
///////////////////////////////////////////////////////////////////////////////////////////////////
32
/**
33
 * Abstract Effect of any type.
34
 */
35
public abstract class Effect
36
  {
37
  private final static int MAX_UNITY_DIM = 4;
38
  private final static int NUM_EFFECTS = EffectName.LENGTH;
39

    
40
  private final long mID;
41
  private final EffectType mType;
42
  private final EffectName mName;
43
  private final int mDimension;
44
  private final int mRegionDim;
45
  private final int mCenterDim;
46

    
47
  private ArrayList<EffectListener> mListeners =null;
48
  private int mNumListeners=0;  // ==mListeners.length(), but we only create mListeners if the first one gets added
49

    
50
  private final static float[] mUnity= new float[MAX_UNITY_DIM*NUM_EFFECTS];
51
  private final static int[]   mUnityDim = new int[NUM_EFFECTS];
52

    
53
  int mAndAssociation;
54
  int mEquAssociation;
55

    
56
  static boolean[] mEnabled = new boolean[NUM_EFFECTS];
57

    
58
  static
59
    {
60
    for(int i=0; i<NUM_EFFECTS; i++) mEnabled[i] = false;
61
    }
62

    
63
///////////////////////////////////////////////////////////////////////////////////////////////////
64

    
65
  public abstract void addQueue(EffectQueue queue);
66
  public abstract void remQueue(EffectQueue queue);
67

    
68
///////////////////////////////////////////////////////////////////////////////////////////////////
69

    
70
  Effect(EffectName name)
71
    {
72
    mName      = name;
73
    mType      = name.getType();
74
    mDimension = name.getEffectDimension();
75
    mCenterDim = name.getCenterDimension();
76
    mRegionDim = name.getRegionDimension();
77

    
78
    mAndAssociation = 0xffffffff;
79
    mEquAssociation = 0;
80

    
81
    int n = name.ordinal();
82
    float[] u = name.getUnity();
83
    int l = u.length;
84

    
85
    System.arraycopy(u, 0, mUnity, MAX_UNITY_DIM*n, l);
86

    
87
    mUnityDim[n] = l;
88

    
89
    mID = (InternalStackFrameList.getNextEffectID()<<EffectType.LENGTH) + mType.ordinal();
90
    }
91

    
92
///////////////////////////////////////////////////////////////////////////////////////////////////
93
/**
94
 * Only for use by the library itself.
95
 *
96
 * @y.exclude
97
 */
98
  public static void onPause()
99
    {
100
    for(int i=0; i<NUM_EFFECTS; i++) mEnabled[i] = false;
101

    
102
    MatrixEffect.destroyStatics();
103
    VertexEffect.destroyStatics();
104
    FragmentEffect.destroyStatics();
105
    PostprocessEffect.destroyStatics();
106
    }
107

    
108
///////////////////////////////////////////////////////////////////////////////////////////////////
109
/**
110
 * Only for use by the library itself.
111
 *
112
 * @y.exclude
113
 */
114
  public abstract boolean compute(float[] uniforms, int index, long currentDuration, long step );
115

    
116
///////////////////////////////////////////////////////////////////////////////////////////////////
117
/**
118
 * Only for use by the library itself.
119
 *
120
 * @y.exclude
121
 */
122
  public int getNumListeners()
123
    {
124
    return mNumListeners;
125
    }
126

    
127
///////////////////////////////////////////////////////////////////////////////////////////////////
128
/**
129
 * Only for use by the library itself.
130
 *
131
 * @y.exclude
132
 */
133
  public EffectListener removeFirstListener()
134
    {
135
    if( mNumListeners>0 )
136
      {
137
      mNumListeners--;
138
      return mListeners.remove(0);
139
      }
140

    
141
    return null;
142
    }
143

    
144
///////////////////////////////////////////////////////////////////////////////////////////////////
145
/**
146
 * Only for use by the library itself.
147
 *
148
 * @y.exclude
149
 */
150
  public void writeAssociations(int[] intUniforms, int index1, int index2)
151
    {
152
    intUniforms[index1] = mAndAssociation;
153
    intUniforms[index2] = mEquAssociation;
154
    }
155

    
156
///////////////////////////////////////////////////////////////////////////////////////////////////
157
// PUBLIC API
158
///////////////////////////////////////////////////////////////////////////////////////////////////
159
/**
160
 * Do the set of Uniforms written in buffer[index], buffer[index+1], etc represent a Unity, i.e a
161
 * null Effect?
162
 */
163
  public boolean isUnity(float[] buffer, int index)
164
    {
165
    int name = mName.ordinal();
166

    
167
    switch(mUnityDim[name])
168
      {
169
      case 0: return true;
170
      case 1: return buffer[index  ]==mUnity[MAX_UNITY_DIM*name  ];
171
      case 2: return buffer[index  ]==mUnity[MAX_UNITY_DIM*name  ] &&
172
                     buffer[index+1]==mUnity[MAX_UNITY_DIM*name+1];
173
      case 3: return buffer[index  ]==mUnity[MAX_UNITY_DIM*name  ] &&
174
                     buffer[index+1]==mUnity[MAX_UNITY_DIM*name+1] &&
175
                     buffer[index+2]==mUnity[MAX_UNITY_DIM*name+2];
176
      case 4: return buffer[index  ]==mUnity[MAX_UNITY_DIM*name  ] &&
177
                     buffer[index+1]==mUnity[MAX_UNITY_DIM*name+1] &&
178
                     buffer[index+2]==mUnity[MAX_UNITY_DIM*name+2] &&
179
                     buffer[index+3]==mUnity[MAX_UNITY_DIM*name+3];
180
      }
181

    
182
    return false;
183
    }
184

    
185
///////////////////////////////////////////////////////////////////////////////////////////////////
186
// this will enable() all Fragment Effects twice (once for smooth variant, once for non-smooth)
187
// but this shouldn't matter.
188
/**
189
 * Enable all effects of a given type.
190
 *
191
 * @param type EffectType to enable.
192
 */
193
  public static void enableEffects(EffectType type)
194
    {
195
    Method method;
196

    
197
    for(EffectName name: EffectName.values())
198
      {
199
      if( name.getType() == type )
200
        {
201
        Class<? extends Effect> cls = name.getEffectClass();
202

    
203
        try
204
          {
205
          method = cls.getMethod("enable");  // getMethod and NOT getDeclaredMethod because enable()
206
                                             // is public
207
          }
208
        catch(NoSuchMethodException ex)
209
          {
210
          DistortedLibrary.logMessage("Effect: exception getting method: "+ex.getMessage());
211
          method = null;
212
          }
213

    
214
        try
215
          {
216
          if( method!=null ) method.invoke(null);
217
          }
218
        catch(Exception ex)
219
          {
220
          DistortedLibrary.logMessage("Effect: exception invoking method: "+ex.getMessage());
221
          }
222
        }
223
      }
224
    }
225

    
226
///////////////////////////////////////////////////////////////////////////////////////////////////
227
/**
228
 * Return the EffectType enum corresponding to this Effect.
229
 *
230
 * @see EffectType
231
 */
232
  public EffectType getType()
233
    {
234
    return mType;
235
    }
236

    
237
///////////////////////////////////////////////////////////////////////////////////////////////////
238
/**
239
 * Return the EffectName enum corresponding to this Effect.
240
 *
241
 * @see EffectName
242
 */
243
  public EffectName getName()
244
    {
245
    return mName;
246
    }
247

    
248
///////////////////////////////////////////////////////////////////////////////////////////////////
249
/**
250
 * Return the unique ID of this Effect.
251
 */
252
  public long getID()
253
    {
254
    return mID;
255
    }
256

    
257
///////////////////////////////////////////////////////////////////////////////////////////////////
258
/**
259
 * Return a printable name of this Effect.
260
 */
261
  public String getString()
262
    {
263
    return mName.name();
264
    }
265

    
266
///////////////////////////////////////////////////////////////////////////////////////////////////
267
/**
268
 * Return the dimension of the Center supported by this effect (0- no center supported at all).
269
 */
270
  public int getCenterDimension()
271
    {
272
    return mCenterDim;
273
    }
274

    
275
///////////////////////////////////////////////////////////////////////////////////////////////////
276
/**
277
 * Return the dimension of the Region supported by this effect (0- no region supported at all).
278
 */
279
  public int getRegionDimension()
280
    {
281
    return mRegionDim;
282
    }
283

    
284
///////////////////////////////////////////////////////////////////////////////////////////////////
285
/**
286
 * Return the number of Uniforms needed to describe this effect.
287
 */
288
  public int getEffectDimension()
289
    {
290
    return mDimension;
291
    }
292

    
293
///////////////////////////////////////////////////////////////////////////////////////////////////
294
/**
295
 * Adds the calling class to the list of Listeners that get notified when this Effect gets 'finished'
296
 * i.e. when the Dynamic inside this Effect reaches its final point and stops moving. This will be sent
297
 * only once, on the first time the Dynamic reaches its final point.
298
 *
299
 * If there's no Dynamic, ths message will never be sent.
300
 *
301
 * @param el A class implementing the EffectListener interface that wants to get notifications.
302
 */
303
  public void notifyWhenFinished(EffectListener el)
304
    {
305
    if( mListeners==null ) mListeners = new ArrayList<>();
306

    
307
    if( !mListeners.contains(el) )
308
      {
309
      mListeners.add(el);
310
      mNumListeners++;
311
      }
312
    }
313
  }
(1-1/34)