Skip to content

Commit 582d506

Browse files
committed
add an event listener
1 parent a6c1d4b commit 582d506

File tree

10 files changed

+131
-18
lines changed

10 files changed

+131
-18
lines changed

CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,9 @@ add_executable(Reactor src/core/main.cpp
4747
src/vulkan/UniformManager.cpp
4848
src/vulkan/UniformManager.hpp
4949
src/vulkan/ShaderModule.cpp
50-
src/vulkan/ShaderModule.hpp)
50+
src/vulkan/ShaderModule.hpp
51+
src/core/EventManager.hpp
52+
src/core/EventManager.cpp)
5153

5254
target_link_libraries(Reactor PRIVATE Vulkan::Vulkan Vulkan::Headers glfw fmt::fmt spdlog::spdlog GPUOpen::VulkanMemoryAllocator glm::glm)
5355
target_link_libraries(Reactor PRIVATE imgui::imgui)

src/core/EventManager.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#include "EventManager.hpp"
2+
3+
namespace reactor {
4+
5+
void EventManager::subscribe(EventType type, IEventListener *listener) {
6+
m_listeners[type].push_back(listener);
7+
}
8+
9+
void EventManager::unsubscribe(EventType type, IEventListener *listener) {
10+
auto& listeners = m_listeners[type];
11+
listeners.erase(std::remove(listeners.begin(), listeners.end(), listener), listeners.end());
12+
}
13+
14+
void EventManager::post(const Event &event) {
15+
if (m_listeners.find(event.type) == m_listeners.end()) {
16+
// no listeners, so nothing to do.
17+
return;
18+
}
19+
20+
for (auto listener : m_listeners.at(event.type)) {
21+
listener->onEvent(event);
22+
}
23+
24+
}
25+
26+
27+
28+
}

src/core/EventManager.hpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#pragma once
2+
#include <unordered_map>
3+
#include <vector>
4+
5+
namespace reactor {
6+
7+
enum class EventType {
8+
MouseMoved,
9+
KeyPressed,
10+
KeyReleased,
11+
};
12+
13+
struct Event {
14+
EventType type;
15+
union {
16+
struct {
17+
double x, y;
18+
} mouseMove;
19+
struct {
20+
int key;
21+
} keyboard;
22+
};
23+
};
24+
25+
class IEventListener {
26+
public:
27+
virtual ~IEventListener() = default;
28+
virtual void onEvent(const Event& event) = 0;
29+
};
30+
31+
class EventManager {
32+
public:
33+
void subscribe(EventType type, IEventListener* listener);
34+
void unsubscribe(EventType type, IEventListener* listener);
35+
void post(const Event& event);
36+
37+
private:
38+
std::unordered_map<EventType, std::vector<IEventListener*>> m_listeners;
39+
};
40+
41+
}

src/core/Window.cpp

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33

