diff --git a/interface/src/main/java/edu/regis/universeplayer/AbstractTask.java b/interface/src/main/java/edu/regis/universeplayer/AbstractTask.java new file mode 100644 index 0000000..82ec8e6 --- /dev/null +++ b/interface/src/main/java/edu/regis/universeplayer/AbstractTask.java @@ -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 + */ +public abstract class AbstractTask extends ForkJoinTask +{ + 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; + } +} diff --git a/interface/src/main/java/edu/regis/universeplayer/PlayerEnvironment.java b/interface/src/main/java/edu/regis/universeplayer/PlayerEnvironment.java index eeae7d3..f99eed3 100644 --- a/interface/src/main/java/edu/regis/universeplayer/PlayerEnvironment.java +++ b/interface/src/main/java/edu/regis/universeplayer/PlayerEnvironment.java @@ -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 command = PlayerManager.getPlayers() - .stopSong(); - try + queue.addSongChangeListener(queue1 -> ForkJoinPool.commonPool().submit(() -> { + ForkJoinTask 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 status = + ForkJoinTask 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(); diff --git a/interface/src/main/java/edu/regis/universeplayer/gui/Interface.java b/interface/src/main/java/edu/regis/universeplayer/gui/Interface.java index 39ae70e..3e8f5b3 100644 --- a/interface/src/main/java/edu/regis/universeplayer/gui/Interface.java +++ b/interface/src/main/java/edu/regis/universeplayer/gui/Interface.java @@ -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 command = PlayerManager + ForkJoinTask 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()); } } diff --git a/interface/src/main/java/edu/regis/universeplayer/gui/PlayerControls.java b/interface/src/main/java/edu/regis/universeplayer/gui/PlayerControls.java index 3fc05fb..e066908 100644 --- a/interface/src/main/java/edu/regis/universeplayer/gui/PlayerControls.java +++ b/interface/src/main/java/edu/regis/universeplayer/gui/PlayerControls.java @@ -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 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 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 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 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 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) diff --git a/interface/src/main/java/edu/regis/universeplayer/player/LocalPlayer.java b/interface/src/main/java/edu/regis/universeplayer/player/LocalPlayer.java index aec2459..7509be7 100644 --- a/interface/src/main/java/edu/regis/universeplayer/player/LocalPlayer.java +++ b/interface/src/main/java/edu/regis/universeplayer/player/LocalPlayer.java @@ -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, MediaPlayerEventListener private final MediaPlayerFactory playerFactory; private final AudioPlayerComponent player; + private final ForkJoinPool service = new ForkJoinPool(); private final LinkedList listeners = new LinkedList<>(); private int currentId; @@ -55,8 +57,6 @@ public class LocalPlayer implements Player, 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, MediaPlayerEventListener } @Override - public QueryFuture loadSong(LocalSong song) + public ForkJoinTask 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 play() + public ForkJoinTask play() + { + this.player.mediaPlayer().submit(() -> this.player.mediaPlayer() + .controls() + .play()); + return new AbstractTask<>() + { + @Override + protected boolean exec() + { + return true; + } + }; + } + + @Override + public ForkJoinTask 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 pause() + public ForkJoinTask togglePlayback() + { + return this.service.submit(new AbstractTask<>() + { + @Override + protected boolean exec() + { + ForkJoinTask 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 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 togglePlayback() - { - if (this.player.mediaPlayer().status().isPlaying()) - { - return this.pause(); - } - else - { - return this.play(); - } - } - - @Override - public QueryFuture stopSong() + public ForkJoinTask seek(float time) { this.player.mediaPlayer() - .submit((WrappedRunnable) () -> this.player.mediaPlayer() - .controls() - .stop()); - return new NullFuture<>(); - } - - @Override - public QueryFuture seek(float time) - { - this.player.mediaPlayer() - .submit((WrappedRunnable) () -> this.player.mediaPlayer() - .controls() - .setTime((long) (time * 1000))); - return new NullFuture<>(); - } - - @Override - public QueryFuture 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 getCurrentTime() + public ForkJoinTask 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 getLength() + public ForkJoinTask 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 close() + public ForkJoinTask 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 close() + { + return this.service.submit(new AbstractTask<>() + { + @Override + protected boolean exec() + { + player.release(); + return true; + } + }); } @Override diff --git a/interface/src/main/java/edu/regis/universeplayer/player/Player.java b/interface/src/main/java/edu/regis/universeplayer/player/Player.java index 1f54cf4..cb2c426 100644 --- a/interface/src/main/java/edu/regis/universeplayer/player/Player.java +++ b/interface/src/main/java/edu/regis/universeplayer/player/Player.java @@ -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 * @param song - The song to load. * @return A confirmation of whether the command was successful or not. */ - QueryFuture loadSong(T song); + ForkJoinTask 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 play(); + ForkJoinTask play(); /** * Pauses playback of the current song. * * @return A confirmation of whether the command was successful or not. */ - QueryFuture pause(); + ForkJoinTask pause(); /** * Toggles between playing and pausing the current song. * * @return A confirmation of whether the command was successful or not. */ - QueryFuture togglePlayback(); + ForkJoinTask togglePlayback(); /** * Stops playback of the current song. */ - QueryFuture stopSong(); + ForkJoinTask stopSong(); /** * Sets the current song time to the specified position. @@ -68,34 +69,34 @@ public interface Player * @param time - The specified time in the song, in seconds. * @return A confirmation of whether the command was successful or not. */ - QueryFuture seek(float time); + ForkJoinTask seek(float time); /** * Obtains the player's current playback status. * @return A future for the request. */ - QueryFuture getStatus(); + ForkJoinTask 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 getCurrentTime(); + ForkJoinTask getCurrentTime(); /** * Gets the length of the current song. * * @return The song length, in seconds. */ - QueryFuture getLength(); + ForkJoinTask getLength(); /** * Closes the player. * * @return A confirmation of whether the player was successfully closed. */ - QueryFuture close(); + ForkJoinTask close(); /** * Adds a listener for playback status updates. diff --git a/interface/src/main/java/edu/regis/universeplayer/player/PlayerManager.java b/interface/src/main/java/edu/regis/universeplayer/player/PlayerManager.java index a56f067..ec6f91c 100644 --- a/interface/src/main/java/edu/regis/universeplayer/player/PlayerManager.java +++ b/interface/src/main/java/edu/regis/universeplayer/player/PlayerManager.java @@ -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 QueryFuture getNullPlayer(String message, T returnValue) { - return new QueryFuture() + 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 QueryFuture getNullPlayer(Throwable message, T returnValue) { - return new QueryFuture() + 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 playSong(Song song) + public ForkJoinTask playSong(Song song) { if (this.currentSong != null) { @@ -274,16 +276,24 @@ public class PlayerManager implements PlaybackListener return this.currentPlayer.loadSong(song); } - public QueryFuture getStatus() + public ForkJoinTask 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 seek(float time) + public ForkJoinTask seek(float time) { if (this.currentPlayer != null) { @@ -292,7 +302,7 @@ public class PlayerManager implements PlaybackListener return null; } - public QueryFuture play() + public ForkJoinTask play() { if (this.currentPlayer != null && this.currentSong != null) { @@ -301,7 +311,7 @@ public class PlayerManager implements PlaybackListener return null; } - public QueryFuture pause() + public ForkJoinTask pause() { if (this.currentPlayer != null && this.currentSong != null) { @@ -310,7 +320,7 @@ public class PlayerManager implements PlaybackListener return null; } - public QueryFuture toggle() + public ForkJoinTask toggle() { if (this.currentPlayer != null && this.currentSong != null) { @@ -319,7 +329,7 @@ public class PlayerManager implements PlaybackListener return null; } - public QueryFuture stopSong() + public ForkJoinTask 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 throwError(boolean forward) + public ForkJoinTask 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); }