From bcf9249dc7f0f0e7f8284596e04a635749b32c59 Mon Sep 17 00:00:00 2001 From: Michael Carlberg Date: Tue, 25 Oct 2016 01:51:55 +0200 Subject: [PATCH] refactor: Use plain std::function callbacks Replace fastdelegate with plain std::function's because of incomplete clang support --- include/components/bar.hpp | 79 ++++++++++++++------------- include/components/controller.hpp | 8 +-- include/components/logger.hpp | 6 ++- include/components/parser.hpp | 90 ++++++++++++++++--------------- include/components/signals.hpp | 33 ++++++------ include/components/x11/tray.hpp | 14 ++--- include/modules/meta.hpp | 21 ++++---- 7 files changed, 133 insertions(+), 118 deletions(-) diff --git a/include/components/bar.hpp b/include/components/bar.hpp index eb944ef6..11644035 100644 --- a/include/components/bar.hpp +++ b/include/components/bar.hpp @@ -46,19 +46,22 @@ class bar : public xpp::event::sink lck(m_lock); - g_signals::parser::alignment_change.disconnect(this, &bar::on_alignment_change); - g_signals::parser::attribute_set.disconnect(this, &bar::on_attribute_set); - g_signals::parser::attribute_unset.disconnect(this, &bar::on_attribute_unset); - g_signals::parser::attribute_toggle.disconnect(this, &bar::on_attribute_toggle); - g_signals::parser::action_block_open.disconnect(this, &bar::on_action_block_open); - g_signals::parser::action_block_close.disconnect(this, &bar::on_action_block_close); - g_signals::parser::color_change.disconnect(this, &bar::on_color_change); - g_signals::parser::font_change.disconnect(this, &bar::on_font_change); - g_signals::parser::pixel_offset.disconnect(this, &bar::on_pixel_offset); - g_signals::parser::ascii_text_write.disconnect(this, &bar::draw_character); - g_signals::parser::unicode_text_write.disconnect(this, &bar::draw_character); - if (m_tray.align != alignment::NONE) - g_signals::tray::report_slotcount.disconnect(this, &bar::on_tray_report); + + // Disconnect signal handlers {{{ + g_signals::parser::alignment_change = nullptr; + g_signals::parser::attribute_set = nullptr; + g_signals::parser::attribute_unset = nullptr; + g_signals::parser::attribute_toggle = nullptr; + g_signals::parser::action_block_open = nullptr; + g_signals::parser::action_block_close = nullptr; + g_signals::parser::color_change = nullptr; + g_signals::parser::font_change = nullptr; + g_signals::parser::pixel_offset = nullptr; + g_signals::parser::ascii_text_write = nullptr; + g_signals::parser::unicode_text_write = nullptr; + g_signals::tray::report_slotcount = nullptr; + // }}} + if (m_sinkattached) m_connection.detach_sink(this, 1); m_window.destroy(); @@ -444,20 +447,22 @@ class bar : public xpp::event::sink hint_num{ - { {alignment::LEFT, 0}, - {alignment::CENTER, 0}, - {alignment::RIGHT, 0}, - }}; + map hint_num{{ + {alignment::LEFT, 0}, {alignment::CENTER, 0}, {alignment::RIGHT, 0}, + }}; #endif for (auto&& action : m_actions) { @@ -625,8 +628,8 @@ class bar : public xpp::event::sinkwindow == m_window && evt->atom == WM_STATE) { - if (g_signals::bar::visibility_change.empty()) { + if (!g_signals::bar::visibility_change) return; - } + try { auto attr = m_connection.get_window_attributes(m_window); if (attr->map_state == XCB_MAP_STATE_VIEWABLE) - g_signals::bar::visibility_change.emit(true); + g_signals::bar::visibility_change(true); else if (attr->map_state == XCB_MAP_STATE_UNVIEWABLE) - g_signals::bar::visibility_change.emit(false); + g_signals::bar::visibility_change(false); else if (attr->map_state == XCB_MAP_STATE_UNMAPPED) - g_signals::bar::visibility_change.emit(false); + g_signals::bar::visibility_change(false); else - g_signals::bar::visibility_change.emit(true); + g_signals::bar::visibility_change(true); } catch (const std::exception& err) { m_log.warn("Failed to emit bar window's visibility change event"); } diff --git a/include/components/controller.hpp b/include/components/controller.hpp index 40120498..0a080ee9 100644 --- a/include/components/controller.hpp +++ b/include/components/controller.hpp @@ -87,7 +87,7 @@ class controller { } m_log.trace("controller: Deconstruct bar instance"); - g_signals::bar::action_click.clear(); + g_signals::bar::action_click = nullptr; m_bar.reset(); m_log.trace("controller: Interrupt X event loop"); @@ -159,7 +159,7 @@ class controller { std::cout << m_bar->settings().wmname << std::endl; return; } else if (!to_stdout) { - g_signals::bar::action_click.connect(this, &controller::on_module_click); + g_signals::bar::action_click = bind(&controller::on_module_click, this, std::placeholders::_1); } } catch (const std::exception& err) { throw application_error("Failed to setup bar renderer: " + string{err.what()}); @@ -411,8 +411,8 @@ class controller { auto& module = modules.back(); - module->set_writer(delegate::MakeDelegate(this, &controller::on_module_update)); - module->set_terminator(delegate::MakeDelegate(this, &controller::on_module_stop)); + module->set_writer(bind(&controller::on_module_update, this, std::placeholders::_1)); + module->set_terminator(bind(&controller::on_module_stop, this, std::placeholders::_1)); module_count++; } diff --git a/include/components/logger.hpp b/include/components/logger.hpp index 06b0d3a7..2eaceaf6 100644 --- a/include/components/logger.hpp +++ b/include/components/logger.hpp @@ -80,11 +80,13 @@ class logger { * Output a trace message */ template - void trace(string message, Args... args) const { #ifdef DEBUG + void trace(string message, Args... args) const { output(loglevel::TRACE, message, args...); -#endif } +#else + void trace(string, Args...) const {} +#endif /** * Output an info message diff --git a/include/components/parser.hpp b/include/components/parser.hpp index ced711b8..d965243b 100644 --- a/include/components/parser.hpp +++ b/include/components/parser.hpp @@ -1,10 +1,8 @@ #pragma once -#include - #include "common.hpp" -#include "components/types.hpp" #include "components/signals.hpp" +#include "components/types.hpp" #include "utils/math.hpp" #include "utils/string.hpp" @@ -63,69 +61,69 @@ class parser { switch (tag) { case 'B': // Ignore tag if it occurs again later in the same block - if (data.find(" B") == string::npos && !g_signals::parser::color_change.empty()) - g_signals::parser::color_change.emit(gc::BG, parse_color(value, m_bar.background)); + if (data.find(" B") == string::npos && g_signals::parser::color_change) + g_signals::parser::color_change(gc::BG, parse_color(value, m_bar.background)); break; case 'F': // Ignore tag if it occurs again later in the same block - if (data.find(" F") == string::npos && !g_signals::parser::color_change.empty()) - g_signals::parser::color_change.emit(gc::FG, parse_color(value, m_bar.foreground)); + if (data.find(" F") == string::npos && g_signals::parser::color_change) + g_signals::parser::color_change(gc::FG, parse_color(value, m_bar.foreground)); break; case 'U': // Ignore tag if it occurs again later in the same block - if (data.find(" U") == string::npos && !g_signals::parser::color_change.empty()) { - g_signals::parser::color_change.emit(gc::UL, parse_color(value, m_bar.linecolor)); - g_signals::parser::color_change.emit(gc::OL, parse_color(value, m_bar.linecolor)); + if (data.find(" U") == string::npos && g_signals::parser::color_change) { + g_signals::parser::color_change(gc::UL, parse_color(value, m_bar.linecolor)); + g_signals::parser::color_change(gc::OL, parse_color(value, m_bar.linecolor)); } break; case 'R': - if (!g_signals::parser::color_change.empty()) { - g_signals::parser::color_change.emit(gc::BG, m_bar.foreground); - g_signals::parser::color_change.emit(gc::FG, m_bar.background); + if (g_signals::parser::color_change) { + g_signals::parser::color_change(gc::BG, m_bar.foreground); + g_signals::parser::color_change(gc::FG, m_bar.background); } break; case 'T': - if (data.find(" T") == string::npos && !g_signals::parser::font_change.empty()) - g_signals::parser::font_change.emit(parse_fontindex(value)); + if (data.find(" T") == string::npos && g_signals::parser::font_change) + g_signals::parser::font_change(parse_fontindex(value)); break; case 'O': - if (!g_signals::parser::pixel_offset.empty()) - g_signals::parser::pixel_offset.emit(std::atoi(value.c_str())); + if (g_signals::parser::pixel_offset) + g_signals::parser::pixel_offset(std::atoi(value.c_str())); break; case 'l': - if (!g_signals::parser::alignment_change.empty()) - g_signals::parser::alignment_change.emit(alignment::LEFT); + if (g_signals::parser::alignment_change) + g_signals::parser::alignment_change(alignment::LEFT); break; case 'c': - if (!g_signals::parser::alignment_change.empty()) - g_signals::parser::alignment_change.emit(alignment::CENTER); + if (g_signals::parser::alignment_change) + g_signals::parser::alignment_change(alignment::CENTER); break; case 'r': - if (!g_signals::parser::alignment_change.empty()) - g_signals::parser::alignment_change.emit(alignment::RIGHT); + if (g_signals::parser::alignment_change) + g_signals::parser::alignment_change(alignment::RIGHT); break; case '+': - if (!g_signals::parser::attribute_set.empty()) - g_signals::parser::attribute_set.emit(parse_attr(value[0])); + if (g_signals::parser::attribute_set) + g_signals::parser::attribute_set(parse_attr(value[0])); break; case '-': - if (!g_signals::parser::attribute_unset.empty()) - g_signals::parser::attribute_unset.emit(parse_attr(value[0])); + if (g_signals::parser::attribute_unset) + g_signals::parser::attribute_unset(parse_attr(value[0])); break; case '!': - if (!g_signals::parser::attribute_toggle.empty()) - g_signals::parser::attribute_toggle.emit(parse_attr(value[0])); + if (g_signals::parser::attribute_toggle) + g_signals::parser::attribute_toggle(parse_attr(value[0])); break; case 'A': @@ -134,16 +132,16 @@ class parser { mousebtn btn = parse_action_btn(data); m_actions.push_back(static_cast(btn)); - if (!g_signals::parser::action_block_open.empty()) - g_signals::parser::action_block_open.emit(btn, value); + if (g_signals::parser::action_block_open) + g_signals::parser::action_block_open(btn, value); // make sure we strip the correct length (btn+wrapping colons) if (data[0] != ':') value += "0"; value += "::"; } else if (!m_actions.empty()) { - if (!g_signals::parser::action_block_close.empty()) - g_signals::parser::action_block_close.emit(parse_action_btn(data)); + if (g_signals::parser::action_block_close) + g_signals::parser::action_block_close(parse_action_btn(data)); m_actions.pop_back(); } break; @@ -170,31 +168,39 @@ class parser { // size_t n = 0; // while (sequence[n] != '\0' && static_cast(sequence[n]) < 0x80 && ++n <= next_tag) // ; - // g_signals::parser::ascii_text_write.emit(data.substr(0, n)); + // if (g_signals::parser::ascii_text_write) + // g_signals::parser::ascii_text_write(data.substr(0, n)); // return data.length(); // } if (utf[0] < 0x80) { - g_signals::parser::ascii_text_write.emit(utf[0]); + if (g_signals::parser::ascii_text_write) + g_signals::parser::ascii_text_write(utf[0]); return 1; } else if ((utf[0] & 0xe0) == 0xc0) { // 2 byte utf-8 sequence - g_signals::parser::unicode_text_write.emit((utf[0] & 0x1f) << 6 | (utf[1] & 0x3f)); + if (g_signals::parser::unicode_text_write) + g_signals::parser::unicode_text_write((utf[0] & 0x1f) << 6 | (utf[1] & 0x3f)); return 2; } else if ((utf[0] & 0xf0) == 0xe0) { // 3 byte utf-8 sequence - g_signals::parser::unicode_text_write.emit( - (utf[0] & 0xf) << 12 | (utf[1] & 0x3f) << 6 | (utf[2] & 0x3f)); + if (g_signals::parser::unicode_text_write) + g_signals::parser::unicode_text_write( + (utf[0] & 0xf) << 12 | (utf[1] & 0x3f) << 6 | (utf[2] & 0x3f)); return 3; } else if ((utf[0] & 0xf8) == 0xf0) { // 4 byte utf-8 sequence - g_signals::parser::unicode_text_write.emit(0xfffd); + if (g_signals::parser::unicode_text_write) + g_signals::parser::unicode_text_write(0xfffd); return 4; } else if ((utf[0] & 0xfc) == 0xf8) { // 5 byte utf-8 sequence - g_signals::parser::unicode_text_write.emit(0xfffd); + if (g_signals::parser::unicode_text_write) + g_signals::parser::unicode_text_write(0xfffd); return 5; } else if ((utf[0] & 0xfe) == 0xfc) { // 6 byte utf-8 sequence - g_signals::parser::unicode_text_write.emit(0xfffd); + if (g_signals::parser::unicode_text_write) + g_signals::parser::unicode_text_write(0xfffd); return 6; } else { // invalid utf-8 sequence - g_signals::parser::ascii_text_write.emit(utf[0]); + if (g_signals::parser::ascii_text_write) + g_signals::parser::ascii_text_write(utf[0]); return 1; } } // }}} diff --git a/include/components/signals.hpp b/include/components/signals.hpp index 1f676835..57bb22d9 100644 --- a/include/components/signals.hpp +++ b/include/components/signals.hpp @@ -1,43 +1,44 @@ #pragma once -#include - #include "common.hpp" #include "components/types.hpp" LEMONBUDDY_NS +/** + * @TODO: Allow multiple signal handlers + */ namespace g_signals { /** * Signals used to communicate with the bar window */ namespace bar { - static delegate::Signal1 action_click; - static delegate::Signal1 visibility_change; + static function action_click; + static function visibility_change; } /** * Signals used to communicate with the input parser */ namespace parser { - static delegate::Signal1 alignment_change; - static delegate::Signal1 attribute_set; - static delegate::Signal1 attribute_unset; - static delegate::Signal1 attribute_toggle; - static delegate::Signal2 action_block_open; - static delegate::Signal1 action_block_close; - static delegate::Signal2 color_change; - static delegate::Signal1 font_change; - static delegate::Signal1 pixel_offset; - static delegate::Signal1 ascii_text_write; - static delegate::Signal1 unicode_text_write; + static function alignment_change; + static function attribute_set; + static function attribute_unset; + static function attribute_toggle; + static function action_block_open; + static function action_block_close; + static function color_change; + static function font_change; + static function pixel_offset; + static function ascii_text_write; + static function unicode_text_write; } /** * Signals used to communicate with the tray manager */ namespace tray { - static delegate::Signal1 report_slotcount; + static function report_slotcount; } } diff --git a/include/components/x11/tray.hpp b/include/components/x11/tray.hpp index 67e7deb8..ae12d921 100644 --- a/include/components/x11/tray.hpp +++ b/include/components/x11/tray.hpp @@ -147,7 +147,8 @@ class traymanager // Listen for visibility change events on the bar window if (!m_restacked) { - g_signals::bar::visibility_change.connect(this, &traymanager::bar_visibility_change); + g_signals::bar::visibility_change = + bind(&traymanager::bar_visibility_change, this, std::placeholders::_1); } // Attempt to get control of the systray selection then @@ -193,7 +194,8 @@ class traymanager } if (!m_restacked) { - g_signals::bar::visibility_change.disconnect(this, &traymanager::bar_visibility_change); + g_signals::bar::visibility_change = + bind(&traymanager::bar_visibility_change, this, std::placeholders::_1); } // Dismiss all clients by reparenting them to the root window @@ -238,8 +240,8 @@ class traymanager } } - if (!g_signals::tray::report_slotcount.empty()) - g_signals::tray::report_slotcount.emit(mapped_clients); + if (g_signals::tray::report_slotcount) + g_signals::tray::report_slotcount(mapped_clients); if (!width && m_mapped) { m_connection.unmap_window(m_tray); @@ -540,7 +542,7 @@ class traymanager void handle(const evt::expose& evt) { if (!m_activated || m_clients.empty()) return; - m_logger.trace("tray: Received expose event"); + m_logger.trace("tray: Received expose event for %s", m_connection.id(evt->window)); reconfigure(); } @@ -550,7 +552,7 @@ class traymanager void handle(const evt::visibility_notify& evt) { if (!m_activated || m_clients.empty()) return; - m_logger.trace("tray: Received visibility_notify"); + m_logger.trace("tray: Received visibility_notify for %s", m_connection.id(evt->window)); reconfigure(); } diff --git a/include/modules/meta.hpp b/include/modules/meta.hpp index ce387b65..eede79c3 100644 --- a/include/modules/meta.hpp +++ b/include/modules/meta.hpp @@ -2,7 +2,6 @@ #include #include -#include #include #include "common.hpp" @@ -158,8 +157,8 @@ namespace modules { virtual bool handle_event(string cmd) = 0; virtual bool receive_events() const = 0; - virtual void set_writer(delegate::Delegate1&& fn) = 0; - virtual void set_terminator(delegate::Delegate1&& fn) = 0; + virtual void set_writer(std::function&& fn) = 0; + virtual void set_terminator(std::function&& fn) = 0; }; // }}} @@ -197,11 +196,11 @@ namespace modules { m_log.trace("%s: Done cleaning up", name()); } - void set_writer(delegate::Delegate1&& fn) { + void set_writer(std::function&& fn) { m_writer = forward(fn); } - void set_terminator(delegate::Delegate1&& fn) { + void set_terminator(std::function&& fn) { m_terminator = forward(fn); } @@ -261,11 +260,13 @@ namespace modules { void broadcast() { if (!enabled()) return; - else if (!m_writer) - m_log.warn("%s: No attach writer, ignoring broadcast...", name()); m_cache = CAST_MOD(Impl)->get_output(); - m_writer(name()); + + if (m_writer) + m_writer(name()); + else + m_log.warn("%s: No handler, ignoring broadcast...", name()); } void idle() {} @@ -318,8 +319,8 @@ namespace modules { } protected: - delegate::Delegate1 m_writer; - delegate::Delegate1 m_terminator; + function m_writer; + function m_terminator; threading_util::spin_lock m_updatelock; // std::timed_mutex m_mutex;