Project

General

Profile

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

library / src / main / java / org / distorted / library / EffectQueue.java @ 568b29d8

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 org.distorted.library.message.EffectListener;
23
import org.distorted.library.message.EffectMessage;
24
import org.distorted.library.type.Dynamic;
25
import org.distorted.library.type.Dynamic2D;
26

    
27
import java.util.Vector;
28

    
29
///////////////////////////////////////////////////////////////////////////////////////////////////
30

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

    
51
  protected Vector<EffectListener> mListeners =null;
52
  protected int mNumListeners=0;  // ==mListeners.length(), but we only create mListeners if the first one gets added
53
  protected long mBitmapID;
54

    
55
  private static boolean mCreated;
56

    
57
  static
58
    {
59
    reset();
60
    }
61
  
62
///////////////////////////////////////////////////////////////////////////////////////////////////
63
   
64
  public EffectQueue(DistortedObject obj, int numUniforms, int index)
65
    {
66
    mNumEffects   = 0;
67
    mTotalEffects = 0;
68
    mMaxIndex     = index;
69

    
70
    if( obj!=null )
71
      {
72
      mObjHalfX = obj.getWidth() / 2.0f;
73
      mObjHalfY = obj.getHeight() / 2.0f;
74
      mObjHalfZ = obj.getDepth() / 2.0f;
75

    
76
      mBitmapID = obj.getID();
77
      }
78

    
79
    if( mMax[mMaxIndex]>0 )
80
      {
81
      mType            = new int[mMax[mMaxIndex]];
82
      mUniforms        = new float[numUniforms*mMax[mMaxIndex]];
83
      mInterI          = new Dynamic[mMax[mMaxIndex]];
84
      mInterP          = new Dynamic2D[mMax[mMaxIndex]];
85
      mCurrentDuration = new long[mMax[mMaxIndex]];
86
      mID              = new long[mMax[mMaxIndex]];
87
      mIDIndex         = new byte[mMax[mMaxIndex]];
88
      mFreeIndexes     = new byte[mMax[mMaxIndex]];
89
     
90
      for(byte i=0; i<mMax[mMaxIndex]; i++) mFreeIndexes[i] = i;
91
      }
92
   
93
    mCreated = true;  
94
    }
95

    
96
///////////////////////////////////////////////////////////////////////////////////////////////////
97

    
98
  int getNumEffects()
99
    {
100
    return mNumEffects;  
101
    }
102

    
103
///////////////////////////////////////////////////////////////////////////////////////////////////
104
// Only max Byte.MAX_VALUE concurrent effects per DistortedObject.
105
// If you want more, change type of the mNumEffects, mIDIndex and mFreeIndexes variables to shorts.
106

    
107
  static boolean setMax(int index, int m)
108
    {
109
    if( (mCreated==false && !Distorted.isInitialized()) || m<=mMax[index] )
110
      {
111
      if( m<0              ) m = 0;
112
      else if( m>Byte.MAX_VALUE ) m = Byte.MAX_VALUE;
113

    
114
      mMax[index] = m;
115
      return true;
116
      }
117

    
118
    return false;
119
    }
120

    
121
///////////////////////////////////////////////////////////////////////////////////////////////////
122

    
123
  static int getMax(int index)
124
    {
125
    return mMax[index];
126
    }
127

    
128
///////////////////////////////////////////////////////////////////////////////////////////////////
129

    
130
  void addListener(EffectListener el)
131
    {
132
    if( mListeners==null ) mListeners = new Vector<>(2,2);
133
   
134
    mListeners.add(el);
135
    mNumListeners++;
136
    }
137
 
138
///////////////////////////////////////////////////////////////////////////////////////////////////
139

    
140
  void removeListener(EffectListener el)
141
    {
142
    if( mNumListeners>0 )  
143
      {
144
      mListeners.remove(el);
145
      mNumListeners--;
146
      }
147
    }
148

    
149
///////////////////////////////////////////////////////////////////////////////////////////////////
150

    
151
  static void reset()
152
    {
153
    EffectTypes.reset(mMax);
154
    mCreated = false;  
155
    }
156
 
157
///////////////////////////////////////////////////////////////////////////////////////////////////
158

    
159
  synchronized int removeByID(long id)
160
    {
161
    int i = getEffectIndex(id);
162
   
163
    if( i>=0 ) 
164
      {
165
      remove(i);
166
      return 1;
167
      }
168
   
169
    return 0;
170
    }
171

    
172
///////////////////////////////////////////////////////////////////////////////////////////////////
173

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

    
200
///////////////////////////////////////////////////////////////////////////////////////////////////
201
  
202
  synchronized int abortAll()
203
    {
204
    int ret = mNumEffects;
205

    
206
    for(int i=0; i<ret; i++ )
207
      {
208
      mInterI[i] = null;
209
      mInterP[i] = null;
210
      }
211

    
212
    mNumEffects= 0;
213

    
214
    return ret;
215
    }
216

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

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

    
336
    return false;  
337
    }
338
 
339
///////////////////////////////////////////////////////////////////////////////////////////////////
340

    
341
  abstract void moveEffect(int index);
342
  }
343
///////////////////////////////////////////////////////////////////////////////////////////////////
(13-13/17)