refactor(eventloop): Typed events

This commit is contained in:
Michael Carlberg 2016-12-03 22:54:58 +01:00
parent c94801a747
commit df85a6492e
5 changed files with 64 additions and 50 deletions

View File

@ -56,7 +56,7 @@ class controller {
void on_ipc_action(const ipc_action& message); void on_ipc_action(const ipc_action& message);
void on_mouse_event(const string& input); void on_mouse_event(const string& input);
void on_unrecognized_action(string input); void on_unrecognized_action(string input);
void on_update(); void on_update(bool force);
private: private:
enum class thread_role { enum class thread_role {

View File

@ -30,6 +30,16 @@ struct quit_event {
bool reload{false}; bool reload{false};
}; };
struct update_event {
const uint8_t type{static_cast<uint8_t>(event_type::UPDATE)};
bool force{false};
};
struct input_event {
const uint8_t type{static_cast<uint8_t>(event_type::INPUT)};
char data[256]{'\0'};
};
class eventloop { class eventloop {
public: public:
/** /**
@ -49,13 +59,28 @@ class eventloop {
bool enqueue(const entry_t& entry); bool enqueue(const entry_t& entry);
bool enqueue_delayed(const entry_t& entry); bool enqueue_delayed(const entry_t& entry);
void set_update_cb(callback<>&& cb); void set_update_cb(callback<bool>&& cb);
void set_input_db(callback<string>&& cb); void set_input_db(callback<string>&& cb);
void add_module(const alignment pos, module_t&& module); void add_module(const alignment pos, module_t&& module);
const modulemap_t& modules() const; const modulemap_t& modules() const;
size_t module_count() const; size_t module_count() const;
static const eventloop::entry_t& make(update_event&& event, bool force = false) {
event.force = force;
return reinterpret_cast<const eventloop::entry_t&>(event);
}
static const eventloop::entry_t& make(quit_event&& event, bool reload = false) {
event.reload = reload;
return reinterpret_cast<const eventloop::entry_t&>(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<const eventloop::entry_t&>(event);
}
protected: protected:
void dispatch_modules(); void dispatch_modules();
void dispatch_queue_worker(); void dispatch_queue_worker();
@ -65,10 +90,10 @@ class eventloop {
inline bool compare_events(entry_t evt, entry_t evt2); inline bool compare_events(entry_t evt, entry_t evt2);
void forward_event(entry_t evt); void forward_event(entry_t evt);
void on_update(); void on_update(const update_event& evt);
void on_input(char* input); void on_input(const input_event& evt);
void on_check(); void on_check();
void on_quit(const quit_event& quit); void on_quit(const quit_event& evt);
private: private:
const logger& m_log; const logger& m_log;
@ -92,7 +117,7 @@ class eventloop {
/** /**
* @brief Callback fired when receiving UPDATE events * @brief Callback fired when receiving UPDATE events
*/ */
callback<> m_update_cb; callback<bool> m_update_cb;
/** /**
* @brief Callback fired for unprocessed INPUT events * @brief Callback fired for unprocessed INPUT events

View File

@ -163,7 +163,7 @@ void controller::bootstrap(bool writeback, bool dump_wmname) {
} }
m_log.trace("controller: Attach eventloop update callback"); 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) { if (!m_writeback) {
m_log.trace("controller: Attach eventloop input callback"); 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)); 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"); 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<uint8_t>(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) { void controller::on_mouse_event(const string& input) {
if (!m_eventloop) { if (!m_eventloop) {
return; return;
} } else if (input.length() >= sizeof(input_event::data)) {
m_log.warn("Ignoring input event (size)");
eventloop::entry_t evt{static_cast<uint8_t>(event_type::INPUT)}; } else if (!m_eventloop->enqueue_delayed(eventloop::make(input_event{}, 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)) {
m_log.trace_x("controller: Dispatcher busy"); m_log.trace_x("controller: Dispatcher busy");
} }
} }
@ -474,7 +464,7 @@ void controller::on_unrecognized_action(string input) {
/** /**
* Callback for module content update * Callback for module content update
*/ */
void controller::on_update() { void controller::on_update(bool force) {
if (!m_bar) { if (!m_bar) {
return; return;
} }
@ -557,12 +547,6 @@ void controller::on_update() {
return; return;
} }
try {
m_bar->parse(contents);
} catch (const exception& err) {
m_log.err("Failed to update bar contents (reason: %s)", err.what());
}
try { try {
if (!m_trayactivated) { if (!m_trayactivated) {
m_trayactivated = true; m_trayactivated = true;
@ -571,6 +555,12 @@ void controller::on_update() {
} catch (const exception& err) { } catch (const exception& err) {
m_log.err("Failed to active tray manager (reason: %s)", err.what()); 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 POLYBAR_NS_END

View File

@ -124,7 +124,7 @@ bool eventloop::enqueue_delayed(const entry_t& entry) {
/** /**
* Set callback handler for UPDATE events * Set callback handler for UPDATE events
*/ */
void eventloop::set_update_cb(callback<>&& cb) { void eventloop::set_update_cb(callback<bool>&& cb) {
m_update_cb = forward<decltype(cb)>(cb); m_update_cb = forward<decltype(cb)>(cb);
} }
@ -267,9 +267,9 @@ inline bool eventloop::compare_events(entry_t evt, entry_t evt2) {
*/ */
void eventloop::forward_event(entry_t evt) { void eventloop::forward_event(entry_t evt) {
if (evt.type == static_cast<uint8_t>(event_type::UPDATE)) { if (evt.type == static_cast<uint8_t>(event_type::UPDATE)) {
on_update(); on_update(reinterpret_cast<const update_event&>(evt));
} else if (evt.type == static_cast<uint8_t>(event_type::INPUT)) { } else if (evt.type == static_cast<uint8_t>(event_type::INPUT)) {
on_input(evt.data); on_input(reinterpret_cast<const input_event&>(evt));
} else if (evt.type == static_cast<uint8_t>(event_type::CHECK)) { } else if (evt.type == static_cast<uint8_t>(event_type::CHECK)) {
on_check(); on_check();
} else if (evt.type == static_cast<uint8_t>(event_type::QUIT)) { } else if (evt.type == static_cast<uint8_t>(event_type::QUIT)) {
@ -282,11 +282,11 @@ void eventloop::forward_event(entry_t evt) {
/** /**
* Handler for enqueued UPDATE events * Handler for enqueued UPDATE events
*/ */
void eventloop::on_update() { void eventloop::on_update(const update_event& evt) {
m_log.trace("eventloop: Received UPDATE event"); m_log.trace("eventloop: Received UPDATE event");
if (m_update_cb) { if (m_update_cb) {
m_update_cb(); m_update_cb(evt.force);
} else { } else {
m_log.warn("No callback to handle update"); m_log.warn("No callback to handle update");
} }
@ -295,7 +295,7 @@ void eventloop::on_update() {
/** /**
* Handler for enqueued INPUT events * 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"); m_log.trace("eventloop: Received INPUT event");
for (auto&& block : m_modules) { for (auto&& block : m_modules) {
@ -303,14 +303,14 @@ void eventloop::on_input(char* input) {
if (!module->receive_events()) { if (!module->receive_events()) {
continue; continue;
} }
if (module->handle_event(input)) { if (module->handle_event(evt.data)) {
return; return;
} }
} }
} }
if (m_unrecognized_input_cb) { if (m_unrecognized_input_cb) {
m_unrecognized_input_cb(input); m_unrecognized_input_cb(evt.data);
} else { } else {
m_log.warn("No callback to handle unrecognized input"); m_log.warn("No callback to handle unrecognized input");
} }
@ -336,11 +336,11 @@ void eventloop::on_check() {
/** /**
* Handler for enqueued QUIT events * 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_log.trace("eventloop: Received QUIT event");
m_running = false; m_running = false;
if (quit.reload) { if (evt.reload) {
kill(getpid(), SIGUSR1); kill(getpid(), SIGUSR1);
} }
} }

View File

@ -100,14 +100,13 @@ void screen::handle(const evt::randr_screen_change_notify& evt) {
} }
} }
if (changed) { if (!changed) {
m_log.warn("randr_screen_change_notify (%ux%u)... reloading", evt->width, evt->height); return;
m_sigraised = true;
quit_event quit{};
quit.reload = true;
g_signals::event::enqueue(reinterpret_cast<const eventloop::entry_t&>(quit));
} }
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 POLYBAR_NS_END