Get rid of event bus, use a custom listener instead.
authorDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Wed, 29 May 2013 19:35:10 +0000 (21:35 +0200)
committerDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Wed, 29 May 2013 19:35:10 +0000 (21:35 +0200)
src/main/java/net/pterodactylus/sonitus/data/source/MultiSource.java
src/main/java/net/pterodactylus/sonitus/data/source/SourceFinishedListener.java [new file with mode: 0644]

index 2123986..80c3f56 100644 (file)
@@ -25,13 +25,13 @@ import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.logging.Logger;
+import javax.swing.event.EventListenerList;
 
 import net.pterodactylus.sonitus.data.AbstractControlledComponent;
 import net.pterodactylus.sonitus.data.Controller;
+import net.pterodactylus.sonitus.data.Metadata;
 import net.pterodactylus.sonitus.data.Source;
-import net.pterodactylus.sonitus.data.event.SourceFinishedEvent;
 
-import com.google.common.eventbus.EventBus;
 import com.google.inject.Inject;
 
 /**
@@ -46,8 +46,8 @@ public class MultiSource extends AbstractControlledComponent implements Source {
        /** The logger. */
        private static final Logger logger = Logger.getLogger(MultiSource.class.getName());
 
-       /** The event bus. */
-       private final EventBus eventBus;
+       /** The source finished listeners. */
+       private final EventListenerList sourceFinishedListeners = new EventListenerList();
 
        /** The current source. */
        private final AtomicReference<Source> source = new AtomicReference<Source>();
@@ -55,13 +55,34 @@ public class MultiSource extends AbstractControlledComponent implements Source {
        /** Whether the source was changed. */
        private boolean sourceChanged;
 
-       /**
-        * Creates a new multi source.
-        */
+       /** Creates a new multi source. */
        @Inject
-       public MultiSource(EventBus eventBus) {
+       public MultiSource() {
                super("Multisource");
-               this.eventBus = eventBus;
+       }
+
+       //
+       // LISTENER MANAGEMENT
+       //
+
+       /**
+        * Adds a source finished listener to the list of registered listeners.
+        *
+        * @param sourceFinishedListener
+        *              The source finished listener to add
+        */
+       public void addSourceFinishedListener(SourceFinishedListener sourceFinishedListener) {
+               sourceFinishedListeners.add(SourceFinishedListener.class, sourceFinishedListener);
+       }
+
+       /**
+        * Removes a source finished listener from the list of registered listeners.
+        *
+        * @param sourceFinishedListener
+        *              The source finished listener to remove
+        */
+       public void removeSourceFinishedListener(SourceFinishedListener sourceFinishedListener) {
+               sourceFinishedListeners.remove(SourceFinishedListener.class, sourceFinishedListener);
        }
 
        //
@@ -78,7 +99,7 @@ public class MultiSource extends AbstractControlledComponent implements Source {
                checkNotNull(source, "source must not be null");
 
                Source oldSource = this.source.getAndSet(source);
-               if (oldSource != null) {
+               if (!source.equals(oldSource)) {
                        synchronized (this.source) {
                                sourceChanged = true;
                                this.source.notifyAll();
@@ -89,6 +110,22 @@ public class MultiSource extends AbstractControlledComponent implements Source {
        }
 
        //
+       // EVENT METHODS
+       //
+
+       /**
+        * Notifies all registered listeners that the current source finished playing
+        * and that a new source should be {@link #setSource(Source) set}.
+        *
+        * @see SourceFinishedListener
+        */
+       private void fireSourceFinished() {
+               for (SourceFinishedListener sourceFinishedListener : sourceFinishedListeners.getListeners(SourceFinishedListener.class)) {
+                       sourceFinishedListener.sourceFinished(this);
+               }
+       }
+
+       //
        // CONTROLLED METHODS
        //
 
@@ -97,6 +134,16 @@ public class MultiSource extends AbstractControlledComponent implements Source {
                return Collections.emptyList();
        }
 
+       @Override
+       public Metadata metadata() {
+               if (super.metadata() == null) {
+                       /* no metadata yet, wait for it. */
+                       waitForNewSource();
+                       sourceChanged = false;
+               }
+               return super.metadata();
+       }
+
        //
        // SOURCE METHODS
        //
@@ -107,18 +154,7 @@ public class MultiSource extends AbstractControlledComponent implements Source {
                        try {
                                return source.get().get(bufferSize);
                        } catch (EOFException eofe1) {
-                               eventBus.post(new SourceFinishedEvent(source.get()));
-                               synchronized (source) {
-                                       while (!sourceChanged) {
-                                               try {
-                                                       logger.info("Waiting for next Source...");
-                                                       source.wait();
-                                                       logger.info("Was notified.");
-                                               } catch (InterruptedException ioe1) {
-                                                       /* ignore: we’ll end up here again if we were interrupted. */
-                                               }
-                                       }
-                               }
+                               waitForNewSource();
                        } finally {
                                synchronized (source) {
                                        sourceChanged = false;
@@ -127,4 +163,24 @@ public class MultiSource extends AbstractControlledComponent implements Source {
                }
        }
 
+       //
+       // PRIVATE METHODS
+       //
+
+       /** Waits for a new source to be {@link #setSource(Source) set}. */
+       private void waitForNewSource() {
+               fireSourceFinished();
+               synchronized (source) {
+                       while (!sourceChanged) {
+                               try {
+                                       logger.info("Waiting for next Source...");
+                                       source.wait();
+                                       logger.info("Was notified.");
+                               } catch (InterruptedException ioe1) {
+                                       /* ignore: we’ll end up here again if we were interrupted. */
+                               }
+                       }
+               }
+       }
+
 }
diff --git a/src/main/java/net/pterodactylus/sonitus/data/source/SourceFinishedListener.java b/src/main/java/net/pterodactylus/sonitus/data/source/SourceFinishedListener.java
new file mode 100644 (file)
index 0000000..35ad426
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Sonitus - SourceFinishedListener.java - Copyright © 2013 David Roden
+ *
+ * This program 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package net.pterodactylus.sonitus.data.source;
+
+import java.util.EventListener;
+
+import net.pterodactylus.sonitus.data.Source;
+
+/**
+ * Interface for {@link MultiSource} notifications if a source is finished
+ * playing.
+ *
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+public interface SourceFinishedListener extends EventListener {
+
+       /**
+        * Notifies the listener that the given multi source has finished playing a
+        * source and a new source should be {@link MultiSource#setSource(Source)
+        * set}.
+        *
+        * @param multiSource
+        *              The multi source that finished playing
+        */
+       public void sourceFinished(MultiSource multiSource);
+
+}