44
namespace reactor {
55
// The constructor initializes GLFW and creates the window.
6-
Window::Window(int width, int height, std::string title) : m_title(std::move(title)) {
6+
Window::Window(int width, int height, std::string title, EventManager& eventManager) :
7+
m_width(width), m_height(height), m_title(title), m_eventManager(eventManager) {
78
// Initialize the GLFW library.
89
if (!glfwInit()) {
910
throw std::runtime_error("Failed to initialize GLFW!");
@@ -19,12 +20,11 @@ namespace reactor {
1920
throw std::runtime_error("Failed to create GLFW window!");
2021
}
2122

22-
// Store a pointer to this Window instance in the GLFW window's user data.
23-
// This allows us to retrieve it in the static callback.
2423
glfwSetWindowUserPointer(m_window, this);
25-
26-
// Set the static callback function for framebuffer resize events.
2724
glfwSetFramebufferSizeCallback(m_window, framebufferResizeCallback);
25+
26+
glfwSetKeyCallback(m_window, keyCallback);
27+
glfwSetCursorPosCallback(m_window, mouseButtonCallback);
2828
}
2929

3030
// The destructor cleans up GLFW resources.
@@ -59,12 +59,38 @@ namespace reactor {
5959

6060

6161
// This is the static callback that GLFW invokes when the window is resized.
62-
void Window::framebufferResizeCallback(GLFWwindow* window, int width, int height) {
62+
void Window::framebufferResizeCallback(GLFWwindow *window, int width, int height) {
6363
// Retrieve the pointer to our Window class instance.
64-
auto* windowInstance = static_cast<Window*>(glfwGetWindowUserPointer(window));
64+
auto *windowInstance = static_cast<Window *>(glfwGetWindowUserPointer(window));
6565
if (windowInstance) {
6666
// Set the flag indicating that a resize has occurred.
6767
windowInstance->m_framebufferResized = true;
6868
}
6969
}
70-
}
70+
void Window::keyCallback(GLFWwindow *window, int key, int scancode, int action, int mods) {
71+
auto* windowInstance = static_cast<Window*>(glfwGetWindowUserPointer(window));
72+
if (!windowInstance) return;
73+
74+
Event event{};
75+
if (action == GLFW_PRESS) {
76+
event.type = EventType::KeyPressed;
77+
event.keyboard.key = key;
78+
windowInstance->m_eventManager.post(event);
79+
} else if (action == GLFW_RELEASE) {
80+
event.type = EventType::KeyReleased;
81+
event.keyboard.key = key;
82+
windowInstance->m_eventManager.post(event);
83+
}
84+
85+
}
86+
void Window::mouseButtonCallback(GLFWwindow *window, double xpos, double ypos) {
87+
auto* windowInstance = static_cast<Window*>(glfwGetWindowUserPointer(window));
88+
if (!windowInstance) return;
89+
Event event{};
90+
event.type = EventType::MouseMoved;
91+
event.mouseMove.x = xpos;
92+
event.mouseMove.y = ypos;
93+
windowInstance->m_eventManager.post(event);
94+
95+
}
96+
} // namespace reactor

src/core/Window.hpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,15 @@
66
#define WINDOW_HPP
77

88
#include <string>
9-
#include <functional>
109
#include <vulkan/vulkan.hpp>
10+
#include "EventManager.hpp"
1111

1212
namespace reactor {
1313

14+
1415
class Window {
1516
public:
16-
Window(int width, int height, std::string title);
17+
Window(int width, int height, std::string title, EventManager& eventManager);
1718
~Window();
1819

1920
// Prevent copying and moving to ensure a single owner for the window resource.
@@ -50,8 +51,13 @@ namespace reactor {
5051
private:
5152
// This is the static callback function that GLFW will call on resize events.
5253
static void framebufferResizeCallback(GLFWwindow* window, int width, int height);
54+
static void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods);
55+
static void mouseButtonCallback(GLFWwindow* window, double xpos, double ypos);
5356

5457
GLFWwindow* m_window = nullptr;
58+
EventManager& m_eventManager;
59+
int m_width;
60+
int m_height;
5561
std::string m_title;
5662
bool m_framebufferResized = false;
5763
};

src/vulkan/Buffer.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88

99
namespace reactor {
1010

11-
Buffer::Buffer(Allocator &allocator, vk::DeviceSize size, vk::BufferUsageFlags usage, VmaMemoryUsage memoryUsage)
12-
: m_allocator(allocator), m_size(size)
11+
Buffer::Buffer(Allocator &allocator, vk::DeviceSize size, vk::BufferUsageFlags usage, VmaMemoryUsage memoryUsage, std::string name)
12+
: m_allocator(allocator), m_size(size), m_name(name)
1313
{
1414
vk::BufferCreateInfo bufferInfo = {};
1515
bufferInfo.size = size;
@@ -36,7 +36,7 @@ namespace reactor {
3636
if (m_buffer && m_allocation) {
3737
vmaDestroyBuffer(m_allocator.get(), m_buffer, m_allocation);
3838

39-
spdlog::info("Buffer destroyed");
39+
spdlog::info("Buffer {} destroyed", m_name.c_str());
4040

4141
m_buffer = nullptr;
4242
m_allocation = nullptr;

src/vulkan/Buffer.hpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@ namespace reactor {
88

99
class Buffer {
1010
public:
11-
Buffer(Allocator& allocator, vk::DeviceSize size, vk::BufferUsageFlags usage, VmaMemoryUsage memoryUsage);
11+
Buffer(Allocator& allocator, vk::DeviceSize size, vk::BufferUsageFlags usage, VmaMemoryUsage memoryUsage, std::string name="");
1212

1313
~Buffer();
1414

15+
[[nodiscard]] const std::string& getName() const { return m_name; }
16+
1517
// Non-copyable
1618
Buffer(const Buffer&) = delete;
1719
Buffer& operator=(const Buffer&) = delete;
@@ -27,6 +29,8 @@ class Buffer {
2729
vk::Buffer m_buffer = VK_NULL_HANDLE;
2830
VmaAllocation m_allocation = VK_NULL_HANDLE;
2931
vk::DeviceSize m_size = 0;
32+
33+
std::string m_name;
3034
};
3135

3236
} // reactor

src/vulkan/UniformManager.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ std::vector<std::unique_ptr<Buffer>>
1717
m_allocator,
1818
size,
1919
vk::BufferUsageFlagBits::eUniformBuffer,
20-
VmaMemoryUsage::VMA_MEMORY_USAGE_CPU_TO_GPU));
20+
VMA_MEMORY_USAGE_CPU_TO_GPU, "Uniform buffer"));
2121
}
2222
return buffers;
2323
}

src/vulkan/VulkanRenderer.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,13 @@ VulkanRenderer::VulkanRenderer(const RendererConfig &config) : m_config(config)
2727
}
2828

2929
void VulkanRenderer::createCoreVulkanObjects() {
30+
m_eventManager = std::make_unique<EventManager>();
3031
m_window =
31-
std::make_unique<Window>(static_cast<int>(m_config.windowWidth),
32-
static_cast<int>(m_config.windowHeight), m_config.windowTitle);
32+
std::make_unique<Window>(
33+
m_config.windowWidth,
34+
m_config.windowHeight,
35+
m_config.windowTitle,
36+
*m_eventManager);
3337
m_context = std::make_unique<VulkanContext>(m_window->getNativeWindow());
3438
m_allocator = std::make_unique<Allocator>(m_context->physicalDevice(), m_context->device(),
3539
m_context->instance());

src/vulkan/VulkanRenderer.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <memory>
88

99
#include "../core/Window.hpp"
10+
#include "../core/EventManager.hpp"
1011
#include "../imgui/Imgui.hpp"
1112
#include "Allocator.hpp"
1213
#include "DescriptorSet.hpp"
@@ -44,6 +45,7 @@ class VulkanRenderer {
4445

4546
private:
4647
RendererConfig m_config{};
48+
std::unique_ptr<EventManager> m_eventManager;
4749
std::unique_ptr<VulkanContext> m_context;
4850
std::unique_ptr<Window> m_window;
4951
std::unique_ptr<Swapchain> m_swapchain;

0 commit comments

Comments
 (0)