From a68ddf84441c1076ba7e334c294d2c260cd6a002 Mon Sep 17 00:00:00 2001 From: Tobias Frisch <tfrisch@uni-koblenz.de> Date: Fri, 4 Jun 2021 19:18:33 +0200 Subject: [PATCH] [#43] Synchronized window events with mutexes Signed-off-by: Tobias Frisch <tfrisch@uni-koblenz.de> --- include/vkcv/Event.hpp | 20 ++++++++++ include/vkcv/Window.hpp | 1 + projects/first_mesh/src/main.cpp | 2 - projects/first_triangle/src/main.cpp | 2 - src/vkcv/Window.cpp | 57 +++++++++++++++++----------- 5 files changed, 56 insertions(+), 26 deletions(-) diff --git a/include/vkcv/Event.hpp b/include/vkcv/Event.hpp index 0836e836..dfa1325a 100644 --- a/include/vkcv/Event.hpp +++ b/include/vkcv/Event.hpp @@ -1,6 +1,7 @@ #pragma once #include <functional> +#include <mutex> namespace vkcv { @@ -17,6 +18,7 @@ namespace vkcv { struct event { private: std::vector<typename event_function<T...>::type> m_handles; + std::mutex m_mutex; public: @@ -25,9 +27,13 @@ namespace vkcv { * @param arguments of the given function */ void operator()(T... arguments) { + lock(); + for (auto &handle : this->m_handles) { handle(arguments...); } + + unlock(); } /** @@ -49,6 +55,20 @@ namespace vkcv { this->m_handles.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 f71671c9..f11a38b7 100644 --- a/include/vkcv/Window.hpp +++ b/include/vkcv/Window.hpp @@ -7,6 +7,7 @@ #define NOMINMAX #include <algorithm> + #include "Event.hpp" struct GLFWwindow; diff --git a/projects/first_mesh/src/main.cpp b/projects/first_mesh/src/main.cpp index 01d8b74f..723bc9a5 100644 --- a/projects/first_mesh/src/main.cpp +++ b/projects/first_mesh/src/main.cpp @@ -17,8 +17,6 @@ int main(int argc, const char** argv) { vkcv::CameraManager cameraManager(window, static_cast<float>(window.getWidth()), static_cast<float>(window.getHeight())); - 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 397498e6..6c3b2272 100644 --- a/projects/first_triangle/src/main.cpp +++ b/projects/first_triangle/src/main.cpp @@ -18,8 +18,6 @@ int main(int argc, const char** argv) { vkcv::CameraManager cameraManager(window, windowWidth, windowHeight); - window.initEvents(); - vkcv::Core core = vkcv::Core::create( window, applicationName, diff --git a/src/vkcv/Window.cpp b/src/vkcv/Window.cpp index c21271b7..210178fa 100644 --- a/src/vkcv/Window.cpp +++ b/src/vkcv/Window.cpp @@ -10,55 +10,68 @@ 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); } 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(); } } Window Window::create( const char *windowTitle, int width, int height, bool resizable) { - if(s_WindowCount == 0) { + 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); - GLFWwindow *window; - window = glfwCreateWindow(width, height, windowTitle, nullptr, nullptr); + GLFWwindow *window = glfwCreateWindow(width, height, windowTitle, nullptr, nullptr); + + s_Windows.push_back(window); return Window(window); } - 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); - } - void Window::pollEvents() { + 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) { -- GitLab