From e729ab0a38b9052504854950189ca49e352eb63b Mon Sep 17 00:00:00 2001 From: Andrzej Rybczak Date: Tue, 14 Aug 2012 23:55:01 +0200 Subject: [PATCH] playlist: rewrite sorting so it's much less cryptic --- src/mpdpp.cpp | 1 - src/ncmpcpp.cpp | 1 + src/playlist.cpp | 53 +++++++++++++++++------------------------------- src/playlist.h | 16 ++++++++++++++- 4 files changed, 35 insertions(+), 36 deletions(-) diff --git a/src/mpdpp.cpp b/src/mpdpp.cpp index 858c9b58..2fe98a8d 100644 --- a/src/mpdpp.cpp +++ b/src/mpdpp.cpp @@ -916,7 +916,6 @@ bool MPD::Connection::AddRandomTag(mpd_tag_type tag, size_t number) } else { - srand(time(0)); std::random_shuffle(tags.begin(), tags.end()); TagList::const_iterator it = tags.begin()+rand()%(tags.size()-number); for (size_t i = 0; i < number && it != tags.end(); ++i) diff --git a/src/ncmpcpp.cpp b/src/ncmpcpp.cpp index 026005b6..9fc383a8 100644 --- a/src/ncmpcpp.cpp +++ b/src/ncmpcpp.cpp @@ -94,6 +94,7 @@ namespace int main(int argc, char **argv) { + srand(time(0)); setlocale(LC_ALL, ""); Config.CheckForCommandLineConfigFilePath(argv, argc); diff --git a/src/playlist.cpp b/src/playlist.cpp index 1ea13061..62c64bc9 100644 --- a/src/playlist.cpp +++ b/src/playlist.cpp @@ -182,39 +182,14 @@ void Playlist::EnterPressed() return; } - ShowMessage("Sorting playlist..."); - MPD::SongList playlist, cmp; - + MPD::SongList playlist; playlist.reserve(end-beginning); for (size_t i = beginning; i < end; ++i) - { - (*Items)[i].SetPosition(i); playlist.push_back(&(*Items)[i]); - } - cmp = playlist; - sort(playlist.begin(), playlist.end(), Playlist::Sorting); - - if (playlist == cmp) - { - ShowMessage("Playlist is already sorted"); - return; - } + ShowMessage("Sorting..."); Mpd.StartCommandsList(); - do - { - for (size_t i = 0, j = beginning; i < playlist.size(); ++i, ++j) - { - if (playlist[i]->GetPosition() > j) - { - Mpd.Swap(playlist[i]->GetPosition(), j); - std::swap(cmp[playlist[i]->GetPosition()-beginning], cmp[i]); - Items->Swap(playlist[i]->GetPosition(), j); - } - cmp[i]->SetPosition(j); - } - } - while (playlist != cmp); + QuickSort(playlist.begin(), playlist.end(), playlist.begin()); if (Mpd.CommitCommandsList()) ShowMessage("Playlist sorted"); w = Items; @@ -445,13 +420,23 @@ void Playlist::EnableHighlighting() UpdateTimer(); } -bool Playlist::Sorting(MPD::Song *a, MPD::Song *b) +void Playlist::QuickSort(MPD::SongList::iterator first, MPD::SongList::iterator last, MPD::SongList::iterator begin) { - CaseInsensitiveStringComparison cmp; - for (size_t i = 0; i < SortOptions; ++i) - if (int ret = cmp(a->GetTags((*SortDialog)[i].second), b->GetTags((*SortDialog)[i].second))) - return ret < 0; - return a->GetPosition() < b->GetPosition(); + if (last-first > 1) + { + MPD::SongList::iterator pivot = first+rand()%(last-first); + IterSwap(pivot, last-1, begin); + pivot = last-1; + + MPD::SongList::iterator tmp = first; + for (MPD::SongList::iterator i = first; i != pivot; ++i) + if (SongComp(*i, *pivot)) + IterSwap(i, tmp++, begin); + IterSwap(tmp, pivot, begin); + + QuickSort(first, tmp, begin); + QuickSort(tmp+1, last, begin); + } } std::string Playlist::TotalLength() diff --git a/src/playlist.h b/src/playlist.h index d08f7b86..9d634f9d 100644 --- a/src/playlist.h +++ b/src/playlist.h @@ -105,7 +105,21 @@ class Playlist : public Screen time_t itsTimer; - static bool Sorting(MPD::Song *a, MPD::Song *b); + // stuff for sorting playlist + static void QuickSort(MPD::SongList::iterator first, MPD::SongList::iterator last, MPD::SongList::iterator begin); + inline static void IterSwap(MPD::SongList::iterator a, MPD::SongList::iterator b, MPD::SongList::iterator begin) + { + iter_swap(a, b); + Mpd.Swap(a-begin, b-begin); + } + inline static bool SongComp(MPD::Song *a, MPD::Song *b) + { + CaseInsensitiveStringComparison cmp; + for (size_t i = 0; i < SortOptions; ++i) + if (int ret = cmp(a->GetTags((*SortDialog)[i].second), b->GetTags((*SortDialog)[i].second))) + return ret < 0; + return a->GetPosition() < b->GetPosition(); + } static Menu< std::pair > *SortDialog; static const size_t SortOptions;