status: make idle events handling independent of the order of their arrival

This commit is contained in:
Andrzej Rybczak
2014-09-04 17:39:15 +02:00
parent b4a8b136c9
commit 0b4d7e203b
5 changed files with 50 additions and 36 deletions

View File

@@ -2681,7 +2681,7 @@ void seek()
Progressbar::lock(); Progressbar::lock();
Statusbar::lock(); Statusbar::lock();
unsigned songpos = Status::elapsedTime(); unsigned songpos = Status::get().elapsedTime();
auto t = Timer; auto t = Timer;
int old_timeout = wFooter->getTimeout(); int old_timeout = wFooter->getTimeout();

View File

@@ -170,6 +170,7 @@ int main(int argc, char **argv)
throw MPD::ClientError(MPD_ERROR_STATE, "MPD < 0.16.0 is not supported", false); throw MPD::ClientError(MPD_ERROR_STATE, "MPD < 0.16.0 is not supported", false);
} }
wFooter->addFDCallback(Mpd.GetFD(), Statusbar::Helpers::mpd); wFooter->addFDCallback(Mpd.GetFD(), Statusbar::Helpers::mpd);
Status::clear(); // reset local status info
Status::update(-1); // we need info about new connection Status::update(-1); // we need info about new connection
if (Config.jump_to_now_playing_song_at_start) if (Config.jump_to_now_playing_song_at_start)
@@ -179,7 +180,9 @@ int main(int argc, char **argv)
myPlaylist->main().highlight(curr_pos); myPlaylist->main().highlight(curr_pos);
} }
// Set TCP_NODELAY on the tcp socket as this significantly speeds up operations. // Set TCP_NODELAY on the tcp socket as we are using write-write-read pattern
// a lot (idle - write, noidle - write, then read the result of noidle), which
// kills the performance.
int flag = 1; int flag = 1;
setsockopt(Mpd.GetFD(), IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag)); setsockopt(Mpd.GetFD(), IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag));

View File

