diff --git a/NEWS b/NEWS index 998836c38..c8969c55d 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,7 @@ ver 0.20.13 (not yet released) * database - simple: don't purge mount points on update/rescan - upnp: work around libupnp 1.6.24 API breakage +* queue: fix spuriously misplaced prioritized songs ver 0.20.12 (2017/11/25) * database diff --git a/src/queue/PlaylistEdit.cxx b/src/queue/PlaylistEdit.cxx index 67675680c..8d7429e27 100644 --- a/src/queue/PlaylistEdit.cxx +++ b/src/queue/PlaylistEdit.cxx @@ -112,7 +112,7 @@ playlist::AppendSong(PlayerControl &pc, DetachedSong &&song) else start = current + 1; if (start < queue.GetLength()) - queue.ShuffleOrderLast(start, queue.GetLength()); + queue.ShuffleOrderLastWithPriority(start, queue.GetLength()); } UpdateQueuedSong(pc, queued_song); diff --git a/src/queue/Queue.cxx b/src/queue/Queue.cxx index 720778099..0997e91e3 100644 --- a/src/queue/Queue.cxx +++ b/src/queue/Queue.cxx @@ -364,8 +364,20 @@ Queue::ShuffleOrderFirst(unsigned start, unsigned end) } void -Queue::ShuffleOrderLast(unsigned start, unsigned end) +Queue::ShuffleOrderLastWithPriority(unsigned start, unsigned end) { + assert(end <= length); + assert(start < end); + + /* skip all items at the start which have a higher priority, + because the last item shall only be shuffled within its + priority group */ + const auto last_priority = items[OrderToPosition(end - 1)].priority; + while (items[OrderToPosition(start)].priority != last_priority) { + ++start; + assert(start < end); + } + rand.AutoCreate(); std::uniform_int_distribution distribution(start, end - 1); diff --git a/src/queue/Queue.hxx b/src/queue/Queue.hxx index 06e800479..fb1d9c8b1 100644 --- a/src/queue/Queue.hxx +++ b/src/queue/Queue.hxx @@ -356,11 +356,12 @@ struct Queue { void ShuffleOrderFirst(unsigned start, unsigned end); /** - * Shuffles the virtual order of the last song in the specified - * (order) range. This is used in random mode after a song has been - * appended by queue_append(). + * Shuffles the virtual order of the last song in the + * specified (order) range; only songs which match this song's + * priority are considered. This is used in random mode after + * a song has been appended by Append(). */ - void ShuffleOrderLast(unsigned start, unsigned end); + void ShuffleOrderLastWithPriority(unsigned start, unsigned end); /** * Shuffles a (position) range in the queue. The songs are physically