diff --git a/src/Application.cpp b/src/Application.cpp index d3a2420..f7a55d2 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -1,14 +1,37 @@ #include "Application.hpp" #include +#include 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) { 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; diff --git a/src/Application.hpp b/src/Application.hpp index 959bcf6..3535f56 100644 --- a/src/Application.hpp +++ b/src/Application.hpp @@ -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); + bool wake(); + void queue_microtask(std::function callback) { m_microtasks.push(callback); } int turn(); int run(); @@ -29,6 +33,11 @@ private: std::vector> 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> m_microtasks; }; } \ No newline at end of file