diff --git a/src/browser.cpp b/src/browser.cpp index c9462175..dcffb933 100644 --- a/src/browser.cpp +++ b/src/browser.cpp @@ -558,9 +558,9 @@ void Browser::remove(const MPD::Item &item) void Browser::fetchSupportedExtensions() { lm_supported_extensions.clear(); - Mpd.GetSupportedExtensions([&](std::string extension) { - lm_supported_extensions.insert("." + std::move(extension)); - }); + MPD::StringIterator extension = Mpd.GetSupportedExtensions(), end; + for (; extension != end; ++extension) + lm_supported_extensions.insert("." + std::move(*extension)); } /***********************************************************************/ diff --git a/src/media_library.cpp b/src/media_library.cpp index 54a5f8e3..083c9175 100644 --- a/src/media_library.cpp +++ b/src/media_library.cpp @@ -321,9 +321,9 @@ void MediaLibrary::update() } else { - Mpd.GetList(Config.media_lib_primary_tag, [&tags](std::string tag) { - tags[tag] = 0; - }); + MPD::StringIterator tag = Mpd.GetList(Config.media_lib_primary_tag), end; + for (; tag != end; ++tag) + tags[std::move(*tag)] = 0; } withUnfilteredMenuReapplyFilter(Tags, [this, &tags]() { size_t idx = 0; diff --git a/src/mpdpp.cpp b/src/mpdpp.cpp index d75a1a73..b09458ab 100644 --- a/src/mpdpp.cpp +++ b/src/mpdpp.cpp @@ -31,16 +31,20 @@ MPD::Connection Mpd; namespace { -bool fetchItem(MPD::ItemIterator::State &state) +template +std::function::State &)> +defaultFetcher(SourceT *(fetcher)(mpd_connection *)) { - auto src = mpd_recv_entity(state.connection()); - if (src != nullptr) - { - state.setObject(src); - return true; - } - else - return false; + return [fetcher](typename MPD::Iterator::State &state) { + auto src = fetcher(state.connection()); + if (src != nullptr) + { + state.setObject(src); + return true; + } + else + return false; + }; } bool fetchItemSong(MPD::SongIterator::State &state) @@ -61,42 +65,6 @@ bool fetchItemSong(MPD::SongIterator::State &state) return false; } -bool fetchPlaylist(MPD::PlaylistIterator::State &state) -{ - auto src = mpd_recv_playlist(state.connection()); - if (src != nullptr) - { - state.setObject(src); - return true; - } - else - return false; -} - -bool fetchSong(MPD::SongIterator::State &state) -{ - auto src = mpd_recv_song(state.connection()); - if (src != nullptr) - { - state.setObject(src); - return true; - } - else - return false; -} - -bool fetchOutput(MPD::OutputIterator::State &state) -{ - auto src = mpd_recv_output(state.connection()); - if (src != nullptr) - { - state.setObject(src); - return true; - } - else - return false; -} - } namespace MPD { @@ -365,7 +333,7 @@ SongIterator Connection::GetPlaylistChanges(unsigned version) prechecksNoCommandsList(); mpd_send_queue_changes_meta(m_connection.get(), version); checkErrors(); - return SongIterator(m_connection.get(), fetchSong); + return SongIterator(m_connection.get(), defaultFetcher(mpd_recv_song)); } Song Connection::GetCurrentSong() @@ -392,7 +360,7 @@ SongIterator Connection::GetPlaylistContent(const std::string &path) { prechecksNoCommandsList(); mpd_send_list_playlist_meta(m_connection.get(), path.c_str()); - SongIterator result(m_connection.get(), fetchSong); + SongIterator result(m_connection.get(), defaultFetcher(mpd_recv_song)); checkErrors(); return result; } @@ -401,22 +369,27 @@ SongIterator Connection::GetPlaylistContentNoInfo(const std::string &path) { prechecksNoCommandsList(); mpd_send_list_playlist(m_connection.get(), path.c_str()); - SongIterator result(m_connection.get(), fetchSong); + SongIterator result(m_connection.get(), defaultFetcher(mpd_recv_song)); checkErrors(); return result; } -void Connection::GetSupportedExtensions(StringConsumer f) +StringIterator Connection::GetSupportedExtensions() { prechecksNoCommandsList(); mpd_send_command(m_connection.get(), "decoders", NULL); - while (mpd_pair *pair = mpd_recv_pair_named(m_connection.get(), "suffix")) - { - f(pair->value); - mpd_return_pair(m_connection.get(), pair); - } - mpd_response_finish(m_connection.get()); checkErrors(); + return StringIterator(m_connection.get(), [](StringIterator::State &state) { + auto src = mpd_recv_pair_named(state.connection(), "suffix"); + if (src != nullptr) + { + state.setObject(src->value); + mpd_return_pair(state.connection(), src); + return true; + } + else + return false; + }); } void Connection::SetRepeat(bool mode) @@ -550,33 +523,27 @@ void Connection::Add(const std::string &path) bool Connection::AddRandomTag(mpd_tag_type tag, size_t number) { - StringList tags; - GetList(tag, [&tags](std::string tag_name) { - tags.push_back(tag_name); - }); + std::vector tags( + std::make_move_iterator(GetList(tag)), + std::make_move_iterator(StringIterator()) + ); if (number > tags.size()) - { - //if (itsErrorHandler) - // itsErrorHandler(this, 0, "Requested number is out of range", itsErrorHandlerUserdata); return false; - } - else + + std::random_shuffle(tags.begin(), tags.end()); + auto it = tags.begin()+rand()%(tags.size()-number); + for (size_t i = 0; i < number && it != tags.end(); ++i) { - std::random_shuffle(tags.begin(), tags.end()); - auto it = tags.begin()+rand()%(tags.size()-number); - for (size_t i = 0; i < number && it != tags.end(); ++i) - { - StartSearch(true); - AddSearch(tag, *it++); - std::vector paths; - MPD::SongIterator s = CommitSearchSongs(), end; - for (; s != end; ++s) - paths.push_back(s->getURI()); - StartCommandsList(); - for (const auto &path : paths) - AddSong(path); - CommitCommandsList(); - } + StartSearch(true); + AddSearch(tag, *it++); + std::vector paths; + MPD::SongIterator s = CommitSearchSongs(), end; + for (; s != end; ++s) + paths.push_back(s->getURI()); + StartCommandsList(); + for (const auto &path : paths) + AddSong(path); + CommitCommandsList(); } return true; } @@ -679,21 +646,26 @@ PlaylistIterator Connection::GetPlaylists() prechecksNoCommandsList(); mpd_send_list_playlists(m_connection.get()); checkErrors(); - return PlaylistIterator(m_connection.get(), fetchPlaylist); + return PlaylistIterator(m_connection.get(), defaultFetcher(mpd_recv_playlist)); } -void Connection::GetList(mpd_tag_type type, StringConsumer f) +StringIterator Connection::GetList(mpd_tag_type type) { prechecksNoCommandsList(); mpd_search_db_tags(m_connection.get(), type); mpd_search_commit(m_connection.get()); - while (mpd_pair *item = mpd_recv_pair_tag(m_connection.get(), type)) - { - f(std::string(item->value)); - mpd_return_pair(m_connection.get(), item); - } - mpd_response_finish(m_connection.get()); checkErrors(); + return StringIterator(m_connection.get(), [type](StringIterator::State &state) { + auto src = mpd_recv_pair_tag(state.connection(), type); + if (src != nullptr) + { + state.setObject(src->value); + mpd_return_pair(state.connection(), src); + return true; + } + else + return false; + }); } void Connection::StartSearch(bool exact_match) @@ -731,20 +703,7 @@ SongIterator Connection::CommitSearchSongs() prechecksNoCommandsList(); mpd_search_commit(m_connection.get()); checkErrors(); - return SongIterator(m_connection.get(), fetchSong); -} - -void Connection::CommitSearchTags(StringConsumer f) -{ - prechecksNoCommandsList(); - mpd_search_commit(m_connection.get()); - while (mpd_pair *tag = mpd_recv_pair_tag(m_connection.get(), m_searched_field)) - { - f(std::string(tag->value)); - mpd_return_pair(m_connection.get(), tag); - } - mpd_response_finish(m_connection.get()); - checkErrors(); + return SongIterator(m_connection.get(), defaultFetcher(mpd_recv_song)); } ItemIterator Connection::GetDirectory(const std::string &directory) @@ -752,7 +711,7 @@ ItemIterator Connection::GetDirectory(const std::string &directory) prechecksNoCommandsList(); mpd_send_list_meta(m_connection.get(), directory.c_str()); checkErrors(); - return ItemIterator(m_connection.get(), fetchItem); + return ItemIterator(m_connection.get(), defaultFetcher(mpd_recv_entity)); } SongIterator Connection::GetDirectoryRecursive(const std::string &directory) @@ -763,17 +722,12 @@ SongIterator Connection::GetDirectoryRecursive(const std::string &directory) return SongIterator(m_connection.get(), fetchItemSong); } -void Connection::GetDirectories(const std::string &directory, StringConsumer f) +DirectoryIterator Connection::GetDirectories(const std::string &directory) { prechecksNoCommandsList(); mpd_send_list_meta(m_connection.get(), directory.c_str()); - while (mpd_directory *dir = mpd_recv_directory(m_connection.get())) - { - f(std::string(mpd_directory_get_path(dir))); - mpd_directory_free(dir); - } - mpd_response_finish(m_connection.get()); checkErrors(); + return DirectoryIterator(m_connection.get(), defaultFetcher(mpd_recv_directory)); } SongIterator Connection::GetSongs(const std::string &directory) @@ -781,7 +735,7 @@ SongIterator Connection::GetSongs(const std::string &directory) prechecksNoCommandsList(); mpd_send_list_meta(m_connection.get(), directory.c_str()); checkErrors(); - return SongIterator(m_connection.get(), fetchSong); + return SongIterator(m_connection.get(), defaultFetcher(mpd_recv_song)); } OutputIterator Connection::GetOutputs() @@ -789,7 +743,7 @@ OutputIterator Connection::GetOutputs() prechecksNoCommandsList(); mpd_send_outputs(m_connection.get()); checkErrors(); - return OutputIterator(m_connection.get(), fetchOutput); + return OutputIterator(m_connection.get(), defaultFetcher(mpd_recv_output)); } void Connection::EnableOutput(int id) @@ -806,31 +760,41 @@ void Connection::DisableOutput(int id) checkErrors(); } -void Connection::GetURLHandlers(StringConsumer f) +StringIterator Connection::GetURLHandlers() { prechecksNoCommandsList(); mpd_send_list_url_schemes(m_connection.get()); - while (mpd_pair *handler = mpd_recv_pair_named(m_connection.get(), "handler")) - { - f(std::string(handler->value)); - mpd_return_pair(m_connection.get(), handler); - } - mpd_response_finish(m_connection.get()); checkErrors(); + return StringIterator(m_connection.get(), [](StringIterator::State &state) { + auto src = mpd_recv_pair_named(state.connection(), "handler"); + if (src != nullptr) + { + state.setObject(src->value); + mpd_return_pair(state.connection(), src); + return true; + } + else + return false; + }); } -void Connection::GetTagTypes(StringConsumer f) +StringIterator Connection::GetTagTypes() { prechecksNoCommandsList(); mpd_send_list_tag_types(m_connection.get()); - while (mpd_pair *tag_type = mpd_recv_pair_named(m_connection.get(), "tagtype")) - { - f(std::string(tag_type->value)); - mpd_return_pair(m_connection.get(), tag_type); - } - mpd_response_finish(m_connection.get()); checkErrors(); + return StringIterator(m_connection.get(), [](StringIterator::State &state) { + auto src = mpd_recv_pair_named(state.connection(), "tagtype"); + if (src != nullptr) + { + state.setObject(src->value); + mpd_return_pair(state.connection(), src); + return true; + } + else + return false; + }); } void Connection::checkConnection() const diff --git a/src/mpdpp.h b/src/mpdpp.h index 9a1b4e5d..b1fea757 100644 --- a/src/mpdpp.h +++ b/src/mpdpp.h @@ -68,7 +68,7 @@ private: struct Statistics { - friend class Connection; + friend struct Connection; bool empty() const { return m_stats.get() == nullptr; } @@ -88,7 +88,7 @@ private: struct Status { - friend class Connection; + friend struct Connection; Status() { } @@ -337,7 +337,7 @@ struct Iterator: std::iterator { friend Iterator; - typedef bool (*Fetcher)(State &); + typedef std::function Fetcher; State(mpd_connection *connection, Fetcher fetcher) : m_connection(connection) @@ -448,16 +448,15 @@ private: std::shared_ptr m_state; }; +typedef Iterator DirectoryIterator; typedef Iterator ItemIterator; typedef Iterator OutputIterator; typedef Iterator PlaylistIterator; typedef Iterator SongIterator; +typedef Iterator StringIterator; -class Connection +struct Connection { - typedef std::function StringConsumer; - -public: Connection(); void Connect(); @@ -503,7 +502,7 @@ public: SongIterator GetPlaylistContent(const std::string &name); SongIterator GetPlaylistContentNoInfo(const std::string &name); - void GetSupportedExtensions(StringConsumer f); + StringIterator GetSupportedExtensions(); void SetRepeat(bool); void SetRandom(bool); @@ -542,21 +541,20 @@ public: void AddSearchAny(const std::string &str) const; void AddSearchURI(const std::string &str) const; SongIterator CommitSearchSongs(); - void CommitSearchTags(StringConsumer f); PlaylistIterator GetPlaylists(); - void GetList(mpd_tag_type type, StringConsumer f); + StringIterator GetList(mpd_tag_type type); ItemIterator GetDirectory(const std::string &directory); SongIterator GetDirectoryRecursive(const std::string &directory); SongIterator GetSongs(const std::string &directory); - void GetDirectories(const std::string &directory, StringConsumer f); + DirectoryIterator GetDirectories(const std::string &directory); OutputIterator GetOutputs(); void EnableOutput(int id); void DisableOutput(int id); - void GetURLHandlers(StringConsumer f); - void GetTagTypes(StringConsumer f); + StringIterator GetURLHandlers(); + StringIterator GetTagTypes(); void idle(); int noidle(); @@ -583,8 +581,6 @@ private: int m_port; int m_timeout; std::string m_password; - - mpd_tag_type m_searched_field; }; } diff --git a/src/server_info.cpp b/src/server_info.cpp index 67f00964..f61d5f97 100644 --- a/src/server_info.cpp +++ b/src/server_info.cpp @@ -36,7 +36,7 @@ ServerInfo::ServerInfo() : m_timer(boost::posix_time::from_time_t(0)) { SetDimensions(); - w = NC::Scrollpad((COLS-itsWidth)/2, (MainHeight-itsHeight)/2+MainStartY, itsWidth, itsHeight, "MPD server info", Config.main_color, Config.window_border); + w = NC::Scrollpad((COLS-m_width)/2, (MainHeight-m_height)/2+MainStartY, m_width, m_height, "MPD server info", Config.main_color, Config.window_border); } void ServerInfo::switchTo() @@ -46,11 +46,19 @@ void ServerInfo::switchTo() { SwitchTo::execute(this); - itsURLHandlers.clear(); - itsTagTypes.clear(); - - Mpd.GetURLHandlers(vectorMoveInserter(itsURLHandlers)); - Mpd.GetTagTypes(vectorMoveInserter(itsTagTypes)); + m_url_handlers.clear(); + std::copy( + std::make_move_iterator(Mpd.GetURLHandlers()), + std::make_move_iterator(MPD::StringIterator()), + std::back_inserter(m_url_handlers) + ); + + m_tag_types.clear(); + std::copy( + std::make_move_iterator(Mpd.GetTagTypes()), + std::make_move_iterator(MPD::StringIterator()), + std::back_inserter(m_tag_types) + ); } else switchToPreviousScreen(); @@ -59,8 +67,8 @@ void ServerInfo::switchTo() void ServerInfo::resize() { SetDimensions(); - w.resize(itsWidth, itsHeight); - w.moveTo((COLS-itsWidth)/2, (MainHeight-itsHeight)/2+MainStartY); + w.resize(m_width, m_height); + w.moveTo((COLS-m_width)/2, (MainHeight-m_height)/2+MainStartY); if (previousScreen() && previousScreen()->hasToBeResized) // resize background window { previousScreen()->resize(); @@ -102,12 +110,12 @@ void ServerInfo::update() w << NC::Format::Bold << "Last DB update: " << NC::Format::NoBold << Timestamp(stats.dbUpdateTime()) << '\n'; w << '\n'; w << NC::Format::Bold << "URL Handlers:" << NC::Format::NoBold; - for (auto it = itsURLHandlers.begin(); it != itsURLHandlers.end(); ++it) - w << (it != itsURLHandlers.begin() ? ", " : " ") << *it; + for (auto it = m_url_handlers.begin(); it != m_url_handlers.end(); ++it) + w << (it != m_url_handlers.begin() ? ", " : " ") << *it; w << "\n\n"; w << NC::Format::Bold << "Tag Types:" << NC::Format::NoBold; - for (auto it = itsTagTypes.begin(); it != itsTagTypes.end(); ++it) - w << (it != itsTagTypes.begin() ? ", " : " ") << *it; + for (auto it = m_tag_types.begin(); it != m_tag_types.end(); ++it) + w << (it != m_tag_types.begin() ? ", " : " ") << *it; w.flush(); w.refresh(); @@ -115,7 +123,7 @@ void ServerInfo::update() void ServerInfo::SetDimensions() { - itsWidth = COLS*0.6; - itsHeight = std::min(size_t(LINES*0.7), MainHeight); + m_width = COLS*0.6; + m_height = std::min(size_t(LINES*0.7), MainHeight); } diff --git a/src/server_info.h b/src/server_info.h index 695a839e..5213fcc0 100644 --- a/src/server_info.h +++ b/src/server_info.h @@ -52,11 +52,11 @@ private: boost::posix_time::ptime m_timer; - MPD::StringList itsURLHandlers; - MPD::StringList itsTagTypes; + std::vector m_url_handlers; + std::vector m_tag_types; - size_t itsWidth; - size_t itsHeight; + size_t m_width; + size_t m_height; }; extern ServerInfo *myServerInfo; diff --git a/src/tag_editor.cpp b/src/tag_editor.cpp index bfe30aa6..bddb6b05 100644 --- a/src/tag_editor.cpp +++ b/src/tag_editor.cpp @@ -239,11 +239,13 @@ void TagEditor::update() Dirs->addItem(std::make_pair("..", getParentDirectory(itsBrowsedDir))); else Dirs->addItem(std::make_pair(".", "/")); - Mpd.GetDirectories(itsBrowsedDir, [this](std::string directory) { - Dirs->addItem(std::make_pair(getBasename(directory), directory)); - if (directory == itsHighlightedDir) + MPD::DirectoryIterator directory = Mpd.GetDirectories(itsBrowsedDir), end; + for (; directory != end; ++directory) + { + Dirs->addItem(std::make_pair(getBasename(directory->path()), directory->path())); + if (directory->path() == itsHighlightedDir) Dirs->highlight(Dirs->size()-1); - }); + }; std::sort(Dirs->beginV()+1, Dirs->endV(), LocaleBasedSorting(std::locale(), Config.ignore_leading_the)); Dirs->display(); @@ -277,10 +279,9 @@ void TagEditor::enterPressed() if (w == Dirs) { - bool has_subdirs = false; - Mpd.GetDirectories(Dirs->current().value().second, [&has_subdirs](std::string) { - has_subdirs = true; - }); + MPD::DirectoryIterator directory = Mpd.GetDirectories(Dirs->current().value().second), end; + bool has_subdirs = directory != end; + directory.finish(); if (has_subdirs) { itsHighlightedDir = itsBrowsedDir;