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_mouse_event(const string& input);
void on_unrecognized_action(string input);
void on_update();
void on_update(bool force);
private:
enum class thread_role {

View File

@ -30,6 +30,16 @@ struct quit_event {
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 {
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<bool>&& cb);
void set_input_db(callback<string>&& 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<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:
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<bool> m_update_cb;
/**
* @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_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<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) {
if (!m_eventloop) {
return;
}
eventloop::entry_t evt{static_cast<uint8_t>(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

View File

@ -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<bool>&& 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) {
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)) {
on_input(evt.data);
on_input(reinterpret_cast<const input_event&>(evt));
} else if (evt.type == static_cast<uint8_t>(event_type::CHECK)) {
on_check();
} 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
*/
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);
}
}

View File

@ -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<const eventloop::entry_t&>(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