commit 20dbec0ea285db7ecbf2b7f92eb60c5fe94d545b
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Sat May 11 23:33:00 2019 +0100

    Simplify the way applications can get notifications when an effect finishes.
    
    Now, instead of the 'DistortedEffects.(de)registerForNotifications()' 2 APIs, we call a single 'Effect.notifyWhenFinished()'.

diff --git a/src/main/java/org/distorted/library/effect/Effect.java b/src/main/java/org/distorted/library/effect/Effect.java
index 3fb87ce..4370fa4 100644
--- a/src/main/java/org/distorted/library/effect/Effect.java
+++ b/src/main/java/org/distorted/library/effect/Effect.java
@@ -19,7 +19,10 @@
 
 package org.distorted.library.effect;
 
+import org.distorted.library.message.EffectListener;
+
 import java.lang.reflect.Method;
+import java.util.ArrayList;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
@@ -37,6 +40,9 @@ public abstract class Effect
   private final int mRegionDim;
   private final int mCenterDim;
 
+  ArrayList<EffectListener> mListeners =null;
+  int mNumListeners=0;  // ==mListeners.length(), but we only create mListeners if the first one gets added
+
   private static long mNextID = 0;
 
   private final static float[] mUnity= new float[MAX_UNITY_DIM*NUM_EFFECTS];
