diff --git a/projects/robodj/src/java/robodj/chooser/ChooserFrame.java b/projects/robodj/src/java/robodj/chooser/ChooserFrame.java
index 9e080613..7a173a03 100644
--- a/projects/robodj/src/java/robodj/chooser/ChooserFrame.java
+++ b/projects/robodj/src/java/robodj/chooser/ChooserFrame.java
@@ -15,6 +15,9 @@ import com.samskivert.swing.*;
import com.samskivert.swing.util.*;
import com.samskivert.util.StringUtil;
+import com.threerings.presents.dobj.AttributeChangeListener;
+import com.threerings.presents.dobj.AttributeChangedEvent;
+
import robodj.Log;
import robodj.Version;
import robodj.repository.*;
@@ -23,7 +26,7 @@ import robodj.util.FancyPanel;
import robodj.util.RDJPrefs;
public class ChooserFrame extends JFrame
- implements ControllerProvider
+ implements ControllerProvider, AttributeChangeListener
{
public ChooserFrame ()
{
@@ -115,8 +118,9 @@ public class ChooserFrame extends JFrame
}
});
- // TODO: add ourselves as a playing listener
- // Chooser.djobj.addListener(this);
+ // listen for pause and stop and whatnot
+ Chooser.djobj.addListener(this);
+ updateButtons();
// create our controller
_controller = new ChooserController();
@@ -158,10 +162,15 @@ public class ChooserFrame extends JFrame
return user;
}
- // TODO: convert to dobj biz
- public void playingUpdated (int songid, boolean paused)
+ // documentation inherited from interface
+ public void attributeChanged (AttributeChangedEvent event)
{
- if (songid == -1 || paused) {
+ updateButtons();
+ }
+
+ protected void updateButtons ()
+ {
+ if (Chooser.djobj.playing == -1 || Chooser.djobj.paused) {
_pause.setToolTipText(PLAY_TIP);
_pause.setActionCommand("play");
_pause.setIcon(_playIcon);
@@ -172,7 +181,8 @@ public class ChooserFrame extends JFrame
_pause.setIcon(_pauseIcon);
}
- _stop.setEnabled(songid != -1);
+ _stop.setEnabled(Chooser.djobj.playing != -1);
+ _pause.setEnabled(Chooser.djobj.playlist != null);
}
/** Our top-level controller. */
diff --git a/projects/robodj/src/java/robodj/data/DJObject.dobj b/projects/robodj/src/java/robodj/data/DJObject.dobj
index 1b1e0452..004527d7 100644
--- a/projects/robodj/src/java/robodj/data/DJObject.dobj
+++ b/projects/robodj/src/java/robodj/data/DJObject.dobj
@@ -22,6 +22,9 @@ public class DJObject extends DObject
/** The index of the currently playing track. */
public int playing = -1;
+ /** Whether or not we're paused. */
+ public boolean paused;
+
/**
* Returns the currently playing track.
*/
@@ -35,7 +38,7 @@ public class DJObject extends DObject
*/
public PlaylistEntry getNext ()
{
- return getEntry(playing + 1);
+ return (playing < 0) ? null : getEntry(playing + 1);
}
/**
@@ -60,10 +63,12 @@ public class DJObject extends DObject
public void play ()
{
if (havePlaylist()) {
- // TODO: handle unpausing
if (playing == -1) {
setPlaying(0);
}
+ if (paused) {
+ setPaused(false);
+ }
}
}
@@ -88,7 +93,7 @@ public class DJObject extends DObject
public void pause ()
{
- // TODO
+ setPaused(!paused);
}
public void remove (int start, int length)
diff --git a/projects/robodj/src/java/robodj/data/DJObject.java b/projects/robodj/src/java/robodj/data/DJObject.java
index 6f508fb2..c1200573 100644
--- a/projects/robodj/src/java/robodj/data/DJObject.java
+++ b/projects/robodj/src/java/robodj/data/DJObject.java
@@ -22,12 +22,18 @@ public class DJObject extends DObject
/** The field name of the playing field. */
public static final String PLAYING = "playing";
+ /** The field name of the paused field. */
+ public static final String PAUSED = "paused";
+
/** The current playlist. */
public PlaylistEntry[] playlist;
/** The index of the currently playing track. */
public int playing = -1;
+ /** Whether or not we're paused. */
+ public boolean paused;
+
/**
* Returns the currently playing track.
*/
@@ -41,7 +47,7 @@ public class DJObject extends DObject
*/
public PlaylistEntry getNext ()
{
- return getEntry(playing + 1);
+ return (playing < 0) ? null : getEntry(playing + 1);
}
/**
@@ -66,10 +72,12 @@ public class DJObject extends DObject
public void play ()
{
if (havePlaylist()) {
- // TODO: handle unpausing
if (playing == -1) {
setPlaying(0);
}
+ if (paused) {
+ setPaused(false);
+ }
}
}
@@ -94,7 +102,7 @@ public class DJObject extends DObject
public void pause ()
{
- // TODO
+ setPaused(!paused);
}
public void remove (int start, int length)
@@ -173,4 +181,18 @@ public class DJObject extends DObject
requestAttributeChange(PLAYING, new Integer(playing));
this.playing = playing;
}
+
+ /**
+ * Requests that the paused field be set to the specified
+ * value. The local value will be updated immediately and an event
+ * will be propagated through the system to notify all listeners that
+ * the attribute did change. Proxied copies of this object (on
+ * clients) will apply the value change when they received the
+ * attribute changed notification.
+ */
+ public void setPaused (boolean paused)
+ {
+ requestAttributeChange(PAUSED, new Boolean(paused));
+ this.paused = paused;
+ }
}
diff --git a/projects/robodj/src/java/robodj/server/MusicPlayer.java b/projects/robodj/src/java/robodj/server/MusicPlayer.java
index 506a46a1..51fa6011 100644
--- a/projects/robodj/src/java/robodj/server/MusicPlayer.java
+++ b/projects/robodj/src/java/robodj/server/MusicPlayer.java
@@ -44,6 +44,12 @@ public class MusicPlayer extends Thread
} else if (event.getName().equals(DJObject.PLAYLIST)) {
recomputeNext();
+
+ } else if (event.getName().equals(DJObject.PAUSED)) {
+ // wake the music thread if necessary
+ synchronized (this) {
+ notify();
+ }
}
}
@@ -55,7 +61,7 @@ public class MusicPlayer extends Thread
Player player = getPlaying();
Log.info("Playing " + _pentry + "...");
while (player.play(PLAY_FRAMES)) {
- // loop!
+ checkPaused();
}
} catch (Throwable t) {
@@ -83,10 +89,18 @@ public class MusicPlayer extends Thread
_fnentry = entry;
_fnext = getPlayer(_fnentry);
+ // if we're clearing the current entry, clear next as well
+ if (entry == null && _next != null) {
+ _next.close();
+ _next = null;
+ _nentry = null;
+ }
+
// clear out any current track
if (_playing != null) {
Log.info("Stopping current track.");
_playing.close();
+ _pentry = null;
}
// finally wake up the player in case it is sleeping
@@ -169,6 +183,17 @@ public class MusicPlayer extends Thread
return _playing;
}
+ protected synchronized void checkPaused ()
+ {
+ while (_djobj.paused) {
+ try {
+ wait();
+ } catch (InterruptedException ie) {
+ Log.warning("Interrupted waiting for unpause.");
+ }
+ }
+ }
+
/** Helper function. */
protected boolean equals (PlaylistEntry e1, PlaylistEntry e2)
{
@@ -185,5 +210,5 @@ public class MusicPlayer extends Thread
protected PlaylistEntry _nentry, _fnentry;
/** The number of frames to play before checking up on things. */
- protected static final int PLAY_FRAMES = 10;
+ protected static final int PLAY_FRAMES = 1;
}