@@ -55,17 +55,18 @@ size_t playing_song_scroll_begin = 0;
size_t first_line_scroll_begin = 0; size_t first_line_scroll_begin = 0;
size_t second_line_scroll_begin = 0; size_t second_line_scroll_begin = 0;
MPD::Status m_status;
// local copies of these are needed to be independent
// of the order of idle events incoming from MPD.
char m_repeat = 0; char m_repeat = 0;
char m_random = 0; char m_random = 0;
char m_single = 0; char m_single = 0;
char m_consume = 0; char m_consume = 0;
char m_crossfade = 0; char m_crossfade = 0;
char m_db_updating = 0; char m_db_updating = 0;
MPD::Status m_status;
// needed for the way events are emitted in consume mode after song ends
int m_current_song_id = 0; int m_current_song_id = 0;
unsigned m_elapsed_time = 0; unsigned m_playlist_version = 0;
void drawTitle(const MPD::Song &np) void drawTitle(const MPD::Song &np)
{ {
@@ -169,21 +170,23 @@ void Status::update(int event)
{ {
MPD::Status old_status = m_status; MPD::Status old_status = m_status;
m_status = Mpd.getStatus(); m_status = Mpd.getStatus();
m_elapsed_time = m_status.elapsedTime();
if (event & MPD_IDLE_DATABASE) if (event & MPD_IDLE_DATABASE)
Changes::database(); Changes::database();
if (event & MPD_IDLE_STORED_PLAYLIST) if (event & MPD_IDLE_STORED_PLAYLIST)
Changes::storedPlaylists(); Changes::storedPlaylists();
if (event & MPD_IDLE_PLAYLIST) if (event & MPD_IDLE_PLAYLIST)
Changes::playlist(old_status.empty() ? 0 : old_status.playlistVersion()); {
Changes::playlist(m_playlist_version);
m_playlist_version = m_status.playlistVersion();
}
if (event & MPD_IDLE_PLAYER) if (event & MPD_IDLE_PLAYER)
{ {
Changes::playerState(); Changes::playerState();
if (m_current_song_id != m_status.currentSongID()) if (m_current_song_id != m_status.currentSongID())
{ {
m_current_song_id = m_status.currentSongID();
Changes::songID(); Changes::songID();
m_current_song_id = m_status.currentSongID();
} }
} }
if (event & MPD_IDLE_MIXER) if (event & MPD_IDLE_MIXER)
@@ -192,20 +195,21 @@ void Status::update(int event)
Changes::outputs(); Changes::outputs();
if (event & (MPD_IDLE_UPDATE | MPD_IDLE_OPTIONS)) if (event & (MPD_IDLE_UPDATE | MPD_IDLE_OPTIONS))
{ {
bool show_msg = !old_status.empty();
if (event & MPD_IDLE_UPDATE) if (event & MPD_IDLE_UPDATE)
Changes::dbUpdateState(!old_status.empty()); Changes::dbUpdateState(show_msg);
if (event & MPD_IDLE_OPTIONS) if (event & MPD_IDLE_OPTIONS)
{ {
if (old_status.empty() || old_status.repeat() != m_status.repeat()) if (('r' == m_repeat) != m_status.repeat())
Changes::repeat(!old_status.empty()); Changes::repeat(show_msg);
if (old_status.empty() || old_status.random() != m_status.random()) if (('z' == m_random) != m_status.random())
Changes::random(!old_status.empty()); Changes::random(show_msg);
if (old_status.empty() || old_status.single() != m_status.single()) if (('s' == m_single) != m_status.single())
Changes::single(!old_status.empty()); Changes::single(show_msg);
if (old_status.empty() || old_status.consume() != m_status.consume()) if (('c' == m_consume) != m_status.consume())
Changes::consume(!old_status.empty()); Changes::consume(show_msg);
if (old_status.empty() || old_status.crossfade() != m_status.crossfade()) if (('x' == m_crossfade) != m_status.crossfade())
Changes::crossfade(!old_status.empty()); Changes::crossfade(show_msg);
} }
Changes::flags(); Changes::flags();
} }
@@ -217,18 +221,25 @@ void Status::update(int event)
applyToVisibleWindows(&BaseScreen::refreshWindow); applyToVisibleWindows(&BaseScreen::refreshWindow);
} }
/*************************************************************************/ void Status::clear()
{
// reset local variables
m_status.clear();
m_repeat = 0;
m_random = 0;
m_single = 0;
m_consume = 0;
m_crossfade = 0;
m_db_updating = 0;
m_current_song_id = 0;
m_playlist_version = 0;
}
const MPD::Status &Status::get() const MPD::Status &Status::get()
{ {
return m_status; return m_status;
} }
unsigned Status::elapsedTime()
{
return m_elapsed_time;
}
/*************************************************************************/ /*************************************************************************/
void Status::Changes::playlist(unsigned previous_version) void Status::Changes::playlist(unsigned previous_version)
@@ -388,7 +399,7 @@ void Status::Changes::songID()
void Status::Changes::elapsedTime(bool update_elapsed) void Status::Changes::elapsedTime(bool update_elapsed)
{ {
if (update_elapsed) if (update_elapsed)
m_elapsed_time = Mpd.getStatus().elapsedTime(); m_status = Mpd.getStatus();
const auto &st = m_status; const auto &st = m_status;
if (st.playerState() == MPD::psStop) if (st.playerState() == MPD::psStop)
@@ -420,17 +431,17 @@ void Status::Changes::elapsedTime(bool update_elapsed)
if (Config.display_remaining_time) if (Config.display_remaining_time)
{ {
tracklength += "-"; tracklength += "-";
tracklength += MPD::Song::ShowTime(st.totalTime()-m_elapsed_time); tracklength += MPD::Song::ShowTime(st.totalTime()-st.elapsedTime());
} }
else else
tracklength += MPD::Song::ShowTime(m_elapsed_time); tracklength += MPD::Song::ShowTime(st.elapsedTime());
tracklength += "/"; tracklength += "/";
tracklength += MPD::Song::ShowTime(st.totalTime()); tracklength += MPD::Song::ShowTime(st.totalTime());
tracklength += "]"; tracklength += "]";
} }
else else
{ {
tracklength += MPD::Song::ShowTime(m_elapsed_time); tracklength += MPD::Song::ShowTime(st.elapsedTime());
tracklength += "]"; tracklength += "]";
} }
NC::WBuffer np_song; NC::WBuffer np_song;
@@ -444,10 +455,10 @@ void Status::Changes::elapsedTime(bool update_elapsed)
if (Config.display_remaining_time) if (Config.display_remaining_time)
{ {
tracklength = "-"; tracklength = "-";
tracklength += MPD::Song::ShowTime(st.totalTime()-m_elapsed_time); tracklength += MPD::Song::ShowTime(st.totalTime()-st.elapsedTime());
} }
else else
tracklength = MPD::Song::ShowTime(m_elapsed_time); tracklength = MPD::Song::ShowTime(st.elapsedTime());
if (st.totalTime()) if (st.totalTime())
{ {
tracklength += "/"; tracklength += "/";
@@ -487,7 +498,7 @@ void Status::Changes::elapsedTime(bool update_elapsed)
flags(); flags();
} }
if (Progressbar::isUnlocked()) if (Progressbar::isUnlocked())
Progressbar::draw(m_elapsed_time, st.totalTime()); Progressbar::draw(st.elapsedTime(), st.totalTime());
} }
void Status::Changes::repeat(bool show_msg) void Status::Changes::repeat(bool show_msg)

View File

@@ -32,9 +32,9 @@ void handleServerError(MPD::ServerError &e);
void trace(bool update_timer, bool update_window_timeout); void trace(bool update_timer, bool update_window_timeout);
inline void trace() { trace(true, false); } inline void trace() { trace(true, false); }
void update(int event); void update(int event);
void clear();
const MPD::Status &get(); const MPD::Status &get();
unsigned elapsedTime();
namespace Changes {// namespace Changes {//

View File

@@ -112,7 +112,7 @@ void Statusbar::unlock()
put() << wclrtoeol; put() << wclrtoeol;
break; break;
case Design::Alternative: case Design::Alternative:
Progressbar::draw(Status::elapsedTime(), Status::get().totalTime()); Progressbar::draw(Status::get().elapsedTime(), Status::get().totalTime());
break; break;
} }
wFooter->refresh(); wFooter->refresh();
@@ -145,7 +145,7 @@ void Statusbar::tryRedraw()
Status::Changes::elapsedTime(false); Status::Changes::elapsedTime(false);
break; break;
case Design::Alternative: case Design::Alternative:
Progressbar::draw(Status::elapsedTime(), Status::get().totalTime()); Progressbar::draw(Status::get().elapsedTime(), Status::get().totalTime());
break; break;
} }
wFooter->refresh(); wFooter->refresh();