@@ -99,6 +105,34 @@ public abstract class Effect
  */
   public abstract boolean compute(float[] uniforms, int index, long currentDuration, long step );
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Only for use by the library itself.
+ *
+ * @y.exclude
+ */
+  public int getNumListeners()
+    {
+    return mNumListeners;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Only for use by the library itself.
+ *
+ * @y.exclude
+ */
+  public EffectListener removeFirstListener()
+    {
+    if( mNumListeners>0 )
+      {
+      mNumListeners--;
+      return mListeners.remove(0);
+      }
+
+    return null;
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // PUBLIC API
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -233,4 +267,25 @@ public abstract class Effect
     {
     return mDimension;
     }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+/**
+ * Adds the calling class to the list of Listeners that get notified when this Effect gets 'finished'
+ * i.e. when the Dynamic inside this Effect reaches its final point and stops moving. This will be sent
+ * only once, on the first time the Dynamic reaches its final point.
+ *
+ * If there's no Dynamic, ths message will never be sent.
+ *
+ * @param el A class implementing the EffectListener interface that wants to get notifications.
+ */
+  public void notifyWhenFinished(EffectListener el)
+    {
+    if( mListeners==null ) mListeners = new ArrayList<>();
+
+    if( !mListeners.contains(el) )
+      {
+      mListeners.add(el);
+      mNumListeners++;
+      }
+    }
   }
diff --git a/src/main/java/org/distorted/library/effectqueue/EffectQueue.java b/src/main/java/org/distorted/library/effectqueue/EffectQueue.java
index 5b09cc2..379a77b 100644
--- a/src/main/java/org/distorted/library/effectqueue/EffectQueue.java
+++ b/src/main/java/org/distorted/library/effectqueue/EffectQueue.java
@@ -24,9 +24,6 @@ import org.distorted.library.effect.EffectName;
 import org.distorted.library.effect.EffectType;
 import org.distorted.library.main.DistortedLibrary;
 import org.distorted.library.main.InternalMaster;
-import org.distorted.library.message.EffectListener;
-import org.distorted.library.message.EffectMessage;
-import org.distorted.library.message.EffectMessageSender;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -53,9 +50,6 @@ public abstract class EffectQueue implements InternalMaster.Slave
   Effect[] mEffects;
   int[] mName;
   long mTime=0;
-  ArrayList<EffectListener> mListeners =null;
-  int mNumListeners=0;  // ==mListeners.length(), but we only create mListeners if the first one gets added
-  long mDistortedEffectsID;
 
   private static int[] mMax = new int[EffectType.LENGTH];
   private static long mNextID;
@@ -90,13 +84,12 @@ public abstract class EffectQueue implements InternalMaster.Slave
   
 ///////////////////////////////////////////////////////////////////////////////////////////////////
    
-  EffectQueue(long id, int numUniforms, int index)
+  EffectQueue(int numUniforms, int index)
     {
     mCreated            = false;
     mID                 = 0;
     mNumEffects         = 0;
     mNumEffectsToBe     = 0;
-    mDistortedEffectsID = id;
     mIndex              = index;
 
     mJobs.add(new Job(CREATE,numUniforms,false,null));  // create the stuff that depends on max number
@@ -105,12 +98,12 @@ public abstract class EffectQueue implements InternalMaster.Slave
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public static void allocateQueues(EffectQueue[] queues, EffectQueue[] from, int flags, long id)
+  public static void allocateQueues(EffectQueue[] queues, EffectQueue[] from, int flags)
     {
-    queues[0] = (flags & DistortedLibrary.CLONE_MATRIX     ) != 0 ? from[0] : new EffectQueueMatrix(id);
-    queues[1] = (flags & DistortedLibrary.CLONE_VERTEX     ) != 0 ? from[1] : new EffectQueueVertex(id);
-    queues[2] = (flags & DistortedLibrary.CLONE_FRAGMENT   ) != 0 ? from[2] : new EffectQueueFragment(id);
-    queues[3] = (flags & DistortedLibrary.CLONE_POSTPROCESS) != 0 ? from[3] : new EffectQueuePostprocess(id);
+    queues[0] = (flags & DistortedLibrary.CLONE_MATRIX     ) != 0 ? from[0] : new EffectQueueMatrix();
+    queues[1] = (flags & DistortedLibrary.CLONE_VERTEX     ) != 0 ? from[1] : new EffectQueueVertex();
+    queues[2] = (flags & DistortedLibrary.CLONE_FRAGMENT   ) != 0 ? from[2] : new EffectQueueFragment();
+    queues[3] = (flags & DistortedLibrary.CLONE_POSTPROCESS) != 0 ? from[3] : new EffectQueuePostprocess();
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -205,29 +198,6 @@ public abstract class EffectQueue implements InternalMaster.Slave
     return mMax[index];
     }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void registerForMessages(EffectListener el)
-    {
-    if( mListeners==null ) mListeners = new ArrayList<>();
-
-    if( !mListeners.contains(el) )
-      {
-      mListeners.add(el);
-      mNumListeners++;
-      }
-    }
- 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public void deregisterForMessages(EffectListener el)
-    {
-    if( mListeners.remove(el) )
-      {
-      mNumListeners--;
-      }
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   public static void onDestroy()
@@ -244,8 +214,6 @@ public abstract class EffectQueue implements InternalMaster.Slave
     {
     mNumEffects--;
 
-    long removedID = mEffects[effect].getID();
-
     for(int j=effect; j<mNumEffects; j++ )
       {
       mEffects[j]         = mEffects[j+1];
@@ -254,9 +222,6 @@ public abstract class EffectQueue implements InternalMaster.Slave
       }
 
     mEffects[mNumEffects] = null;
-
-    for(int i=0; i<mNumListeners; i++)
-      EffectMessageSender.newMessage( mListeners.get(i), EffectMessage.EFFECT_REMOVED, removedID, mDistortedEffectsID);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -441,13 +406,6 @@ public abstract class EffectQueue implements InternalMaster.Slave
         case DETALL: for(int j=0; j<mNumEffects; j++ )
                        {
                        changed = true;
-
-                       if( job.notify )
-                         {
-                         for(int k=0; k<mNumListeners; k++)
-                           EffectMessageSender.newMessage( mListeners.get(k), EffectMessage.EFFECT_REMOVED, mEffects[j].getID(), mDistortedEffectsID);
-                         }
-
                        mEffects[j] = null;
                        }
 
diff --git a/src/main/java/org/distorted/library/effectqueue/EffectQueueFragment.java b/src/main/java/org/distorted/library/effectqueue/EffectQueueFragment.java
index b112f49..048c5e8 100644
--- a/src/main/java/org/distorted/library/effectqueue/EffectQueueFragment.java
+++ b/src/main/java/org/distorted/library/effectqueue/EffectQueueFragment.java
@@ -23,7 +23,6 @@ import android.opengl.GLES31;
 
 import org.distorted.library.effect.EffectType;
 import org.distorted.library.effect.FragmentEffect;
-import org.distorted.library.message.EffectMessage;
 import org.distorted.library.message.EffectMessageSender;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -39,9 +38,9 @@ class EffectQueueFragment extends EffectQueue
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
    
-  EffectQueueFragment(long id)
+  EffectQueueFragment()
     { 
-    super(id,NUM_UNIFORMS,INDEX);
+    super(NUM_UNIFORMS,INDEX);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -67,8 +66,7 @@ class EffectQueueFragment extends EffectQueue
 
       if( mEffects[i].compute(mUniforms, NUM_UNIFORMS*i, mCurrentDuration[i], step) )
         {
-        for(int j=0; j<mNumListeners; j++)
-          EffectMessageSender.newMessage( mListeners.get(j), EffectMessage.EFFECT_FINISHED, mEffects[i].getID(), mDistortedEffectsID);
+        EffectMessageSender.newMessage(mEffects[i]);
         }
 
       mUniforms[NUM_UNIFORMS*i+5] -= halfX;
diff --git a/src/main/java/org/distorted/library/effectqueue/EffectQueueMatrix.java b/src/main/java/org/distorted/library/effectqueue/EffectQueueMatrix.java
index d2c5cac..c38d5b1 100644
--- a/src/main/java/org/distorted/library/effectqueue/EffectQueueMatrix.java
+++ b/src/main/java/org/distorted/library/effectqueue/EffectQueueMatrix.java
@@ -24,7 +24,6 @@ import android.opengl.Matrix;
 
 import org.distorted.library.effect.EffectType;
 import org.distorted.library.effect.MatrixEffect;
-import org.distorted.library.message.EffectMessage;
 import org.distorted.library.message.EffectMessageSender;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -48,9 +47,9 @@ class EffectQueueMatrix extends EffectQueue
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
    
-  EffectQueueMatrix(long id)
+  EffectQueueMatrix()
     { 
-    super(id,NUM_UNIFORMS,INDEX );
+    super(NUM_UNIFORMS,INDEX );
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -128,8 +127,7 @@ class EffectQueueMatrix extends EffectQueue
 
       if( mEffects[i].compute(mUniforms, NUM_UNIFORMS*i, mCurrentDuration[i], step) )
         {
-        for(int j=0; j<mNumListeners; j++)
-          EffectMessageSender.newMessage( mListeners.get(j), EffectMessage.EFFECT_FINISHED, mEffects[i].getID(), mDistortedEffectsID);
+        EffectMessageSender.newMessage(mEffects[i]);
         }
       }
      
diff --git a/src/main/java/org/distorted/library/effectqueue/EffectQueuePostprocess.java b/src/main/java/org/distorted/library/effectqueue/EffectQueuePostprocess.java
index fcc006b..1b128db 100644
--- a/src/main/java/org/distorted/library/effectqueue/EffectQueuePostprocess.java
+++ b/src/main/java/org/distorted/library/effectqueue/EffectQueuePostprocess.java
@@ -34,7 +34,6 @@ import org.distorted.library.main.InternalOutputSurface;
 import org.distorted.library.main.InternalRenderState;
 import org.distorted.library.main.InternalSurface;
 import org.distorted.library.mesh.MeshBase;
-import org.distorted.library.message.EffectMessage;
 import org.distorted.library.message.EffectMessageSender;
 import org.distorted.library.program.DistortedProgram;
 
@@ -60,9 +59,9 @@ public class EffectQueuePostprocess extends EffectQueue
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  EffectQueuePostprocess(long id)
+  EffectQueuePostprocess()
     { 
-    super(id,NUM_UNIFORMS,INDEX );
+    super(NUM_UNIFORMS,INDEX );
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -88,8 +87,7 @@ public class EffectQueuePostprocess extends EffectQueue
 
       if( mEffects[i].compute(mUniforms, NUM_UNIFORMS*i, mCurrentDuration[i], step) )
         {
-        for(int j=0; j<mNumListeners; j++)
-          EffectMessageSender.newMessage( mListeners.get(j), EffectMessage.EFFECT_FINISHED, mEffects[i].getID(), mDistortedEffectsID);
+        EffectMessageSender.newMessage(mEffects[i]);
         }
 
       halo = (int)mUniforms[NUM_UNIFORMS*i];
diff --git a/src/main/java/org/distorted/library/effectqueue/EffectQueueVertex.java b/src/main/java/org/distorted/library/effectqueue/EffectQueueVertex.java
index 7ee0d1c..a365cf6 100644
--- a/src/main/java/org/distorted/library/effectqueue/EffectQueueVertex.java
+++ b/src/main/java/org/distorted/library/effectqueue/EffectQueueVertex.java
@@ -23,7 +23,6 @@ import android.opengl.GLES31;
 
 import org.distorted.library.effect.EffectType;
 import org.distorted.library.effect.VertexEffect;
-import org.distorted.library.message.EffectMessage;
 import org.distorted.library.message.EffectMessageSender;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -40,9 +39,9 @@ class EffectQueueVertex extends EffectQueue
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
    
-  EffectQueueVertex(long id)
+  EffectQueueVertex()
     { 
-    super(id,NUM_UNIFORMS,INDEX);
+    super(NUM_UNIFORMS,INDEX);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -69,8 +68,7 @@ class EffectQueueVertex extends EffectQueue
 
       if( mEffects[i].compute(mUniforms, NUM_UNIFORMS*i, mCurrentDuration[i], step) )
         {
-        for(int j=0; j<mNumListeners; j++)
-          EffectMessageSender.newMessage( mListeners.get(j), EffectMessage.EFFECT_FINISHED, mEffects[i].getID(), mDistortedEffectsID);
+        EffectMessageSender.newMessage(mEffects[i]);
         }
 
       mUniforms[NUM_UNIFORMS*i+5] -= halfX;
diff --git a/src/main/java/org/distorted/library/main/DistortedEffects.java b/src/main/java/org/distorted/library/main/DistortedEffects.java
index cf62b8b..dbc398c 100644
--- a/src/main/java/org/distorted/library/main/DistortedEffects.java
+++ b/src/main/java/org/distorted/library/main/DistortedEffects.java
@@ -23,7 +23,6 @@ import org.distorted.library.effect.Effect;
 import org.distorted.library.effect.EffectName;
 import org.distorted.library.effectqueue.EffectQueue;
 import org.distorted.library.effect.EffectType;
-import org.distorted.library.message.EffectListener;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
@@ -63,7 +62,7 @@ public class DistortedEffects
     {
     mID = ++mNextID;
     mQueues = new EffectQueue[EffectType.LENGTH];
-    EffectQueue.allocateQueues(mQueues,null,0,mID);
+    EffectQueue.allocateQueues(mQueues,null,0);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -80,7 +79,7 @@ public class DistortedEffects
     {
     mID = ++mNextID;
     mQueues = new EffectQueue[EffectType.LENGTH];
-    EffectQueue.allocateQueues(mQueues,dc.getQueues(),flags,mID);
+    EffectQueue.allocateQueues(mQueues,dc.getQueues(),flags);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -94,35 +93,6 @@ public class DistortedEffects
       return mID;
       }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Adds the calling class to the list of Listeners that get notified each time some event happens 
- * to one of the Effects in our queues. Nothing will happen if 'el' is already in the list.
- * 
- * @param el A class implementing the EffectListener interface that wants to get notifications.
- */
-  public void registerForMessages(EffectListener el)
-    {
-    for( int i=0; i<EffectType.LENGTH; i++)
-      {
-      mQueues[i].registerForMessages(el);
-      }
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-/**
- * Removes the calling class from the list of Listeners that get notified if something happens to Effects in our queue.
- * 
- * @param el A class implementing the EffectListener interface that no longer wants to get notifications.
- */
-  public void deregisterForMessages(EffectListener el)
-    {
-    for( int i=0; i<EffectType.LENGTH; i++)
-      {
-      mQueues[i].deregisterForMessages(el);
-      }
-    }
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
  * Aborts all Effects.
diff --git a/src/main/java/org/distorted/library/message/EffectListener.java b/src/main/java/org/distorted/library/message/EffectListener.java
index 73a4b28..d08a8c9 100644
--- a/src/main/java/org/distorted/library/message/EffectListener.java
+++ b/src/main/java/org/distorted/library/message/EffectListener.java
@@ -21,27 +21,22 @@ package org.distorted.library.message;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-import org.distorted.library.main.DistortedEffects;
+import org.distorted.library.effect.Effect;
 
 /**
- * This interface lets users of the DistortedLibrary library get notified when something happens to one of the effects.
- * To receive the notifications, we first have to register with a call to {@link DistortedEffects#registerForMessages(EffectListener)}.
- * List of all possible events that can happen is defined in {@link EffectMessage}
+ * This interface lets users of the DistortedLibrary library get notified when a given effect finishes.
+ * To receive the notifications, we first have to register with a call to {@link Effect#notifyWhenFinished(EffectListener)}.
  */
 
 public interface EffectListener 
   {
 /**
- * Gets called when event of type 'eventType' happens to effect 'effectID'.
+ * Gets called when Effect 'effectID' finishes execution (i.e. the Dynamic inside it reaches its final point).
  * 
- * @param eventType  Type of event that happened.
- * @param effectID   ID of the effect the event happened to, as returned by {@link org.distorted.library.effect.Effect#getID() }
- * @param objectID   the ID of the DistortedEffects object, as returned by {@link org.distorted.library.main.DistortedEffects#getID()},
- *                   this event happened to.
- * @see EffectMessage
+ * @param effectID ID of the finished effect, as returned by {@link org.distorted.library.effect.Effect#getID() }
  */
    
-  void effectMessage(final EffectMessage eventType, final long effectID, final long objectID);
+  void effectFinished(final long effectID);
   }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/library/message/EffectMessage.java b/src/main/java/org/distorted/library/message/EffectMessage.java
deleted file mode 100644
index 5ccf38d..0000000
--- a/src/main/java/org/distorted/library/message/EffectMessage.java
+++ /dev/null
@@ -1,53 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2016 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Distorted.                                                               //
-//                                                                                               //
-// Distorted is free software: you can redistribute it and/or modify                             //
-// it under the terms of the GNU General Public License as published by                          //
-// the Free Software Foundation, either version 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Distorted is distributed in the hope that it will be useful,                                  //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
-// GNU General Public License for more details.                                                  //
-//                                                                                               //
-// You should have received a copy of the GNU General Public License                             //
-// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.library.message;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-import org.distorted.library.main.DistortedEffects;
-
-/**
-* Defines all possible events a class implementing the {@link EffectListener} interface can receive.
-*/
-
-public enum EffectMessage 
-  {
-/**
- * The effect has been removed. This can happen if someone explicitly removed the effect with a call to
- * {@link DistortedEffects#abortById(long)} (or one of the other 'abort' methods)
- */
-  EFFECT_REMOVED,
-  
-/**
- * Interpolation of the effect has finished. 
- * <p>
- * If you set up an interpolated effect and set its Dynamic to do 3.5 interpolations of 1000 ms each
- * with calls to {@link org.distorted.library.type.Dynamic#setCount(float)} and {@link org.distorted.library.type.Dynamic#makeRunNowFor(long)},
- * then you are going to get this message exactly once after 3.5*1000 = 3500 milliseconds when the interpolation 
- * finishes. You will never get this message if you set the effect to go on indefinitely with a call to 
- * {@link org.distorted.library.type.Dynamic#setCount(float)} where float=0.0f.
- * <p>  
- * If then the end effect is equal to the effect's unity, then immediately after this message you
- * will also get a EFFECT_REMOVED message.
- */
-  EFFECT_FINISHED
-  }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/library/message/EffectMessageSender.java b/src/main/java/org/distorted/library/message/EffectMessageSender.java
index cdcc38e..f7b86e1 100644
--- a/src/main/java/org/distorted/library/message/EffectMessageSender.java
+++ b/src/main/java/org/distorted/library/message/EffectMessageSender.java
@@ -19,6 +19,8 @@
 
 package org.distorted.library.message;
 
+import org.distorted.library.effect.Effect;
+
 import java.util.Vector;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -32,16 +34,12 @@ public final class EffectMessageSender extends Thread
   private class Message
     {
     EffectListener mListener;
-    EffectMessage mMessage;
     long mEffectID;
-    long mObjectID;
 
-    Message(EffectListener l, EffectMessage m, long effID, long objID)
+    Message(EffectListener listener, long effectID)
       {
-      mListener = l;
-      mMessage  = m;
-      mEffectID = effID;
-      mObjectID = objID;
+      mListener = listener;
+      mEffectID = effectID;
       }
     }
   
@@ -104,7 +102,7 @@ public final class EffectMessageSender extends Thread
       while( mList.size()>0 )
         {
         tmp = mList.remove(0);
-        tmp.mListener.effectMessage(tmp.mMessage, tmp.mEffectID, tmp.mObjectID);
+        tmp.mListener.effectFinished(tmp.mEffectID);
         }
 
       synchronized(mThis)
@@ -124,15 +122,25 @@ public final class EffectMessageSender extends Thread
   
 ///////////////////////////////////////////////////////////////////////////////////////////////////
         
-  public static void newMessage(EffectListener l, EffectMessage m, long effID, long objID)
+  public static void newMessage(Effect effect)
     {
-    Message msg = mThis.new Message(l,m,effID,objID);
-    mList.add(msg);
+    int numListeners = effect.getNumListeners();
 
-    synchronized(mThis)
+    if( numListeners>0 )
       {
-      mNotify = true;
-      mThis.notify();
+      long id = effect.getID();
+
+      for(int i=0; i<numListeners; i++)
+        {
+        Message msg = mThis.new Message(effect.removeFirstListener(), id);
+        mList.add(msg);
+        }
+
+      synchronized(mThis)
+        {
+        mNotify = true;
+        mThis.notify();
+        }
       }
     }
   }
