1
0
Fork 0
mirror of https://github.com/polybar/polybar.git synced 2024-11-18 13:55:11 -05:00
polybar/include/modules/meta/base.inl

212 lines
5.6 KiB
Text
Raw Normal View History

2016-11-20 17:04:31 -05:00
#include "components/builder.hpp"
2016-12-09 03:40:46 -05:00
#include "components/config.hpp"
#include "components/logger.hpp"
#include "events/signal.hpp"
#include "events/signal_emitter.hpp"
2019-08-06 13:35:07 -04:00
#include "modules/meta/base.hpp"
2016-11-20 17:04:31 -05:00
POLYBAR_NS
namespace modules {
// module<Impl> public {{{
template <typename Impl>
2016-12-09 03:40:46 -05:00
module<Impl>::module(const bar_settings bar, string name)
: m_sig(signal_emitter::make())
, m_bar(bar)
, m_log(logger::make())
, m_conf(config::make())
, m_name("module/" + name)
, m_name_raw(name)
, m_builder(make_unique<builder>(bar))
, m_formatter(make_unique<module_formatter>(m_conf, m_name))
, m_handle_events(m_conf.get(m_name, "handle-events", true)) {}
2016-11-20 17:04:31 -05:00
template <typename Impl>
module<Impl>::~module() noexcept {
m_log.trace("%s: Deconstructing", name());
for (auto&& thread_ : m_threads) {
if (thread_.joinable()) {
thread_.join();
}
}
if (m_mainthread.joinable()) {
m_mainthread.join();
}
2016-11-20 17:04:31 -05:00
}
template <typename Impl>
string module<Impl>::name() const {
return m_name;
}
template <typename Impl>
string module<Impl>::name_raw() const {
return m_name_raw;
}
template <typename Impl>
string module<Impl>::type() const {
return string(module<Impl>::TYPE);
}
2016-11-20 17:04:31 -05:00
template <typename Impl>
bool module<Impl>::running() const {
return static_cast<bool>(m_enabled);
2016-11-20 17:04:31 -05:00
}
template <typename Impl>
void module<Impl>::stop() {
2016-12-22 23:18:58 -05:00
if (!static_cast<bool>(m_enabled)) {
2016-11-20 17:04:31 -05:00
return;
}
m_log.info("%s: Stopping", name());
m_enabled = false;
2016-11-20 17:04:31 -05:00
std::lock(m_buildlock, m_updatelock);
std::lock_guard<std::mutex> guard_a(m_buildlock, std::adopt_lock);
std::lock_guard<std::mutex> guard_b(m_updatelock, std::adopt_lock);
2016-11-20 17:04:31 -05:00
{
CAST_MOD(Impl)->wakeup();
2016-11-20 17:04:31 -05:00
CAST_MOD(Impl)->teardown();
2017-01-12 10:34:14 -05:00
m_sig.emit(signals::eventqueue::check_state{});
2016-11-20 17:04:31 -05:00
}
}
template <typename Impl>
void module<Impl>::halt(string error_message) {
m_log.err("%s: %s", name(), error_message);
m_log.notice("Stopping '%s'...", name());
2016-11-20 17:04:31 -05:00
stop();
}
template <typename Impl>
void module<Impl>::teardown() {}
template <typename Impl>
string module<Impl>::contents() {
2016-12-22 23:19:45 -05:00
if (m_changed) {
m_log.info("%s: Rebuilding cache", name());
2016-12-22 23:19:45 -05:00
m_cache = CAST_MOD(Impl)->get_output();
// Make sure builder is really empty
m_builder->flush();
if (!m_cache.empty()) {
// Add a reset tag after the module
m_builder->control(controltag::R);
m_cache += m_builder->flush();
}
2016-12-22 23:19:45 -05:00
m_changed = false;
}
2016-11-20 17:04:31 -05:00
return m_cache;
}
template <typename Impl>
2020-05-31 15:11:36 -04:00
bool module<Impl>::input(const string&, const string&) {
// By default a module doesn't support inputs
return false;
}
2016-11-20 17:04:31 -05:00
// }}}
// module<Impl> protected {{{
template <typename Impl>
void module<Impl>::broadcast() {
2016-12-22 23:19:45 -05:00
m_changed = true;
2017-01-12 10:34:14 -05:00
m_sig.emit(signals::eventqueue::notify_change{});
2016-11-20 17:04:31 -05:00
}
template <typename Impl>
void module<Impl>::idle() {
if (running()) {
CAST_MOD(Impl)->sleep(25ms);
}
2016-11-20 17:04:31 -05:00
}
template <typename Impl>
void module<Impl>::sleep(chrono::duration<double> sleep_duration) {
if (running()) {
std::unique_lock<std::mutex> lck(m_sleeplock);
m_sleephandler.wait_for(lck, sleep_duration);
}
2016-11-20 17:04:31 -05:00
}
template <typename Impl>
template <class Clock, class Duration>
void module<Impl>::sleep_until(chrono::time_point<Clock, Duration> point) {
if (running()) {
std::unique_lock<std::mutex> lck(m_sleeplock);
m_sleephandler.wait_until(lck, point);
}
}
2016-11-20 17:04:31 -05:00
template <typename Impl>
void module<Impl>::wakeup() {
m_log.trace("%s: Release sleep lock", name());
m_sleephandler.notify_all();
}
template <typename Impl>
string module<Impl>::get_format() const {
return DEFAULT_FORMAT;
}
template <typename Impl>
string module<Impl>::get_output() {
2016-12-16 04:23:54 -05:00
std::lock_guard<std::mutex> guard(m_buildlock);
2016-11-20 17:04:31 -05:00
auto format_name = CONST_MOD(Impl).get_format();
auto format = m_formatter->get(format_name);
bool no_tag_built{true};
bool fake_no_tag_built{false};
bool tag_built{false};
2017-01-12 19:14:50 -05:00
auto mingap = std::max(1_z, format->spacing);
size_t start, end;
string value{format->value};
while ((start = value.find('<')) != string::npos && (end = value.find('>', start)) != string::npos) {
if (start > 0) {
if (no_tag_built) {
// If no module tag has been built we do not want to add
// whitespace defined between the format tags, but we do still
// want to output other non-tag content
auto trimmed = string_util::ltrim(value.substr(0, start), ' ');
if (!trimmed.empty()) {
fake_no_tag_built = false;
m_builder->node(move(trimmed));
}
} else {
m_builder->node(value.substr(0, start));
}
value.erase(0, start);
end -= start;
start = 0;
}
string tag{value.substr(start, end + 1)};
if (tag.empty()) {
continue;
} else if (tag[0] == '<' && tag[tag.size() - 1] == '>') {
if (!no_tag_built)
2016-11-20 17:04:31 -05:00
m_builder->space(format->spacing);
else if (fake_no_tag_built)
no_tag_built = false;
if (!(tag_built = CONST_MOD(Impl).build(m_builder.get(), tag)) && !no_tag_built)
m_builder->remove_trailing_space(mingap);
if (tag_built)
no_tag_built = false;
2016-11-20 17:04:31 -05:00
}
value.erase(0, tag.size());
}
if (!value.empty()) {
m_builder->append(value);
2016-11-20 17:04:31 -05:00
}
2016-12-26 22:03:46 -05:00
return format->decorate(&*m_builder, m_builder->flush());
2016-11-20 17:04:31 -05:00
}
// }}}
2019-08-06 13:35:07 -04:00
} // namespace modules
2016-11-20 17:04:31 -05:00
POLYBAR_NS_END