fix(mpd): Connection state broadcasting

This commit is contained in:
Michael Carlberg 2016-10-29 06:52:48 +02:00
parent 1075144b00
commit e21d084fdd
3 changed files with 43 additions and 21 deletions

View File

@ -17,6 +17,10 @@ namespace mpd {
DEFINE_CHILD_ERROR(client_error, mpd_exception);
DEFINE_CHILD_ERROR(server_error, mpd_exception);
enum class connection_state {
NONE = 0, CONNECTED, DISCONNECTED
};
// type details {{{
namespace details {
@ -123,12 +127,14 @@ namespace mpd {
class mpdstatus;
class mpdconnection {
public:
explicit mpdconnection(const logger& logger, string host, unsigned int port = 6600, string password = "", unsigned int timeout = 15)
: m_log(logger), m_host(host), m_port(port), m_password(password), m_timeout(timeout) {}
explicit mpdconnection(const logger& logger, string host, unsigned int port = 6600,
string password = "", unsigned int timeout = 15)
: m_log(logger), m_host(host), m_port(port), m_password(password), m_timeout(timeout) {}
void connect() {
try {
m_log.trace("mpdconnection.connect: %s, %i, \"%s\", timeout: %i", m_host, m_port, m_password, m_timeout);
m_log.trace("mpdconnection.connect: %s, %i, \"%s\", timeout: %i", m_host, m_port,
m_password, m_timeout);
m_connection.reset(mpd_connection_new(m_host.c_str(), m_port, m_timeout * 1000));
check_errors(m_connection.get());

View File

@ -1,5 +1,7 @@
#pragma once
#include <csignal>
#include "adapters/mpd.hpp"
#include "drawtypes/iconset.hpp"
#include "drawtypes/label.hpp"
@ -99,61 +101,75 @@ namespace modules {
}
bool has_event() {
if (!m_mpd)
m_mpd = make_unique<mpdconnection>(m_log, m_host, m_port, m_pass);
bool def = false;
if (!connected() && m_statebroadcasted == mpd::connection_state::CONNECTED) {
def = true;
} else if (connected() && m_statebroadcasted == mpd::connection_state::DISCONNECTED) {
def = true;
}
try {
if (!m_mpd)
m_mpd = make_unique<mpdconnection>(m_log, m_host, m_port, m_pass);
if (!connected())
m_mpd->connect();
if (m_connection_state_broadcasted)
m_connection_state_broadcasted = false;
} catch (const mpd_exception& err) {
m_log.trace("%s: %s", name(), err.what());
m_mpd.reset();
return !m_connection_state_broadcasted;
return def;
}
if (!connected())
return !m_connection_state_broadcasted;
return def;
if (!m_status)
m_status = m_mpd->get_status_safe();
try {
m_mpd->idle();
int idle_flags = 0;
if ((idle_flags = m_mpd->noidle()) != 0) {
m_status->update(idle_flags, m_mpd.get());
return true;
} else if (m_status->match_state(mpdstate::PLAYING)) {
}
if (m_status->match_state(mpdstate::PLAYING)) {
m_status->update_timer();
}
} catch (const mpd_exception& err) {
m_log.err(err.what());
m_mpd.reset();
return !m_connection_state_broadcasted;
return def;
}
if ((m_label_time || m_bar_progress) && m_status->match_state(mpdstate::PLAYING)) {
auto now = chrono::system_clock::now();
auto diff = now - m_lastsync;
if (chrono::duration_cast<chrono::milliseconds>(diff).count() > m_synctime * 1000) {
m_lastsync = now;
return true;
}
}
return !m_connection_state_broadcasted;
return def;
}
bool update() {
if (m_connection_state_broadcasted) {
if (!connected())
if (connected())
m_statebroadcasted = mpd::connection_state::CONNECTED;
else if (!connected() && m_statebroadcasted != mpd::connection_state::DISCONNECTED)
m_statebroadcasted = mpd::connection_state::DISCONNECTED;
else if (!connected())
return false;
if (!m_status) {
if (connected() && (m_status = m_mpd->get_status_safe())) {
return false;
if (!m_status && !(m_status = m_mpd->get_status_safe()))
return false;
} else {
m_connection_state_broadcasted = true;
}
}
string artist;
@ -167,8 +183,10 @@ namespace modules {
elapsed_str = m_status->get_formatted_elapsed();
total_str = m_status->get_formatted_total();
}
if (m_mpd) {
auto song = m_mpd->get_song();
if (song && song.get()) {
artist = song->get_artist();
album = song->get_album();
@ -377,7 +395,7 @@ namespace modules {
// This flag is used to let thru a broadcast once every time
// the connection state changes
stateflag m_connection_state_broadcasted{false};
mpd::connection_state m_statebroadcasted;
};
}

View File

@ -43,8 +43,6 @@ namespace modules {
}
void idle() {
if (!enabled())
sleep(100ms);
if (!m_tail)
sleep(m_interval);
else if (!m_command || !m_command->is_running())