lyrics: add support for showing notifications about fetching lyrics in background
This commit is contained in:
@@ -317,6 +317,10 @@ void UpdateEnvironment::run(bool update_timer, bool refresh_window)
|
|||||||
// update timer, status if necessary etc.
|
// update timer, status if necessary etc.
|
||||||
Status::trace(update_timer, true);
|
Status::trace(update_timer, true);
|
||||||
|
|
||||||
|
// show lyrics consumer notification if appropriate
|
||||||
|
if (auto message = myLyrics->tryTakeConsumerMessage())
|
||||||
|
Statusbar::print(*message);
|
||||||
|
|
||||||
// header stuff
|
// header stuff
|
||||||
if ((myScreen == myPlaylist || myScreen == myBrowser || myScreen == myLyrics)
|
if ((myScreen == myPlaylist || myScreen == myBrowser || myScreen == myLyrics)
|
||||||
&& (Timer - m_past > boost::posix_time::milliseconds(500))
|
&& (Timer - m_past > boost::posix_time::milliseconds(500))
|
||||||
|
|||||||
@@ -190,7 +190,6 @@ Lyrics::Lyrics()
|
|||||||
, m_refresh_window(false)
|
, m_refresh_window(false)
|
||||||
, m_scroll_begin(0)
|
, m_scroll_begin(0)
|
||||||
, m_fetcher(nullptr)
|
, m_fetcher(nullptr)
|
||||||
, m_shared_queue(std::make_pair(false, std::queue<MPD::Song>{}))
|
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
void Lyrics::resize()
|
void Lyrics::resize()
|
||||||
@@ -359,42 +358,62 @@ void Lyrics::toggleFetcher()
|
|||||||
Statusbar::print("Using all lyrics fetchers");
|
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;
|
std::string lyrics_file;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
MPD::Song qs;
|
ConsumerState::Song cs;
|
||||||
{
|
{
|
||||||
auto queue = m_shared_queue.acquire();
|
auto consumer = m_consumer_state.acquire();
|
||||||
assert(queue->first);
|
assert(consumer->running);
|
||||||
if (queue->second.empty())
|
if (consumer->songs.empty())
|
||||||
{
|
{
|
||||||
queue->first = false;
|
consumer->running = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
lyrics_file = lyricsFilename(queue->second.front());
|
lyrics_file = lyricsFilename(consumer->songs.front().song());
|
||||||
if (!boost::filesystem::exists(lyrics_file))
|
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<char>(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)
|
if (lyrics)
|
||||||
saveLyrics(lyrics_file, *lyrics);
|
saveLyrics(lyrics_file, *lyrics);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
auto queue = m_shared_queue.acquire();
|
auto consumer = m_consumer_state.acquire();
|
||||||
queue->second.push(s);
|
consumer->songs.emplace(s, notify_);
|
||||||
// Start the consumer if it's not running.
|
// 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();
|
t.detach();
|
||||||
queue->first = true;
|
consumer->running = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boost::optional<std::string> Lyrics::tryTakeConsumerMessage()
|
||||||
|
{
|
||||||
|
boost::optional<std::string> result;
|
||||||
|
auto consumer = m_consumer_state.acquire();
|
||||||
|
if (consumer->message)
|
||||||
|
{
|
||||||
|
result = std::move(consumer->message);
|
||||||
|
consumer->message = boost::none;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|||||||
34
src/lyrics.h
34
src/lyrics.h
@@ -55,9 +55,39 @@ struct Lyrics: Screen<NC::Scrollpad>, Tabbable
|
|||||||
void edit();
|
void edit();
|
||||||
void toggleFetcher();
|
void toggleFetcher();
|
||||||
|
|
||||||
void fetchInBackground(const MPD::Song &s);
|
void fetchInBackground(const MPD::Song &s, bool notify_);
|
||||||
|
boost::optional<std::string> tryTakeConsumerMessage();
|
||||||
|
|
||||||
private:
|
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<Song> songs;
|
||||||
|
boost::optional<std::string> message;
|
||||||
|
};
|
||||||
|
|
||||||
bool m_refresh_window;
|
bool m_refresh_window;
|
||||||
size_t m_scroll_begin;
|
size_t m_scroll_begin;
|
||||||
|
|
||||||
@@ -67,7 +97,7 @@ private:
|
|||||||
LyricsFetcher *m_fetcher;
|
LyricsFetcher *m_fetcher;
|
||||||
std::future<boost::optional<std::string>> m_worker;
|
std::future<boost::optional<std::string>> m_worker;
|
||||||
|
|
||||||
Shared<std::pair<bool, std::queue<MPD::Song>>> m_shared_queue;
|
Shared<ConsumerState> m_consumer_state;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Lyrics *myLyrics;
|
extern Lyrics *myLyrics;
|
||||||
|
|||||||
@@ -573,7 +573,7 @@ void Status::Changes::songID(int song_id)
|
|||||||
res = system(Config.execute_on_song_change.c_str());
|
res = system(Config.execute_on_song_change.c_str());
|
||||||
|
|
||||||
if (Config.fetch_lyrics_in_background)
|
if (Config.fetch_lyrics_in_background)
|
||||||
myLyrics->fetchInBackground(s);
|
myLyrics->fetchInBackground(s, false);
|
||||||
|
|
||||||
drawTitle(s);
|
drawTitle(s);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user