command/QueueCommands: reimplement relative "move"/"moveid" offsets

The existing implementation has been utterly broken forever; I cannot
explain what it actually does, but it doesn't do what the
documentation says.
This commit is contained in:
Max Kellermann
2021-10-07 22:04:12 +02:00
parent e63ecd81ec
commit c0bcfe244c
6 changed files with 86 additions and 55 deletions

View File

@@ -258,9 +258,7 @@ public:
void Shuffle(PlayerControl &pc, RangeArg range);
void MoveRange(PlayerControl &pc, RangeArg range, int to);
void MoveId(PlayerControl &pc, unsigned id, int to);
void MoveRange(PlayerControl &pc, RangeArg range, unsigned to);
void SwapPositions(PlayerControl &pc, unsigned song1, unsigned song2);

View File

@@ -315,51 +315,31 @@ playlist::StaleSong(PlayerControl &pc, const char *uri) noexcept
}
void
playlist::MoveRange(PlayerControl &pc, RangeArg range, int to)
playlist::MoveRange(PlayerControl &pc, RangeArg range, unsigned to)
{
if (!queue.IsValidPosition(range.start) ||
!queue.IsValidPosition(range.end - 1))
throw PlaylistError::BadRange();
if ((to >= 0 && to + range.Count() - 1 >= GetLength()) ||
(to < 0 && unsigned(std::abs(to)) > GetLength()))
if (to + range.Count() - 1 >= GetLength())
throw PlaylistError::BadRange();
if ((int)range.start == to)
if (range.start == to)
/* nothing happens */
return;
const DetachedSong *const queued_song = GetQueuedSong();
/*
* (to < 0) => move to offset from current song
* (-playlist.length == to) => move to position BEFORE current song
*/
const int currentSong = GetCurrentPosition();
if (to < 0) {
if (currentSong < 0)
/* can't move relative to current song,
because there is no current song */
throw PlaylistError::BadRange();
if (range.Contains(currentSong))
/* no-op, can't be moved to offset of itself */
return;
to = (currentSong + std::abs(to)) % GetLength();
if (range.start < (unsigned)to)
to -= range.Count();
}
queue.MoveRange(range.start, range.end, to);
if (!queue.random && current >= 0) {
/* update current */
if (range.Contains(current))
current += unsigned(to) - range.start;
current += to - range.start;
else if (unsigned(current) >= range.end &&
unsigned(current) <= unsigned(to))
unsigned(current) <= to)
current -= range.Count();
else if (unsigned(current) >= unsigned(to) &&
else if (unsigned(current) >= to &&
unsigned(current) < range.start)
current += range.Count();
}
@@ -368,16 +348,6 @@ playlist::MoveRange(PlayerControl &pc, RangeArg range, int to)
OnModified();
}
void
playlist::MoveId(PlayerControl &pc, unsigned id1, int to)
{
int song = queue.IdToPosition(id1);
if (song < 0)
throw PlaylistError::NoSuchSong();
MoveRange(pc, RangeArg::Single(song), to);
}
void
playlist::Shuffle(PlayerControl &pc, RangeArg range)
{