refactor: Drop tokenized labels
Handle placeholder tokens inside each label instead of cloning into a new instance each time
This commit is contained in:
parent
37e367eb79
commit
68f72d69cc
@ -154,7 +154,7 @@ class builder {
|
||||
if (!label || !*label)
|
||||
return;
|
||||
|
||||
auto text = label->m_text;
|
||||
auto text = label->get();
|
||||
|
||||
if (label->m_maxlen > 0 && text.length() > label->m_maxlen) {
|
||||
text = text.substr(0, label->m_maxlen) + "...";
|
||||
|
@ -105,4 +105,7 @@ struct action_block {
|
||||
#endif
|
||||
};
|
||||
|
||||
struct wmsettings_bspwm {
|
||||
};
|
||||
|
||||
LEMONBUDDY_NS_END
|
||||
|
@ -14,23 +14,21 @@ namespace drawtypes {
|
||||
|
||||
class label : public non_copyable_mixin<label> {
|
||||
public:
|
||||
string m_text{""};
|
||||
string m_foreground{""};
|
||||
string m_background{""};
|
||||
string m_underline{""};
|
||||
string m_overline{""};
|
||||
int m_font{0};
|
||||
int m_padding{0};
|
||||
int m_margin{0};
|
||||
size_t m_maxlen{0};
|
||||
bool m_ellipsis{true};
|
||||
string m_foreground;
|
||||
string m_background;
|
||||
string m_underline;
|
||||
string m_overline;
|
||||
int m_font = 0;
|
||||
int m_padding = 0;
|
||||
int m_margin = 0;
|
||||
size_t m_maxlen = 0;
|
||||
bool m_ellipsis = true;
|
||||
|
||||
explicit label(string text, int font) : m_text(text), m_font(font) {}
|
||||
explicit label(string text, int font) : m_font(font), m_text(text), m_tokenized(m_text) {}
|
||||
explicit label(string text, string foreground = "", string background = "",
|
||||
string underline = "", string overline = "", int font = 0, int padding = 0, int margin = 0,
|
||||
size_t maxlen = 0, bool ellipsis = true)
|
||||
: m_text(text)
|
||||
, m_foreground(foreground)
|
||||
: m_foreground(foreground)
|
||||
, m_background(background)
|
||||
, m_underline(underline)
|
||||
, m_overline(overline)
|
||||
@ -38,7 +36,13 @@ namespace drawtypes {
|
||||
, m_padding(padding)
|
||||
, m_margin(margin)
|
||||
, m_maxlen(maxlen)
|
||||
, m_ellipsis(ellipsis) {}
|
||||
, m_ellipsis(ellipsis)
|
||||
, m_text(text)
|
||||
, m_tokenized(m_text) {}
|
||||
|
||||
string get() const {
|
||||
return m_tokenized;
|
||||
}
|
||||
|
||||
operator bool() {
|
||||
return !m_text.empty();
|
||||
@ -49,8 +53,12 @@ namespace drawtypes {
|
||||
m_padding, m_margin, m_maxlen, m_ellipsis)};
|
||||
}
|
||||
|
||||
void reset_tokens() {
|
||||
m_tokenized = m_text;
|
||||
}
|
||||
|
||||
void replace_token(string token, string replacement) {
|
||||
m_text = string_util::replace_all(m_text, token, replacement);
|
||||
m_tokenized = string_util::replace_all(m_tokenized, token, replacement);
|
||||
}
|
||||
|
||||
void replace_defined_values(label_t label) {
|
||||
@ -63,6 +71,9 @@ namespace drawtypes {
|
||||
if (!label->m_overline.empty())
|
||||
m_overline = label->m_overline;
|
||||
}
|
||||
|
||||
private:
|
||||
string m_text, m_tokenized;
|
||||
};
|
||||
|
||||
inline label_t get_config_label(const config& conf, string section, string name = "label",
|
||||
|
@ -27,9 +27,6 @@ namespace modules {
|
||||
if (m_formatter->has(TAG_RAMP))
|
||||
m_ramp = get_config_ramp(m_conf, name(), TAG_RAMP);
|
||||
|
||||
if (m_label)
|
||||
m_tokenized = m_label->clone();
|
||||
|
||||
// Build path to the file where the current/maximum brightness value is located
|
||||
m_path_val = string_util::replace(PATH_BACKLIGHT_VAL, "%card%", card);
|
||||
m_path_max = string_util::replace(PATH_BACKLIGHT_MAX, "%card%", card);
|
||||
@ -55,22 +52,21 @@ namespace modules {
|
||||
|
||||
m_percentage = static_cast<int>(float(m_val) / float(m_max) * 100.0f + 0.5f);
|
||||
|
||||
if (!m_label)
|
||||
return true;
|
||||
|
||||
m_tokenized->m_text = m_label->m_text;
|
||||
m_tokenized->replace_token("%percentage%", to_string(m_percentage) + "%");
|
||||
if (m_label) {
|
||||
m_label->reset_tokens();
|
||||
m_label->replace_token("%percentage%", to_string(m_percentage) + "%");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool build(builder* builder, string tag) {
|
||||
bool build(builder* builder, string tag) const {
|
||||
if (tag == TAG_BAR)
|
||||
builder->node(m_progressbar->output(m_percentage));
|
||||
else if (tag == TAG_RAMP)
|
||||
builder->node(m_ramp->get_by_percentage(m_percentage));
|
||||
else if (tag == TAG_LABEL)
|
||||
builder->node(m_tokenized);
|
||||
builder->node(m_label);
|
||||
else
|
||||
return false;
|
||||
return true;
|
||||
@ -87,7 +83,6 @@ namespace modules {
|
||||
|
||||
ramp_t m_ramp;
|
||||
label_t m_label;
|
||||
label_t m_tokenized;
|
||||
progressbar_t m_progressbar;
|
||||
|
||||
string m_path_val;
|
||||
|
@ -57,16 +57,13 @@ namespace modules {
|
||||
if (m_formatter->has(TAG_LABEL_CHARGING, FORMAT_CHARGING)) {
|
||||
m_label_charging =
|
||||
get_optional_config_label(m_conf, name(), TAG_LABEL_CHARGING, "%percentage%");
|
||||
m_label_charging_tokenized = m_label_charging->clone();
|
||||
}
|
||||
if (m_formatter->has(TAG_LABEL_DISCHARGING, FORMAT_DISCHARGING)) {
|
||||
m_label_discharging =
|
||||
get_optional_config_label(m_conf, name(), TAG_LABEL_DISCHARGING, "%percentage%");
|
||||
m_label_discharging_tokenized = m_label_discharging->clone();
|
||||
}
|
||||
if (m_formatter->has(TAG_LABEL_FULL, FORMAT_FULL)) {
|
||||
m_label_full = get_optional_config_label(m_conf, name(), TAG_LABEL_FULL, "%percentage%");
|
||||
m_label_full_tokenized = m_label_full->clone();
|
||||
}
|
||||
|
||||
// }}}
|
||||
@ -124,17 +121,17 @@ namespace modules {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_label_charging_tokenized) {
|
||||
m_label_charging_tokenized->m_text = m_label_charging->m_text;
|
||||
m_label_charging_tokenized->replace_token("%percentage%", to_string(percentage) + "%");
|
||||
if (m_label_charging) {
|
||||
m_label_charging->reset_tokens();
|
||||
m_label_charging->replace_token("%percentage%", to_string(percentage) + "%");
|
||||
}
|
||||
if (m_label_discharging_tokenized) {
|
||||
m_label_discharging_tokenized->m_text = m_label_discharging->m_text;
|
||||
m_label_discharging_tokenized->replace_token("%percentage%", to_string(percentage) + "%");
|
||||
if (m_label_discharging) {
|
||||
m_label_discharging->reset_tokens();
|
||||
m_label_discharging->replace_token("%percentage%", to_string(percentage) + "%");
|
||||
}
|
||||
if (m_label_full_tokenized) {
|
||||
m_label_full_tokenized->m_text = m_label_full->m_text;
|
||||
m_label_full_tokenized->replace_token("%percentage%", to_string(percentage) + "%");
|
||||
if (m_label_full) {
|
||||
m_label_full->reset_tokens();
|
||||
m_label_full->replace_token("%percentage%", to_string(percentage) + "%");
|
||||
}
|
||||
|
||||
m_state = state;
|
||||
@ -143,7 +140,7 @@ namespace modules {
|
||||
return true;
|
||||
}
|
||||
|
||||
string get_format() {
|
||||
string get_format() const {
|
||||
if (m_state == STATE_FULL)
|
||||
return FORMAT_FULL;
|
||||
else if (m_state == STATE_CHARGING)
|
||||
@ -152,7 +149,7 @@ namespace modules {
|
||||
return FORMAT_DISCHARGING;
|
||||
}
|
||||
|
||||
bool build(builder* builder, string tag) {
|
||||
bool build(builder* builder, string tag) const {
|
||||
if (tag == TAG_ANIMATION_CHARGING)
|
||||
builder->node(m_animation_charging->get());
|
||||
else if (tag == TAG_BAR_CAPACITY) {
|
||||
@ -160,11 +157,11 @@ namespace modules {
|
||||
} else if (tag == TAG_RAMP_CAPACITY)
|
||||
builder->node(m_ramp_capacity->get_by_percentage(m_percentage));
|
||||
else if (tag == TAG_LABEL_CHARGING)
|
||||
builder->node(m_label_charging_tokenized);
|
||||
builder->node(m_label_charging);
|
||||
else if (tag == TAG_LABEL_DISCHARGING)
|
||||
builder->node(m_label_discharging_tokenized);
|
||||
builder->node(m_label_discharging);
|
||||
else if (tag == TAG_LABEL_FULL)
|
||||
builder->node(m_label_full_tokenized);
|
||||
builder->node(m_label_full);
|
||||
else
|
||||
return false;
|
||||
return true;
|
||||
@ -222,11 +219,8 @@ namespace modules {
|
||||
ramp_t m_ramp_capacity;
|
||||
progressbar_t m_bar_capacity;
|
||||
label_t m_label_charging;
|
||||
label_t m_label_charging_tokenized;
|
||||
label_t m_label_discharging;
|
||||
label_t m_label_discharging_tokenized;
|
||||
label_t m_label_full;
|
||||
label_t m_label_full_tokenized;
|
||||
|
||||
string m_battery;
|
||||
string m_adapter;
|
||||
|
@ -269,8 +269,9 @@ namespace modules {
|
||||
if (!monitor_focused)
|
||||
label->replace_defined_values(m_statelabels.find(bspwm_flag::WORKSPACE_DIMMED)->second);
|
||||
|
||||
label->reset_tokens();
|
||||
label->replace_token("%name%", value);
|
||||
label->replace_token("%icon%", icon->m_text);
|
||||
label->replace_token("%icon%", icon->get());
|
||||
label->replace_token("%index%", to_string(++workspace_n));
|
||||
|
||||
m_workspaces.emplace_back(make_unique<bspwm_workspace>(workspace_flag, std::move(label)));
|
||||
@ -286,14 +287,14 @@ namespace modules {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool build(builder* builder, string tag) {
|
||||
bool build(builder* builder, string tag) const {
|
||||
if (tag != TAG_LABEL_STATE)
|
||||
return false;
|
||||
|
||||
int workspace_n = 0;
|
||||
|
||||
for (auto&& ws : m_workspaces) {
|
||||
if (!ws.get()->label->m_text.empty())
|
||||
if (!ws.get()->label->get().empty())
|
||||
builder->cmd(mousebtn::LEFT, string(EVENT_CLICK) + to_string(++workspace_n));
|
||||
|
||||
builder->node(ws.get()->label);
|
||||
@ -302,7 +303,7 @@ namespace modules {
|
||||
for (auto&& mode : m_modes) builder->node(mode);
|
||||
}
|
||||
|
||||
if (!ws.get()->label->m_text.empty())
|
||||
if (!ws.get()->label->get().empty())
|
||||
builder->cmd_close(true);
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ namespace modules {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool build(builder* builder, string tag) {
|
||||
bool build(builder* builder, string tag) const {
|
||||
if (tag == TAG_COUNTER) {
|
||||
builder->node(to_string(m_counter));
|
||||
return true;
|
||||
|
@ -37,10 +37,8 @@ namespace modules {
|
||||
m_rampload = get_config_ramp(m_conf, name(), TAG_RAMP_LOAD);
|
||||
if (m_formatter->has(TAG_RAMP_LOAD_PER_CORE))
|
||||
m_rampload_core = get_config_ramp(m_conf, name(), TAG_RAMP_LOAD_PER_CORE);
|
||||
if (m_formatter->has(TAG_LABEL)) {
|
||||
if (m_formatter->has(TAG_LABEL))
|
||||
m_label = get_optional_config_label(m_conf, name(), TAG_LABEL, "%percentage%");
|
||||
m_tokenized = m_label->clone();
|
||||
}
|
||||
|
||||
// warmup
|
||||
read_values();
|
||||
@ -67,18 +65,17 @@ namespace modules {
|
||||
|
||||
m_total = m_total / static_cast<float>(cores_n);
|
||||
|
||||
if (m_tokenized) {
|
||||
m_tokenized->m_text = m_label->m_text;
|
||||
m_tokenized->replace_token(
|
||||
"%percentage%", to_string(static_cast<int>(m_total + 0.5f)) + "%");
|
||||
if (m_label) {
|
||||
m_label->reset_tokens();
|
||||
m_label->replace_token("%percentage%", to_string(static_cast<int>(m_total + 0.5f)) + "%");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool build(builder* builder, string tag) {
|
||||
bool build(builder* builder, string tag) const {
|
||||
if (tag == TAG_LABEL)
|
||||
builder->node(m_tokenized);
|
||||
builder->node(m_label);
|
||||
else if (tag == TAG_BAR_LOAD)
|
||||
builder->node(m_barload->output(m_total));
|
||||
else if (tag == TAG_RAMP_LOAD)
|
||||
@ -127,7 +124,7 @@ namespace modules {
|
||||
return !m_cputimes.empty();
|
||||
}
|
||||
|
||||
float get_load(size_t core) {
|
||||
float get_load(size_t core) const {
|
||||
if (m_cputimes.empty() || m_cputimes_prev.empty())
|
||||
return 0;
|
||||
else if (core >= m_cputimes.size() || core >= m_cputimes_prev.size())
|
||||
@ -159,7 +156,6 @@ namespace modules {
|
||||
ramp_t m_rampload;
|
||||
ramp_t m_rampload_core;
|
||||
label_t m_label;
|
||||
label_t m_tokenized;
|
||||
|
||||
vector<cpu_time_t> m_cputimes;
|
||||
vector<cpu_time_t> m_cputimes_prev;
|
||||
|
@ -46,7 +46,7 @@ namespace modules {
|
||||
return m_builder->flush();
|
||||
}
|
||||
|
||||
bool build(builder* builder, string tag) {
|
||||
bool build(builder* builder, string tag) const {
|
||||
if (tag == TAG_DATE)
|
||||
builder->node(m_buffer);
|
||||
return tag == TAG_DATE;
|
||||
|
@ -167,9 +167,10 @@ namespace modules {
|
||||
auto icon = m_icons->get(workspace->name, DEFAULT_WS_ICON);
|
||||
auto label = m_statelabels.find(flag)->second->clone();
|
||||
|
||||
label->reset_tokens();
|
||||
label->replace_token("%output%", workspace->output);
|
||||
label->replace_token("%name%", wsname);
|
||||
label->replace_token("%icon%", icon->m_text);
|
||||
label->replace_token("%icon%", icon->get());
|
||||
label->replace_token("%index%", to_string(workspace->num));
|
||||
m_workspaces.emplace_back(
|
||||
make_unique<i3_workspace>(workspace->num, flag, std::move(label)));
|
||||
@ -184,7 +185,7 @@ namespace modules {
|
||||
// }}}
|
||||
}
|
||||
|
||||
bool build(builder* builder, string tag) {
|
||||
bool build(builder* builder, string tag) const {
|
||||
// Output workspace info {{{
|
||||
|
||||
if (tag != TAG_LABEL_STATE)
|
||||
|
@ -25,11 +25,8 @@ namespace modules {
|
||||
m_bars[memtype::USED] = get_config_bar(m_bar, m_conf, name(), TAG_BAR_USED);
|
||||
if (m_formatter->has(TAG_BAR_FREE))
|
||||
m_bars[memtype::FREE] = get_config_bar(m_bar, m_conf, name(), TAG_BAR_FREE);
|
||||
|
||||
if (m_formatter->has(TAG_LABEL)) {
|
||||
if (m_formatter->has(TAG_LABEL))
|
||||
m_label = get_optional_config_label(m_conf, name(), TAG_LABEL, "%percentage_used%");
|
||||
m_tokenized = m_label->clone();
|
||||
}
|
||||
}
|
||||
|
||||
bool update() {
|
||||
@ -72,38 +69,36 @@ namespace modules {
|
||||
m_perc[memtype::USED] = 100 - m_perc[memtype::FREE];
|
||||
|
||||
// replace tokens
|
||||
if (m_tokenized) {
|
||||
m_tokenized->m_text = m_label->m_text;
|
||||
if (m_label) {
|
||||
m_label->reset_tokens();
|
||||
|
||||
auto replace_unit = [](label_t& label, string token, float value, string unit) {
|
||||
if (label->m_text.find(token) == string::npos)
|
||||
return;
|
||||
auto formatted = string_util::from_stream(
|
||||
stringstream() << std::setprecision(2) << std::fixed << value << " " << unit);
|
||||
label->replace_token(token, formatted);
|
||||
};
|
||||
|
||||
replace_unit(m_tokenized, "%gb_used%", (kb_total - kb_avail) / 1024 / 1024, "GB");
|
||||
replace_unit(m_tokenized, "%gb_free%", kb_avail / 1024 / 1024, "GB");
|
||||
replace_unit(m_tokenized, "%gb_total%", kb_total / 1024 / 1024, "GB");
|
||||
replace_unit(m_tokenized, "%mb_used%", (kb_total - kb_avail) / 1024, "MB");
|
||||
replace_unit(m_tokenized, "%mb_free%", kb_avail / 1024, "MB");
|
||||
replace_unit(m_tokenized, "%mb_total%", kb_total / 1024, "MB");
|
||||
replace_unit(m_label, "%gb_used%", (kb_total - kb_avail) / 1024 / 1024, "GB");
|
||||
replace_unit(m_label, "%gb_free%", kb_avail / 1024 / 1024, "GB");
|
||||
replace_unit(m_label, "%gb_total%", kb_total / 1024 / 1024, "GB");
|
||||
replace_unit(m_label, "%mb_used%", (kb_total - kb_avail) / 1024, "MB");
|
||||
replace_unit(m_label, "%mb_free%", kb_avail / 1024, "MB");
|
||||
replace_unit(m_label, "%mb_total%", kb_total / 1024, "MB");
|
||||
|
||||
m_tokenized->replace_token("%percentage_used%", to_string(m_perc[memtype::USED]) + "%");
|
||||
m_tokenized->replace_token("%percentage_free%", to_string(m_perc[memtype::FREE]) + "%");
|
||||
m_label->replace_token("%percentage_used%", to_string(m_perc[memtype::USED]) + "%");
|
||||
m_label->replace_token("%percentage_free%", to_string(m_perc[memtype::FREE]) + "%");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool build(builder* builder, string tag) {
|
||||
bool build(builder* builder, string tag) const {
|
||||
if (tag == TAG_BAR_USED) {
|
||||
builder->node(m_bars[memtype::USED]->output(m_perc[memtype::USED]));
|
||||
builder->node(m_bars.at(memtype::USED)->output(m_perc.at(memtype::USED)));
|
||||
} else if (tag == TAG_BAR_FREE)
|
||||
builder->node(m_bars[memtype::FREE]->output(m_perc[memtype::FREE]));
|
||||
builder->node(m_bars.at(memtype::FREE)->output(m_perc.at(memtype::FREE)));
|
||||
else if (tag == TAG_LABEL)
|
||||
builder->node(m_tokenized);
|
||||
builder->node(m_label);
|
||||
else
|
||||
return false;
|
||||
return true;
|
||||
@ -115,7 +110,7 @@ namespace modules {
|
||||
static constexpr auto TAG_BAR_FREE = "<bar-free>";
|
||||
|
||||
label_t m_label;
|
||||
label_t m_tokenized;
|
||||
progressbar_t m_bar_free;
|
||||
map<memtype, progressbar_t> m_bars;
|
||||
map<memtype, int> m_perc;
|
||||
};
|
||||
|
@ -58,7 +58,7 @@ namespace modules {
|
||||
}
|
||||
}
|
||||
|
||||
bool build(builder* builder, string tag) {
|
||||
bool build(builder* builder, string tag) const {
|
||||
if (tag == TAG_LABEL_TOGGLE && m_level == -1) {
|
||||
builder->cmd(mousebtn::LEFT, string(EVENT_MENU_OPEN) + "0");
|
||||
builder->node(m_labelopen);
|
||||
|
@ -287,7 +287,7 @@ namespace modules {
|
||||
return "";
|
||||
}
|
||||
|
||||
auto format_name = CAST_MODULE(Impl)->get_format();
|
||||
auto format_name = CONST_CAST_MODULE(Impl).get_format();
|
||||
auto format = m_formatter->get(format_name);
|
||||
|
||||
int i = 0;
|
||||
@ -299,7 +299,7 @@ namespace modules {
|
||||
if (tag[0] == '<' && tag[tag.length() - 1] == '>') {
|
||||
if (i > 0)
|
||||
m_builder->space(format->spacing);
|
||||
if (!(tag_built = CAST_MODULE(Impl)->build(m_builder.get(), tag)) && i > 0)
|
||||
if (!(tag_built = CONST_CAST_MODULE(Impl).build(m_builder.get(), tag)) && i > 0)
|
||||
m_builder->remove_trailing_space(format->spacing);
|
||||
if (tag_built)
|
||||
i++;
|
||||
@ -361,7 +361,7 @@ namespace modules {
|
||||
CAST_MODULE(Impl)->broadcast();
|
||||
}
|
||||
|
||||
bool build(builder*, string) {
|
||||
bool build(builder*, string) const {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@ -427,18 +427,15 @@ namespace modules {
|
||||
CAST_MODULE(Impl)->broadcast();
|
||||
|
||||
while (CONST_CAST_MODULE(Impl).enabled()) {
|
||||
CAST_MODULE(Impl)->idle();
|
||||
{
|
||||
std::lock_guard<threading_util::spin_lock> lck(this->update_lock);
|
||||
|
||||
if (!CAST_MODULE(Impl)->has_event())
|
||||
continue;
|
||||
if (!CAST_MODULE(Impl)->update())
|
||||
continue;
|
||||
|
||||
CAST_MODULE(Impl)->idle();
|
||||
else if (!CAST_MODULE(Impl)->update())
|
||||
CAST_MODULE(Impl)->idle();
|
||||
else
|
||||
CAST_MODULE(Impl)->broadcast();
|
||||
}
|
||||
}
|
||||
} catch (const std::exception& err) {
|
||||
this->m_log.err("%s: %s", this->name(), err.what());
|
||||
this->m_log.warn("Stopping '%s'...", this->name());
|
||||
|
@ -57,12 +57,10 @@ namespace modules {
|
||||
if (m_formatter->has(TAG_LABEL_SONG)) {
|
||||
m_label_song =
|
||||
get_optional_config_label(m_conf, name(), TAG_LABEL_SONG, "%artist% - %title%");
|
||||
m_label_song_tokenized = m_label_song->clone();
|
||||
}
|
||||
if (m_formatter->has(TAG_LABEL_TIME)) {
|
||||
m_label_time =
|
||||
get_optional_config_label(m_conf, name(), TAG_LABEL_TIME, "%elapsed% / %total%");
|
||||
m_label_time_tokenized = m_label_time->clone();
|
||||
}
|
||||
if (m_formatter->has(TAG_ICON_RANDOM) || m_formatter->has(TAG_ICON_REPEAT) ||
|
||||
m_formatter->has(TAG_ICON_REPEAT_ONE)) {
|
||||
@ -83,64 +81,58 @@ namespace modules {
|
||||
m_mpd = make_unique<mpdconnection>(m_log, m_host, m_port, m_pass);
|
||||
m_mpd->connect();
|
||||
m_status = m_mpd->get_status();
|
||||
} catch (const mpd_exception& e) {
|
||||
m_log.err("%s: %s", name(), e.what());
|
||||
} catch (const mpd_exception& err) {
|
||||
m_log.err("%s: %s", name(), err.what());
|
||||
m_mpd.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void teardown() {
|
||||
if (m_mpd && m_mpd->connected()) {
|
||||
try {
|
||||
m_mpd->disconnect();
|
||||
} catch (const mpd_exception& e) {
|
||||
m_log.trace("%s: %s", name(), e.what());
|
||||
}
|
||||
} else {
|
||||
wakeup();
|
||||
}
|
||||
inline bool connected() const {
|
||||
return m_mpd && m_mpd->connected();
|
||||
}
|
||||
|
||||
void idle() {
|
||||
if (m_mpd && m_mpd->connected())
|
||||
if (connected())
|
||||
sleep(80ms);
|
||||
else {
|
||||
sleep(10s);
|
||||
sleep(2s);
|
||||
}
|
||||
}
|
||||
|
||||
bool has_event() {
|
||||
if (!m_mpd->connected()) {
|
||||
m_connection_state_broadcasted = false;
|
||||
if (!m_mpd)
|
||||
m_mpd = make_unique<mpdconnection>(m_log, m_host, m_port, m_pass);
|
||||
|
||||
try {
|
||||
if (!connected())
|
||||
m_mpd->connect();
|
||||
} catch (const mpd_exception& e) {
|
||||
m_log.trace("%s: %s", name(), e.what());
|
||||
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;
|
||||
}
|
||||
|
||||
if (!m_mpd->connected()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!connected())
|
||||
return !m_connection_state_broadcasted;
|
||||
|
||||
if (!m_status)
|
||||
m_status = m_mpd->get_status_safe();
|
||||
|
||||
try {
|
||||
m_mpd->idle();
|
||||
|
||||
int idle_flags;
|
||||
|
||||
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)) {
|
||||
m_status->update_timer();
|
||||
}
|
||||
} catch (const mpd_exception& e) {
|
||||
m_log.err(e.what());
|
||||
m_mpd->disconnect();
|
||||
return true;
|
||||
} catch (const mpd_exception& err) {
|
||||
m_log.err(err.what());
|
||||
m_mpd.reset();
|
||||
return !m_connection_state_broadcasted;
|
||||
}
|
||||
|
||||
if ((m_label_time || m_bar_progress) && m_status->match_state(mpdstate::PLAYING)) {
|
||||
@ -156,12 +148,14 @@ namespace modules {
|
||||
}
|
||||
|
||||
bool update() {
|
||||
if (!m_mpd->connected())
|
||||
return true;
|
||||
if (m_connection_state_broadcasted) {
|
||||
if (!connected())
|
||||
return false;
|
||||
if (!m_status && !(m_status = m_mpd->get_status_safe()))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
} else {
|
||||
m_connection_state_broadcasted = true;
|
||||
}
|
||||
|
||||
string artist;
|
||||
string album;
|
||||
@ -170,52 +164,55 @@ namespace modules {
|
||||
string total_str;
|
||||
|
||||
try {
|
||||
if (m_status) {
|
||||
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();
|
||||
title = song->get_title();
|
||||
}
|
||||
} catch (const mpd_exception& e) {
|
||||
m_log.err(e.what());
|
||||
m_mpd->disconnect();
|
||||
return true;
|
||||
}
|
||||
} catch (const mpd_exception& err) {
|
||||
m_log.err(err.what());
|
||||
m_mpd.reset();
|
||||
}
|
||||
|
||||
if (m_label_song_tokenized) {
|
||||
m_label_song_tokenized->m_text = m_label_song->m_text;
|
||||
m_label_song_tokenized->replace_token(
|
||||
if (m_label_song) {
|
||||
m_label_song->reset_tokens();
|
||||
m_label_song->replace_token(
|
||||
"%artist%", !artist.empty() ? artist : "untitled artist");
|
||||
m_label_song_tokenized->replace_token("%album%", !album.empty() ? album : "untitled album");
|
||||
m_label_song_tokenized->replace_token("%title%", !title.empty() ? title : "untitled track");
|
||||
m_label_song->replace_token("%album%", !album.empty() ? album : "untitled album");
|
||||
m_label_song->replace_token("%title%", !title.empty() ? title : "untitled track");
|
||||
}
|
||||
|
||||
if (m_label_time_tokenized) {
|
||||
m_label_time_tokenized->m_text = m_label_time->m_text;
|
||||
m_label_time_tokenized->replace_token("%elapsed%", elapsed_str);
|
||||
m_label_time_tokenized->replace_token("%total%", total_str);
|
||||
if (m_label_time) {
|
||||
m_label_time->reset_tokens();
|
||||
m_label_time->replace_token("%elapsed%", elapsed_str);
|
||||
m_label_time->replace_token("%total%", total_str);
|
||||
}
|
||||
|
||||
if (m_icons->has("random"))
|
||||
m_icons->get("random")->m_foreground =
|
||||
m_status->random() ? m_toggle_on_color : m_toggle_off_color;
|
||||
m_status && m_status->random() ? m_toggle_on_color : m_toggle_off_color;
|
||||
if (m_icons->has("repeat"))
|
||||
m_icons->get("repeat")->m_foreground =
|
||||
m_status->repeat() ? m_toggle_on_color : m_toggle_off_color;
|
||||
m_status && m_status->repeat() ? m_toggle_on_color : m_toggle_off_color;
|
||||
if (m_icons->has("repeat_one"))
|
||||
m_icons->get("repeat_one")->m_foreground =
|
||||
m_status->single() ? m_toggle_on_color : m_toggle_off_color;
|
||||
m_status && m_status->single() ? m_toggle_on_color : m_toggle_off_color;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
string get_format() {
|
||||
return m_mpd->connected() ? FORMAT_ONLINE : FORMAT_OFFLINE;
|
||||
string get_format() const {
|
||||
return connected() ? FORMAT_ONLINE : FORMAT_OFFLINE;
|
||||
}
|
||||
|
||||
bool build(builder* builder, string tag) {
|
||||
bool build(builder* builder, string tag) const {
|
||||
bool is_playing = false;
|
||||
bool is_paused = false;
|
||||
bool is_stopped = true;
|
||||
@ -239,9 +236,9 @@ namespace modules {
|
||||
};
|
||||
|
||||
if (tag == TAG_LABEL_SONG && !is_stopped)
|
||||
builder->node(m_label_song_tokenized);
|
||||
builder->node(m_label_song);
|
||||
else if (tag == TAG_LABEL_TIME && !is_stopped)
|
||||
builder->node(m_label_time_tokenized);
|
||||
builder->node(m_label_time);
|
||||
else if (tag == TAG_BAR_PROGRESS && !is_stopped)
|
||||
builder->node(m_bar_progress->output(elapsed_percentage));
|
||||
else if (tag == TAG_LABEL_OFFLINE)
|
||||
@ -312,8 +309,9 @@ namespace modules {
|
||||
mpd->seek(status->get_songid(), status->get_seek_position(percentage));
|
||||
} else
|
||||
return false;
|
||||
} catch (const mpd_exception& e) {
|
||||
m_log.err("%s: %s", name(), e.what());
|
||||
} catch (const mpd_exception& err) {
|
||||
m_log.err("%s: %s", name(), err.what());
|
||||
m_mpd.reset();
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -359,9 +357,7 @@ namespace modules {
|
||||
progressbar_t m_bar_progress;
|
||||
iconset_t m_icons;
|
||||
label_t m_label_song;
|
||||
label_t m_label_song_tokenized;
|
||||
label_t m_label_time;
|
||||
label_t m_label_time_tokenized;
|
||||
label_t m_label_offline;
|
||||
|
||||
unique_ptr<mpdconnection> m_mpd;
|
||||
@ -383,7 +379,7 @@ namespace modules {
|
||||
|
||||
// This flag is used to let thru a broadcast once every time
|
||||
// the connection state changes
|
||||
stateflag m_connection_state_broadcasted{true};
|
||||
stateflag m_connection_state_broadcasted{false};
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -38,13 +38,13 @@ namespace modules {
|
||||
if (m_formatter->has(TAG_LABEL_CONNECTED, FORMAT_CONNECTED)) {
|
||||
m_label[connection_state::CONNECTED] =
|
||||
get_optional_config_label(m_conf, name(), TAG_LABEL_CONNECTED, "%ifname% %local_ip%");
|
||||
m_tokenized[connection_state::CONNECTED] = m_label[connection_state::CONNECTED]->clone();
|
||||
}
|
||||
|
||||
// Create elements for format-disconnected
|
||||
if (m_formatter->has(TAG_LABEL_DISCONNECTED, FORMAT_DISCONNECTED)) {
|
||||
m_label[connection_state::DISCONNECTED] =
|
||||
get_optional_config_label(m_conf, name(), TAG_LABEL_DISCONNECTED, "");
|
||||
m_label[connection_state::DISCONNECTED]->reset_tokens();
|
||||
m_label[connection_state::DISCONNECTED]->replace_token("%ifname%", m_interface);
|
||||
}
|
||||
|
||||
@ -56,8 +56,6 @@ namespace modules {
|
||||
if (m_formatter->has(TAG_LABEL_PACKETLOSS, FORMAT_PACKETLOSS)) {
|
||||
m_label[connection_state::PACKETLOSS] =
|
||||
get_optional_config_label(m_conf, name(), TAG_LABEL_PACKETLOSS, "");
|
||||
m_tokenized[connection_state::PACKETLOSS] =
|
||||
m_label[connection_state::PACKETLOSS]->clone();
|
||||
}
|
||||
if (m_formatter->has(TAG_ANIMATION_PACKETLOSS, FORMAT_PACKETLOSS))
|
||||
m_animation_packetloss = get_config_animation(m_conf, name(), TAG_ANIMATION_PACKETLOSS);
|
||||
@ -112,6 +110,7 @@ namespace modules {
|
||||
|
||||
// Update label contents
|
||||
const auto replace_tokens = [&](label_t& label) {
|
||||
label->reset_tokens();
|
||||
label->replace_token("%ifname%", m_interface);
|
||||
label->replace_token("%local_ip%", network->ip());
|
||||
label->replace_token("%upspeed%", upspeed);
|
||||
@ -126,22 +125,15 @@ namespace modules {
|
||||
}
|
||||
};
|
||||
|
||||
if (m_label[connection_state::CONNECTED]) {
|
||||
m_tokenized[connection_state::CONNECTED]->m_text =
|
||||
m_label[connection_state::CONNECTED]->m_text;
|
||||
replace_tokens(m_tokenized[connection_state::CONNECTED]);
|
||||
}
|
||||
|
||||
if (m_label[connection_state::PACKETLOSS]) {
|
||||
m_tokenized[connection_state::PACKETLOSS]->m_text =
|
||||
m_label[connection_state::PACKETLOSS]->m_text;
|
||||
replace_tokens(m_tokenized[connection_state::PACKETLOSS]);
|
||||
}
|
||||
if (m_label[connection_state::CONNECTED])
|
||||
replace_tokens(m_label[connection_state::CONNECTED]);
|
||||
if (m_label[connection_state::PACKETLOSS])
|
||||
replace_tokens(m_label[connection_state::PACKETLOSS]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
string get_format() {
|
||||
string get_format() const {
|
||||
if (!m_connected)
|
||||
return FORMAT_DISCONNECTED;
|
||||
else if (m_packetloss && m_ping_nth_update > 0)
|
||||
@ -150,13 +142,13 @@ namespace modules {
|
||||
return FORMAT_CONNECTED;
|
||||
}
|
||||
|
||||
bool build(builder* builder, string tag) {
|
||||
bool build(builder* builder, string tag) const {
|
||||
if (tag == TAG_LABEL_CONNECTED)
|
||||
builder->node(m_tokenized[connection_state::CONNECTED]);
|
||||
builder->node(m_label.at(connection_state::CONNECTED));
|
||||
else if (tag == TAG_LABEL_DISCONNECTED)
|
||||
builder->node(m_label[connection_state::DISCONNECTED]);
|
||||
builder->node(m_label.at(connection_state::DISCONNECTED));
|
||||
else if (tag == TAG_LABEL_PACKETLOSS)
|
||||
builder->node(m_tokenized[connection_state::PACKETLOSS]);
|
||||
builder->node(m_label.at(connection_state::PACKETLOSS));
|
||||
else if (tag == TAG_ANIMATION_PACKETLOSS)
|
||||
builder->node(m_animation_packetloss->get());
|
||||
else if (tag == TAG_RAMP_SIGNAL)
|
||||
@ -200,7 +192,6 @@ namespace modules {
|
||||
ramp_t m_ramp_quality;
|
||||
animation_t m_animation_packetloss;
|
||||
map<connection_state, label_t> m_label;
|
||||
map<connection_state, label_t> m_tokenized;
|
||||
|
||||
stateflag m_connected{false};
|
||||
stateflag m_packetloss{false};
|
||||
|
@ -129,7 +129,7 @@ namespace modules {
|
||||
return m_builder->flush();
|
||||
}
|
||||
|
||||
bool build(builder* builder, string tag) {
|
||||
bool build(builder* builder, string tag) const {
|
||||
if (tag != TAG_OUTPUT)
|
||||
return false;
|
||||
builder->node(string_util::replace_all(m_output, "\n", ""));
|
||||
|
@ -19,7 +19,7 @@ namespace modules {
|
||||
string_util::replace_all(m_formatter->get("content")->value, " ", BUILDER_SPACE_TOKEN);
|
||||
}
|
||||
|
||||
string get_format() {
|
||||
string get_format() const {
|
||||
return "content";
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
throw application_error("No built-in support for '" + string{MODULE_TYPE} + "'"); \
|
||||
} \
|
||||
void start() {} \
|
||||
bool build(builder*, string) { \
|
||||
bool build(builder*, string) const { \
|
||||
return true; \
|
||||
} \
|
||||
}
|
||||
|
@ -98,11 +98,9 @@ namespace modules {
|
||||
if (m_formatter->has(TAG_LABEL_VOLUME, FORMAT_VOLUME)) {
|
||||
m_label_volume =
|
||||
get_optional_config_label(m_conf, name(), TAG_LABEL_VOLUME, "%percentage%");
|
||||
m_label_volume_tokenized = m_label_volume->clone();
|
||||
}
|
||||
if (m_formatter->has(TAG_LABEL_MUTED, FORMAT_MUTED)) {
|
||||
m_label_muted = get_optional_config_label(m_conf, name(), TAG_LABEL_MUTED, "%percentage%");
|
||||
m_label_muted_tokenized = m_label_muted->clone();
|
||||
}
|
||||
|
||||
// }}}
|
||||
@ -172,13 +170,13 @@ namespace modules {
|
||||
// }}}
|
||||
// Replace label tokens {{{
|
||||
|
||||
if (m_label_volume_tokenized) {
|
||||
m_label_volume_tokenized->m_text = m_label_volume->m_text;
|
||||
m_label_volume_tokenized->replace_token("%percentage%", to_string(m_volume) + "%");
|
||||
if (m_label_volume) {
|
||||
m_label_volume->reset_tokens();
|
||||
m_label_volume->replace_token("%percentage%", to_string(m_volume) + "%");
|
||||
}
|
||||
if (m_label_muted_tokenized) {
|
||||
m_label_muted_tokenized->m_text = m_label_muted->m_text;
|
||||
m_label_muted_tokenized->replace_token("%percentage%", to_string(m_volume) + "%");
|
||||
if (m_label_muted) {
|
||||
m_label_muted->reset_tokens();
|
||||
m_label_muted->replace_token("%percentage%", to_string(m_volume) + "%");
|
||||
}
|
||||
|
||||
// }}}
|
||||
@ -186,7 +184,7 @@ namespace modules {
|
||||
return true;
|
||||
}
|
||||
|
||||
string get_format() {
|
||||
string get_format() const {
|
||||
return m_muted ? FORMAT_MUTED : FORMAT_VOLUME;
|
||||
}
|
||||
|
||||
@ -202,7 +200,7 @@ namespace modules {
|
||||
return m_builder->flush();
|
||||
}
|
||||
|
||||
bool build(builder* builder, string tag) {
|
||||
bool build(builder* builder, string tag) const {
|
||||
if (tag == TAG_BAR_VOLUME)
|
||||
builder->node(m_bar_volume->output(m_volume));
|
||||
else if (tag == TAG_RAMP_VOLUME && (!m_headphones || !*m_ramp_headphones))
|
||||
@ -210,9 +208,9 @@ namespace modules {
|
||||
else if (tag == TAG_RAMP_VOLUME && m_headphones && *m_ramp_headphones)
|
||||
builder->node(m_ramp_headphones->get_by_percentage(m_volume));
|
||||
else if (tag == TAG_LABEL_VOLUME)
|
||||
builder->node(m_label_volume_tokenized);
|
||||
builder->node(m_label_volume);
|
||||
else if (tag == TAG_LABEL_MUTED)
|
||||
builder->node(m_label_muted_tokenized);
|
||||
builder->node(m_label_muted);
|
||||
else
|
||||
return false;
|
||||
return true;
|
||||
@ -283,9 +281,7 @@ namespace modules {
|
||||
ramp_t m_ramp_volume;
|
||||
ramp_t m_ramp_headphones;
|
||||
label_t m_label_volume;
|
||||
label_t m_label_volume_tokenized;
|
||||
label_t m_label_muted;
|
||||
label_t m_label_muted_tokenized;
|
||||
|
||||
map<mixer, mixer_t> m_mixers;
|
||||
map<control, control_t> m_controls;
|
||||
|
Loading…
Reference in New Issue
Block a user