Moved most player tasks to ForkJoin.

This system works a bit better.
This commit is contained in:
Markil3
2021-09-18 16:04:37 -06:00
parent 2e2748f9e9
commit 0ffa626cb7
7 changed files with 366 additions and 262 deletions

View File

@@ -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;
}
}

View File

@@ -17,6 +17,8 @@ import java.util.Map;
import java.util.ResourceBundle;
import java.util.Scanner;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
@@ -149,66 +151,47 @@ public class PlayerEnvironment
Queue queue = Queue.getInstance();
PlayerManager playback = PlayerManager.getPlayers();
queue.addSongChangeListener(queue1 -> {
QueryFuture<Void> command = PlayerManager.getPlayers()
.stopSong();
try
queue.addSongChangeListener(queue1 -> ForkJoinPool.commonPool().submit(() -> {
ForkJoinTask<Void> command = PlayerManager.getPlayers()
.stopSong();
command.join();
if (command.isCompletedAbnormally())
{
if (command != null && !command.getConfirmation()
.wasSuccessful())
logger.error("Could not run command",
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)
{
JOptionPane
.showMessageDialog(Interface.getInstance(),
command.getConfirmation()
.getError(),
command.getConfirmation()
.getMessage(),
command.getException(),
command.getException().getMessage(),
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 -> {
logger.info("Receiving {} from {}", status.getInfo(), status.getSource());
logger.info("Receiving {} from {}", status.getInfo(), status
.getSource());
if (status.getInfo().getStatus() == PlaybackStatus.FINISHED)
{
Queue.getInstance().skipNext();
@@ -411,16 +394,9 @@ public class PlayerEnvironment
out.println("Clearing");
}
case "status" -> {
QueryFuture<PlaybackStatus> status =
ForkJoinTask<PlaybackStatus> status =
PlayerManager.getPlayers().getStatus();
try
{
out.println(status.get());
}
catch (InterruptedException | ExecutionException e)
{
e.printStackTrace(out);
}
out.println(status.join());
}
case "song" -> {
Song song = PlayerManager.getPlayers().getCurrentSong();

View File

@@ -29,6 +29,7 @@ import java.util.Locale;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinTask;
/**
* 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 int currentPlayer = -1;
public static Interface getInstance()
{
return INSTANCE;
@@ -230,41 +229,23 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
* thread.
*
* @return the computed result
* @throws Exception if unable to compute a result
*/
@Override
protected Void doInBackground() throws Exception
protected Void doInBackground()
{
QueryFuture<Void> command = PlayerManager
ForkJoinTask<Void> command = PlayerManager
.getPlayers().throwError(false);
try
command.join();
if (command.isCompletedAbnormally())
{
if (!command.getConfirmation()
.wasSuccessful())
{
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);
logger.error("Could not run command",
command.getException());
JOptionPane
.showMessageDialog(Interface.this, executionException
.getMessage(), langs
.getString(
"error.command"), JOptionPane.ERROR_MESSAGE);
.showMessageDialog(Interface.this,
command.getException(),
command.getException()
.getMessage(),
JOptionPane.ERROR_MESSAGE);
}
return null;
}
@@ -298,7 +279,8 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
if (this.isEnabled())
{
collectionTypes
.triggerSongDisplayListeners(new ArrayList<>(PlayerEnvironment.getSongs()
.triggerSongDisplayListeners(new ArrayList<>(PlayerEnvironment
.getSongs()
.getSongs()));
}
}
@@ -314,7 +296,8 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
if (this.isEnabled())
{
collectionTypes
.triggerCollectionDisplayListeners(CollectionType.albumArtist, PlayerEnvironment.getAlbums()
.triggerCollectionDisplayListeners(CollectionType.albumArtist, PlayerEnvironment
.getAlbums()
.getAlbumArtists());
}
}
@@ -330,7 +313,8 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
if (this.isEnabled())
{
collectionTypes
.triggerCollectionDisplayListeners(CollectionType.album, PlayerEnvironment.getSongs()
.triggerCollectionDisplayListeners(CollectionType.album, PlayerEnvironment
.getSongs()
.getAlbums());
}
}
@@ -346,7 +330,8 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
if (this.isEnabled())
{
collectionTypes
.triggerCollectionDisplayListeners(CollectionType.genre, PlayerEnvironment.getAlbums()
.triggerCollectionDisplayListeners(CollectionType.genre, PlayerEnvironment
.getAlbums()
.getGenres());
}
}
@@ -362,7 +347,8 @@ public class Interface extends JFrame implements SongDisplayListener, ComponentL
if (this.isEnabled())
{
collectionTypes
.triggerCollectionDisplayListeners(CollectionType.year, PlayerEnvironment.getAlbums()
.triggerCollectionDisplayListeners(CollectionType.year, PlayerEnvironment
.getAlbums()
.getYears());
}
}

View File

@@ -29,6 +29,7 @@ import java.util.Locale;
import java.util.ResourceBundle;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
/**
* 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)
{
this.service.execute(() -> {
QueryFuture<Void> command = PlayerManager.getPlayers().seek(value);
try
{
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)
ForkJoinTask<Void> status = PlayerManager.getPlayers().seek(value);
status.join();
if (status.isCompletedAbnormally())
{
logger.error("Could not run command",
e);
status.getException());
JOptionPane.showMessageDialog(this,
e,
e.getMessage(),
status.getException(),
status.getException().getMessage(),
JOptionPane.ERROR_MESSAGE);
}
});
@@ -213,16 +202,15 @@ public class PlayerControls extends JPanel implements PlaybackListener
this.service.execute(() -> {
try
{
QueryFuture<PlaybackStatus> status =
ForkJoinTask status =
PlayerManager.getPlayers().getStatus();
CommandConfirmation confirmation = status.getConfirmation();
if (status.getConfirmation().wasSuccessful())
status.join();
if (status.isCompletedNormally())
{
switch (status.get())
switch ((PlaybackStatus) status.get())
{
case PAUSED -> confirmation = PlayerManager.getPlayers()
.play()
.getConfirmation();
case PAUSED -> status = PlayerManager.getPlayers()
.play();
case STOPPED, EMPTY -> {
if (Queue.getInstance().size() > 0)
{
@@ -230,23 +218,30 @@ public class PlayerControls extends JPanel implements PlaybackListener
.getCurrentSong() == null)
{
Queue.getInstance().skipToSong(0);
status = null;
}
else
{
confirmation = PlayerManager.getPlayers().play()
.getConfirmation();
status = PlayerManager.getPlayers().play();
}
}
}
default -> {
status = null;
}
}
if (status != null)
{
status.join();
}
}
if (confirmation != null && !confirmation.wasSuccessful())
if (status != null && status.isCompletedAbnormally())
{
logger.error("Could not run command",
confirmation.getError());
status.getException());
JOptionPane.showMessageDialog(this,
confirmation.getError(),
confirmation.getMessage(),
status.getException(),
status.getException().getMessage(),
JOptionPane.ERROR_MESSAGE);
}
}
@@ -266,25 +261,25 @@ public class PlayerControls extends JPanel implements PlaybackListener
this.service.execute(() -> {
try
{
QueryFuture<PlaybackStatus> status =
ForkJoinTask status =
PlayerManager.getPlayers().getStatus();
CommandConfirmation confirmation = status.getConfirmation();
if (status.getConfirmation().wasSuccessful())
status.join();
if (status.isCompletedNormally())
{
if (status.get() == PlaybackStatus.PLAYING)
{
confirmation =
PlayerManager.getPlayers().pause()
.getConfirmation();
status =
PlayerManager.getPlayers().pause();
status.join();
}
}
if (confirmation != null && !confirmation.wasSuccessful())
if (status.isCompletedAbnormally())
{
logger.error("Could not run command",
confirmation.getError());
status.getException());
JOptionPane.showMessageDialog(this,
confirmation.getError(),
confirmation.getMessage(),
status.getException(),
status.getException().getMessage(),
JOptionPane.ERROR_MESSAGE);
}
}
@@ -307,19 +302,17 @@ public class PlayerControls extends JPanel implements PlaybackListener
this.service.execute(() -> {
try
{
QueryFuture<PlaybackStatus> status =
ForkJoinTask status =
PlayerManager.getPlayers().getStatus();
CommandConfirmation confirmation = status.getConfirmation();
if (status.getConfirmation().wasSuccessful())
status.join();
if (status.isCompletedNormally())
{
switch (status.get())
switch ((PlaybackStatus) status.get())
{
case PAUSED -> confirmation = PlayerManager.getPlayers()
.play()
.getConfirmation();
case PLAYING -> confirmation = PlayerManager.getPlayers()
.pause()
.getConfirmation();
case PAUSED -> status = PlayerManager.getPlayers()
.play();
case PLAYING -> status = PlayerManager.getPlayers()
.pause();
case STOPPED, EMPTY -> {
if (Queue.getInstance().size() > 0)
{
@@ -327,24 +320,29 @@ public class PlayerControls extends JPanel implements PlaybackListener
.getCurrentSong() == null)
{
Queue.getInstance().skipToSong(0);
status = null;
}
else
{
confirmation = PlayerManager.getPlayers().play()
.getConfirmation();
status = PlayerManager.getPlayers().play();
}
}
}
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",
confirmation.getError());
status.getException());
JOptionPane.showMessageDialog(this,
status.getException(),
status.getException().getMessage(),
JOptionPane.ERROR_MESSAGE);
}
}
catch (ExecutionException | InterruptedException e)

View File

@@ -5,6 +5,7 @@ package edu.regis.universeplayer.player;
import com.intervigil.wave.WaveReader;
import edu.regis.universeplayer.AbstractTask;
import edu.regis.universeplayer.PlaybackInfo;
import edu.regis.universeplayer.PlaybackListener;
import edu.regis.universeplayer.PlaybackStatus;
@@ -48,6 +49,7 @@ public class LocalPlayer implements Player<LocalSong>, MediaPlayerEventListener
private final MediaPlayerFactory playerFactory;
private final AudioPlayerComponent player;
private final ForkJoinPool service = new ForkJoinPool();
private final LinkedList<PlaybackListener> listeners = new LinkedList<>();
private int currentId;
@@ -55,8 +57,6 @@ public class LocalPlayer implements Player<LocalSong>, MediaPlayerEventListener
private LocalSong currentSong;
private AudioFile currentFile;
private final ExecutorService service = Executors.newSingleThreadExecutor();
public LocalPlayer()
{
this.playerFactory = new MediaPlayerFactory();
@@ -118,112 +118,196 @@ public class LocalPlayer implements Player<LocalSong>, MediaPlayerEventListener
}
@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();
}
this.currentSong = song;
if (!this.player.mediaPlayer().media()
.play(song.file.getAbsolutePath()))
{
return new NullFuture<>(new RuntimeException("Could not play " +
"song " + song));
}
else
{
return new NullFuture<>();
}
@Override
protected boolean exec()
{
if (currentSong != null)
{
stopSong();
}
currentSong = song;
if (!player.mediaPlayer().media()
.play(song.file.getAbsolutePath()))
{
this.completeExceptionally(new RuntimeException("Could not play " +
"song " + song));
return false;
}
else
{
return true;
}
}
});
}
@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()
.submit((WrappedRunnable) () -> this.player.mediaPlayer()
.controls()
.play());
return new NullFuture<>();
.submit(() -> this.player.mediaPlayer()
.controls()
.pause());
return new AbstractTask<>()
{
@Override
protected boolean exec()
{
return true;
}
};
}
@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()
.submit((WrappedRunnable) () -> this.player.mediaPlayer()
.controls()
.pause());
return new NullFuture<>();
.submit(() -> this.player.mediaPlayer()
.controls()
.stop());
return new AbstractTask<>()
{
@Override
protected boolean exec()
{
return true;
}
};
}
@Override
public QueryFuture<Void> togglePlayback()
{
if (this.player.mediaPlayer().status().isPlaying())
{
return this.pause();
}
else
{
return this.play();
}
}
@Override
public QueryFuture<Void> stopSong()
public ForkJoinTask<Void> seek(float time)
{
this.player.mediaPlayer()
.submit((WrappedRunnable) () -> this.player.mediaPlayer()
.controls()
.stop());
return new NullFuture<>();
}
@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())
.submit(() -> this.player.mediaPlayer()
.controls()
.setTime((long) (time * 1000)));
return new AbstractTask<>()
{
case NOTHING_SPECIAL -> returnStatus = PlaybackStatus.EMPTY;
case PLAYING -> returnStatus = PlaybackStatus.PLAYING;
case PAUSED -> returnStatus = PlaybackStatus.PAUSED;
default -> returnStatus = PlaybackStatus.STOPPED;
}
return new NullFuture<>(returnStatus);
@Override
protected boolean exec()
{
return true;
}
};
}
@Override
public QueryFuture<Float> getCurrentTime()
public ForkJoinTask<PlaybackStatus> getStatus()
{
return new NullFuture<>(this.player.mediaPlayer().status()
.time() / 1000F);
return this.service.submit(new AbstractTask<>()
{
@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
public QueryFuture<Float> getLength()
public ForkJoinTask<Float> getCurrentTime()
{
return new NullFuture<>(this.player.mediaPlayer().status()
.length() / 1000F);
return this.service.submit(new AbstractTask<>()
{
@Override
protected boolean exec()
{
complete(player.mediaPlayer().status()
.time() / 1000F);
return true;
}
});
}
@Override
public QueryFuture<Void> close()
public ForkJoinTask<Float> getLength()
{
this.player.release();
return new NullFuture<>();
return this.service.submit(new AbstractTask<>()
{
@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

View File

@@ -10,6 +10,7 @@ import edu.regis.universeplayer.browserCommands.QueryFuture;
import edu.regis.universeplayer.data.Song;
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
@@ -34,33 +35,33 @@ public interface Player<T extends Song>
* @param song - The song to load.
* @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.
*
* @return A confirmation of whether the command was successful or not.
*/
QueryFuture<Void> play();
ForkJoinTask<Void> play();
/**
* Pauses playback of the current song.
*
* @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.
*
* @return A confirmation of whether the command was successful or not.
*/
QueryFuture<Void> togglePlayback();
ForkJoinTask<Void> togglePlayback();
/**
* Stops playback of the current song.
*/
QueryFuture<Void> stopSong();
ForkJoinTask<Void> stopSong();
/**
* 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.
* @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.
* @return A future for the request.
*/
QueryFuture<PlaybackStatus> getStatus();
ForkJoinTask<PlaybackStatus> getStatus();
/**
* 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.
*/
QueryFuture<Float> getCurrentTime();
ForkJoinTask<Float> getCurrentTime();
/**
* Gets the length of the current song.
*
* @return The song length, in seconds.
*/
QueryFuture<Float> getLength();
ForkJoinTask<Float> getLength();
/**
* Closes the player.
*
* @return A confirmation of whether the player was successfully closed.
*/
QueryFuture<Void> close();
ForkJoinTask<Void> close();
/**
* Adds a listener for playback status updates.

View File

@@ -7,11 +7,13 @@ import java.util.HashMap;
import java.util.LinkedList;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import javax.swing.JOptionPane;
import edu.regis.universeplayer.AbstractTask;
import edu.regis.universeplayer.PlaybackListener;
import edu.regis.universeplayer.PlaybackStatus;
import edu.regis.universeplayer.browserCommands.CommandConfirmation;
@@ -150,10 +152,10 @@ public class PlayerManager implements PlaybackListener
*/
private <T> QueryFuture<T> getNullPlayer(String message, T returnValue)
{
return new QueryFuture<T>()
return new QueryFuture<>()
{
@Override
public CommandConfirmation getConfirmation() throws CancellationException, ExecutionException, InterruptedException
public CommandConfirmation getConfirmation() throws CancellationException
{
if (returnValue instanceof Throwable)
{
@@ -166,7 +168,7 @@ public class PlayerManager implements PlaybackListener
}
@Override
public CommandConfirmation getConfirmation(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException
public CommandConfirmation getConfirmation(long timeout, TimeUnit unit)
{
return this.getConfirmation();
}
@@ -190,13 +192,13 @@ public class PlayerManager implements PlaybackListener
}
@Override
public T get() throws InterruptedException, ExecutionException
public T get()
{
return returnValue;
}
@Override
public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException
public T get(long timeout, TimeUnit unit)
{
return this.get();
}
@@ -211,16 +213,16 @@ public class PlayerManager implements PlaybackListener
*/
private <T> QueryFuture<T> getNullPlayer(Throwable message, T returnValue)
{
return new QueryFuture<T>()
return new QueryFuture<>()
{
@Override
public CommandConfirmation getConfirmation() throws CancellationException, ExecutionException, InterruptedException
public CommandConfirmation getConfirmation() throws CancellationException
{
return new CommandConfirmation(message);
}
@Override
public CommandConfirmation getConfirmation(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException
public CommandConfirmation getConfirmation(long timeout, TimeUnit unit)
{
return this.getConfirmation();
}
@@ -244,20 +246,20 @@ public class PlayerManager implements PlaybackListener
}
@Override
public T get() throws InterruptedException, ExecutionException
public T get()
{
return returnValue;
}
@Override
public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException
public T get(long timeout, TimeUnit unit)
{
return this.get();
}
};
}
public QueryFuture<Void> playSong(Song song)
public ForkJoinTask<Void> playSong(Song song)
{
if (this.currentSong != null)
{
@@ -274,16 +276,24 @@ public class PlayerManager implements PlaybackListener
return this.currentPlayer.loadSong(song);
}
public QueryFuture<PlaybackStatus> getStatus()
public ForkJoinTask<PlaybackStatus> getStatus()
{
if (this.currentPlayer != null)
{
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)
{
@@ -292,7 +302,7 @@ public class PlayerManager implements PlaybackListener
return null;
}
public QueryFuture<Void> play()
public ForkJoinTask<Void> play()
{
if (this.currentPlayer != null && this.currentSong != null)
{
@@ -301,7 +311,7 @@ public class PlayerManager implements PlaybackListener
return null;
}
public QueryFuture<Void> pause()
public ForkJoinTask<Void> pause()
{
if (this.currentPlayer != null && this.currentSong != null)
{
@@ -310,7 +320,7 @@ public class PlayerManager implements PlaybackListener
return null;
}
public QueryFuture<Void> toggle()
public ForkJoinTask<Void> toggle()
{
if (this.currentPlayer != null && this.currentSong != null)
{
@@ -319,7 +329,7 @@ public class PlayerManager implements PlaybackListener
return null;
}
public QueryFuture<Void> stopSong()
public ForkJoinTask<Void> stopSong()
{
if (this.currentPlayer != null && this.currentSong != null)
{
@@ -370,14 +380,22 @@ public class PlayerManager implements PlaybackListener
* script or a background script.
* @return The command future.
*/
public QueryFuture<Void> throwError(boolean forward)
public ForkJoinTask<Void> throwError(boolean forward)
{
BrowserPlayer player =
(BrowserPlayer) this.players.get(InternetSong.class);
if (player == null)
{
return this.getNullPlayer(new NullPointerException(
"No browser found"), null);
return new AbstractTask<>()
{
@Override
protected boolean exec()
{
completeExceptionally(new NullPointerException("Couldn't " +
"find internet player"));
return false;
}
};
}
return player.throwError(forward);
}