Project

General

Profile

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

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

1 d333eb6b Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
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 fe82a979 Leszek Koltunski
package org.distorted.library.main;
21 6a06a912 Leszek Koltunski
22 fe82a979 Leszek Koltunski
import org.distorted.library.effect.Effect;
23 e458a4ba Leszek Koltunski
import org.distorted.library.message.EffectListener;
24
import org.distorted.library.message.EffectMessage;
25 568b29d8 Leszek Koltunski
import org.distorted.library.type.Dynamic;
26 a4835695 Leszek Koltunski
27 6a06a912 Leszek Koltunski
import java.util.Vector;
28
29
///////////////////////////////////////////////////////////////////////////////////////////////////
30
31 d07f2950 Leszek Koltunski
abstract class EffectQueue
32 6a06a912 Leszek Koltunski
  {
33
  protected byte mNumEffects;   // number of effects at the moment
34
  protected long mTotalEffects; // total number of effects ever created
35 e8c81a8e Leszek Koltunski
  protected int[] mName;
36 310e14fb leszek
  protected int[] mType;
37 6a06a912 Leszek Koltunski
  protected float[] mUniforms;
38 0a046359 Leszek Koltunski
  protected float[] mCache;
39 0318e7e3 Leszek Koltunski
  protected Dynamic[][] mInter;
40 6a06a912 Leszek Koltunski
  protected long[] mCurrentDuration;
41
  protected byte[] mFreeIndexes;
42
  protected byte[] mIDIndex;
43
  protected long[] mID;
44
  protected long mTime=0;
45 310e14fb leszek
  protected static int[] mMax = new int[Effect.LENGTH];
46 6a06a912 Leszek Koltunski
  protected int mMaxIndex;
47
  protected Vector<EffectListener> mListeners =null;
48
  protected int mNumListeners=0;  // ==mListeners.length(), but we only create mListeners if the first one gets added
49 65362dd4 Leszek Koltunski
  protected long mObjectID;
50 71887484 Leszek Koltunski
51
  private static boolean mCreated;
52
53 6a06a912 Leszek Koltunski
  static
54
    {
55 7b8086eb Leszek Koltunski
    onDestroy();
56 6a06a912 Leszek Koltunski
    }
57
  
58
///////////////////////////////////////////////////////////////////////////////////////////////////
59
   
60 0a046359 Leszek Koltunski
  EffectQueue(long id, int numUniforms, int numCache, int index)
61 6a06a912 Leszek Koltunski
    {
62
    mNumEffects   = 0;
63
    mTotalEffects = 0;
64
    mMaxIndex     = index;
65 0a046359 Leszek Koltunski
    mObjectID     = id;
66 1e438fc7 Leszek Koltunski
67 4c1dd6e9 Leszek Koltunski
    int max = mMax[mMaxIndex];
68
69
    if( max>0 )
70 6a06a912 Leszek Koltunski
      {
71 4c1dd6e9 Leszek Koltunski
      mName            = new int[max];
72 310e14fb leszek
      mType            = new int[max];
73 4c1dd6e9 Leszek Koltunski
      mUniforms        = new float[numUniforms*max];
74
      mInter           = new Dynamic[3][max];
75
      mCurrentDuration = new long[max];
76
      mID              = new long[max];
77
      mIDIndex         = new byte[max];
78
      mFreeIndexes     = new byte[max];
79 6a06a912 Leszek Koltunski
     
80 4c1dd6e9 Leszek Koltunski
      for(byte i=0; i<max; i++) mFreeIndexes[i] = i;
81 0a046359 Leszek Koltunski
82
      if( numCache>0 )
83
        {
84 4c1dd6e9 Leszek Koltunski
        mCache = new float[numCache*max];
85 0a046359 Leszek Koltunski
        }
86 6a06a912 Leszek Koltunski
      }
87
   
88
    mCreated = true;  
89
    }
90
91
///////////////////////////////////////////////////////////////////////////////////////////////////
92
93 24d22f93 Leszek Koltunski
  @SuppressWarnings("unused")
94 6a06a912 Leszek Koltunski
  int getNumEffects()
95
    {
96
    return mNumEffects;  
97
    }
98
99 71887484 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
100 cacc63de Leszek Koltunski
// Only max Byte.MAX_VALUE concurrent effects per DistortedEffects object.
101 71887484 Leszek Koltunski
// If you want more, change type of the mNumEffects, mIDIndex and mFreeIndexes variables to shorts.
102 cacc63de Leszek Koltunski
// (although probably this many uniforms will not fit in the shaders anyway!)
103 71887484 Leszek Koltunski
104
  static boolean setMax(int index, int m)
105
    {
106 8e34674e Leszek Koltunski
    if( (!mCreated && !Distorted.isInitialized()) || m<=mMax[index] )
107 71887484 Leszek Koltunski
      {
108
      if( m<0              ) m = 0;
109
      else if( m>Byte.MAX_VALUE ) m = Byte.MAX_VALUE;
110
111
      mMax[index] = m;
112
      return true;
113
      }
114
115
    return false;
116
    }
117
118
///////////////////////////////////////////////////////////////////////////////////////////////////
119
120
  static int getMax(int index)
121
    {
122
    return mMax[index];
123
    }
124
125 6a06a912 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
126
127 3fc994b2 Leszek Koltunski
  void registerForMessages(EffectListener el)
128 6a06a912 Leszek Koltunski
    {
129 b3618cb5 Leszek Koltunski
    if( mListeners==null ) mListeners = new Vector<>(2,2);
130 452f8632 Leszek Koltunski
131
    if( !mListeners.contains(el) )
132
      {
133
      mListeners.add(el);
134
      mNumListeners++;
135
      }
136 6a06a912 Leszek Koltunski
    }
137
 
138
///////////////////////////////////////////////////////////////////////////////////////////////////
139
140 3fc994b2 Leszek Koltunski
  void deregisterForMessages(EffectListener el)
141 6a06a912 Leszek Koltunski
    {
142 452f8632 Leszek Koltunski
    if( mListeners.remove(el) )
143 6a06a912 Leszek Koltunski
      {
144
      mNumListeners--;
145
      }
146
    }
147
148
///////////////////////////////////////////////////////////////////////////////////////////////////
149
150 7b8086eb Leszek Koltunski
  static void onDestroy()
151 6a06a912 Leszek Koltunski
    {
152 310e14fb leszek
    Effect.reset(mMax);
153 6a06a912 Leszek Koltunski
    mCreated = false;  
154
    }
155
 
156
///////////////////////////////////////////////////////////////////////////////////////////////////
157
158 476bbc81 Leszek Koltunski
  synchronized int removeByID(long id)
159 6a06a912 Leszek Koltunski
    {
160
    int i = getEffectIndex(id);
161
   
162
    if( i>=0 ) 
163
      {
164
      remove(i);
165 476bbc81 Leszek Koltunski
      return 1;
166 6a06a912 Leszek Koltunski
      }
167
   
168 476bbc81 Leszek Koltunski
    return 0;
169 6a06a912 Leszek Koltunski
    }
170
171
///////////////////////////////////////////////////////////////////////////////////////////////////
172
173 310e14fb leszek
  synchronized int removeByType(Effect effect)
174 6a06a912 Leszek Koltunski
    {
175 310e14fb leszek
    int ret  = 0;
176
    int name = effect.getName();
177
    int type = effect.getType();
178
179 6a06a912 Leszek Koltunski
    for(int i=0; i<mNumEffects; i++)
180
      {
181 310e14fb leszek
      if( mName[i]==name && mType[i]==type )
182 6a06a912 Leszek Koltunski
        {
183
        remove(i);
184 476bbc81 Leszek Koltunski
        i--;
185
        ret++;
186 6a06a912 Leszek Koltunski
        }
187
      }
188
   
189
    return ret;
190
    }
191
  
192
///////////////////////////////////////////////////////////////////////////////////////////////////
193
  
194 2e18813f Leszek Koltunski
  private synchronized int getEffectIndex(long id)
195 6a06a912 Leszek Koltunski
    {
196
    int index = mIDIndex[(int)(id%mMax[mMaxIndex])];
197
    return (index<mNumEffects && mID[index]==id ? index : -1);
198
    }
199
200
///////////////////////////////////////////////////////////////////////////////////////////////////
201 0df17fad Leszek Koltunski
// we do want to notify Listeners if they called 'abortAll' themselves but don't want to notify
202
// them if it is the library itself which is releasing resources.
203
204
  synchronized int abortAll(boolean notify)
205 6a06a912 Leszek Koltunski
    {
206 d07f2950 Leszek Koltunski
    int ret = mNumEffects;
207 3a35681a Leszek Koltunski
    long removedID;
208 310e14fb leszek
    int removedName, removedType;
209 d07f2950 Leszek Koltunski
210
    for(int i=0; i<ret; i++ )
211 6a06a912 Leszek Koltunski
      {
212 d425545a Leszek Koltunski
      mInter[0][i] = null;
213
      mInter[1][i] = null;
214
      mInter[2][i] = null;
215 3a35681a Leszek Koltunski
216 0df17fad Leszek Koltunski
      if( notify )
217
        {
218
        removedID = mID[i];
219 e8c81a8e Leszek Koltunski
        removedName= mName[i];
220 310e14fb leszek
        removedType= mType[i];
221 0df17fad Leszek Koltunski
222
        for(int j=0; j<mNumListeners; j++)
223
          EffectMessageSender.newMessage( mListeners.elementAt(j),
224
                                          EffectMessage.EFFECT_REMOVED,
225 310e14fb leszek
                                          (removedID<<Effect.LENGTH)+removedType,
226 e8c81a8e Leszek Koltunski
                                          removedName,
227 cacc63de Leszek Koltunski
                                          mObjectID);
228 0df17fad Leszek Koltunski
        }
229 d07f2950 Leszek Koltunski
      }
230
231
    mNumEffects= 0;
232
233
    return ret;
234 6a06a912 Leszek Koltunski
    }
235
236
///////////////////////////////////////////////////////////////////////////////////////////////////
237
// this assumes 0<=effect<mNumEffects
238
  
239
  protected void remove(int effect)
240
    {
241
    mNumEffects--;     
242
    
243
    byte removedIndex = (byte)(mID[effect]%mMax[mMaxIndex]);
244
    byte removedPosition = mIDIndex[removedIndex];
245
    mFreeIndexes[mNumEffects] = removedIndex;
246
    
247
    long removedID = mID[effect];
248 e8c81a8e Leszek Koltunski
    int removedName= mName[effect];
249 310e14fb leszek
    int removedType= mType[effect];
250
251 6a06a912 Leszek Koltunski
    for(int j=0; j<mMax[mMaxIndex]; j++)
252
      {
253
      if( mIDIndex[j] > removedPosition ) mIDIndex[j]--; 
254
      }
255
         
256
    for(int j=effect; j<mNumEffects; j++ ) 
257
      {
258 e8c81a8e Leszek Koltunski
      mName[j]            = mName[j+1];
259 310e14fb leszek
      mType[j]            = mType[j+1];
260 a595ee16 Leszek Koltunski
      mInter[0][j]        = mInter[0][j+1];
261
      mInter[1][j]        = mInter[1][j+1];
262
      mInter[2][j]        = mInter[2][j+1];
263 6a06a912 Leszek Koltunski
      mCurrentDuration[j] = mCurrentDuration[j+1];
264
      mID[j]              = mID[j+1];
265
    
266
      moveEffect(j);
267
      }
268
   
269 d425545a Leszek Koltunski
    mInter[0][mNumEffects] = null;
270
    mInter[1][mNumEffects] = null;
271
    mInter[2][mNumEffects] = null;
272
273 6a06a912 Leszek Koltunski
    for(int i=0; i<mNumListeners; i++) 
274
      EffectMessageSender.newMessage( mListeners.elementAt(i),
275 e458a4ba Leszek Koltunski
                                      EffectMessage.EFFECT_REMOVED,
276 310e14fb leszek
                                      (removedID<<Effect.LENGTH)+removedType,
277 e8c81a8e Leszek Koltunski
                                      removedName,
278 cacc63de Leszek Koltunski
                                      mObjectID);
279 6a06a912 Leszek Koltunski
    }
280
  
281
///////////////////////////////////////////////////////////////////////////////////////////////////
282
  
283 310e14fb leszek
  protected long addBase(Effect effect)
284
    {
285
    int type = effect.getType();
286
287
    mName[mNumEffects] = effect.getName();
288
    mType[mNumEffects] = type;
289 6a06a912 Leszek Koltunski
    mCurrentDuration[mNumEffects] = 0;
290
    
291
    int index = mFreeIndexes[mNumEffects];
292
    long id = mTotalEffects*mMax[mMaxIndex] + index;
293
    mID[mNumEffects] = id;
294
    mIDIndex[index] = mNumEffects;  
295
   
296
    mNumEffects++; 
297
    mTotalEffects++;
298
   
299 310e14fb leszek
    return (id<<Effect.LENGTH)+type;
300 6a06a912 Leszek Koltunski
    }
301
    
302
///////////////////////////////////////////////////////////////////////////////////////////////////
303
// used only for debugging
304 24d22f93 Leszek Koltunski
305
  @SuppressWarnings("unused")
306 6a06a912 Leszek Koltunski
  protected String printEffects(int max)
307
    {
308
    long[] indexes = new long[mMax[mMaxIndex]];
309
   
310
    for(int g=0; g<mMax[mMaxIndex]; g++)
311
      {
312
      indexes[g] = -1;  
313
      }
314
   
315 b329f352 Leszek Koltunski
    String ret="(";
316 6a06a912 Leszek Koltunski
    int f;
317
   
318
    for(int g=0; g<max; g++) 
319
      {
320
      f = getEffectIndex(g);
321
      if( f>=0 ) indexes[f] = g;
322
      }
323
   
324
    for(int g=0; g<mMax[mMaxIndex]; g++)
325
      {
326
      ret += (g>0 ? ",":"")+(indexes[g]>=0 ? indexes[g] : " ");   
327
      }
328
   
329
    ret += ")";
330
   
331
    return ret;
332
    }
333
334
///////////////////////////////////////////////////////////////////////////////////////////////////
335
// Only used for debugging
336
  
337
  protected boolean printByID(long id)
338
    {
339
    int index = getEffectIndex(id);
340
   
341
    if( index>=0 ) 
342
      {
343 d425545a Leszek Koltunski
      boolean inter0 = mInter[0][index]==null;
344
      boolean inter1 = mInter[1][index]==null;
345
      boolean inter2 = mInter[2][index]==null;
346
347
      android.util.Log.e("EffectQueue", "numEffects="+mNumEffects+" effect id="+id+" index="+index+
348
                         " duration="+mCurrentDuration[index]+" inter[0] null="+inter0+" inter[1] null="+inter1+" inter[2] null="+inter2);
349 80ae684e Leszek Koltunski
350
      if( !inter0 ) android.util.Log.e("EffectQueue","inter[0]: "+mInter[0][index].print());
351
      if( !inter1 ) android.util.Log.e("EffectQueue","inter[1]: "+mInter[1][index].print());
352
      if( !inter2 ) android.util.Log.e("EffectQueue","inter[2]: "+mInter[2][index].print());
353 d425545a Leszek Koltunski
354 6a06a912 Leszek Koltunski
      return true;
355
      }
356
   
357 d07f2950 Leszek Koltunski
    android.util.Log.e("EffectQueue", "effect id="+id+" not found");
358 6a06a912 Leszek Koltunski
359
    return false;  
360
    }
361
 
362
///////////////////////////////////////////////////////////////////////////////////////////////////
363
364
  abstract void moveEffect(int index);
365
  }
366
///////////////////////////////////////////////////////////////////////////////////////////////////