queue/PlaylistEdit: convert start/end parameters to RangeArg
This commit is contained in:
parent
157ddcbab1
commit
471c37be59
|
@ -27,6 +27,7 @@
|
|||
#include "mixer/Listener.hxx"
|
||||
#include "player/Control.hxx"
|
||||
#include "player/Listener.hxx"
|
||||
#include "protocol/RangeArg.hxx"
|
||||
#include "ReplayGainMode.hxx"
|
||||
#include "SingleMode.hxx"
|
||||
#include "Chrono.hxx"
|
||||
|
@ -38,6 +39,7 @@
|
|||
#include <memory>
|
||||
|
||||
struct Instance;
|
||||
struct RangeArg;
|
||||
class MultipleOutputs;
|
||||
class SongLoader;
|
||||
class ClientListener;
|
||||
|
@ -133,20 +135,20 @@ struct Partition final : QueueListener, PlayerListener, MixerListener {
|
|||
* @param start the position of the first song to delete
|
||||
* @param end the position after the last song to delete
|
||||
*/
|
||||
void DeleteRange(unsigned start, unsigned end) {
|
||||
playlist.DeleteRange(pc, start, end);
|
||||
void DeleteRange(RangeArg range) {
|
||||
playlist.DeleteRange(pc, range);
|
||||
}
|
||||
|
||||
void StaleSong(const char *uri) noexcept {
|
||||
playlist.StaleSong(pc, uri);
|
||||
}
|
||||
|
||||
void Shuffle(unsigned start, unsigned end) noexcept {
|
||||
playlist.Shuffle(pc, start, end);
|
||||
void Shuffle(RangeArg range) {
|
||||
playlist.Shuffle(pc, range);
|
||||
}
|
||||
|
||||
void MoveRange(unsigned start, unsigned end, int to) {
|
||||
playlist.MoveRange(pc, start, end, to);
|
||||
void MoveRange(RangeArg range, int to) {
|
||||
playlist.MoveRange(pc, range, to);
|
||||
}
|
||||
|
||||
void MoveId(unsigned id, int to) {
|
||||
|
@ -161,10 +163,8 @@ struct Partition final : QueueListener, PlayerListener, MixerListener {
|
|||
playlist.SwapIds(pc, id1, id2);
|
||||
}
|
||||
|
||||
void SetPriorityRange(unsigned start_position, unsigned end_position,
|
||||
uint8_t priority) {
|
||||
playlist.SetPriorityRange(pc, start_position, end_position,
|
||||
priority);
|
||||
void SetPriorityRange(RangeArg position_range, uint8_t priority) {
|
||||
playlist.SetPriorityRange(pc, position_range, priority);
|
||||
}
|
||||
|
||||
void SetPriorityId(unsigned song_id, uint8_t priority) {
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "PlaylistError.hxx"
|
||||
#include "queue/Playlist.hxx"
|
||||
#include "queue/QueuePrint.hxx"
|
||||
#include "protocol/RangeArg.hxx"
|
||||
|
||||
#define SONG_FILE "file: "
|
||||
#define SONG_TIME "Time: "
|
||||
|
@ -35,20 +36,17 @@ playlist_print_uris(Response &r, const playlist &playlist)
|
|||
}
|
||||
|
||||
void
|
||||
playlist_print_info(Response &r, const playlist &playlist,
|
||||
unsigned start, unsigned end)
|
||||
playlist_print_info(Response &r, const playlist &playlist, RangeArg range)
|
||||
{
|
||||
const Queue &queue = playlist.queue;
|
||||
|
||||
if (end > queue.GetLength())
|
||||
/* correct the "end" offset */
|
||||
end = queue.GetLength();
|
||||
|
||||
if (start > end)
|
||||
/* an invalid "start" offset is fatal */
|
||||
if (!range.CheckClip(queue.GetLength()))
|
||||
throw PlaylistError::BadRange();
|
||||
|
||||
queue_print_info(r, queue, start, end);
|
||||
if (range.IsEmpty())
|
||||
return;
|
||||
|
||||
queue_print_info(r, queue, range.start, range.end);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -62,7 +60,7 @@ playlist_print_id(Response &r, const playlist &playlist,
|
|||
/* no such song */
|
||||
throw PlaylistError::NoSuchSong();
|
||||
|
||||
playlist_print_info(r, playlist, position, position + 1);
|
||||
playlist_print_info(r, playlist, {unsigned(position), position + 1U});
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -87,18 +85,24 @@ playlist_print_find(Response &r, const playlist &playlist,
|
|||
void
|
||||
playlist_print_changes_info(Response &r, const playlist &playlist,
|
||||
uint32_t version,
|
||||
unsigned start, unsigned end)
|
||||
RangeArg range)
|
||||
{
|
||||
queue_print_changes_info(r, playlist.queue, version,
|
||||
start, end);
|
||||
const Queue &queue = playlist.queue;
|
||||
range.ClipRelaxed(queue.GetLength());
|
||||
|
||||
queue_print_changes_info(r, queue, version,
|
||||
range.start, range.end);
|
||||
}
|
||||
|
||||
void
|
||||
playlist_print_changes_position(Response &r,
|
||||
const playlist &playlist,
|
||||
uint32_t version,
|
||||
unsigned start, unsigned end)
|
||||
RangeArg range)
|
||||
{
|
||||
const Queue &queue = playlist.queue;
|
||||
range.ClipRelaxed(queue.GetLength());
|
||||
|
||||
queue_print_changes_position(r, playlist.queue, version,
|
||||
start, end);
|
||||
range.start, range.end);
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <cstdint>
|
||||
|
||||
struct playlist;
|
||||
struct RangeArg;
|
||||
class SongFilter;
|
||||
class Response;
|
||||
|
||||
|
@ -41,8 +42,7 @@ playlist_print_uris(Response &r, const playlist &playlist);
|
|||
* Throws #PlaylistError if the range is invalid.
|
||||
*/
|
||||
void
|
||||
playlist_print_info(Response &r, const playlist &playlist,
|
||||
unsigned start, unsigned end);
|
||||
playlist_print_info(Response &r, const playlist &playlist, RangeArg range);
|
||||
|
||||
/**
|
||||
* Sends the song with the specified id to the client.
|
||||
|
@ -73,7 +73,7 @@ playlist_print_find(Response &r, const playlist &playlist,
|
|||
void
|
||||
playlist_print_changes_info(Response &r, const playlist &playlist,
|
||||
uint32_t version,
|
||||
unsigned start, unsigned end);
|
||||
RangeArg range);
|
||||
|
||||
/**
|
||||
* Print changes since the specified playlist version, position only.
|
||||
|
@ -82,6 +82,6 @@ void
|
|||
playlist_print_changes_position(Response &r,
|
||||
const playlist &playlist,
|
||||
uint32_t version,
|
||||
unsigned start, unsigned end);
|
||||
RangeArg range);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -182,7 +182,7 @@ CommandResult
|
|||
handle_delete(Client &client, Request args, [[maybe_unused]] Response &r)
|
||||
{
|
||||
RangeArg range = args.ParseRange(0);
|
||||
client.GetPartition().DeleteRange(range.start, range.end);
|
||||
client.GetPartition().DeleteRange(range);
|
||||
return CommandResult::OK;
|
||||
}
|
||||
|
||||
|
@ -205,7 +205,7 @@ CommandResult
|
|||
handle_shuffle([[maybe_unused]] Client &client, Request args, [[maybe_unused]] Response &r)
|
||||
{
|
||||
RangeArg range = args.ParseOptional(0, RangeArg::All());
|
||||
client.GetPartition().Shuffle(range.start, range.end);
|
||||
client.GetPartition().Shuffle(range);
|
||||
return CommandResult::OK;
|
||||
}
|
||||
|
||||
|
@ -221,8 +221,7 @@ handle_plchanges(Client &client, Request args, Response &r)
|
|||
{
|
||||
uint32_t version = ParseCommandArgU32(args.front());
|
||||
RangeArg range = args.ParseOptional(1, RangeArg::All());
|
||||
playlist_print_changes_info(r, client.GetPlaylist(), version,
|
||||
range.start, range.end);
|
||||
playlist_print_changes_info(r, client.GetPlaylist(), version, range);
|
||||
return CommandResult::OK;
|
||||
}
|
||||
|
||||
|
@ -232,7 +231,7 @@ handle_plchangesposid(Client &client, Request args, Response &r)
|
|||
uint32_t version = ParseCommandArgU32(args.front());
|
||||
RangeArg range = args.ParseOptional(1, RangeArg::All());
|
||||
playlist_print_changes_position(r, client.GetPlaylist(), version,
|
||||
range.start, range.end);
|
||||
range);
|
||||
return CommandResult::OK;
|
||||
}
|
||||
|
||||
|
@ -241,8 +240,7 @@ handle_playlistinfo(Client &client, Request args, Response &r)
|
|||
{
|
||||
RangeArg range = args.ParseOptional(0, RangeArg::All());
|
||||
|
||||
playlist_print_info(r, client.GetPlaylist(),
|
||||
range.start, range.end);
|
||||
playlist_print_info(r, client.GetPlaylist(), range);
|
||||
return CommandResult::OK;
|
||||
}
|
||||
|
||||
|
@ -253,8 +251,7 @@ handle_playlistid(Client &client, Request args, Response &r)
|
|||
unsigned id = args.ParseUnsigned(0);
|
||||
playlist_print_id(r, client.GetPlaylist(), id);
|
||||
} else {
|
||||
playlist_print_info(r, client.GetPlaylist(),
|
||||
0, std::numeric_limits<unsigned>::max());
|
||||
playlist_print_info(r, client.GetPlaylist(), RangeArg::All());
|
||||
}
|
||||
|
||||
return CommandResult::OK;
|
||||
|
@ -300,7 +297,7 @@ handle_prio(Client &client, Request args, [[maybe_unused]] Response &r)
|
|||
|
||||
for (const char *i : args) {
|
||||
RangeArg range = ParseCommandArgRange(i);
|
||||
partition.SetPriorityRange(range.start, range.end, priority);
|
||||
partition.SetPriorityRange(range, priority);
|
||||
}
|
||||
|
||||
return CommandResult::OK;
|
||||
|
@ -332,7 +329,7 @@ handle_move(Client &client, Request args, [[maybe_unused]] Response &r)
|
|||
}
|
||||
|
||||
int to = args.ParseInt(1);
|
||||
client.GetPartition().MoveRange(range.start, range.end, to);
|
||||
client.GetPartition().MoveRange(range, to);
|
||||
return CommandResult::OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
enum TagType : uint8_t;
|
||||
struct Tag;
|
||||
struct RangeArg;
|
||||
class PlayerControl;
|
||||
class DetachedSong;
|
||||
class Database;
|
||||
|
@ -240,7 +241,7 @@ public:
|
|||
* @param start the position of the first song to delete
|
||||
* @param end the position after the last song to delete
|
||||
*/
|
||||
void DeleteRange(PlayerControl &pc, unsigned start, unsigned end);
|
||||
void DeleteRange(PlayerControl &pc, RangeArg range);
|
||||
|
||||
/**
|
||||
* Mark the given song as "stale", i.e. as not being available
|
||||
|
@ -250,10 +251,9 @@ public:
|
|||
*/
|
||||
void StaleSong(PlayerControl &pc, const char *uri) noexcept;
|
||||
|
||||
void Shuffle(PlayerControl &pc, unsigned start, unsigned end) noexcept;
|
||||
void Shuffle(PlayerControl &pc, RangeArg range);
|
||||
|
||||
void MoveRange(PlayerControl &pc, unsigned start,
|
||||
unsigned end, int to);
|
||||
void MoveRange(PlayerControl &pc, RangeArg range, int to);
|
||||
|
||||
void MoveId(PlayerControl &pc, unsigned id, int to);
|
||||
|
||||
|
@ -262,7 +262,7 @@ public:
|
|||
void SwapIds(PlayerControl &pc, unsigned id1, unsigned id2);
|
||||
|
||||
void SetPriorityRange(PlayerControl &pc,
|
||||
unsigned start_position, unsigned end_position,
|
||||
RangeArg position_range,
|
||||
uint8_t priority);
|
||||
|
||||
void SetPriorityId(PlayerControl &pc,
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "Listener.hxx"
|
||||
#include "PlaylistError.hxx"
|
||||
#include "player/Control.hxx"
|
||||
#include "protocol/RangeArg.hxx"
|
||||
#include "song/DetachedSong.hxx"
|
||||
#include "SongLoader.hxx"
|
||||
|
||||
|
@ -168,16 +169,13 @@ playlist::SwapIds(PlayerControl &pc, unsigned id1, unsigned id2)
|
|||
|
||||
void
|
||||
playlist::SetPriorityRange(PlayerControl &pc,
|
||||
unsigned start, unsigned end,
|
||||
RangeArg range,
|
||||
uint8_t priority)
|
||||
{
|
||||
if (start >= GetLength())
|
||||
if (!range.CheckClip(GetLength()))
|
||||
throw PlaylistError::BadRange();
|
||||
|
||||
if (end > GetLength())
|
||||
end = GetLength();
|
||||
|
||||
if (start >= end)
|
||||
if (range.IsEmpty())
|
||||
return;
|
||||
|
||||
/* remember "current" and "queued" */
|
||||
|
@ -187,7 +185,7 @@ playlist::SetPriorityRange(PlayerControl &pc,
|
|||
|
||||
/* apply the priority changes */
|
||||
|
||||
queue.SetPriorityRange(start, end, priority, current);
|
||||
queue.SetPriorityRange(range.start, range.end, priority, current);
|
||||
|
||||
/* restore "current" and choose a new "queued" */
|
||||
|
||||
|
@ -206,7 +204,7 @@ playlist::SetPriorityId(PlayerControl &pc,
|
|||
if (song_position < 0)
|
||||
throw PlaylistError::NoSuchSong();
|
||||
|
||||
SetPriorityRange(pc, song_position, song_position + 1, priority);
|
||||
SetPriorityRange(pc, {unsigned(song_position), song_position + 1U}, priority);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -272,22 +270,19 @@ playlist::DeletePosition(PlayerControl &pc, unsigned song)
|
|||
}
|
||||
|
||||
void
|
||||
playlist::DeleteRange(PlayerControl &pc, unsigned start, unsigned end)
|
||||
playlist::DeleteRange(PlayerControl &pc, RangeArg range)
|
||||
{
|
||||
if (start >= queue.GetLength())
|
||||
if (!range.CheckClip(GetLength()))
|
||||
throw PlaylistError::BadRange();
|
||||
|
||||
if (end > queue.GetLength())
|
||||
end = queue.GetLength();
|
||||
|
||||
if (start >= end)
|
||||
if (range.IsEmpty())
|
||||
return;
|
||||
|
||||
const DetachedSong *queued_song = GetQueuedSong();
|
||||
|
||||
do {
|
||||
DeleteInternal(pc, --end, &queued_song);
|
||||
} while (end != start);
|
||||
DeleteInternal(pc, --range.end, &queued_song);
|
||||
} while (range.end != range.start);
|
||||
|
||||
UpdateQueuedSong(pc, queued_song);
|
||||
OnModified();
|
||||
|
@ -320,17 +315,17 @@ playlist::StaleSong(PlayerControl &pc, const char *uri) noexcept
|
|||
}
|
||||
|
||||
void
|
||||
playlist::MoveRange(PlayerControl &pc,
|
||||
unsigned start, unsigned end, int to)
|
||||
playlist::MoveRange(PlayerControl &pc, RangeArg range, int to)
|
||||
{
|
||||
if (!queue.IsValidPosition(start) || !queue.IsValidPosition(end - 1))
|
||||
if (!queue.IsValidPosition(range.start) ||
|
||||
!queue.IsValidPosition(range.end - 1))
|
||||
throw PlaylistError::BadRange();
|
||||
|
||||
if ((to >= 0 && to + end - start - 1 >= GetLength()) ||
|
||||
if ((to >= 0 && to + range.Count() - 1 >= GetLength()) ||
|
||||
(to < 0 && unsigned(std::abs(to)) > GetLength()))
|
||||
throw PlaylistError::BadRange();
|
||||
|
||||
if ((int)start == to)
|
||||
if ((int)range.start == to)
|
||||
/* nothing happens */
|
||||
return;
|
||||
|
||||
|
@ -347,26 +342,26 @@ playlist::MoveRange(PlayerControl &pc,
|
|||
because there is no current song */
|
||||
throw PlaylistError::BadRange();
|
||||
|
||||
if (start <= (unsigned)currentSong && (unsigned)currentSong < end)
|
||||
if (range.Contains(currentSong))
|
||||
/* no-op, can't be moved to offset of itself */
|
||||
return;
|
||||
to = (currentSong + std::abs(to)) % GetLength();
|
||||
if (start < (unsigned)to)
|
||||
to -= end - start;
|
||||
if (range.start < (unsigned)to)
|
||||
to -= range.Count();
|
||||
}
|
||||
|
||||
queue.MoveRange(start, end, to);
|
||||
queue.MoveRange(range.start, range.end, to);
|
||||
|
||||
if (!queue.random && current >= 0) {
|
||||
/* update current */
|
||||
if (start <= unsigned(current) && unsigned(current) < end)
|
||||
current += unsigned(to) - start;
|
||||
else if (unsigned(current) >= end &&
|
||||
if (range.Contains(current))
|
||||
current += unsigned(to) - range.start;
|
||||
else if (unsigned(current) >= range.end &&
|
||||
unsigned(current) <= unsigned(to))
|
||||
current -= end - start;
|
||||
current -= range.Count();
|
||||
else if (unsigned(current) >= unsigned(to) &&
|
||||
unsigned(current) < start)
|
||||
current += end - start;
|
||||
unsigned(current) < range.start)
|
||||
current += range.Count();
|
||||
}
|
||||
|
||||
UpdateQueuedSong(pc, queued_song);
|
||||
|
@ -380,17 +375,16 @@ playlist::MoveId(PlayerControl &pc, unsigned id1, int to)
|
|||
if (song < 0)
|
||||
throw PlaylistError::NoSuchSong();
|
||||
|
||||
MoveRange(pc, song, song + 1, to);
|
||||
MoveRange(pc, RangeArg::Single(song), to);
|
||||
}
|
||||
|
||||
void
|
||||
playlist::Shuffle(PlayerControl &pc, unsigned start, unsigned end) noexcept
|
||||
playlist::Shuffle(PlayerControl &pc, RangeArg range)
|
||||
{
|
||||
if (end > GetLength())
|
||||
/* correct the "end" offset */
|
||||
end = GetLength();
|
||||
if (!range.CheckClip(GetLength()))
|
||||
throw PlaylistError::BadRange();
|
||||
|
||||
if (start + 1 >= end)
|
||||
if (range.HasAtLeast(2))
|
||||
/* needs at least two entries. */
|
||||
return;
|
||||
|
||||
|
@ -398,17 +392,17 @@ playlist::Shuffle(PlayerControl &pc, unsigned start, unsigned end) noexcept
|
|||
if (playing && current >= 0) {
|
||||
unsigned current_position = queue.OrderToPosition(current);
|
||||
|
||||
if (current_position >= start && current_position < end) {
|
||||
if (range.Contains(current_position)) {
|
||||
/* put current playing song first */
|
||||
queue.SwapPositions(start, current_position);
|
||||
queue.SwapPositions(range.start, current_position);
|
||||
|
||||
if (queue.random) {
|
||||
current = queue.PositionToOrder(start);
|
||||
current = queue.PositionToOrder(range.start);
|
||||
} else
|
||||
current = start;
|
||||
current = range.start;
|
||||
|
||||
/* start shuffle after the current song */
|
||||
start++;
|
||||
range.start++;
|
||||
}
|
||||
} else {
|
||||
/* no playback currently: reset current */
|
||||
|
@ -416,7 +410,7 @@ playlist::Shuffle(PlayerControl &pc, unsigned start, unsigned end) noexcept
|
|||
current = -1;
|
||||
}
|
||||
|
||||
queue.ShuffleRange(start, end);
|
||||
queue.ShuffleRange(range.start, range.end);
|
||||
|
||||
UpdateQueuedSong(pc, queued_song);
|
||||
OnModified();
|
||||
|
|
|
@ -76,12 +76,7 @@ queue_print_changes_info(Response &r, const Queue &queue,
|
|||
unsigned start, unsigned end)
|
||||
{
|
||||
assert(start <= end);
|
||||
|
||||
if (start >= queue.GetLength())
|
||||
return;
|
||||
|
||||
if (end > queue.GetLength())
|
||||
end = queue.GetLength();
|
||||
assert(end <= queue.GetLength());
|
||||
|
||||
for (unsigned i = start; i < end; i++)
|
||||
if (queue.IsNewerAtPosition(i, version))
|
||||
|
@ -94,12 +89,7 @@ queue_print_changes_position(Response &r, const Queue &queue,
|
|||
unsigned start, unsigned end)
|
||||
{
|
||||
assert(start <= end);
|
||||
|
||||
if (start >= queue.GetLength())
|
||||
return;
|
||||
|
||||
if (end > queue.GetLength())
|
||||
end = queue.GetLength();
|
||||
assert(end <= queue.GetLength());
|
||||
|
||||
for (unsigned i = start; i < end; i++)
|
||||
if (queue.IsNewerAtPosition(i, version))
|
||||
|
|
Loading…
Reference in New Issue