Project

General

Profile

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

library / src / main / java / org / distorted / library / EffectQueue.java @ d333eb6b

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2016 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.library;
21

    
22
import java.util.Vector;
23

    
24
///////////////////////////////////////////////////////////////////////////////////////////////////
25

    
26
abstract class EffectQueue
27
  {
28
  protected byte mNumEffects;   // number of effects at the moment
29
  protected long mTotalEffects; // total number of effects ever created
30
  
31
  protected int[] mType;
32
  protected float[] mUniforms;
33
  protected Interpolator[] mInterP;  // center of the effect
34
  protected Interpolator[] mInterI;  // all other interpolated values
35
  protected long[] mCurrentDuration;
36
  protected byte[] mFreeIndexes;
37
  protected byte[] mIDIndex;
38
  protected long[] mID;
39
  
40
  protected long mTime=0;
41
  protected float mObjHalfX, mObjHalfY, mObjHalfZ;
42
  
43
  protected static int[] mMax = new int[EffectTypes.LENGTH];
44
  protected int mMaxIndex;
45

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

    
50
  private static boolean mCreated;
51

    
52
  static
53
    {
54
    reset();
55
    }
56
  
57
///////////////////////////////////////////////////////////////////////////////////////////////////
58
   
59
  public EffectQueue(DistortedObject obj, int numUniforms, int index)
60
    {
61
    mNumEffects   = 0;
62
    mTotalEffects = 0;
63
    mMaxIndex     = index;
64

    
65
    if( obj!=null )
66
      {
67
      mObjHalfX = obj.getWidth() / 2.0f;
68
      mObjHalfY = obj.getHeight() / 2.0f;
69
      mObjHalfZ = obj.getDepth() / 2.0f;
70

    
71
      mBitmapID = obj.getID();
72
      }
73

    
74
    if( mMax[mMaxIndex]>0 )
75
      {
76
      mType            = new int[mMax[mMaxIndex]];
77
      mUniforms        = new float[numUniforms*mMax[mMaxIndex]];
78
      mInterI          = new Interpolator[mMax[mMaxIndex]];
79
      mInterP          = new Interpolator2D[mMax[mMaxIndex]];
80
      mCurrentDuration = new long[mMax[mMaxIndex]];
81
      mID              = new long[mMax[mMaxIndex]];
82
      mIDIndex         = new byte[mMax[mMaxIndex]];
83
      mFreeIndexes     = new byte[mMax[mMaxIndex]];
84
     
85
      for(byte i=0; i<mMax[mMaxIndex]; i++) mFreeIndexes[i] = i;
86
      }
87
   
88
    mCreated = true;  
89
    }
90

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

    
93
  int getNumEffects()
94
    {
95
    return mNumEffects;  
96
    }
97

    
98
///////////////////////////////////////////////////////////////////////////////////////////////////
99
// Only max Byte.MAX_VALUE concurrent effects per DistortedObject.
100
// If you want more, change type of the mNumEffects, mIDIndex and mFreeIndexes variables to shorts.
101

    
102
  static boolean setMax(int index, int m)
103
    {
104
    if( (mCreated==false && !Distorted.isInitialized()) || m<=mMax[index] )
105
      {
106
      if( m<0              ) m = 0;
107
      else if( m>Byte.MAX_VALUE ) m = Byte.MAX_VALUE;
108

    
109
      mMax[index] = m;
110
      return true;
111
      }
112

    
113
    return false;
114
    }
115

    
116
///////////////////////////////////////////////////////////////////////////////////////////////////
117

    
118
  static int getMax(int index)
119
    {
120
    return mMax[index];
121
    }
122

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

    
125
  void addListener(EffectListener el)
126
    {
127
    if( mListeners==null ) mListeners = new Vector<>(2,2);
128
   
129
    mListeners.add(el);
130
    mNumListeners++;
131
    }
132
 
133
///////////////////////////////////////////////////////////////////////////////////////////////////
134

    
135
  void removeListener(EffectListener el)
136
    {
137
    if( mNumListeners>0 )  
138
      {
139
      mListeners.remove(el);
140
      mNumListeners--;
141
      }
142
    }
143

    
144
///////////////////////////////////////////////////////////////////////////////////////////////////
145

    
146
  static void reset()
147
    {
148
    EffectTypes.reset(mMax);
149
    mCreated = false;  
150
    }
151
 
152
///////////////////////////////////////////////////////////////////////////////////////////////////
153

    
154
  synchronized int removeByID(long id)
155
    {
156
    int i = getEffectIndex(id);
157
   
158
    if( i>=0 ) 
159
      {
160
      remove(i);
161
      return 1;
162
      }
163
   
164
    return 0;
165
    }
166

    
167
///////////////////////////////////////////////////////////////////////////////////////////////////
168

    
169
  synchronized int removeByType(EffectNames effect)
170
    {
171
    int ret = 0;
172
    int ord = effect.ordinal();  
173
     
174
    for(int i=0; i<mNumEffects; i++)
175
      {
176
      if( mType[i]==ord )
177
        {
178
        remove(i);
179
        i--;
180
        ret++;
181
        }
182
      }
183
   
184
    return ret;
185
    }
186
  
187
///////////////////////////////////////////////////////////////////////////////////////////////////
188
  
189
  private synchronized int getEffectIndex(long id)
190
    {
191
    int index = mIDIndex[(int)(id%mMax[mMaxIndex])];
192
    return (index<mNumEffects && mID[index]==id ? index : -1);
193
    }
194

    
195
///////////////////////////////////////////////////////////////////////////////////////////////////
196
  
197
  synchronized int abortAll()
198
    {
199
    int ret = mNumEffects;
200

    
201
    for(int i=0; i<ret; i++ )
202
      {
203
      mInterI[i] = null;
204
      mInterP[i] = null;
205
      }
206

    
207
    mNumEffects= 0;
208

    
209
    return ret;
210
    }
211

    
212
///////////////////////////////////////////////////////////////////////////////////////////////////
213
// this assumes 0<=effect<mNumEffects
214
  
215
  protected void remove(int effect)
216
    {
217
    mNumEffects--;     
218
    
219
    byte removedIndex = (byte)(mID[effect]%mMax[mMaxIndex]);
220
    byte removedPosition = mIDIndex[removedIndex];
221
    mFreeIndexes[mNumEffects] = removedIndex;
222
    
223
    long removedID = mID[effect];
224
    int removedType= mType[effect];
225
    
226
    for(int j=0; j<mMax[mMaxIndex]; j++)
227
      {
228
      if( mIDIndex[j] > removedPosition ) mIDIndex[j]--; 
229
      }
230
         
231
    for(int j=effect; j<mNumEffects; j++ ) 
232
      {
233
      mType[j]            = mType[j+1];
234
      mInterI[j]          = mInterI[j+1];
235
      mInterP[j]          = mInterP[j+1];
236
      mCurrentDuration[j] = mCurrentDuration[j+1];
237
      mID[j]              = mID[j+1];
238
    
239
      moveEffect(j);
240
      }
241
   
242
    mInterI[mNumEffects] = null;
243
    mInterP[mNumEffects] = null;
244
   
245
    for(int i=0; i<mNumListeners; i++) 
246
      EffectMessageSender.newMessage( mListeners.elementAt(i),
247
                                      EffectMessage.EFFECT_REMOVED, 
248
                                      (removedID<<EffectTypes.LENGTH)+EffectNames.getType(removedType).type,
249
                                      removedType,
250
                                      mBitmapID,
251
                                      null);
252
    }
253
  
254
///////////////////////////////////////////////////////////////////////////////////////////////////
255
  
256
  protected long addBase(EffectNames eln)
257
    {    
258
    mType[mNumEffects]  = eln.ordinal();  
259
    mCurrentDuration[mNumEffects] = 0;
260
    
261
    int index = mFreeIndexes[mNumEffects];
262
    long id = mTotalEffects*mMax[mMaxIndex] + index;
263
    mID[mNumEffects] = id;
264
    mIDIndex[index] = mNumEffects;  
265
   
266
    mNumEffects++; 
267
    mTotalEffects++;
268
   
269
    return (id<<EffectTypes.LENGTH)+eln.getType().type;
270
    }
271
    
272
///////////////////////////////////////////////////////////////////////////////////////////////////
273
// used only for debugging
274
  
275
  protected String printEffects(int max)
276
    {
277
    long[] indexes = new long[mMax[mMaxIndex]];
278
   
279
    for(int g=0; g<mMax[mMaxIndex]; g++)
280
      {
281
      indexes[g] = -1;  
282
      }
283
   
284
    String ret="(";
285
    int f;
286
   
287
    for(int g=0; g<max; g++) 
288
      {
289
      f = getEffectIndex(g);
290
      if( f>=0 ) indexes[f] = g;
291
      }
292
   
293
    for(int g=0; g<mMax[mMaxIndex]; g++)
294
      {
295
      ret += (g>0 ? ",":"")+(indexes[g]>=0 ? indexes[g] : " ");   
296
      }
297
   
298
    ret += ")";
299
   
300
    return ret;
301
    }
302

    
303
///////////////////////////////////////////////////////////////////////////////////////////////////
304
// Only used for debugging
305
  
306
  protected boolean printByID(long id)
307
    {
308
    int index = getEffectIndex(id);
309
   
310
    if( index>=0 ) 
311
      {
312
      boolean interI = mInterI[index]==null; 
313
      boolean interP = mInterP[index]==null; 
314
      
315
      android.util.Log.e("EffectQueue", "numEffects="+mNumEffects+" effect id="+id+" index="+index+" duration="+mCurrentDuration[index]+" interI null="+interI+" interP null="+interP);
316
      
317
      if( interI==false )
318
        {
319
        android.util.Log.e("EffectQueue","interI: "+mInterI[index].print());
320
        }
321
      if( interP==false )
322
        {
323
        android.util.Log.e("EffectQueue","interP: "+mInterP[index].print());
324
        }
325
     
326
      return true;
327
      }
328
   
329
    android.util.Log.e("EffectQueue", "effect id="+id+" not found");
330

    
331
    return false;  
332
    }
333
 
334
///////////////////////////////////////////////////////////////////////////////////////////////////
335

    
336
  abstract void moveEffect(int index);
337
  }
338
///////////////////////////////////////////////////////////////////////////////////////////////////
(12-12/30)