Commit 39529204 authored by Max Kellermann's avatar Max Kellermann

Playlist: use std::chrono::duration for Seek*()

parent c2001a72
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include "mixer/Listener.hxx" #include "mixer/Listener.hxx"
#include "PlayerControl.hxx" #include "PlayerControl.hxx"
#include "PlayerListener.hxx" #include "PlayerListener.hxx"
#include "Chrono.hxx"
struct Instance; struct Instance;
class MultipleOutputs; class MultipleOutputs;
...@@ -141,15 +142,15 @@ struct Partition final : private PlayerListener, private MixerListener { ...@@ -141,15 +142,15 @@ struct Partition final : private PlayerListener, private MixerListener {
} }
PlaylistResult SeekSongPosition(unsigned song_position, PlaylistResult SeekSongPosition(unsigned song_position,
float seek_time) { SongTime seek_time) {
return playlist.SeekSongPosition(pc, song_position, seek_time); return playlist.SeekSongPosition(pc, song_position, seek_time);
} }
PlaylistResult SeekSongId(unsigned song_id, float seek_time) { PlaylistResult SeekSongId(unsigned song_id, SongTime seek_time) {
return playlist.SeekSongId(pc, song_id, seek_time); return playlist.SeekSongId(pc, song_id, seek_time);
} }
PlaylistResult SeekCurrent(float seek_time, bool relative) { PlaylistResult SeekCurrent(SignedSongTime seek_time, bool relative) {
return playlist.SeekCurrent(pc, seek_time, relative); return playlist.SeekCurrent(pc, seek_time, relative);
} }
......
...@@ -300,11 +300,12 @@ handle_clearerror(gcc_unused Client &client, ...@@ -300,11 +300,12 @@ handle_clearerror(gcc_unused Client &client,
CommandResult CommandResult
handle_seek(Client &client, gcc_unused unsigned argc, char *argv[]) handle_seek(Client &client, gcc_unused unsigned argc, char *argv[])
{ {
unsigned song, seek_time; unsigned song;
SongTime seek_time;
if (!check_unsigned(client, &song, argv[1])) if (!check_unsigned(client, &song, argv[1]))
return CommandResult::ERROR; return CommandResult::ERROR;
if (!check_unsigned(client, &seek_time, argv[2])) if (!ParseCommandArg(client, seek_time, argv[2]))
return CommandResult::ERROR; return CommandResult::ERROR;
PlaylistResult result = PlaylistResult result =
...@@ -315,11 +316,12 @@ handle_seek(Client &client, gcc_unused unsigned argc, char *argv[]) ...@@ -315,11 +316,12 @@ handle_seek(Client &client, gcc_unused unsigned argc, char *argv[])
CommandResult CommandResult
handle_seekid(Client &client, gcc_unused unsigned argc, char *argv[]) handle_seekid(Client &client, gcc_unused unsigned argc, char *argv[])
{ {
unsigned id, seek_time; unsigned id;
SongTime seek_time;
if (!check_unsigned(client, &id, argv[1])) if (!check_unsigned(client, &id, argv[1]))
return CommandResult::ERROR; return CommandResult::ERROR;
if (!check_unsigned(client, &seek_time, argv[2])) if (!ParseCommandArg(client, seek_time, argv[2]))
return CommandResult::ERROR; return CommandResult::ERROR;
PlaylistResult result = PlaylistResult result =
...@@ -332,8 +334,8 @@ handle_seekcur(Client &client, gcc_unused unsigned argc, char *argv[]) ...@@ -332,8 +334,8 @@ handle_seekcur(Client &client, gcc_unused unsigned argc, char *argv[])
{ {
const char *p = argv[1]; const char *p = argv[1];
bool relative = *p == '+' || *p == '-'; bool relative = *p == '+' || *p == '-';
int seek_time; SignedSongTime seek_time;
if (!check_int(client, &seek_time, p)) if (!ParseCommandArg(client, seek_time, p))
return CommandResult::ERROR; return CommandResult::ERROR;
PlaylistResult result = PlaylistResult result =
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "config.h" #include "config.h"
#include "ArgParser.hxx" #include "ArgParser.hxx"
#include "Result.hxx" #include "Result.hxx"
#include "Chrono.hxx"
#include <limits> #include <limits>
...@@ -186,3 +187,25 @@ check_float(Client &client, float *value_r, const char *s) ...@@ -186,3 +187,25 @@ check_float(Client &client, float *value_r, const char *s)
*value_r = value; *value_r = value;
return true; return true;
} }
bool
ParseCommandArg(Client &client, SongTime &value_r, const char *s)
{
unsigned value;
bool success = check_unsigned(client, &value, s);
if (success)
value_r = SongTime::FromS(value);
return success;
}
bool
ParseCommandArg(Client &client, SignedSongTime &value_r, const char *s)
{
int value;
bool success = check_int(client, &value, s);
if (success)
value_r = SignedSongTime::FromS(value);
return success;
}
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
#include <stdint.h> #include <stdint.h>
class Client; class Client;
class SongTime;
class SignedSongTime;
bool bool
check_uint32(Client &client, uint32_t *dst, const char *s); check_uint32(Client &client, uint32_t *dst, const char *s);
...@@ -45,4 +47,10 @@ check_bool(Client &client, bool *value_r, const char *s); ...@@ -45,4 +47,10 @@ check_bool(Client &client, bool *value_r, const char *s);
bool bool
check_float(Client &client, float *value_r, const char *s); check_float(Client &client, float *value_r, const char *s);
bool
ParseCommandArg(Client &client, SongTime &value_r, const char *s);
bool
ParseCommandArg(Client &client, SignedSongTime &value_r, const char *s);
#endif #endif
...@@ -29,6 +29,8 @@ class DetachedSong; ...@@ -29,6 +29,8 @@ class DetachedSong;
class Database; class Database;
class Error; class Error;
class SongLoader; class SongLoader;
class SongTime;
class SignedSongTime;
struct playlist { struct playlist {
/** /**
...@@ -251,10 +253,10 @@ public: ...@@ -251,10 +253,10 @@ public:
PlaylistResult SeekSongPosition(PlayerControl &pc, PlaylistResult SeekSongPosition(PlayerControl &pc,
unsigned song_position, unsigned song_position,
float seek_time); SongTime seek_time);
PlaylistResult SeekSongId(PlayerControl &pc, PlaylistResult SeekSongId(PlayerControl &pc,
unsigned song_id, float seek_time); unsigned song_id, SongTime seek_time);
/** /**
* Seek within the current song. Fails if MPD is not currently * Seek within the current song. Fails if MPD is not currently
...@@ -265,7 +267,7 @@ public: ...@@ -265,7 +267,7 @@ public:
* current position * current position
*/ */
PlaylistResult SeekCurrent(PlayerControl &pc, PlaylistResult SeekCurrent(PlayerControl &pc,
float seek_time, bool relative); SignedSongTime seek_time, bool relative);
bool GetRepeat() const { bool GetRepeat() const {
return queue.repeat; return queue.repeat;
......
...@@ -190,7 +190,8 @@ playlist::PlayPrevious(PlayerControl &pc) ...@@ -190,7 +190,8 @@ playlist::PlayPrevious(PlayerControl &pc)
} }
PlaylistResult PlaylistResult
playlist::SeekSongPosition(PlayerControl &pc, unsigned song, float seek_time) playlist::SeekSongPosition(PlayerControl &pc,
unsigned song, SongTime seek_time)
{ {
if (!queue.IsValidPosition(song)) if (!queue.IsValidPosition(song))
return PlaylistResult::BAD_RANGE; return PlaylistResult::BAD_RANGE;
...@@ -215,8 +216,7 @@ playlist::SeekSongPosition(PlayerControl &pc, unsigned song, float seek_time) ...@@ -215,8 +216,7 @@ playlist::SeekSongPosition(PlayerControl &pc, unsigned song, float seek_time)
queued_song = nullptr; queued_song = nullptr;
} }
if (!pc.Seek(new DetachedSong(queue.GetOrder(i)), if (!pc.Seek(new DetachedSong(queue.GetOrder(i)), seek_time)) {
SongTime::FromS(seek_time))) {
UpdateQueuedSong(pc, queued_song); UpdateQueuedSong(pc, queued_song);
return PlaylistResult::NOT_PLAYING; return PlaylistResult::NOT_PLAYING;
...@@ -229,7 +229,7 @@ playlist::SeekSongPosition(PlayerControl &pc, unsigned song, float seek_time) ...@@ -229,7 +229,7 @@ playlist::SeekSongPosition(PlayerControl &pc, unsigned song, float seek_time)
} }
PlaylistResult PlaylistResult
playlist::SeekSongId(PlayerControl &pc, unsigned id, float seek_time) playlist::SeekSongId(PlayerControl &pc, unsigned id, SongTime seek_time)
{ {
int song = queue.IdToPosition(id); int song = queue.IdToPosition(id);
if (song < 0) if (song < 0)
...@@ -239,7 +239,8 @@ playlist::SeekSongId(PlayerControl &pc, unsigned id, float seek_time) ...@@ -239,7 +239,8 @@ playlist::SeekSongId(PlayerControl &pc, unsigned id, float seek_time)
} }
PlaylistResult PlaylistResult
playlist::SeekCurrent(PlayerControl &pc, float seek_time, bool relative) playlist::SeekCurrent(PlayerControl &pc,
SignedSongTime seek_time, bool relative)
{ {
if (!playing) if (!playing)
return PlaylistResult::NOT_PLAYING; return PlaylistResult::NOT_PLAYING;
...@@ -251,11 +252,10 @@ playlist::SeekCurrent(PlayerControl &pc, float seek_time, bool relative) ...@@ -251,11 +252,10 @@ playlist::SeekCurrent(PlayerControl &pc, float seek_time, bool relative)
status.state != PlayerState::PAUSE) status.state != PlayerState::PAUSE)
return PlaylistResult::NOT_PLAYING; return PlaylistResult::NOT_PLAYING;
seek_time += (int)status.elapsed_time; seek_time += SignedSongTime::FromS(status.elapsed_time);
if (seek_time.IsNegative())
seek_time = SignedSongTime::zero();
} }
if (seek_time < 0) return SeekSongPosition(pc, current, SongTime(seek_time));
seek_time = 0;
return SeekSongPosition(pc, current, seek_time);
} }
...@@ -132,7 +132,7 @@ playlist_state_restore(const char *line, TextFile &file, ...@@ -132,7 +132,7 @@ playlist_state_restore(const char *line, TextFile &file,
struct playlist &playlist, PlayerControl &pc) struct playlist &playlist, PlayerControl &pc)
{ {
int current = -1; int current = -1;
int seek_time = 0; SongTime seek_time = SongTime::zero();
bool random_mode = false; bool random_mode = false;
if (!StringStartsWith(line, PLAYLIST_STATE_FILE_STATE)) if (!StringStartsWith(line, PLAYLIST_STATE_FILE_STATE))
...@@ -150,8 +150,8 @@ playlist_state_restore(const char *line, TextFile &file, ...@@ -150,8 +150,8 @@ playlist_state_restore(const char *line, TextFile &file,
while ((line = file.ReadLine()) != nullptr) { while ((line = file.ReadLine()) != nullptr) {
if (StringStartsWith(line, PLAYLIST_STATE_FILE_TIME)) { if (StringStartsWith(line, PLAYLIST_STATE_FILE_TIME)) {
seek_time = unsigned seconds = atoi(&(line[strlen(PLAYLIST_STATE_FILE_TIME)]));
atoi(&(line[strlen(PLAYLIST_STATE_FILE_TIME)])); seek_time = SongTime::FromS(seconds);
} else if (StringStartsWith(line, PLAYLIST_STATE_FILE_REPEAT)) { } else if (StringStartsWith(line, PLAYLIST_STATE_FILE_REPEAT)) {
playlist.SetRepeat(pc, playlist.SetRepeat(pc,
strcmp(&(line[strlen(PLAYLIST_STATE_FILE_REPEAT)]), strcmp(&(line[strlen(PLAYLIST_STATE_FILE_REPEAT)]),
...@@ -209,7 +209,7 @@ playlist_state_restore(const char *line, TextFile &file, ...@@ -209,7 +209,7 @@ playlist_state_restore(const char *line, TextFile &file,
if (state == PlayerState::STOP /* && config_option */) if (state == PlayerState::STOP /* && config_option */)
playlist.current = current; playlist.current = current;
else if (seek_time == 0) else if (seek_time.count() == 0)
playlist.PlayPosition(pc, current); playlist.PlayPosition(pc, current);
else else
playlist.SeekSongPosition(pc, current, seek_time); playlist.SeekSongPosition(pc, current, seek_time);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment