/** * PlayProcessorImpl.java * * This program is distributed under the terms of the GNU General Public * License * Copyright 2008 NJ Pearman * * This file is part of MobScrob. * * MobScrob 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. * * MobScrob 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 MobScrob. If not, see <http://www.gnu.org/licenses/>. */ package mobscrob.player; import java.util.Enumeration; import java.util.Vector; import mobscrob.id3.TrackMetadata; import mobscrob.logging.Log; import mobscrob.logging.LogFactory; /** * @author Neill * */ public abstract class PlayProcessorImpl implements PlayProcessor, Runnable { private static final Log log = LogFactory.getLogger(PlayProcessorImpl.class); private final int waitTime; private Vector queue; private boolean isRunning; protected Thread runThread; public PlayProcessorImpl(int waitTime) { this.waitTime = waitTime; isRunning = false; queue = new Vector(); } /** * Starts a new thread for this PlayProcessorImpl instance, provided * that the instance is not already running. */ public void start() { if(!isRunning) { runThread = new Thread(this); runThread.start(); } } public void queueTrack(TrackMetadata track) { final String methodName = "1"; if (track != null) { synchronized (queue) { queue.addElement(track); } } else { log.warn(methodName, "Can't add a null track to queue"); } } public void queueAtStart(TrackMetadata track) { final String methodName = "2"; if (track != null) { if (queue.size() > 0) { synchronized (queue) { queue.insertElementAt(track, 0); } } else { synchronized (queue) { queue.addElement(track); } } } else { log.warn(methodName, "Can't add a null track to start of queue"); } } /** * Gets a snapshot of the queue being used by this processor, as an array * of TrackMetadata objects. * * @return */ public TrackMetadata[] getQueueSnapshot() { synchronized (queue) { TrackMetadata[] tracks = new TrackMetadata[queue.size()]; Enumeration e = queue.elements(); int curr = 0; while (e.hasMoreElements()) { tracks[curr++] = (TrackMetadata)e.nextElement(); } return tracks; } } public abstract void process(TrackMetadata next); public void run() { final String methodName = "3"; isRunning = true; log.info(methodName, "Starting " + this.getClass().getName()); while (isRunning) { try { // wait for item in queue while (queue.isEmpty() && isRunning) { Thread.sleep(waitTime); } if (!isRunning) { // break if the processor has been stopped break; } TrackMetadata next; synchronized (queue) { // take item off top of queue next = (TrackMetadata) queue.elementAt(0); queue.removeElementAt(0); log.info(methodName, "Removed "+next.getTrackTitle()+" from queue"); } process(next); log.info(methodName, "Track length " + next.getTrackLength() + ", played for " + next.getCurrentPosition()); } catch (InterruptedException ex) { log.error(methodName, "PostPlayTagReader thread was interrupted" + ex.getMessage(), ex); } } } protected void stopProcessing() { this.isRunning = false; } }