Moved most player tasks to ForkJoin.
This system works a bit better.
This commit is contained in:
@@ -0,0 +1,41 @@
|
|||||||
|
package edu.regis.universeplayer;
|
||||||
|
|
||||||
|
import java.util.concurrent.ForkJoinTask;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An abstract {@link ForkJoinTask} that has getters and setters automatically
|
||||||
|
* set up.
|
||||||
|
*
|
||||||
|
* @param <T>
|
||||||
|
*/
|
||||||
|
public abstract class AbstractTask<T> extends ForkJoinTask<T>
|
||||||
|
{
|
||||||
|
private T value;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the result that would be returned by {@link #join}, even if this
|
||||||
|
* task completed abnormally, or {@code null} if this task is not known to
|
||||||
|
* have been completed. This method is designed to aid debugging, as well
|
||||||
|
* as to support extensions. Its use in any other context is discouraged.
|
||||||
|
*
|
||||||
|
* @return the result, or {@code null} if not completed
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public T getRawResult()
|
||||||
|
{
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forces the given value to be returned as a result. This method is
|
||||||
|
* designed to support extensions, and should not in general be called
|
||||||
|
* otherwise.
|
||||||
|
*
|
||||||
|
* @param value the value
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void setRawResult(T value)
|
||||||
|
{
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,6 +17,8 @@ import java.util.Map;
|
|||||||
import java.util.ResourceBundle;
|
import java.util.ResourceBundle;
|
||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.ForkJoinPool;
|
||||||
|
import java.util.concurrent.ForkJoinTask;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@@ -149,66 +151,47 @@ public class PlayerEnvironment
|
|||||||
|
|
||||||
Queue queue = Queue.getInstance();
|
Queue queue = Queue.getInstance();
|
||||||
PlayerManager playback = PlayerManager.getPlayers();
|
PlayerManager playback = PlayerManager.getPlayers();
|
||||||
queue.addSongChangeListener(queue1 -> {
|
queue.addSongChangeListener(queue1 -> ForkJoinPool.commonPool().submit(() -> {
|
||||||
QueryFuture<Void> command = PlayerManager.getPlayers()
|
ForkJoinTask<Void> command = PlayerManager.getPlayers()
|
||||||
.stopSong();
|
.stopSong();
|
||||||
try
|
command.join();
|
||||||
|
if (command.isCompletedAbnormally())
|
||||||
{
|
{
|
||||||
if (command != null && !command.getConfirmation()
|
logger.error("Could not run command",
|
||||||
.wasSuccessful())
|
command.getException());
|
||||||
|
if (Interface.getInstance() != null)
|
||||||
{
|
{
|
||||||
|
JOptionPane
|
||||||
|
.showMessageDialog(Interface.getInstance(),
|
||||||
|
command.getException(),
|
||||||
|
command.getException().getMessage(),
|
||||||
|
JOptionPane.ERROR_MESSAGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (queue1.getCurrentSong() != null)
|
||||||
|
{
|
||||||
|
command =
|
||||||
|
PlayerManager.getPlayers()
|
||||||
|
.playSong(queue1.getCurrentSong());
|
||||||
|
command.join();
|
||||||
|
if (command.isCompletedAbnormally())
|
||||||
|
{
|
||||||
|
logger.error("Could not run command",
|
||||||
|
command.getException());
|
||||||
if (Interface.getInstance() != null)
|
if (Interface.getInstance() != null)
|
||||||
{
|
{
|
||||||
JOptionPane
|
JOptionPane
|
||||||
.showMessageDialog(Interface.getInstance(),
|
.showMessageDialog(Interface.getInstance(),
|
||||||
command.getConfirmation()
|
command.getException(),
|
||||||
.getError(),
|
command.getException().getMessage(),
|
||||||
command.getConfirmation()
|
|
||||||
.getMessage(),
|
|
||||||
JOptionPane.ERROR_MESSAGE);
|
JOptionPane.ERROR_MESSAGE);
|
||||||
}
|
}
|
||||||
logger.error("Could not run command",
|
|
||||||
command.getConfirmation().getError());
|
|
||||||
}
|
|
||||||
else if (queue1.getCurrentSong() != null)
|
|
||||||
{
|
|
||||||
command =
|
|
||||||
PlayerManager.getPlayers()
|
|
||||||
.playSong(queue1.getCurrentSong());
|
|
||||||
if (!command.getConfirmation().wasSuccessful())
|
|
||||||
{
|
|
||||||
if (Interface.getInstance() != null)
|
|
||||||
{
|
|
||||||
JOptionPane.showMessageDialog(Interface
|
|
||||||
.getInstance(),
|
|
||||||
command.getConfirmation().getError(),
|
|
||||||
command.getConfirmation().getMessage(),
|
|
||||||
JOptionPane.ERROR_MESSAGE);
|
|
||||||
}
|
|
||||||
logger.error("Could not run command",
|
|
||||||
command.getConfirmation().getError());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (ExecutionException | InterruptedException e)
|
}));
|
||||||
{
|
|
||||||
logger.error("Could not get current playback status", e);
|
|
||||||
if (Interface.getInstance() != null)
|
|
||||||
{
|
|
||||||
JOptionPane
|
|
||||||
.showMessageDialog(Interface.getInstance(), e
|
|
||||||
.getMessage()
|
|
||||||
, langs
|
|
||||||
.getString(
|
|
||||||
"error.command"), JOptionPane.ERROR_MESSAGE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
playback.addPlaybackListener(status -> {
|
playback.addPlaybackListener(status -> {
|
||||||
logger.info("Receiving {} from {}", status.getInfo(), status.getSource());
|
logger.info("Receiving {} from {}", status.getInfo(), status
|
||||||
|
.getSource());
|
||||||
if (status.getInfo().getStatus() == PlaybackStatus.FINISHED)
|
if (status.getInfo().getStatus() == PlaybackStatus.FINISHED)
|
||||||
{
|
{
|
||||||
Queue.getInstance().skipNext();
|
Queue.getInstance().skipNext();
|
||||||
@@ -411,16 +394,9 @@ public class PlayerEnvironment
|
|||||||
out.println("Clearing");
|
out.println("Clearing");
|
||||||
}
|
}
|
||||||
case "status" -> {
|
case "status" -> {
|
||||||
QueryFuture<PlaybackStatus> status =
|
ForkJoinTask<PlaybackStatus> status =
|
||||||
PlayerManager.getPlayers().getStatus();
|
PlayerManager.getPlayers().getStatus();
|
||||||
try
|
out.println(status.join());
|
||||||
{
|
|
||||||
out.println(status.get());
|
|
||||||
}
|
|
||||||
catch (InterruptedException | ExecutionException e)
|
|
||||||
{
|
|
||||||
e.printStackTrace(out);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
case "song" -> {
|
case "song" -> {
|
||||||
Song song = PlayerManager.getPlayers().getCurrentSong();
|
Song song = PlayerManager.getPlayers().getCurrentSong();
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import java.util.Locale;
|
|||||||
import java.util.ResourceBundle;
|
import java.util.ResourceBundle;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.ForkJoinTask;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Interface class serves as the primary GUI that the player interacts
|
* The Interface class serves as the primary GUI that the player interacts
|
||||||
@@ -76,8 +77,6 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
|
|||||||
*/
|
*/
|
||||||
private final PlayerControls controls;
|
private final PlayerControls controls;
|
||||||
|
|
||||||
private int currentPlayer = -1;
|
|
||||||
|
|
||||||
public static Interface getInstance()
|
public static Interface getInstance()
|
||||||
{
|
{
|
||||||
return INSTANCE;
|
return INSTANCE;
|
||||||
@@ -230,41 +229,23 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
|
|||||||
* thread.
|
* thread.
|
||||||
*
|
*
|
||||||
* @return the computed result
|
* @return the computed result
|
||||||
* @throws Exception if unable to compute a result
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Void doInBackground() throws Exception
|
protected Void doInBackground()
|
||||||
{
|
{
|
||||||
QueryFuture<Void> command = PlayerManager
|
ForkJoinTask<Void> command = PlayerManager
|
||||||
.getPlayers().throwError(false);
|
.getPlayers().throwError(false);
|
||||||
try
|
command.join();
|
||||||
|
if (command.isCompletedAbnormally())
|
||||||
{
|
{
|
||||||
if (!command.getConfirmation()
|
logger.error("Could not run command",
|
||||||
.wasSuccessful())
|
command.getException());
|
||||||
{
|
|
||||||
logger.error("Could not run command",
|
|
||||||
command.getConfirmation()
|
|
||||||
.getError());
|
|
||||||
JOptionPane
|
|
||||||
.showMessageDialog(Interface.this,
|
|
||||||
command.getConfirmation()
|
|
||||||
.getError(),
|
|
||||||
command.getConfirmation()
|
|
||||||
.getMessage(),
|
|
||||||
JOptionPane.ERROR_MESSAGE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (ExecutionException | InterruptedException executionException)
|
|
||||||
{
|
|
||||||
logger.error("Error" +
|
|
||||||
" creating " +
|
|
||||||
"debug " +
|
|
||||||
"message", executionException);
|
|
||||||
JOptionPane
|
JOptionPane
|
||||||
.showMessageDialog(Interface.this, executionException
|
.showMessageDialog(Interface.this,
|
||||||
.getMessage(), langs
|
command.getException(),
|
||||||
.getString(
|
command.getException()
|
||||||
"error.command"), JOptionPane.ERROR_MESSAGE);
|
.getMessage(),
|
||||||
|
JOptionPane.ERROR_MESSAGE);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -298,7 +279,8 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
|
|||||||
if (this.isEnabled())
|
if (this.isEnabled())
|
||||||
{
|
{
|
||||||
collectionTypes
|
collectionTypes
|
||||||
.triggerSongDisplayListeners(new ArrayList<>(PlayerEnvironment.getSongs()
|
.triggerSongDisplayListeners(new ArrayList<>(PlayerEnvironment
|
||||||
|
.getSongs()
|
||||||
.getSongs()));
|
.getSongs()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -314,7 +296,8 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
|
|||||||
if (this.isEnabled())
|
if (this.isEnabled())
|
||||||
{
|
{
|
||||||
collectionTypes
|
collectionTypes
|
||||||
.triggerCollectionDisplayListeners(CollectionType.albumArtist, PlayerEnvironment.getAlbums()
|
.triggerCollectionDisplayListeners(CollectionType.albumArtist, PlayerEnvironment
|
||||||
|
.getAlbums()
|
||||||
.getAlbumArtists());
|
.getAlbumArtists());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -330,7 +313,8 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
|
|||||||
if (this.isEnabled())
|
if (this.isEnabled())
|
||||||
{
|
{
|
||||||
collectionTypes
|
collectionTypes
|
||||||
.triggerCollectionDisplayListeners(CollectionType.album, PlayerEnvironment.getSongs()
|
.triggerCollectionDisplayListeners(CollectionType.album, PlayerEnvironment
|
||||||
|
.getSongs()
|
||||||
.getAlbums());
|
.getAlbums());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -346,7 +330,8 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
|
|||||||
if (this.isEnabled())
|
if (this.isEnabled())
|
||||||
{
|
{
|
||||||
collectionTypes
|
collectionTypes
|
||||||
.triggerCollectionDisplayListeners(CollectionType.genre, PlayerEnvironment.getAlbums()
|
.triggerCollectionDisplayListeners(CollectionType.genre, PlayerEnvironment
|
||||||
|
.getAlbums()
|
||||||
.getGenres());
|
.getGenres());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -362,7 +347,8 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
|
|||||||
if (this.isEnabled())
|
if (this.isEnabled())
|
||||||
{
|
{
|
||||||
collectionTypes
|
collectionTypes
|
||||||
.triggerCollectionDisplayListeners(CollectionType.year, PlayerEnvironment.getAlbums()
|
.triggerCollectionDisplayListeners(CollectionType.year, PlayerEnvironment
|
||||||
|
.getAlbums()
|
||||||
.getYears());
|
.getYears());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import java.util.Locale;
|
|||||||
import java.util.ResourceBundle;
|
import java.util.ResourceBundle;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.ForkJoinPool;
|
import java.util.concurrent.ForkJoinPool;
|
||||||
|
import java.util.concurrent.ForkJoinTask;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This panel contains the buttons necessary for controlling the playback of
|
* This panel contains the buttons necessary for controlling the playback of
|
||||||
@@ -181,27 +182,15 @@ public class PlayerControls extends JPanel implements PlaybackListener
|
|||||||
private void seek(float value)
|
private void seek(float value)
|
||||||
{
|
{
|
||||||
this.service.execute(() -> {
|
this.service.execute(() -> {
|
||||||
QueryFuture<Void> command = PlayerManager.getPlayers().seek(value);
|
ForkJoinTask<Void> status = PlayerManager.getPlayers().seek(value);
|
||||||
try
|
status.join();
|
||||||
{
|
if (status.isCompletedAbnormally())
|
||||||
if (command != null && !command.getConfirmation()
|
|
||||||
.wasSuccessful())
|
|
||||||
{
|
|
||||||
logger.error("Could not run command",
|
|
||||||
command.getConfirmation().getError());
|
|
||||||
JOptionPane.showMessageDialog(this,
|
|
||||||
command.getConfirmation().getError(),
|
|
||||||
command.getConfirmation().getMessage(),
|
|
||||||
JOptionPane.ERROR_MESSAGE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (ExecutionException | InterruptedException e)
|
|
||||||
{
|
{
|
||||||
logger.error("Could not run command",
|
logger.error("Could not run command",
|
||||||
e);
|
status.getException());
|
||||||
JOptionPane.showMessageDialog(this,
|
JOptionPane.showMessageDialog(this,
|
||||||
e,
|
status.getException(),
|
||||||
e.getMessage(),
|
status.getException().getMessage(),
|
||||||
JOptionPane.ERROR_MESSAGE);
|
JOptionPane.ERROR_MESSAGE);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -213,16 +202,15 @@ public class PlayerControls extends JPanel implements PlaybackListener
|
|||||||
this.service.execute(() -> {
|
this.service.execute(() -> {
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
QueryFuture<PlaybackStatus> status =
|
ForkJoinTask status =
|
||||||
PlayerManager.getPlayers().getStatus();
|
PlayerManager.getPlayers().getStatus();
|
||||||
CommandConfirmation confirmation = status.getConfirmation();
|
status.join();
|
||||||
if (status.getConfirmation().wasSuccessful())
|
if (status.isCompletedNormally())
|
||||||
{
|
{
|
||||||
switch (status.get())
|
switch ((PlaybackStatus) status.get())
|
||||||
{
|
{
|
||||||
case PAUSED -> confirmation = PlayerManager.getPlayers()
|
case PAUSED -> status = PlayerManager.getPlayers()
|
||||||
.play()
|
.play();
|
||||||
.getConfirmation();
|
|
||||||
case STOPPED, EMPTY -> {
|
case STOPPED, EMPTY -> {
|
||||||
if (Queue.getInstance().size() > 0)
|
if (Queue.getInstance().size() > 0)
|
||||||
{
|
{
|
||||||
@@ -230,23 +218,30 @@ public class PlayerControls extends JPanel implements PlaybackListener
|
|||||||
.getCurrentSong() == null)
|
.getCurrentSong() == null)
|
||||||
{
|
{
|
||||||
Queue.getInstance().skipToSong(0);
|
Queue.getInstance().skipToSong(0);
|
||||||
|
status = null;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
confirmation = PlayerManager.getPlayers().play()
|
status = PlayerManager.getPlayers().play();
|
||||||
.getConfirmation();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
default -> {
|
||||||
|
status = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (status != null)
|
||||||
|
{
|
||||||
|
status.join();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (confirmation != null && !confirmation.wasSuccessful())
|
if (status != null && status.isCompletedAbnormally())
|
||||||
{
|
{
|
||||||
logger.error("Could not run command",
|
logger.error("Could not run command",
|
||||||
confirmation.getError());
|
status.getException());
|
||||||
JOptionPane.showMessageDialog(this,
|
JOptionPane.showMessageDialog(this,
|
||||||
confirmation.getError(),
|
status.getException(),
|
||||||
confirmation.getMessage(),
|
status.getException().getMessage(),
|
||||||
JOptionPane.ERROR_MESSAGE);
|
JOptionPane.ERROR_MESSAGE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -266,25 +261,25 @@ public class PlayerControls extends JPanel implements PlaybackListener
|
|||||||
this.service.execute(() -> {
|
this.service.execute(() -> {
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
QueryFuture<PlaybackStatus> status =
|
ForkJoinTask status =
|
||||||
PlayerManager.getPlayers().getStatus();
|
PlayerManager.getPlayers().getStatus();
|
||||||
CommandConfirmation confirmation = status.getConfirmation();
|
status.join();
|
||||||
if (status.getConfirmation().wasSuccessful())
|
if (status.isCompletedNormally())
|
||||||
{
|
{
|
||||||
if (status.get() == PlaybackStatus.PLAYING)
|
if (status.get() == PlaybackStatus.PLAYING)
|
||||||
{
|
{
|
||||||
confirmation =
|
status =
|
||||||
PlayerManager.getPlayers().pause()
|
PlayerManager.getPlayers().pause();
|
||||||
.getConfirmation();
|
status.join();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (confirmation != null && !confirmation.wasSuccessful())
|
if (status.isCompletedAbnormally())
|
||||||
{
|
{
|
||||||
logger.error("Could not run command",
|
logger.error("Could not run command",
|
||||||
confirmation.getError());
|
status.getException());
|
||||||
JOptionPane.showMessageDialog(this,
|
JOptionPane.showMessageDialog(this,
|
||||||
confirmation.getError(),
|
status.getException(),
|
||||||
confirmation.getMessage(),
|
status.getException().getMessage(),
|
||||||
JOptionPane.ERROR_MESSAGE);
|
JOptionPane.ERROR_MESSAGE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -307,19 +302,17 @@ public class PlayerControls extends JPanel implements PlaybackListener
|
|||||||
this.service.execute(() -> {
|
this.service.execute(() -> {
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
QueryFuture<PlaybackStatus> status =
|
ForkJoinTask status =
|
||||||
PlayerManager.getPlayers().getStatus();
|
PlayerManager.getPlayers().getStatus();
|
||||||
CommandConfirmation confirmation = status.getConfirmation();
|
status.join();
|
||||||
if (status.getConfirmation().wasSuccessful())
|
if (status.isCompletedNormally())
|
||||||
{
|
{
|
||||||
switch (status.get())
|
switch ((PlaybackStatus) status.get())
|
||||||
{
|
{
|
||||||
case PAUSED -> confirmation = PlayerManager.getPlayers()
|
case PAUSED -> status = PlayerManager.getPlayers()
|
||||||
.play()
|
.play();
|
||||||
.getConfirmation();
|
case PLAYING -> status = PlayerManager.getPlayers()
|
||||||
case PLAYING -> confirmation = PlayerManager.getPlayers()
|
.pause();
|
||||||
.pause()
|
|
||||||
.getConfirmation();
|
|
||||||
case STOPPED, EMPTY -> {
|
case STOPPED, EMPTY -> {
|
||||||
if (Queue.getInstance().size() > 0)
|
if (Queue.getInstance().size() > 0)
|
||||||
{
|
{
|
||||||
@@ -327,24 +320,29 @@ public class PlayerControls extends JPanel implements PlaybackListener
|
|||||||
.getCurrentSong() == null)
|
.getCurrentSong() == null)
|
||||||
{
|
{
|
||||||
Queue.getInstance().skipToSong(0);
|
Queue.getInstance().skipToSong(0);
|
||||||
|
status = null;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
confirmation = PlayerManager.getPlayers().play()
|
status = PlayerManager.getPlayers().play();
|
||||||
.getConfirmation();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
default -> status = null;
|
||||||
|
}
|
||||||
|
if (status != null)
|
||||||
|
{
|
||||||
|
status.join();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (confirmation != null && !confirmation.wasSuccessful())
|
if (status != null && status.isCompletedAbnormally())
|
||||||
{
|
{
|
||||||
JOptionPane.showMessageDialog(this,
|
|
||||||
confirmation.getError(),
|
|
||||||
confirmation.getMessage(),
|
|
||||||
JOptionPane.ERROR_MESSAGE);
|
|
||||||
logger.error("Could not run command",
|
logger.error("Could not run command",
|
||||||
confirmation.getError());
|
status.getException());
|
||||||
|
JOptionPane.showMessageDialog(this,
|
||||||
|
status.getException(),
|
||||||
|
status.getException().getMessage(),
|
||||||
|
JOptionPane.ERROR_MESSAGE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (ExecutionException | InterruptedException e)
|
catch (ExecutionException | InterruptedException e)
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ package edu.regis.universeplayer.player;
|
|||||||
|
|
||||||
import com.intervigil.wave.WaveReader;
|
import com.intervigil.wave.WaveReader;
|
||||||
|
|
||||||
|
import edu.regis.universeplayer.AbstractTask;
|
||||||
import edu.regis.universeplayer.PlaybackInfo;
|
import edu.regis.universeplayer.PlaybackInfo;
|
||||||
import edu.regis.universeplayer.PlaybackListener;
|
import edu.regis.universeplayer.PlaybackListener;
|
||||||
import edu.regis.universeplayer.PlaybackStatus;
|
import edu.regis.universeplayer.PlaybackStatus;
|
||||||
@@ -48,6 +49,7 @@ public class LocalPlayer implements Player<LocalSong>, MediaPlayerEventListener
|
|||||||
private final MediaPlayerFactory playerFactory;
|
private final MediaPlayerFactory playerFactory;
|
||||||
private final AudioPlayerComponent player;
|
private final AudioPlayerComponent player;
|
||||||
|
|
||||||
|
private final ForkJoinPool service = new ForkJoinPool();
|
||||||
private final LinkedList<PlaybackListener> listeners = new LinkedList<>();
|
private final LinkedList<PlaybackListener> listeners = new LinkedList<>();
|
||||||
|
|
||||||
private int currentId;
|
private int currentId;
|
||||||
@@ -55,8 +57,6 @@ public class LocalPlayer implements Player<LocalSong>, MediaPlayerEventListener
|
|||||||
private LocalSong currentSong;
|
private LocalSong currentSong;
|
||||||
private AudioFile currentFile;
|
private AudioFile currentFile;
|
||||||
|
|
||||||
private final ExecutorService service = Executors.newSingleThreadExecutor();
|
|
||||||
|
|
||||||
public LocalPlayer()
|
public LocalPlayer()
|
||||||
{
|
{
|
||||||
this.playerFactory = new MediaPlayerFactory();
|
this.playerFactory = new MediaPlayerFactory();
|
||||||
@@ -118,112 +118,196 @@ public class LocalPlayer implements Player<LocalSong>, MediaPlayerEventListener
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public QueryFuture<Void> loadSong(LocalSong song)
|
public ForkJoinTask<Void> loadSong(LocalSong song)
|
||||||
{
|
{
|
||||||
if (this.currentSong != null)
|
return this.service.submit(new AbstractTask<>()
|
||||||
{
|
{
|
||||||
this.stopSong();
|
@Override
|
||||||
}
|
protected boolean exec()
|
||||||
this.currentSong = song;
|
{
|
||||||
if (!this.player.mediaPlayer().media()
|
if (currentSong != null)
|
||||||
.play(song.file.getAbsolutePath()))
|
{
|
||||||
{
|
stopSong();
|
||||||
return new NullFuture<>(new RuntimeException("Could not play " +
|
}
|
||||||
"song " + song));
|
currentSong = song;
|
||||||
}
|
if (!player.mediaPlayer().media()
|
||||||
else
|
.play(song.file.getAbsolutePath()))
|
||||||
{
|
{
|
||||||
return new NullFuture<>();
|
this.completeExceptionally(new RuntimeException("Could not play " +
|
||||||
}
|
"song " + song));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public QueryFuture<Void> play()
|
public ForkJoinTask<Void> play()
|
||||||
|
{
|
||||||
|
this.player.mediaPlayer().submit(() -> this.player.mediaPlayer()
|
||||||
|
.controls()
|
||||||
|
.play());
|
||||||
|
return new AbstractTask<>()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
protected boolean exec()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ForkJoinTask<Void> pause()
|
||||||
{
|
{
|
||||||
this.player.mediaPlayer()
|
this.player.mediaPlayer()
|
||||||
.submit((WrappedRunnable) () -> this.player.mediaPlayer()
|
.submit(() -> this.player.mediaPlayer()
|
||||||
.controls()
|
.controls()
|
||||||
.play());
|
.pause());
|
||||||
return new NullFuture<>();
|
return new AbstractTask<>()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
protected boolean exec()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public QueryFuture<Void> pause()
|
public ForkJoinTask<Void> togglePlayback()
|
||||||
|
{
|
||||||
|
return this.service.submit(new AbstractTask<>()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
protected boolean exec()
|
||||||
|
{
|
||||||
|
ForkJoinTask<Void> command;
|
||||||
|
if (player.mediaPlayer().status().isPlaying())
|
||||||
|
{
|
||||||
|
command = pause();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
command = play();
|
||||||
|
}
|
||||||
|
command.join();
|
||||||
|
if (command.isCompletedAbnormally())
|
||||||
|
{
|
||||||
|
this.completeExceptionally(command.getException());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ForkJoinTask<Void> stopSong()
|
||||||
{
|
{
|
||||||
this.player.mediaPlayer()
|
this.player.mediaPlayer()
|
||||||
.submit((WrappedRunnable) () -> this.player.mediaPlayer()
|
.submit(() -> this.player.mediaPlayer()
|
||||||
.controls()
|
.controls()
|
||||||
.pause());
|
.stop());
|
||||||
return new NullFuture<>();
|
return new AbstractTask<>()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
protected boolean exec()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public QueryFuture<Void> togglePlayback()
|
public ForkJoinTask<Void> seek(float time)
|
||||||
{
|
|
||||||
if (this.player.mediaPlayer().status().isPlaying())
|
|
||||||
{
|
|
||||||
return this.pause();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return this.play();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public QueryFuture<Void> stopSong()
|
|
||||||
{
|
{
|
||||||
this.player.mediaPlayer()
|
this.player.mediaPlayer()
|
||||||
.submit((WrappedRunnable) () -> this.player.mediaPlayer()
|
.submit(() -> this.player.mediaPlayer()
|
||||||
.controls()
|
.controls()
|
||||||
.stop());
|
.setTime((long) (time * 1000)));
|
||||||
return new NullFuture<>();
|
return new AbstractTask<>()
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public QueryFuture<Void> seek(float time)
|
|
||||||
{
|
|
||||||
this.player.mediaPlayer()
|
|
||||||
.submit((WrappedRunnable) () -> this.player.mediaPlayer()
|
|
||||||
.controls()
|
|
||||||
.setTime((long) (time * 1000)));
|
|
||||||
return new NullFuture<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public QueryFuture<PlaybackStatus> getStatus()
|
|
||||||
{
|
|
||||||
PlaybackStatus returnStatus;
|
|
||||||
StatusApi status = this.player.mediaPlayer().status();
|
|
||||||
switch (status.state())
|
|
||||||
{
|
{
|
||||||
case NOTHING_SPECIAL -> returnStatus = PlaybackStatus.EMPTY;
|
@Override
|
||||||
case PLAYING -> returnStatus = PlaybackStatus.PLAYING;
|
protected boolean exec()
|
||||||
case PAUSED -> returnStatus = PlaybackStatus.PAUSED;
|
{
|
||||||
default -> returnStatus = PlaybackStatus.STOPPED;
|
return true;
|
||||||
}
|
}
|
||||||
return new NullFuture<>(returnStatus);
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public QueryFuture<Float> getCurrentTime()
|
public ForkJoinTask<PlaybackStatus> getStatus()
|
||||||
{
|
{
|
||||||
return new NullFuture<>(this.player.mediaPlayer().status()
|
return this.service.submit(new AbstractTask<>()
|
||||||
.time() / 1000F);
|
{
|
||||||
|
@Override
|
||||||
|
protected boolean exec()
|
||||||
|
{
|
||||||
|
PlaybackStatus returnStatus;
|
||||||
|
StatusApi status = player.mediaPlayer().status();
|
||||||
|
switch (status.state())
|
||||||
|
{
|
||||||
|
case NOTHING_SPECIAL -> returnStatus = PlaybackStatus.EMPTY;
|
||||||
|
case PLAYING -> returnStatus = PlaybackStatus.PLAYING;
|
||||||
|
case PAUSED -> returnStatus = PlaybackStatus.PAUSED;
|
||||||
|
default -> returnStatus = PlaybackStatus.STOPPED;
|
||||||
|
}
|
||||||
|
this.complete(returnStatus);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public QueryFuture<Float> getLength()
|
public ForkJoinTask<Float> getCurrentTime()
|
||||||
{
|
{
|
||||||
return new NullFuture<>(this.player.mediaPlayer().status()
|
return this.service.submit(new AbstractTask<>()
|
||||||
.length() / 1000F);
|
{
|
||||||
|
@Override
|
||||||
|
protected boolean exec()
|
||||||
|
{
|
||||||
|
complete(player.mediaPlayer().status()
|
||||||
|
.time() / 1000F);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public QueryFuture<Void> close()
|
public ForkJoinTask<Float> getLength()
|
||||||
{
|
{
|
||||||
this.player.release();
|
return this.service.submit(new AbstractTask<>()
|
||||||
return new NullFuture<>();
|
{
|
||||||
|
@Override
|
||||||
|
protected boolean exec()
|
||||||
|
{
|
||||||
|
complete(player.mediaPlayer().status()
|
||||||
|
.length() / 1000F);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ForkJoinTask<Void> close()
|
||||||
|
{
|
||||||
|
return this.service.submit(new AbstractTask<>()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
protected boolean exec()
|
||||||
|
{
|
||||||
|
player.release();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import edu.regis.universeplayer.browserCommands.QueryFuture;
|
|||||||
import edu.regis.universeplayer.data.Song;
|
import edu.regis.universeplayer.data.Song;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.concurrent.ForkJoinTask;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This interface serves as the connection to a music player of some sort, whether it be
|
* This interface serves as the connection to a music player of some sort, whether it be
|
||||||
@@ -34,33 +35,33 @@ public interface Player<T extends Song>
|
|||||||
* @param song - The song to load.
|
* @param song - The song to load.
|
||||||
* @return A confirmation of whether the command was successful or not.
|
* @return A confirmation of whether the command was successful or not.
|
||||||
*/
|
*/
|
||||||
QueryFuture<Void> loadSong(T song);
|
ForkJoinTask<Void> loadSong(T song);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enables playback of the current song, if one is active.
|
* Enables playback of the current song, if one is active.
|
||||||
*
|
*
|
||||||
* @return A confirmation of whether the command was successful or not.
|
* @return A confirmation of whether the command was successful or not.
|
||||||
*/
|
*/
|
||||||
QueryFuture<Void> play();
|
ForkJoinTask<Void> play();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pauses playback of the current song.
|
* Pauses playback of the current song.
|
||||||
*
|
*
|
||||||
* @return A confirmation of whether the command was successful or not.
|
* @return A confirmation of whether the command was successful or not.
|
||||||
*/
|
*/
|
||||||
QueryFuture<Void> pause();
|
ForkJoinTask<Void> pause();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggles between playing and pausing the current song.
|
* Toggles between playing and pausing the current song.
|
||||||
*
|
*
|
||||||
* @return A confirmation of whether the command was successful or not.
|
* @return A confirmation of whether the command was successful or not.
|
||||||
*/
|
*/
|
||||||
QueryFuture<Void> togglePlayback();
|
ForkJoinTask<Void> togglePlayback();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stops playback of the current song.
|
* Stops playback of the current song.
|
||||||
*/
|
*/
|
||||||
QueryFuture<Void> stopSong();
|
ForkJoinTask<Void> stopSong();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the current song time to the specified position.
|
* Sets the current song time to the specified position.
|
||||||
@@ -68,34 +69,34 @@ public interface Player<T extends Song>
|
|||||||
* @param time - The specified time in the song, in seconds.
|
* @param time - The specified time in the song, in seconds.
|
||||||
* @return A confirmation of whether the command was successful or not.
|
* @return A confirmation of whether the command was successful or not.
|
||||||
*/
|
*/
|
||||||
QueryFuture<Void> seek(float time);
|
ForkJoinTask<Void> seek(float time);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtains the player's current playback status.
|
* Obtains the player's current playback status.
|
||||||
* @return A future for the request.
|
* @return A future for the request.
|
||||||
*/
|
*/
|
||||||
QueryFuture<PlaybackStatus> getStatus();
|
ForkJoinTask<PlaybackStatus> getStatus();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtains the time we are currently at in the current song.
|
* Obtains the time we are currently at in the current song.
|
||||||
*
|
*
|
||||||
* @return - The current song position in seconds, or -1 if no song is playing.
|
* @return - The current song position in seconds, or -1 if no song is playing.
|
||||||
*/
|
*/
|
||||||
QueryFuture<Float> getCurrentTime();
|
ForkJoinTask<Float> getCurrentTime();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the length of the current song.
|
* Gets the length of the current song.
|
||||||
*
|
*
|
||||||
* @return The song length, in seconds.
|
* @return The song length, in seconds.
|
||||||
*/
|
*/
|
||||||
QueryFuture<Float> getLength();
|
ForkJoinTask<Float> getLength();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Closes the player.
|
* Closes the player.
|
||||||
*
|
*
|
||||||
* @return A confirmation of whether the player was successfully closed.
|
* @return A confirmation of whether the player was successfully closed.
|
||||||
*/
|
*/
|
||||||
QueryFuture<Void> close();
|
ForkJoinTask<Void> close();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a listener for playback status updates.
|
* Adds a listener for playback status updates.
|
||||||
|
|||||||
@@ -7,11 +7,13 @@ import java.util.HashMap;
|
|||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.concurrent.CancellationException;
|
import java.util.concurrent.CancellationException;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.ForkJoinTask;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
|
|
||||||
|
import edu.regis.universeplayer.AbstractTask;
|
||||||
import edu.regis.universeplayer.PlaybackListener;
|
import edu.regis.universeplayer.PlaybackListener;
|
||||||
import edu.regis.universeplayer.PlaybackStatus;
|
import edu.regis.universeplayer.PlaybackStatus;
|
||||||
import edu.regis.universeplayer.browserCommands.CommandConfirmation;
|
import edu.regis.universeplayer.browserCommands.CommandConfirmation;
|
||||||
@@ -150,10 +152,10 @@ public class PlayerManager implements PlaybackListener
|
|||||||
*/
|
*/
|
||||||
private <T> QueryFuture<T> getNullPlayer(String message, T returnValue)
|
private <T> QueryFuture<T> getNullPlayer(String message, T returnValue)
|
||||||
{
|
{
|
||||||
return new QueryFuture<T>()
|
return new QueryFuture<>()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public CommandConfirmation getConfirmation() throws CancellationException, ExecutionException, InterruptedException
|
public CommandConfirmation getConfirmation() throws CancellationException
|
||||||
{
|
{
|
||||||
if (returnValue instanceof Throwable)
|
if (returnValue instanceof Throwable)
|
||||||
{
|
{
|
||||||
@@ -166,7 +168,7 @@ public class PlayerManager implements PlaybackListener
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommandConfirmation getConfirmation(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException
|
public CommandConfirmation getConfirmation(long timeout, TimeUnit unit)
|
||||||
{
|
{
|
||||||
return this.getConfirmation();
|
return this.getConfirmation();
|
||||||
}
|
}
|
||||||
@@ -190,13 +192,13 @@ public class PlayerManager implements PlaybackListener
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public T get() throws InterruptedException, ExecutionException
|
public T get()
|
||||||
{
|
{
|
||||||
return returnValue;
|
return returnValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException
|
public T get(long timeout, TimeUnit unit)
|
||||||
{
|
{
|
||||||
return this.get();
|
return this.get();
|
||||||
}
|
}
|
||||||
@@ -211,16 +213,16 @@ public class PlayerManager implements PlaybackListener
|
|||||||
*/
|
*/
|
||||||
private <T> QueryFuture<T> getNullPlayer(Throwable message, T returnValue)
|
private <T> QueryFuture<T> getNullPlayer(Throwable message, T returnValue)
|
||||||
{
|
{
|
||||||
return new QueryFuture<T>()
|
return new QueryFuture<>()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public CommandConfirmation getConfirmation() throws CancellationException, ExecutionException, InterruptedException
|
public CommandConfirmation getConfirmation() throws CancellationException
|
||||||
{
|
{
|
||||||
return new CommandConfirmation(message);
|
return new CommandConfirmation(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommandConfirmation getConfirmation(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException
|
public CommandConfirmation getConfirmation(long timeout, TimeUnit unit)
|
||||||
{
|
{
|
||||||
return this.getConfirmation();
|
return this.getConfirmation();
|
||||||
}
|
}
|
||||||
@@ -244,20 +246,20 @@ public class PlayerManager implements PlaybackListener
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public T get() throws InterruptedException, ExecutionException
|
public T get()
|
||||||
{
|
{
|
||||||
return returnValue;
|
return returnValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException
|
public T get(long timeout, TimeUnit unit)
|
||||||
{
|
{
|
||||||
return this.get();
|
return this.get();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public QueryFuture<Void> playSong(Song song)
|
public ForkJoinTask<Void> playSong(Song song)
|
||||||
{
|
{
|
||||||
if (this.currentSong != null)
|
if (this.currentSong != null)
|
||||||
{
|
{
|
||||||
@@ -274,16 +276,24 @@ public class PlayerManager implements PlaybackListener
|
|||||||
return this.currentPlayer.loadSong(song);
|
return this.currentPlayer.loadSong(song);
|
||||||
}
|
}
|
||||||
|
|
||||||
public QueryFuture<PlaybackStatus> getStatus()
|
public ForkJoinTask<PlaybackStatus> getStatus()
|
||||||
{
|
{
|
||||||
if (this.currentPlayer != null)
|
if (this.currentPlayer != null)
|
||||||
{
|
{
|
||||||
return this.currentPlayer.getStatus();
|
return this.currentPlayer.getStatus();
|
||||||
}
|
}
|
||||||
return this.getNullPlayer("Command successful", PlaybackStatus.EMPTY);
|
return new AbstractTask<>()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
protected boolean exec()
|
||||||
|
{
|
||||||
|
complete(PlaybackStatus.EMPTY);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public QueryFuture<Void> seek(float time)
|
public ForkJoinTask<Void> seek(float time)
|
||||||
{
|
{
|
||||||
if (this.currentPlayer != null)
|
if (this.currentPlayer != null)
|
||||||
{
|
{
|
||||||
@@ -292,7 +302,7 @@ public class PlayerManager implements PlaybackListener
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public QueryFuture<Void> play()
|
public ForkJoinTask<Void> play()
|
||||||
{
|
{
|
||||||
if (this.currentPlayer != null && this.currentSong != null)
|
if (this.currentPlayer != null && this.currentSong != null)
|
||||||
{
|
{
|
||||||
@@ -301,7 +311,7 @@ public class PlayerManager implements PlaybackListener
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public QueryFuture<Void> pause()
|
public ForkJoinTask<Void> pause()
|
||||||
{
|
{
|
||||||
if (this.currentPlayer != null && this.currentSong != null)
|
if (this.currentPlayer != null && this.currentSong != null)
|
||||||
{
|
{
|
||||||
@@ -310,7 +320,7 @@ public class PlayerManager implements PlaybackListener
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public QueryFuture<Void> toggle()
|
public ForkJoinTask<Void> toggle()
|
||||||
{
|
{
|
||||||
if (this.currentPlayer != null && this.currentSong != null)
|
if (this.currentPlayer != null && this.currentSong != null)
|
||||||
{
|
{
|
||||||
@@ -319,7 +329,7 @@ public class PlayerManager implements PlaybackListener
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public QueryFuture<Void> stopSong()
|
public ForkJoinTask<Void> stopSong()
|
||||||
{
|
{
|
||||||
if (this.currentPlayer != null && this.currentSong != null)
|
if (this.currentPlayer != null && this.currentSong != null)
|
||||||
{
|
{
|
||||||
@@ -370,14 +380,22 @@ public class PlayerManager implements PlaybackListener
|
|||||||
* script or a background script.
|
* script or a background script.
|
||||||
* @return The command future.
|
* @return The command future.
|
||||||
*/
|
*/
|
||||||
public QueryFuture<Void> throwError(boolean forward)
|
public ForkJoinTask<Void> throwError(boolean forward)
|
||||||
{
|
{
|
||||||
BrowserPlayer player =
|
BrowserPlayer player =
|
||||||
(BrowserPlayer) this.players.get(InternetSong.class);
|
(BrowserPlayer) this.players.get(InternetSong.class);
|
||||||
if (player == null)
|
if (player == null)
|
||||||
{
|
{
|
||||||
return this.getNullPlayer(new NullPointerException(
|
return new AbstractTask<>()
|
||||||
"No browser found"), null);
|
{
|
||||||
|
@Override
|
||||||
|
protected boolean exec()
|
||||||
|
{
|
||||||
|
completeExceptionally(new NullPointerException("Couldn't " +
|
||||||
|
"find internet player"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
return player.throwError(forward);
|
return player.throwError(forward);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user