From cbc9741e66777e076e24a245bf58a759422d1b0d Mon Sep 17 00:00:00 2001 From: Andrzej Rybczak Date: Sat, 19 Dec 2020 16:54:51 +0100 Subject: [PATCH] Faster loading of playlists from the playlist editor --- src/mpdpp.cpp | 13 ++++++++----- src/mpdpp.h | 4 ++-- src/screens/browser.cpp | 28 +++++++++++++--------------- src/screens/playlist_editor.cpp | 31 ++++++++++++++++++++++++------- 4 files changed, 47 insertions(+), 29 deletions(-) diff --git a/src/mpdpp.cpp b/src/mpdpp.cpp index f09fe869..b1f532b3 100644 --- a/src/mpdpp.cpp +++ b/src/mpdpp.cpp @@ -567,16 +567,18 @@ int Connection::AddSong(const Song &s, int pos) return AddSong((!s.isFromDatabase() ? "file://" : "") + s.getURI(), pos); } -void Connection::Add(const std::string &path) +bool Connection::Add(const std::string &path) { + bool result; prechecks(); if (m_command_list_active) - mpd_send_add(m_connection.get(), path.c_str()); + result = mpd_send_add(m_connection.get(), path.c_str()); else { - mpd_run_add(m_connection.get(), path.c_str()); + result = mpd_run_add(m_connection.get(), path.c_str()); checkErrors(); } + return result; } bool Connection::AddRandomTag(mpd_tag_type tag, size_t number, std::mt19937 &rng) @@ -689,11 +691,12 @@ void Connection::DeletePlaylist(const std::string &name) checkErrors(); } -void Connection::LoadPlaylist(const std::string &name) +bool Connection::LoadPlaylist(const std::string &name) { prechecksNoCommandsList(); - mpd_run_load(m_connection.get(), name.c_str()); + bool result = mpd_run_load(m_connection.get(), name.c_str()); checkErrors(); + return result; } void Connection::SavePlaylist(const std::string &name) diff --git a/src/mpdpp.h b/src/mpdpp.h index 8b2138bf..11577142 100644 --- a/src/mpdpp.h +++ b/src/mpdpp.h @@ -548,14 +548,14 @@ struct Connection int AddSong(const Song &, int = -1); // returns id of added song bool AddRandomTag(mpd_tag_type, size_t, std::mt19937 &rng); bool AddRandomSongs(size_t number, const std::string &random_exclude_pattern, std::mt19937 &rng); - void Add(const std::string &path); + bool Add(const std::string &path); void Delete(unsigned int pos); void PlaylistDelete(const std::string &playlist, unsigned int pos); void StartCommandsList(); void CommitCommandsList(); void DeletePlaylist(const std::string &name); - void LoadPlaylist(const std::string &name); + bool LoadPlaylist(const std::string &name); void SavePlaylist(const std::string &); void ClearPlaylist(const std::string &playlist); void AddToPlaylist(const std::string &, const Song &); diff --git a/src/screens/browser.cpp b/src/screens/browser.cpp index 7303f41c..7111e5c5 100644 --- a/src/screens/browser.cpp +++ b/src/screens/browser.cpp @@ -305,14 +305,13 @@ bool Browser::itemAvailable() bool Browser::addItemToPlaylist(bool play) { - bool result = false; + bool success = false; auto tryToPlay = [] { - // Cheap trick that might fail in presence of multiple - // clients modifying the playlist at the same time, but - // oh well, this approach correctly loads cue playlists - // and is much faster in general as it doesn't require - // fetching song data. + // Cheap trick that might fail in presence of multiple clients modifying the + // playlist at the same time, but oh well, this approach correctly loads cue + // playlists and is much faster in general as it doesn't require fetching + // song data. try { Mpd.Play(Status::State::playlistLength()); @@ -334,31 +333,30 @@ bool Browser::addItemToPlaylist(bool play) { std::vector songs; getLocalDirectoryRecursively(songs, item.directory().path()); - result = addSongsToPlaylist(songs.begin(), songs.end(), play, -1); + success = addSongsToPlaylist(songs.begin(), songs.end(), play, -1); } else { - Mpd.Add(item.directory().path()); + success = Mpd.Add(item.directory().path()); if (play) tryToPlay(); - result = true; } Statusbar::printf("Directory \"%1%\" added%2%", - item.directory().path(), withErrors(result)); + item.directory().path(), withErrors(success)); break; } case MPD::Item::Type::Song: - result = addSongToPlaylist(item.song(), play); + success = addSongToPlaylist(item.song(), play); break; case MPD::Item::Type::Playlist: - Mpd.LoadPlaylist(item.playlist().path()); + success = Mpd.LoadPlaylist(item.playlist().path()); if (play) tryToPlay(); - Statusbar::printf("Playlist \"%1%\" loaded", item.playlist().path()); - result = true; + if (success) + Statusbar::printf("Playlist \"%1%\" loaded", item.playlist().path()); break; } - return result; + return success; } std::vector Browser::getSelectedSongs() diff --git a/src/screens/playlist_editor.cpp b/src/screens/playlist_editor.cpp index 4943a73f..f5ed7e8f 100644 --- a/src/screens/playlist_editor.cpp +++ b/src/screens/playlist_editor.cpp @@ -374,17 +374,34 @@ bool PlaylistEditor::itemAvailable() bool PlaylistEditor::addItemToPlaylist(bool play) { - bool result = false; + bool success = false; if (isActiveWindow(Playlists)) { - ScopedUnfilteredMenu sunfilter_content(ReapplyFilter::No, Content); - result = addSongsToPlaylist(Content.beginV(), Content.endV(), play, -1); - Statusbar::printf("Playlist \"%1%\" loaded%2%", - Playlists.current()->value().path(), withErrors(result)); + const auto &playlist = Playlists.current()->value(); + success = Mpd.LoadPlaylist(playlist.path()); + if (play) + { + // Cheap trick that might fail in presence of multiple clients modifying the + // playlist at the same time, but oh well, this approach correctly loads cue + // playlists and is much faster in general as it doesn't require fetching + // song data. + try + { + Mpd.Play(Status::State::playlistLength()); + } + catch (MPD::ServerError &e) + { + // If not bad index, rethrow. + if (e.code() != MPD_SERVER_ERROR_ARG) + throw; + } + } + if (success) + Statusbar::printf("Playlist \"%1%\" loaded", playlist.path()); } else if (isActiveWindow(Content)) - result = addSongToPlaylist(Content.current()->value(), play); - return result; + success = addSongToPlaylist(Content.current()->value(), play); + return success; } std::vector PlaylistEditor::getSelectedSongs()