Faster loading of playlists from the playlist editor

This commit is contained in:
Andrzej Rybczak
2020-12-19 16:54:51 +01:00
parent d724e06262
commit cbc9741e66
4 changed files with 47 additions and 29 deletions

View File

@@ -567,16 +567,18 @@ int Connection::AddSong(const Song &s, int pos)
return AddSong((!s.isFromDatabase() ? "file://" : "") + s.getURI(), 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(); prechecks();
if (m_command_list_active) 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 else
{ {
mpd_run_add(m_connection.get(), path.c_str()); result = mpd_run_add(m_connection.get(), path.c_str());
checkErrors(); checkErrors();
} }
return result;
} }
bool Connection::AddRandomTag(mpd_tag_type tag, size_t number, std::mt19937 &rng) 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(); checkErrors();
} }
void Connection::LoadPlaylist(const std::string &name) bool Connection::LoadPlaylist(const std::string &name)
{ {
prechecksNoCommandsList(); prechecksNoCommandsList();
mpd_run_load(m_connection.get(), name.c_str()); bool result = mpd_run_load(m_connection.get(), name.c_str());
checkErrors(); checkErrors();
return result;
} }
void Connection::SavePlaylist(const std::string &name) void Connection::SavePlaylist(const std::string &name)

View File

@@ -548,14 +548,14 @@ struct Connection
int AddSong(const Song &, int = -1); // returns id of added song int AddSong(const Song &, int = -1); // returns id of added song
bool AddRandomTag(mpd_tag_type, size_t, std::mt19937 &rng); bool AddRandomTag(mpd_tag_type, size_t, std::mt19937 &rng);
bool AddRandomSongs(size_t number, const std::string &random_exclude_pattern, 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 Delete(unsigned int pos);
void PlaylistDelete(const std::string &playlist, unsigned int pos); void PlaylistDelete(const std::string &playlist, unsigned int pos);
void StartCommandsList(); void StartCommandsList();
void CommitCommandsList(); void CommitCommandsList();
void DeletePlaylist(const std::string &name); void DeletePlaylist(const std::string &name);
void LoadPlaylist(const std::string &name); bool LoadPlaylist(const std::string &name);
void SavePlaylist(const std::string &); void SavePlaylist(const std::string &);
void ClearPlaylist(const std::string &playlist); void ClearPlaylist(const std::string &playlist);
void AddToPlaylist(const std::string &, const Song &); void AddToPlaylist(const std::string &, const Song &);

View File

@@ -305,14 +305,13 @@ bool Browser::itemAvailable()
bool Browser::addItemToPlaylist(bool play) bool Browser::addItemToPlaylist(bool play)
{ {
bool result = false; bool success = false;
auto tryToPlay = [] { auto tryToPlay = [] {
// Cheap trick that might fail in presence of multiple // Cheap trick that might fail in presence of multiple clients modifying the
// clients modifying the playlist at the same time, but // playlist at the same time, but oh well, this approach correctly loads cue
// oh well, this approach correctly loads cue playlists // playlists and is much faster in general as it doesn't require fetching
// and is much faster in general as it doesn't require // song data.
// fetching song data.
try try
{ {
Mpd.Play(Status::State::playlistLength()); Mpd.Play(Status::State::playlistLength());
@@ -334,31 +333,30 @@ bool Browser::addItemToPlaylist(bool play)
{ {
std::vector<MPD::Song> songs; std::vector<MPD::Song> songs;
getLocalDirectoryRecursively(songs, item.directory().path()); getLocalDirectoryRecursively(songs, item.directory().path());
result = addSongsToPlaylist(songs.begin(), songs.end(), play, -1); success = addSongsToPlaylist(songs.begin(), songs.end(), play, -1);
} }
else else
{ {
Mpd.Add(item.directory().path()); success = Mpd.Add(item.directory().path());
if (play) if (play)
tryToPlay(); tryToPlay();
result = true;
} }
Statusbar::printf("Directory \"%1%\" added%2%", Statusbar::printf("Directory \"%1%\" added%2%",
item.directory().path(), withErrors(result)); item.directory().path(), withErrors(success));
break; break;
} }
case MPD::Item::Type::Song: case MPD::Item::Type::Song:
result = addSongToPlaylist(item.song(), play); success = addSongToPlaylist(item.song(), play);
break; break;
case MPD::Item::Type::Playlist: case MPD::Item::Type::Playlist:
Mpd.LoadPlaylist(item.playlist().path()); success = Mpd.LoadPlaylist(item.playlist().path());
if (play) if (play)
tryToPlay(); tryToPlay();
Statusbar::printf("Playlist \"%1%\" loaded", item.playlist().path()); if (success)
result = true; Statusbar::printf("Playlist \"%1%\" loaded", item.playlist().path());
break; break;
} }
return result; return success;
} }
std::vector<MPD::Song> Browser::getSelectedSongs() std::vector<MPD::Song> Browser::getSelectedSongs()

View File

@@ -374,17 +374,34 @@ bool PlaylistEditor::itemAvailable()
bool PlaylistEditor::addItemToPlaylist(bool play) bool PlaylistEditor::addItemToPlaylist(bool play)
{ {
bool result = false; bool success = false;
if (isActiveWindow(Playlists)) if (isActiveWindow(Playlists))
{ {
ScopedUnfilteredMenu<MPD::Song> sunfilter_content(ReapplyFilter::No, Content); const auto &playlist = Playlists.current()->value();
result = addSongsToPlaylist(Content.beginV(), Content.endV(), play, -1); success = Mpd.LoadPlaylist(playlist.path());
Statusbar::printf("Playlist \"%1%\" loaded%2%", if (play)
Playlists.current()->value().path(), withErrors(result)); {
// 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)) else if (isActiveWindow(Content))
result = addSongToPlaylist(Content.current()->value(), play); success = addSongToPlaylist(Content.current()->value(), play);
return result; return success;
} }
std::vector<MPD::Song> PlaylistEditor::getSelectedSongs() std::vector<MPD::Song> PlaylistEditor::getSelectedSongs()