Handle click commands in eventloop

This commit is contained in:
patrick96 2021-09-11 12:19:00 +02:00 committed by Patrick Ziegler
parent 88cd525dc8
commit c89fc7f73b
3 changed files with 29 additions and 20 deletions

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <moodycamel/blockingconcurrentqueue.h> #include <moodycamel/blockingconcurrentqueue.h>
#include <uv.h>
#include <thread> #include <thread>
@ -51,7 +52,7 @@ class controller
bool run(bool writeback, string snapshot_dst); bool run(bool writeback, string snapshot_dst);
bool enqueue(event&& evt); bool enqueue(event&& evt);
bool enqueue(string&& input_data); bool trigger_action(string&& input_data);
void stop(bool reload); void stop(bool reload);
@ -60,6 +61,7 @@ class controller
void conn_cb(int status, int events); void conn_cb(int status, int events);
void ipc_cb(string buf); void ipc_cb(string buf);
void confwatch_handler(const char* fname, int events, int status); void confwatch_handler(const char* fname, int events, int status);
void notifier_handler();
protected: protected:
void read_events(); void read_events();
@ -95,6 +97,14 @@ class controller
std::unique_ptr<eventloop> eloop; std::unique_ptr<eventloop> eloop;
/**
* \brief Async handle to notify the eventloop
*
* This handle is used to notify the eventloop of changes which are not otherwise covered by other handles.
* E.g. click actions.
*/
std::unique_ptr<uv_async_t> m_notifier{nullptr};
/** /**
* \brief State flag * \brief State flag
*/ */

View File

@ -10,7 +10,6 @@ enum class event_type {
NONE = 0, NONE = 0,
UPDATE, UPDATE,
CHECK, CHECK,
INPUT,
QUIT, QUIT,
}; };
@ -48,13 +47,6 @@ namespace {
return event{static_cast<int>(event_type::UPDATE), force}; return event{static_cast<int>(event_type::UPDATE), force};
} }
/**
* Create INPUT event
*/
inline event make_input_evt() {
return event{static_cast<int>(event_type::INPUT)};
}
/** /**
* Create CHECK event * Create CHECK event
*/ */

View File

@ -160,12 +160,12 @@ bool controller::enqueue(event&& evt) {
/** /**
* Enqueue input data * Enqueue input data
*/ */
bool controller::enqueue(string&& input_data) { bool controller::trigger_action(string&& input_data) {
if (!m_inputdata.empty()) { if (!m_inputdata.empty()) {
m_log.trace("controller: Swallowing input event (pending data)"); m_log.trace("controller: Swallowing input event (pending data)");
} else { } else {
m_inputdata = forward<string>(input_data); m_inputdata = forward<string>(input_data);
return enqueue(make_input_evt()); UV(uv_async_send, m_notifier.get());
} }
return false; return false;
} }
@ -223,6 +223,12 @@ void controller::confwatch_handler(const char* filename, int, int) {
stop(true); stop(true);
} }
void controller::notifier_handler() {
if (!m_inputdata.empty()) {
process_inputdata();
}
}
static void ipc_alloc_cb(uv_handle_t*, size_t, uv_buf_t* buf) { static void ipc_alloc_cb(uv_handle_t*, size_t, uv_buf_t* buf) {
buf->base = new char[BUFSIZ]; buf->base = new char[BUFSIZ];
buf->len = BUFSIZ; buf->len = BUFSIZ;
@ -247,6 +253,10 @@ static void ipc_read_cb_wrapper(uv_stream_t* stream, ssize_t nread, const uv_buf
} }
} }
static void notifier_cb_wrapper(uv_async_t *handle) {
static_cast<controller*>(handle->data)->notifier_handler();
}
/** /**
* Read events from configured file descriptors * Read events from configured file descriptors
*/ */
@ -279,6 +289,10 @@ void controller::read_events() {
uv_read_start((uv_stream_t*)ipc_handle.get(), ipc_alloc_cb, ipc_read_cb_wrapper); uv_read_start((uv_stream_t*)ipc_handle.get(), ipc_alloc_cb, ipc_read_cb_wrapper);
} }
m_notifier = std::make_unique<uv_async_t>();
uv_async_init(loop, m_notifier.get(), notifier_cb_wrapper);
m_notifier->data = this;
eloop->run(); eloop->run();
} catch (const exception& err) { } catch (const exception& err) {
m_log.err("Fatal Error in eventloop: %s", err.what()); m_log.err("Fatal Error in eventloop: %s", err.what());
@ -317,8 +331,6 @@ void controller::process_eventqueue() {
} else { } else {
on(signals::eventqueue::exit_terminate{}); on(signals::eventqueue::exit_terminate{});
} }
} else if (evt.type == event_type::INPUT) {
process_inputdata();
} else if (evt.type == event_type::UPDATE && evt.flag) { } else if (evt.type == event_type::UPDATE && evt.flag) {
process_update(true); process_update(true);
} else { } else {
@ -328,9 +340,6 @@ void controller::process_eventqueue() {
if (next.type == event_type::QUIT) { if (next.type == event_type::QUIT) {
evt = next; evt = next;
break; break;
} else if (next.type == event_type::INPUT) {
evt = next;
break;
} else if (evt.type != next.type) { } else if (evt.type != next.type) {
enqueue(move(next)); enqueue(move(next));
break; break;
@ -342,8 +351,6 @@ void controller::process_eventqueue() {
if (evt.type == event_type::UPDATE) { if (evt.type == event_type::UPDATE) {
process_update(evt.flag); process_update(evt.flag);
} else if (evt.type == event_type::INPUT) {
process_inputdata();
} else if (evt.type == event_type::QUIT) { } else if (evt.type == event_type::QUIT) {
if (evt.flag) { if (evt.flag) {
on(signals::eventqueue::exit_reload{}); on(signals::eventqueue::exit_reload{});
@ -763,7 +770,7 @@ bool controller::on(const signals::ui::button_press& evt) {
return false; return false;
} }
enqueue(move(input)); trigger_action(move(input));
return true; return true;
} }
@ -779,7 +786,7 @@ bool controller::on(const signals::ipc::action& evt) {
} }
m_log.info("Enqueuing ipc action: %s", action); m_log.info("Enqueuing ipc action: %s", action);
enqueue(move(action)); trigger_action(move(action));
return true; return true;
} }