From df85a6492e907735d7335108a8fdb74d14240006 Mon Sep 17 00:00:00 2001 From: Michael Carlberg Date: Sat, 3 Dec 2016 22:54:58 +0100 Subject: [PATCH] refactor(eventloop): Typed events --- include/components/controller.hpp | 2 +- include/components/eventloop.hpp | 35 ++++++++++++++++++++---- src/components/controller.cpp | 44 ++++++++++++------------------- src/components/eventloop.cpp | 20 +++++++------- src/components/screen.cpp | 13 +++++---- 5 files changed, 64 insertions(+), 50 deletions(-) diff --git a/include/components/controller.hpp b/include/components/controller.hpp index f55a9b93..7981571a 100644 --- a/include/components/controller.hpp +++ b/include/components/controller.hpp @@ -56,7 +56,7 @@ class controller { void on_ipc_action(const ipc_action& message); void on_mouse_event(const string& input); void on_unrecognized_action(string input); - void on_update(); + void on_update(bool force); private: enum class thread_role { diff --git a/include/components/eventloop.hpp b/include/components/eventloop.hpp index db2bb8c0..aa442fd7 100644 --- a/include/components/eventloop.hpp +++ b/include/components/eventloop.hpp @@ -30,6 +30,16 @@ struct quit_event { bool reload{false}; }; +struct update_event { + const uint8_t type{static_cast(event_type::UPDATE)}; + bool force{false}; +}; + +struct input_event { + const uint8_t type{static_cast(event_type::INPUT)}; + char data[256]{'\0'}; +}; + class eventloop { public: /** @@ -49,13 +59,28 @@ class eventloop { bool enqueue(const entry_t& entry); bool enqueue_delayed(const entry_t& entry); - void set_update_cb(callback<>&& cb); + void set_update_cb(callback&& cb); void set_input_db(callback&& cb); void add_module(const alignment pos, module_t&& module); const modulemap_t& modules() const; size_t module_count() const; + static const eventloop::entry_t& make(update_event&& event, bool force = false) { + event.force = force; + return reinterpret_cast(event); + } + + static const eventloop::entry_t& make(quit_event&& event, bool reload = false) { + event.reload = reload; + return reinterpret_cast(event); + } + + static const eventloop::entry_t& make(input_event&& event, const string& data) { + snprintf(event.data, sizeof(event.data), "%s", data.c_str()); + return reinterpret_cast(event); + } + protected: void dispatch_modules(); void dispatch_queue_worker(); @@ -65,10 +90,10 @@ class eventloop { inline bool compare_events(entry_t evt, entry_t evt2); void forward_event(entry_t evt); - void on_update(); - void on_input(char* input); + void on_update(const update_event& evt); + void on_input(const input_event& evt); void on_check(); - void on_quit(const quit_event& quit); + void on_quit(const quit_event& evt); private: const logger& m_log; @@ -92,7 +117,7 @@ class eventloop { /** * @brief Callback fired when receiving UPDATE events */ - callback<> m_update_cb; + callback m_update_cb; /** * @brief Callback fired for unprocessed INPUT events diff --git a/src/components/controller.cpp b/src/components/controller.cpp index 72b9131d..5539addf 100644 --- a/src/components/controller.cpp +++ b/src/components/controller.cpp @@ -163,7 +163,7 @@ void controller::bootstrap(bool writeback, bool dump_wmname) { } m_log.trace("controller: Attach eventloop update callback"); - m_eventloop->set_update_cb(bind(&controller::on_update, this)); + m_eventloop->set_update_cb(bind(&controller::on_update, this, placeholders::_1)); if (!m_writeback) { m_log.trace("controller: Attach eventloop input callback"); @@ -418,16 +418,14 @@ void controller::on_ipc_action(const ipc_action& message) { string action = message.payload.substr(strlen(ipc_action::prefix)); - if (action.empty()) { + if (action.size() >= sizeof(input_event::data)) { + m_log.warn("Ignoring input event (size)"); + } else if (action.empty()) { m_log.err("Cannot enqueue empty IPC action"); - return; + } else { + m_log.info("Enqueuing IPC action: %s", action); + m_eventloop->enqueue(eventloop::make(input_event{}, action)); } - - eventloop::entry_t evt{static_cast(event_type::INPUT)}; - snprintf(evt.data, sizeof(evt.data), "%s", action.c_str()); - - m_log.info("Enqueuing IPC action: %s", action); - m_eventloop->enqueue(evt); } /** @@ -436,17 +434,9 @@ void controller::on_ipc_action(const ipc_action& message) { void controller::on_mouse_event(const string& input) { if (!m_eventloop) { return; - } - - eventloop::entry_t evt{static_cast(event_type::INPUT)}; - - if (input.length() > sizeof(evt.data)) { - return m_log.warn("Ignoring input event (size)"); - } - - snprintf(evt.data, sizeof(evt.data), "%s", input.c_str()); - - if (!m_eventloop->enqueue_delayed(evt)) { + } else if (input.length() >= sizeof(input_event::data)) { + m_log.warn("Ignoring input event (size)"); + } else if (!m_eventloop->enqueue_delayed(eventloop::make(input_event{}, input))) { m_log.trace_x("controller: Dispatcher busy"); } } @@ -474,7 +464,7 @@ void controller::on_unrecognized_action(string input) { /** * Callback for module content update */ -void controller::on_update() { +void controller::on_update(bool force) { if (!m_bar) { return; } @@ -557,12 +547,6 @@ void controller::on_update() { return; } - try { - m_bar->parse(contents); - } catch (const exception& err) { - m_log.err("Failed to update bar contents (reason: %s)", err.what()); - } - try { if (!m_trayactivated) { m_trayactivated = true; @@ -571,6 +555,12 @@ void controller::on_update() { } catch (const exception& err) { m_log.err("Failed to active tray manager (reason: %s)", err.what()); } + + try { + m_bar->parse(contents, force); + } catch (const exception& err) { + m_log.err("Failed to update bar contents (reason: %s)", err.what()); + } } POLYBAR_NS_END diff --git a/src/components/eventloop.cpp b/src/components/eventloop.cpp index d7e1e87e..59b693b3 100644 --- a/src/components/eventloop.cpp +++ b/src/components/eventloop.cpp @@ -124,7 +124,7 @@ bool eventloop::enqueue_delayed(const entry_t& entry) { /** * Set callback handler for UPDATE events */ -void eventloop::set_update_cb(callback<>&& cb) { +void eventloop::set_update_cb(callback&& cb) { m_update_cb = forward(cb); } @@ -267,9 +267,9 @@ inline bool eventloop::compare_events(entry_t evt, entry_t evt2) { */ void eventloop::forward_event(entry_t evt) { if (evt.type == static_cast(event_type::UPDATE)) { - on_update(); + on_update(reinterpret_cast(evt)); } else if (evt.type == static_cast(event_type::INPUT)) { - on_input(evt.data); + on_input(reinterpret_cast(evt)); } else if (evt.type == static_cast(event_type::CHECK)) { on_check(); } else if (evt.type == static_cast(event_type::QUIT)) { @@ -282,11 +282,11 @@ void eventloop::forward_event(entry_t evt) { /** * Handler for enqueued UPDATE events */ -void eventloop::on_update() { +void eventloop::on_update(const update_event& evt) { m_log.trace("eventloop: Received UPDATE event"); if (m_update_cb) { - m_update_cb(); + m_update_cb(evt.force); } else { m_log.warn("No callback to handle update"); } @@ -295,7 +295,7 @@ void eventloop::on_update() { /** * Handler for enqueued INPUT events */ -void eventloop::on_input(char* input) { +void eventloop::on_input(const input_event& evt) { m_log.trace("eventloop: Received INPUT event"); for (auto&& block : m_modules) { @@ -303,14 +303,14 @@ void eventloop::on_input(char* input) { if (!module->receive_events()) { continue; } - if (module->handle_event(input)) { + if (module->handle_event(evt.data)) { return; } } } if (m_unrecognized_input_cb) { - m_unrecognized_input_cb(input); + m_unrecognized_input_cb(evt.data); } else { m_log.warn("No callback to handle unrecognized input"); } @@ -336,11 +336,11 @@ void eventloop::on_check() { /** * Handler for enqueued QUIT events */ -void eventloop::on_quit(const quit_event& quit) { +void eventloop::on_quit(const quit_event& evt) { m_log.trace("eventloop: Received QUIT event"); m_running = false; - if (quit.reload) { + if (evt.reload) { kill(getpid(), SIGUSR1); } } diff --git a/src/components/screen.cpp b/src/components/screen.cpp index 53c36cce..abd32426 100644 --- a/src/components/screen.cpp +++ b/src/components/screen.cpp @@ -100,14 +100,13 @@ void screen::handle(const evt::randr_screen_change_notify& evt) { } } - if (changed) { - m_log.warn("randr_screen_change_notify (%ux%u)... reloading", evt->width, evt->height); - m_sigraised = true; - - quit_event quit{}; - quit.reload = true; - g_signals::event::enqueue(reinterpret_cast(quit)); + if (!changed) { + return; } + + m_log.warn("randr_screen_change_notify (%ux%u)... reloading", evt->width, evt->height); + m_sigraised = true; + g_signals::event::enqueue(eventloop::make(quit_event{}, true)); } POLYBAR_NS_END