diff --git a/include/vkcv/Event.hpp b/include/vkcv/Event.hpp index e324917674cd2e1773ee23a9411ab28f6eb0d684..b66e4e6579d887f3beee5cdd20c88dff361bd3b9 100644 --- a/include/vkcv/Event.hpp +++ b/include/vkcv/Event.hpp @@ -1,6 +1,7 @@ #pragma once #include <functional> +#include <mutex> namespace vkcv { @@ -26,6 +27,7 @@ namespace vkcv { private: std::vector< event_function<T...> > m_functions; uint32_t m_id_counter; + std::mutex m_mutex; public: @@ -34,9 +36,13 @@ namespace vkcv { * @param arguments of the given function */ void operator()(T... arguments) { + lock(); + for (auto &function : this->m_functions) { function.callback(arguments...); - } + } + + unlock(); } /** @@ -64,6 +70,20 @@ namespace vkcv { this->m_functions.end() ); } + + /** + * locks the event so its function handles won't be called + */ + void lock() { + m_mutex.lock(); + } + + /** + * unlocks the event so its function handles can be called after locking + */ + void unlock() { + m_mutex.unlock(); + } event() = default; diff --git a/include/vkcv/Window.hpp b/include/vkcv/Window.hpp index bc5223826bca406e8d44142cff0f3829a3ea6208..7dc6c1b7dc8fef4d5de7de5b0a9976bf714e6ac2 100644 --- a/include/vkcv/Window.hpp +++ b/include/vkcv/Window.hpp @@ -7,6 +7,7 @@ #define NOMINMAX #include <algorithm> + #include "Event.hpp" struct GLFWwindow; @@ -23,8 +24,6 @@ namespace vkcv { */ explicit Window(GLFWwindow *window); - static GLFWwindow* createGLFWWindow(const char *windowTitle, int width, int height, bool resizable); - private: /** * mouse callback for moving the mouse on the screen @@ -99,11 +98,6 @@ namespace vkcv { [[nodiscard]] bool isWindowOpen() const; - /** - * binds windowEvents to lambda events - */ - void initEvents(); - /** * polls all events on the GLFWwindow */ diff --git a/projects/first_mesh/src/main.cpp b/projects/first_mesh/src/main.cpp index 4834e4b85e09f1eca123e40f684a464d40ec9a0d..dc43c905784525a34732bc0e66343fbdcc17a639 100644 --- a/projects/first_mesh/src/main.cpp +++ b/projects/first_mesh/src/main.cpp @@ -18,8 +18,6 @@ int main(int argc, const char** argv) { true ); - window.initEvents(); - vkcv::Core core = vkcv::Core::create( window, applicationName, diff --git a/projects/first_triangle/src/main.cpp b/projects/first_triangle/src/main.cpp index 89e1b8d43d71685a6cdd2e2f7c10fda90716ce60..20cfdddf5c1baa9e8727312daa36de94bd56672f 100644 --- a/projects/first_triangle/src/main.cpp +++ b/projects/first_triangle/src/main.cpp @@ -19,8 +19,6 @@ int main(int argc, const char** argv) { false ); - window.initEvents(); - vkcv::Core core = vkcv::Core::create( window, applicationName, diff --git a/src/vkcv/Window.cpp b/src/vkcv/Window.cpp index bca207443e4462405229bfd502adbacaee9e37e8..03ac915aea5e89e2c5b0927cafe52e56454d49b5 100644 --- a/src/vkcv/Window.cpp +++ b/src/vkcv/Window.cpp @@ -9,64 +9,74 @@ namespace vkcv { - static uint32_t s_WindowCount = 0; + static std::vector<GLFWwindow*> s_Windows; Window::Window(GLFWwindow *window) : m_window(window) { + glfwSetWindowUserPointer(m_window, this); + + // combine Callbacks with Events + glfwSetMouseButtonCallback(m_window, Window::onMouseButtonEvent); + glfwSetCursorPosCallback(m_window, Window::onMouseMoveEvent); + glfwSetWindowSizeCallback(m_window, Window::onResize); + glfwSetKeyCallback(m_window, Window::onKeyEvent); + glfwSetScrollCallback(m_window, Window::onMouseScrollEvent); + glfwSetCharCallback(m_window, Window::onCharEvent); + + glfwSetJoystickCallback(nullptr); + glfwSetJoystickUserPointer(GLFW_JOYSTICK_1, this); } Window::~Window() { + s_Windows.erase(std::find(s_Windows.begin(), s_Windows.end(), m_window)); glfwDestroyWindow(m_window); - s_WindowCount--; - if(s_WindowCount == 0) { + if(s_Windows.empty()) { glfwTerminate(); } } - - GLFWwindow* Window::createGLFWWindow(const char *windowTitle, int width, int height, bool resizable) { - if(s_WindowCount == 0) { + + Window Window::create( const char *windowTitle, int width, int height, bool resizable) { + if(s_Windows.empty()) { glfwInit(); } - s_WindowCount++; - width = std::max(width, 1); height = std::max(height, 1); glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); glfwWindowHint(GLFW_RESIZABLE, resizable ? GLFW_TRUE : GLFW_FALSE); - - return glfwCreateWindow(width, height, windowTitle, nullptr, nullptr); - } - - Window Window::create( const char *windowTitle, int width, int height, bool resizable) { - return Window(createGLFWWindow(windowTitle, width, height, resizable)); - } - - void Window::initEvents() { - glfwSetWindowUserPointer(m_window, this); - - // combine Callbacks with Events - glfwSetMouseButtonCallback(m_window, Window::onMouseButtonEvent); - - glfwSetCursorPosCallback(m_window, Window::onMouseMoveEvent); - - glfwSetWindowSizeCallback(m_window, Window::onResize); - - glfwSetKeyCallback(m_window, Window::onKeyEvent); - - glfwSetScrollCallback(m_window, Window::onMouseScrollEvent); + GLFWwindow *window = glfwCreateWindow(width, height, windowTitle, nullptr, nullptr); - glfwSetCharCallback(m_window, Window::onCharEvent); - - glfwSetJoystickCallback(nullptr); // use this before to avoid crashing - glfwSetJoystickUserPointer(GLFW_JOYSTICK_1, this); + s_Windows.push_back(window); + + return Window(window); } void Window::pollEvents() { - onGamepadEvent(GLFW_JOYSTICK_1); + onGamepadEvent(GLFW_JOYSTICK_1); + + for (auto glfwWindow : s_Windows) { + auto window = static_cast<Window *>(glfwGetWindowUserPointer(glfwWindow)); + + window->e_mouseButton.unlock(); + window->e_mouseMove.unlock(); + window->e_resize.unlock(); + window->e_key.unlock(); + window->e_mouseScroll.unlock(); + } + glfwPollEvents(); + + for (auto glfwWindow : s_Windows) { + auto window = static_cast<Window *>(glfwGetWindowUserPointer(glfwWindow)); + + window->e_mouseButton.lock(); + window->e_mouseMove.lock(); + window->e_resize.lock(); + window->e_key.lock(); + window->e_mouseScroll.lock(); + } } void Window::onMouseButtonEvent(GLFWwindow *callbackWindow, int button, int action, int mods) {