add application event loop "wake-up"
This commit is contained in:
parent
e76e2b43a1
commit
3fa1647fc9
2 changed files with 45 additions and 4 deletions
|
@ -1,14 +1,37 @@
|
|||
#include "Application.hpp"
|
||||
#include <poll.h>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace Raven {
|
||||
|
||||
bool Application::wake() {
|
||||
if (!m_wakeup_pipe_available) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t buf = 0;
|
||||
write(m_wakeup_pipe_write_end, &buf, 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Application::add_window(std::shared_ptr<Window> window) {
|
||||
m_windows.push_back(window);
|
||||
update_fds();
|
||||
}
|
||||
|
||||
void Application::update_fds() {
|
||||
if (m_should_create_wakeup_pipe) {
|
||||
m_should_create_wakeup_pipe = false;
|
||||
int pipe_fds[2];
|
||||
if (pipe(pipe_fds) != 0) {
|
||||
// TODO: handle this?
|
||||
return;
|
||||
}
|
||||
|
||||
m_wakeup_pipe_read_end = pipe_fds[0];
|
||||
m_wakeup_pipe_write_end = pipe_fds[1];
|
||||
m_wakeup_pipe_available = true;
|
||||
}
|
||||
for (int i = 0; i < RAVEN_APPLICATION_MAX_WINDOWS; i++) {
|
||||
m_fds[i].fd = -1;
|
||||
m_fds[i].events = 0;
|
||||
|
@ -18,6 +41,12 @@ void Application::update_fds() {
|
|||
m_fds[i].fd = m_windows[i]->file_descriptor();
|
||||
m_fds[i].events = POLL_IN;
|
||||
}
|
||||
if (m_wakeup_pipe_available) {
|
||||
int wakeup_pipe_index = m_windows.size();
|
||||
m_fds[wakeup_pipe_index].fd = m_wakeup_pipe_read_end;
|
||||
m_fds[wakeup_pipe_index].events = POLL_IN;
|
||||
m_fds[wakeup_pipe_index].revents = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int Application::turn() {
|
||||
|
@ -25,11 +54,14 @@ int Application::turn() {
|
|||
update_fds();
|
||||
m_fds_need_update = false;
|
||||
}
|
||||
if (poll(m_fds, m_windows.size(), -1) > 0) {
|
||||
if (poll(m_fds, m_windows.size() + 1, -1) > 0) {
|
||||
for (size_t i = 0; i < m_windows.size(); i++) {
|
||||
if (m_fds[i].revents & POLLIN) {
|
||||
m_windows[i]->run(false);
|
||||
}
|
||||
m_windows[i]->run(false);
|
||||
}
|
||||
while (!m_microtasks.empty()) {
|
||||
auto callback = m_microtasks.front();
|
||||
callback();
|
||||
m_microtasks.pop();
|
||||
}
|
||||
} else {
|
||||
return 1;
|
||||
|
|
|
@ -12,8 +12,12 @@ namespace Raven {
|
|||
class Application {
|
||||
public:
|
||||
Application() {}
|
||||
Application(bool should_create_wakeup_pipe)
|
||||
: m_should_create_wakeup_pipe(should_create_wakeup_pipe) {}
|
||||
|
||||
void add_window(std::shared_ptr<Window>);
|
||||
bool wake();
|
||||
void queue_microtask(std::function<void()> callback) { m_microtasks.push(callback); }
|
||||
int turn();
|
||||
int run();
|
||||
|
||||
|
@ -29,6 +33,11 @@ private:
|
|||
std::vector<std::shared_ptr<Window>> m_windows;
|
||||
struct pollfd m_fds[RAVEN_APPLICATION_MAX_WINDOWS];
|
||||
bool m_fds_need_update { true };
|
||||
bool m_should_create_wakeup_pipe { false };
|
||||
bool m_wakeup_pipe_available { false };
|
||||
int m_wakeup_pipe_read_end { -1 };
|
||||
int m_wakeup_pipe_write_end { -1 };
|
||||
std::queue<std::function<void()>> m_microtasks;
|
||||
};
|
||||
|
||||
}
|
Loading…
Reference in a new issue