From 5b56c48c4aa55a7eb410b2bae61d194f484ef7cc Mon Sep 17 00:00:00 2001 From: Andrzej Rybczak Date: Mon, 21 Nov 2016 10:47:27 +0100 Subject: [PATCH] lyrics: add support for showing notifications about fetching lyrics in background --- src/actions.cpp | 4 ++++ src/lyrics.cpp | 55 +++++++++++++++++++++++++++++++++---------------- src/lyrics.h | 34 ++++++++++++++++++++++++++++-- src/status.cpp | 2 +- 4 files changed, 74 insertions(+), 21 deletions(-) diff --git a/src/actions.cpp b/src/actions.cpp index 699efcaf..fb338445 100644 --- a/src/actions.cpp +++ b/src/actions.cpp @@ -317,6 +317,10 @@ void UpdateEnvironment::run(bool update_timer, bool refresh_window) // update timer, status if necessary etc. Status::trace(update_timer, true); + // show lyrics consumer notification if appropriate + if (auto message = myLyrics->tryTakeConsumerMessage()) + Statusbar::print(*message); + // header stuff if ((myScreen == myPlaylist || myScreen == myBrowser || myScreen == myLyrics) && (Timer - m_past > boost::posix_time::milliseconds(500)) diff --git a/src/lyrics.cpp b/src/lyrics.cpp index 02d440d7..13a79b6b 100644 --- a/src/lyrics.cpp +++ b/src/lyrics.cpp @@ -190,7 +190,6 @@ Lyrics::Lyrics() , m_refresh_window(false) , m_scroll_begin(0) , m_fetcher(nullptr) - , m_shared_queue(std::make_pair(false, std::queue{})) { } void Lyrics::resize() @@ -359,42 +358,62 @@ void Lyrics::toggleFetcher() Statusbar::print("Using all lyrics fetchers"); } -void Lyrics::fetchInBackground(const MPD::Song &s) +void Lyrics::fetchInBackground(const MPD::Song &s, bool notify_) { - auto consumer = [this] { + auto consumer_impl = [this] { std::string lyrics_file; while (true) { - MPD::Song qs; + ConsumerState::Song cs; { - auto queue = m_shared_queue.acquire(); - assert(queue->first); - if (queue->second.empty()) + auto consumer = m_consumer_state.acquire(); + assert(consumer->running); + if (consumer->songs.empty()) { - queue->first = false; + consumer->running = false; break; } - lyrics_file = lyricsFilename(queue->second.front()); + lyrics_file = lyricsFilename(consumer->songs.front().song()); if (!boost::filesystem::exists(lyrics_file)) - qs = queue->second.front(); - queue->second.pop(); + { + cs = consumer->songs.front(); + if (cs.notify()) + { + consumer->message = "Fetching lyrics for \"" + + Format::stringify(Config.song_status_format, &cs.song()) + + "\"..."; + } + } + consumer->songs.pop(); } - if (!qs.empty()) + if (!cs.song().empty()) { - auto lyrics = downloadLyrics(qs, nullptr, m_fetcher); + auto lyrics = downloadLyrics(cs.song(), nullptr, m_fetcher); if (lyrics) saveLyrics(lyrics_file, *lyrics); } } }; - auto queue = m_shared_queue.acquire(); - queue->second.push(s); + auto consumer = m_consumer_state.acquire(); + consumer->songs.emplace(s, notify_); // Start the consumer if it's not running. - if (!queue->first) + if (!consumer->running) { - std::thread t(consumer); + std::thread t(consumer_impl); t.detach(); - queue->first = true; + consumer->running = true; } } + +boost::optional Lyrics::tryTakeConsumerMessage() +{ + boost::optional result; + auto consumer = m_consumer_state.acquire(); + if (consumer->message) + { + result = std::move(consumer->message); + consumer->message = boost::none; + } + return result; +} diff --git a/src/lyrics.h b/src/lyrics.h index 32739c32..4b842aed 100644 --- a/src/lyrics.h +++ b/src/lyrics.h @@ -55,9 +55,39 @@ struct Lyrics: Screen, Tabbable void edit(); void toggleFetcher(); - void fetchInBackground(const MPD::Song &s); + void fetchInBackground(const MPD::Song &s, bool notify_); + boost::optional tryTakeConsumerMessage(); private: + struct ConsumerState + { + struct Song + { + Song() + : m_notify(false) + { } + + Song(const MPD::Song &s, bool notify_) + : m_song(s), m_notify(notify_) + { } + + const MPD::Song &song() const { return m_song; } + bool notify() const { return m_notify; } + + private: + MPD::Song m_song; + bool m_notify; + }; + + ConsumerState() + : running(false) + { } + + bool running; + std::queue songs; + boost::optional message; + }; + bool m_refresh_window; size_t m_scroll_begin; @@ -67,7 +97,7 @@ private: LyricsFetcher *m_fetcher; std::future> m_worker; - Shared>> m_shared_queue; + Shared m_consumer_state; }; extern Lyrics *myLyrics; diff --git a/src/status.cpp b/src/status.cpp index 019b6853..7f3f8fe1 100644 --- a/src/status.cpp +++ b/src/status.cpp @@ -573,7 +573,7 @@ void Status::Changes::songID(int song_id) res = system(Config.execute_on_song_change.c_str()); if (Config.fetch_lyrics_in_background) - myLyrics->fetchInBackground(s); + myLyrics->fetchInBackground(s, false); drawTitle(s);