aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorWBoerenkamps <wrj.boerenkamps@student.avans.nl>2024-12-07 20:39:19 +0100
committerWBoerenkamps <wrj.boerenkamps@student.avans.nl>2024-12-07 20:39:19 +0100
commit666292e33d6997a61d9eaff31e8180a602656474 (patch)
treedfe0f1cca9b3f8cecf0467fc598598caa32027af /src
parentfdb4c99e139a264d4e15e6913a3756fc6cccb2f2 (diff)
save
Diffstat (limited to 'src')
-rw-r--r--src/crepe/api/Event.h97
-rw-r--r--src/crepe/api/Transform.h8
-rw-r--r--src/crepe/facade/SDLContext.cpp134
-rw-r--r--src/crepe/facade/SDLContext.h35
-rw-r--r--src/crepe/system/InputSystem.cpp102
-rw-r--r--src/test/EventTest.cpp39
-rw-r--r--src/test/InputTest.cpp586
7 files changed, 550 insertions, 451 deletions
diff --git a/src/crepe/api/Event.h b/src/crepe/api/Event.h
index f2f3daf..265e925 100644
--- a/src/crepe/api/Event.h
+++ b/src/crepe/api/Event.h
@@ -4,7 +4,7 @@
#include <string>
#include "KeyCodes.h"
-
+#include "types.h"
namespace crepe {
/**
@@ -38,11 +38,8 @@ public:
*/
class MousePressEvent : public Event {
public:
- //! X-coordinate of the mouse position at the time of the event.
- int mouse_x = 0;
-
- //! Y-coordinate of the mouse position at the time of the event.
- int mouse_y = 0;
+ //! mouse position
+ ivec2 mouse_pos = {0,0};
//! The mouse button that was pressed.
MouseButton button = MouseButton::NONE;
@@ -53,11 +50,8 @@ public:
*/
class MouseClickEvent : public Event {
public:
- //! X-coordinate of the mouse position at the time of the event.
- int mouse_x = 0;
-
- //! Y-coordinate of the mouse position at the time of the event.
- int mouse_y = 0;
+ //! mouse position
+ ivec2 mouse_pos = {0,0};
//! The mouse button that was clicked.
MouseButton button = MouseButton::NONE;
@@ -68,11 +62,8 @@ public:
*/
class MouseReleaseEvent : public Event {
public:
- //! X-coordinate of the mouse position at the time of the event.
- int mouse_x = 0;
-
- //! Y-coordinate of the mouse position at the time of the event.
- int mouse_y = 0;
+ //! mouse position
+ ivec2 mouse_pos = {0,0};
//! The mouse button that was released.
MouseButton button = MouseButton::NONE;
@@ -83,17 +74,10 @@ public:
*/
class MouseMoveEvent : public Event {
public:
- //! X-coordinate of the mouse position at the time of the event.
- int mouse_x = 0;
-
- //! Y-coordinate of the mouse position at the time of the event.
- int mouse_y = 0;
-
- // Movement since last event in x
- int delta_x = 0;
-
- // Movement since last event in y
- int delta_y = 0;
+ //! new mouse position
+ ivec2 mouse_pos = {0,0};
+ //! The change in mouse position relative to the last position (in pixels).
+ ivec2 mouse_delta = {0,0};
};
/**
@@ -101,12 +85,8 @@ public:
*/
class MouseScrollEvent : public Event {
public:
- //! X-coordinate of the mouse position at the time of the event.
- int mouse_x = 0;
-
- //! Y-coordinate of the mouse position at the time of the event.
- int mouse_y = 0;
-
+ //! mouse position when the scroll happened.
+ ivec2 mouse_pos = {0,0};
//! scroll direction (-1 = down, 1 = up)
int scroll_direction = 0;
//! scroll amount in y axis (from and away from the person).
@@ -127,4 +107,55 @@ public:
*/
class ShutDownEvent : public Event {};
+/**
+ * \brief Event triggered to indicate the window is overlapped by another window.
+ *
+ * When two windows overlap the bottom window gets distorted and that window has to be redrawn.
+ */
+class WindowExposeEvent : public Event{};
+
+/**
+ * \brief Event triggered to indicate the window is resized.
+ */
+class WindowResizeEvent : public Event{
+ public:
+ //! new window dimensions
+ ivec2 dimensions = {0,0};
+};
+
+/**
+ * \brief Event triggered to indicate the window is moved.
+ */
+class WindowMoveEvent : public Event{
+ public:
+ //! The change in position relative to the last position (in pixels).
+ ivec2 delta_move = {0,0};
+};
+
+/**
+ * \brief Event triggered to indicate the window is minimized.
+ */
+class WindowMinimizeEvent : public Event{};
+
+/**
+ * \brief Event triggered to indicate the window is maximized
+ */
+class WindowMaximizeEvent : public Event{};
+
+/**
+ * \brief Event triggered to indicate the window gained focus
+ *
+ * This event is triggered when the window receives focus, meaning it becomes the active window
+ * for user interaction.
+ */
+class WindowFocusGainEvent : public Event{};
+
+/**
+ * \brief Event triggered to indicate the window lost focus
+ *
+ * This event is triggered when the window loses focus, meaning it is no longer the active window
+ * for user interaction.
+ */
+class WindowFocusLostEvent : public Event{};
+
} // namespace crepe
diff --git a/src/crepe/api/Transform.h b/src/crepe/api/Transform.h
index 7ee6d65..78407ee 100644
--- a/src/crepe/api/Transform.h
+++ b/src/crepe/api/Transform.h
@@ -13,6 +13,14 @@ namespace crepe {
*/
class Transform : public Component {
public:
+ //! Specifies the coordinate space for transformations.
+ enum Space {
+ //! coordinates are relative to the active camera
+ HUD,
+ //! coordinates are relative to the game world
+ WORLD,
+ };
+ Space coordinate_space = Space::WORLD;
//! Translation (shift)
vec2 position = {0, 0};
//! Rotation, in degrees clockwise
diff --git a/src/crepe/facade/SDLContext.cpp b/src/crepe/facade/SDLContext.cpp
index 4cc2206..e3410cb 100644
--- a/src/crepe/facade/SDLContext.cpp
+++ b/src/crepe/facade/SDLContext.cpp
@@ -375,65 +375,83 @@ ivec2 SDLContext::get_size(const Texture & ctx) {
void SDLContext::delay(int ms) const { SDL_Delay(ms); }
std::vector<SDLContext::EventData> SDLContext::get_events() {
- std::vector<SDLContext::EventData> event_list;
- SDL_Event event;
- while (SDL_PollEvent(&event)) {
- switch (event.type) {
- case SDL_QUIT:
- event_list.push_back(EventData{
- .event_type = SDLContext::EventType::SHUTDOWN,
- });
- break;
- case SDL_KEYDOWN:
- event_list.push_back(EventData{
- .event_type = SDLContext::EventType::KEYDOWN,
- .key = sdl_to_keycode(event.key.keysym.scancode),
- .key_repeat = (event.key.repeat != 0),
- });
- break;
- case SDL_KEYUP:
- event_list.push_back(EventData{
- .event_type = SDLContext::EventType::KEYUP,
- .key = sdl_to_keycode(event.key.keysym.scancode),
- });
- break;
- case SDL_MOUSEBUTTONDOWN:
- event_list.push_back(EventData{
- .event_type = SDLContext::EventType::MOUSEDOWN,
- .mouse_button = sdl_to_mousebutton(event.button.button),
- .mouse_position = {event.button.x, event.button.y},
- });
- break;
- case SDL_MOUSEBUTTONUP: {
- int x, y;
- SDL_GetMouseState(&x, &y);
- event_list.push_back(EventData{
- .event_type = SDLContext::EventType::MOUSEUP,
- .mouse_button = sdl_to_mousebutton(event.button.button),
- .mouse_position = {event.button.x, event.button.y},
- });
- } break;
-
- case SDL_MOUSEMOTION: {
- event_list.push_back(
- EventData{.event_type = SDLContext::EventType::MOUSEMOVE,
- .mouse_position = {event.motion.x, event.motion.y},
- .rel_mouse_move = {event.motion.xrel, event.motion.yrel}});
- } break;
-
- case SDL_MOUSEWHEEL: {
- event_list.push_back(EventData{
- .event_type = SDLContext::EventType::MOUSEWHEEL,
- .mouse_position = {event.motion.x, event.motion.y},
- // TODO: why is this needed?
- .scroll_direction = event.wheel.y < 0 ? -1 : 1,
- .scroll_delta = event.wheel.preciseY,
- });
- } break;
- }
- }
- return event_list;
+ std::vector<SDLContext::EventData> event_list;
+ SDL_Event event;
+
+ // Handle general SDL events
+ while (SDL_PollEvent(&event)) {
+ switch (event.type) {
+ case SDL_QUIT:
+ event_list.push_back({SDLContext::EventType::SHUTDOWN, {}, {}, {}});
+ break;
+ case SDL_KEYDOWN:
+ event_list.push_back({SDLContext::EventType::KEYDOWN,
+ {sdl_to_keycode(event.key.keysym.scancode), event.key.repeat != 0}, {}, {}});
+ break;
+ case SDL_KEYUP:
+ event_list.push_back({SDLContext::EventType::KEYUP,
+ {sdl_to_keycode(event.key.keysym.scancode), false}, {}, {}});
+ break;
+ case SDL_MOUSEBUTTONDOWN:
+ event_list.push_back({SDLContext::EventType::MOUSEDOWN, {},
+ {sdl_to_mousebutton(event.button.button), {event.button.x, event.button.y}}, {}});
+ break;
+ case SDL_MOUSEBUTTONUP:
+ event_list.push_back({SDLContext::EventType::MOUSEUP, {},
+ {sdl_to_mousebutton(event.button.button), {event.button.x, event.button.y}}, {}});
+ break;
+ case SDL_MOUSEMOTION:
+ event_list.push_back({SDLContext::EventType::MOUSEMOVE, {},
+ {{}, {event.motion.x, event.motion.y}, -1, INFINITY, {event.motion.xrel, event.motion.yrel}}, {}});
+ break;
+ case SDL_MOUSEWHEEL:
+ event_list.push_back({SDLContext::EventType::MOUSEWHEEL, {},
+ {{}, {}, event.wheel.y < 0 ? -1 : 1, event.wheel.preciseY, {}}, {}});
+ break;
+
+ // Forward window events for further processing
+ case SDL_WINDOWEVENT:
+ handle_window_event(event.window, event_list);
+ break;
+ }
+ }
+
+ return event_list;
+}
+
+// Separate function for SDL_WINDOWEVENT subtypes
+void SDLContext::handle_window_event(const SDL_WindowEvent& window_event,
+ std::vector<SDLContext::EventData>& event_list) {
+ switch (window_event.event) {
+ case SDL_WINDOWEVENT_EXPOSED:
+ event_list.push_back({SDLContext::EventType::WINDOW_EXPOSE, {}, {}, {}});
+ break;
+ case SDL_WINDOWEVENT_RESIZED:
+ event_list.push_back({SDLContext::EventType::WINDOW_RESIZE, {}, {},
+ {{}, {window_event.data1, window_event.data2}}});
+ break;
+ case SDL_WINDOWEVENT_MOVED:
+ event_list.push_back({SDLContext::EventType::WINDOW_MOVE, {}, {},
+ {{window_event.data1, window_event.data2}, {}}});
+ break;
+ case SDL_WINDOWEVENT_MINIMIZED:
+ event_list.push_back({SDLContext::EventType::WINDOW_MINIMIZE, {}, {}, {}});
+ break;
+ case SDL_WINDOWEVENT_MAXIMIZED:
+ event_list.push_back({SDLContext::EventType::WINDOW_MAXIMIZE, {}, {}, {}});
+ break;
+ case SDL_WINDOWEVENT_FOCUS_GAINED:
+ event_list.push_back({SDLContext::EventType::WINDOW_FOCUS_GAIN, {}, {}, {}});
+ break;
+ case SDL_WINDOWEVENT_FOCUS_LOST:
+ event_list.push_back({SDLContext::EventType::WINDOW_FOCUS_LOST, {}, {}, {}});
+ break;
+ }
}
+
+
+
+
void SDLContext::set_color_texture(const Texture & texture, const Color & color) {
SDL_SetTextureColorMod(texture.texture.get(), color.r, color.g, color.b);
SDL_SetTextureAlphaMod(texture.texture.get(), color.a);
diff --git a/src/crepe/facade/SDLContext.h b/src/crepe/facade/SDLContext.h
index e232511..1f83985 100644
--- a/src/crepe/facade/SDLContext.h
+++ b/src/crepe/facade/SDLContext.h
@@ -79,19 +79,37 @@ public:
KEYUP,
KEYDOWN,
SHUTDOWN,
-
+ WINDOW_MINIMIZE,
+ WINDOW_MAXIMIZE,
+ WINDOW_FOCUS_GAIN,
+ WINDOW_FOCUS_LOST,
+ WINDOW_MOVE,
+ WINDOW_RESIZE,
+ WINDOW_EXPOSE,
};
- //! EventData struct for passing event data from facade
- struct EventData {
- SDLContext::EventType event_type = SDLContext::EventType::NONE;
+ struct KeyData{
Keycode key = Keycode::NONE;
bool key_repeat = false;
+ };
+ struct MouseData{
MouseButton mouse_button = MouseButton::NONE;
ivec2 mouse_position = {-1, -1};
int scroll_direction = -1;
float scroll_delta = INFINITY;
ivec2 rel_mouse_move = {-1, -1};
};
+ struct WindowData{
+ ivec2 move_delta;
+ ivec2 resize_dimension;
+ };
+ //! EventData struct for passing event data from facade
+ struct EventData {
+ SDLContext::EventType event_type = SDLContext::EventType::NONE;
+ KeyData key_data;
+ MouseData mouse_data;
+ WindowData window_data;
+ };
+
/**
* \brief Gets the singleton instance of SDLContext.
* \return Reference to the SDLContext instance.
@@ -116,7 +134,14 @@ private:
* \return Events that occurred since last call to `get_events()`
*/
std::vector<SDLContext::EventData> get_events();
-
+ /**
+ * \brief Fills event_list with triggered window events
+ *
+ * This method checks if any window events are triggered and adds them to the event_list.
+ *
+ */
+ void handle_window_event(const SDL_WindowEvent& window_event,
+ std::vector<SDLContext::EventData>& event_list);
/**
* \brief Converts an SDL key code to the custom Keycode type.
*
diff --git a/src/crepe/system/InputSystem.cpp b/src/crepe/system/InputSystem.cpp
index aaa8bdf..b7d2eb4 100644
--- a/src/crepe/system/InputSystem.cpp
+++ b/src/crepe/system/InputSystem.cpp
@@ -26,29 +26,31 @@ void InputSystem::update() {
Transform & cam_transform = transform_vec.front().get();
int camera_origin_x = cam_transform.position.x + current_cam.data.postion_offset.x
- (current_cam.viewport_size.x / 2);
- int camera_origin_y = cam_transform.position.y + current_cam.data.postion_offset.y
+ int camera_origin_y =
+ ivec2 camera_origin;
+ camera_origin.y = cam_transform.position.y + current_cam.data.postion_offset.y
- (current_cam.viewport_size.y / 2);
-
+ camera_origin
for (const SDLContext::EventData & event : event_list) {
- int world_mouse_x = event.mouse_position.x + camera_origin_x;
- int world_mouse_y = event.mouse_position.y + camera_origin_y;
+ int adjusted_mouse_x = event.mouse_data.mouse_position.x + camera_origin_x;
+ int adjusted_mouse_y = event.mouse_data.mouse_position.y + camera_origin_y;
// check if the mouse is within the viewport
bool mouse_in_viewport
- = !(world_mouse_x < camera_origin_x
- || world_mouse_x > camera_origin_x + current_cam.viewport_size.x
- || world_mouse_y < camera_origin_y
- || world_mouse_y > camera_origin_y + current_cam.viewport_size.y);
+ = !(adjusted_mouse_x < camera_origin_x
+ || adjusted_mouse_x > camera_origin_x + current_cam.viewport_size.x
+ || adjusted_mouse_y < camera_origin_y
+ || adjusted_mouse_y > camera_origin_y + current_cam.viewport_size.y);
switch (event.event_type) {
case SDLContext::EventType::KEYDOWN:
event_mgr.queue_event<KeyPressEvent>(KeyPressEvent{
- .repeat = event.key_repeat,
- .key = event.key,
+ .repeat = event.key_data.key_repeat,
+ .key = event.key_data.key,
});
break;
case SDLContext::EventType::KEYUP:
event_mgr.queue_event<KeyReleaseEvent>(KeyReleaseEvent{
- .key = event.key,
+ .key = event.key_data.key,
});
break;
case SDLContext::EventType::MOUSEDOWN:
@@ -56,36 +58,32 @@ void InputSystem::update() {
break;
}
event_mgr.queue_event<MousePressEvent>(MousePressEvent{
- .mouse_x = world_mouse_x,
- .mouse_y = world_mouse_y,
- .button = event.mouse_button,
+ .mouse_pos = {adjusted_mouse_x,adjusted_mouse_y},
+ .button = event.mouse_data.mouse_button,
});
- this->last_mouse_down_position = {world_mouse_x, world_mouse_y};
- this->last_mouse_button = event.mouse_button;
+ this->last_mouse_down_position = {adjusted_mouse_x, adjusted_mouse_y};
+ this->last_mouse_button = event.mouse_data.mouse_button;
break;
case SDLContext::EventType::MOUSEUP: {
if (!mouse_in_viewport) {
break;
}
event_mgr.queue_event<MouseReleaseEvent>(MouseReleaseEvent{
- .mouse_x = world_mouse_x,
- .mouse_y = world_mouse_y,
- .button = event.mouse_button,
+ .mouse_pos = {adjusted_mouse_x,adjusted_mouse_y},
+ .button = event.mouse_data.mouse_button,
});
- //check if its a click by checking the last button down
- int delta_x = world_mouse_x - this->last_mouse_down_position.x;
- int delta_y = world_mouse_y - this->last_mouse_down_position.y;
+ int delta_x = adjusted_mouse_x - this->last_mouse_down_position.x;
+ int delta_y = adjusted_mouse_y - this->last_mouse_down_position.y;
- if (this->last_mouse_button == event.mouse_button
+ if (this->last_mouse_button == event.mouse_data.mouse_button
&& std::abs(delta_x) <= click_tolerance
&& std::abs(delta_y) <= click_tolerance) {
event_mgr.queue_event<MouseClickEvent>(MouseClickEvent{
- .mouse_x = world_mouse_x,
- .mouse_y = world_mouse_y,
- .button = event.mouse_button,
+ .mouse_pos = {adjusted_mouse_x,adjusted_mouse_y},
+ .button = event.mouse_data.mouse_button,
});
- this->handle_click(event.mouse_button, world_mouse_x, world_mouse_y);
+ this->handle_click(event.mouse_data.mouse_button, adjusted_mouse_x, adjusted_mouse_y);
}
} break;
case SDLContext::EventType::MOUSEMOVE:
@@ -93,31 +91,53 @@ void InputSystem::update() {
break;
}
event_mgr.queue_event<MouseMoveEvent>(MouseMoveEvent{
- .mouse_x = world_mouse_x,
- .mouse_y = world_mouse_y,
- .delta_x = event.rel_mouse_move.x,
- .delta_y = event.rel_mouse_move.y,
+ .mouse_pos = {adjusted_mouse_x,adjusted_mouse_y},
+ .mouse_delta = event.mouse_data.rel_mouse_move,
});
- this->handle_move(event, world_mouse_x, world_mouse_y);
+ this->handle_move(event, adjusted_mouse_x, adjusted_mouse_y);
break;
case SDLContext::EventType::MOUSEWHEEL:
event_mgr.queue_event<MouseScrollEvent>(MouseScrollEvent{
- .mouse_x = world_mouse_x,
- .mouse_y = world_mouse_y,
- .scroll_direction = event.scroll_direction,
- .scroll_delta = event.scroll_delta,
+ .mouse_pos = {adjusted_mouse_x,adjusted_mouse_y},
+ .scroll_direction = event.mouse_data.scroll_direction,
+ .scroll_delta = event.mouse_data.scroll_delta,
});
break;
case SDLContext::EventType::SHUTDOWN:
event_mgr.queue_event<ShutDownEvent>(ShutDownEvent{});
break;
+ case SDLContext::EventType::WINDOW_EXPOSE:
+ event_mgr.queue_event<WindowExposeEvent>(WindowExposeEvent{});
+ break;
+ case SDLContext::EventType::WINDOW_RESIZE:
+ event_mgr.queue_event<WindowResizeEvent>(WindowResizeEvent{
+ .dimensions = event.window_data.resize_dimension,
+ });
+ break;
+ case SDLContext::EventType::WINDOW_MOVE:
+ event_mgr.queue_event<WindowMoveEvent>(WindowMoveEvent{
+ .delta_move = event.window_data.move_delta,
+ });
+ break;
+ case SDLContext::EventType::WINDOW_MINIMIZE:
+ event_mgr.queue_event<WindowMinimizeEvent>(WindowMinimizeEvent{});
+ break;
+ case SDLContext::EventType::WINDOW_MAXIMIZE:
+ event_mgr.queue_event<WindowMaximizeEvent>(WindowMaximizeEvent{});
+ break;
+ case SDLContext::EventType::WINDOW_FOCUS_GAIN:
+ event_mgr.queue_event<WindowFocusGainEvent>(WindowFocusGainEvent{});
+ break;
+ case SDLContext::EventType::WINDOW_FOCUS_LOST:
+ event_mgr.queue_event<WindowFocusLostEvent>(WindowFocusLostEvent{});
+ break;
default:
break;
}
}
}
void InputSystem::handle_move(const SDLContext::EventData & event_data,
- const int world_mouse_x, const int world_mouse_y) {
+ const int adjusted_mouse_x, const int adjusted_mouse_y) {
ComponentManager & mgr = this->mediator.component_manager;
RefVector<Button> buttons = mgr.get_components_by_type<Button>();
@@ -129,7 +149,7 @@ void InputSystem::handle_move(const SDLContext::EventData & event_data,
bool was_hovering = button.hover;
if (button.active
- && this->is_mouse_inside_button(world_mouse_x, world_mouse_y, button, transform)) {
+ && this->is_mouse_inside_button(adjusted_mouse_x, adjusted_mouse_y, button, transform)) {
button.hover = true;
if (!was_hovering && button.on_mouse_enter) {
button.on_mouse_enter();
@@ -144,8 +164,8 @@ void InputSystem::handle_move(const SDLContext::EventData & event_data,
}
}
-void InputSystem::handle_click(const MouseButton & mouse_button, const int world_mouse_x,
- const int world_mouse_y) {
+void InputSystem::handle_click(const MouseButton & mouse_button, const int adjusted_mouse_x,
+ const int adjusted_mouse_y) {
ComponentManager & mgr = this->mediator.component_manager;
RefVector<Button> buttons = mgr.get_components_by_type<Button>();
@@ -156,7 +176,7 @@ void InputSystem::handle_click(const MouseButton & mouse_button, const int world
Transform & transform = transform_vec.front().get();
if (button.active
- && this->is_mouse_inside_button(world_mouse_x, world_mouse_y, button, transform)) {
+ && this->is_mouse_inside_button(adjusted_mouse_x, adjusted_mouse_y, button, transform)) {
this->handle_button_press(button);
}
}
diff --git a/src/test/EventTest.cpp b/src/test/EventTest.cpp
index 4a4872d..53c2469 100644
--- a/src/test/EventTest.cpp
+++ b/src/test/EventTest.cpp
@@ -63,16 +63,15 @@ TEST_F(EventManagerTest, EventManagerTest_trigger_all_channels) {
EventHandler<MouseClickEvent> mouse_handler = [&](const MouseClickEvent & e) {
triggered = true;
- EXPECT_EQ(e.mouse_x, 100);
- EXPECT_EQ(e.mouse_y, 200);
+ EXPECT_EQ(e.mouse_pos.x, 100);
+ EXPECT_EQ(e.mouse_pos.y, 200);
EXPECT_EQ(e.button, MouseButton::LEFT_MOUSE);
return false;
};
EventManager::get_instance().subscribe<MouseClickEvent>(mouse_handler,
EventManager::CHANNEL_ALL);
- MouseClickEvent click_event{
- .mouse_x = 100, .mouse_y = 200, .button = MouseButton::LEFT_MOUSE};
+ MouseClickEvent click_event{.mouse_pos = {100,200}, .button = MouseButton::LEFT_MOUSE};
EventManager::get_instance().trigger_event<MouseClickEvent>(click_event,
EventManager::CHANNEL_ALL);
@@ -83,15 +82,14 @@ TEST_F(EventManagerTest, EventManagerTest_trigger_one_channel) {
int test_channel = 1;
EventHandler<MouseClickEvent> mouse_handler = [&](const MouseClickEvent & e) {
triggered = true;
- EXPECT_EQ(e.mouse_x, 100);
- EXPECT_EQ(e.mouse_y, 200);
+ EXPECT_EQ(e.mouse_pos.x, 100);
+ EXPECT_EQ(e.mouse_pos.y, 200);
EXPECT_EQ(e.button, MouseButton::LEFT_MOUSE);
return false;
};
EventManager::get_instance().subscribe<MouseClickEvent>(mouse_handler, test_channel);
- MouseClickEvent click_event{
- .mouse_x = 100, .mouse_y = 200, .button = MouseButton::LEFT_MOUSE};
+ MouseClickEvent click_event{.mouse_pos = {100,200}, .button = MouseButton::LEFT_MOUSE};
EventManager::get_instance().trigger_event<MouseClickEvent>(click_event,
EventManager::CHANNEL_ALL);
@@ -109,23 +107,22 @@ TEST_F(EventManagerTest, EventManagerTest_callback_propagation) {
// Handlers
EventHandler<MouseClickEvent> mouse_handler_true = [&](const MouseClickEvent & e) {
triggered_true = true;
- EXPECT_EQ(e.mouse_x, 100);
- EXPECT_EQ(e.mouse_y, 200);
+ EXPECT_EQ(e.mouse_pos.x, 100);
+ EXPECT_EQ(e.mouse_pos.y, 200);
EXPECT_EQ(e.button, MouseButton::LEFT_MOUSE);
return true; // Stops propagation
};
EventHandler<MouseClickEvent> mouse_handler_false = [&](const MouseClickEvent & e) {
triggered_false = true;
- EXPECT_EQ(e.mouse_x, 100);
- EXPECT_EQ(e.mouse_y, 200);
+ EXPECT_EQ(e.mouse_pos.x, 100);
+ EXPECT_EQ(e.mouse_pos.y, 200);
EXPECT_EQ(e.button, MouseButton::LEFT_MOUSE);
return false; // Allows propagation
};
// Test event
- MouseClickEvent click_event{
- .mouse_x = 100, .mouse_y = 200, .button = MouseButton::LEFT_MOUSE};
+ MouseClickEvent click_event{.mouse_pos = {100,200}, .button = MouseButton::LEFT_MOUSE};
event_manager.subscribe<MouseClickEvent>(mouse_handler_true, EventManager::CHANNEL_ALL);
event_manager.subscribe<MouseClickEvent>(mouse_handler_false, EventManager::CHANNEL_ALL);
@@ -201,16 +198,16 @@ TEST_F(EventManagerTest, EventManagerTest_unsubscribe) {
// Define EventHandlers
EventHandler<MouseClickEvent> mouse_handler1 = [&](const MouseClickEvent & e) {
triggered1 = true;
- EXPECT_EQ(e.mouse_x, 100);
- EXPECT_EQ(e.mouse_y, 200);
+ EXPECT_EQ(e.mouse_pos.x, 100);
+ EXPECT_EQ(e.mouse_pos.y, 200);
EXPECT_EQ(e.button, MouseButton::LEFT_MOUSE);
return false; // Allows propagation
};
EventHandler<MouseClickEvent> mouse_handler2 = [&](const MouseClickEvent & e) {
triggered2 = true;
- EXPECT_EQ(e.mouse_x, 100);
- EXPECT_EQ(e.mouse_y, 200);
+ EXPECT_EQ(e.mouse_pos.x, 100);
+ EXPECT_EQ(e.mouse_pos.y, 200);
EXPECT_EQ(e.button, MouseButton::LEFT_MOUSE);
return false; // Allows propagation
};
@@ -220,7 +217,7 @@ TEST_F(EventManagerTest, EventManagerTest_unsubscribe) {
// Queue events
event_manager.queue_event<MouseClickEvent>(
- MouseClickEvent{.mouse_x = 100, .mouse_y = 200, .button = MouseButton::LEFT_MOUSE});
+ MouseClickEvent{.mouse_pos = {100,200}, .button = MouseButton::LEFT_MOUSE});
// Dispatch events - both handlers should be triggered
event_manager.dispatch_events();
@@ -236,7 +233,7 @@ TEST_F(EventManagerTest, EventManagerTest_unsubscribe) {
// Queue the same event again
event_manager.queue_event<MouseClickEvent>(
- MouseClickEvent{.mouse_x = 100, .mouse_y = 200, .button = MouseButton::LEFT_MOUSE});
+ MouseClickEvent{.mouse_pos = {100,200}, .button = MouseButton::LEFT_MOUSE});
// Dispatch events - only handler 2 should be triggered, handler 1 should NOT
event_manager.dispatch_events();
@@ -251,7 +248,7 @@ TEST_F(EventManagerTest, EventManagerTest_unsubscribe) {
// Queue the event again
event_manager.queue_event<MouseClickEvent>(
- MouseClickEvent{.mouse_x = 100, .mouse_y = 200, .button = MouseButton::LEFT_MOUSE});
+ MouseClickEvent{.mouse_pos = {100,200}, .button = MouseButton::LEFT_MOUSE});
// Dispatch events - no handler should be triggered
event_manager.dispatch_events();
diff --git a/src/test/InputTest.cpp b/src/test/InputTest.cpp
index a7c0157..0b48d5b 100644
--- a/src/test/InputTest.cpp
+++ b/src/test/InputTest.cpp
@@ -1,293 +1,293 @@
-#include <gtest/gtest.h>
-#define protected public
-#define private public
-#include "api/KeyCodes.h"
-#include "manager/ComponentManager.h"
-#include "manager/EventManager.h"
-#include "manager/Mediator.h"
-#include "system/InputSystem.h"
-#include <SDL2/SDL.h>
-#include <SDL2/SDL_keycode.h>
-#include <crepe/api/Button.h>
-#include <crepe/api/Camera.h>
-#include <crepe/api/GameObject.h>
-#include <crepe/api/Metadata.h>
-#include <crepe/api/Transform.h>
-#include <crepe/api/Vector2.h>
-#include <gmock/gmock.h>
-
-using namespace std;
-using namespace std::chrono_literals;
-using namespace crepe;
-
-class InputTest : public ::testing::Test {
-public:
- Mediator mediator;
- ComponentManager mgr{mediator};
-
- InputSystem input_system{mediator};
-
- EventManager & event_manager = EventManager::get_instance();
- //GameObject camera;
-
-protected:
- void SetUp() override {
- mediator.event_manager = event_manager;
- mediator.component_manager = mgr;
- event_manager.clear();
- }
-
- void simulate_mouse_click(int mouse_x, int mouse_y, Uint8 mouse_button) {
- SDL_Event event;
-
- // Simulate Mouse Button Down event
- SDL_zero(event);
- event.type = SDL_MOUSEBUTTONDOWN;
- event.button.x = mouse_x;
- event.button.y = mouse_y;
- event.button.button = mouse_button;
- SDL_PushEvent(&event);
-
- // Simulate Mouse Button Up event
- SDL_zero(event);
- event.type = SDL_MOUSEBUTTONUP;
- event.button.x = mouse_x;
- event.button.y = mouse_y;
- event.button.button = mouse_button;
- SDL_PushEvent(&event);
- }
-};
-
-TEST_F(InputTest, MouseDown) {
- GameObject obj = mgr.new_object("camera", "camera", vec2{0, 0}, 0, 1);
- auto & camera = obj.add_component<Camera>(
- ivec2{100, 100}, vec2{100, 100}, Camera::Data{.bg_color = Color::WHITE, .zoom = 1.0f});
- camera.active = true;
- bool mouse_triggered = false;
- EventHandler<MousePressEvent> on_mouse_down = [&](const MousePressEvent & event) {
- mouse_triggered = true;
- //middle of the screen = 0,0
- EXPECT_EQ(event.mouse_x, 0);
- EXPECT_EQ(event.mouse_y, 0);
- EXPECT_EQ(event.button, MouseButton::LEFT_MOUSE);
- return false;
- };
- event_manager.subscribe<MousePressEvent>(on_mouse_down);
-
- SDL_Event event;
- SDL_zero(event);
- event.type = SDL_MOUSEBUTTONDOWN;
- // middle of the screen of a 500*500 camera = 250*250
- event.button.x = 250;
- event.button.y = 250;
- event.button.button = SDL_BUTTON_LEFT;
- SDL_PushEvent(&event);
-
- input_system.update();
- event_manager.dispatch_events();
- EXPECT_TRUE(mouse_triggered);
-}
-
-TEST_F(InputTest, MouseUp) {
- GameObject obj = mgr.new_object("camera", "camera", vec2{0, 0}, 0, 1);
- auto & camera = obj.add_component<Camera>(
- ivec2{100, 100}, vec2{100, 100}, Camera::Data{.bg_color = Color::WHITE, .zoom = 1.0f});
- camera.active = true;
- bool function_triggered = false;
- EventHandler<MouseReleaseEvent> on_mouse_release = [&](const MouseReleaseEvent & e) {
- function_triggered = true;
- EXPECT_EQ(e.mouse_x, 0);
- EXPECT_EQ(e.mouse_y, 0);
- EXPECT_EQ(e.button, MouseButton::LEFT_MOUSE);
- return false;
- };
- event_manager.subscribe<MouseReleaseEvent>(on_mouse_release);
-
- SDL_Event event;
- SDL_zero(event);
- event.type = SDL_MOUSEBUTTONUP;
- event.button.x = 250;
- event.button.y = 250;
- event.button.button = SDL_BUTTON_LEFT;
- SDL_PushEvent(&event);
-
- input_system.update();
- event_manager.dispatch_events();
- EXPECT_TRUE(function_triggered);
-}
-
-TEST_F(InputTest, MouseMove) {
- GameObject obj = mgr.new_object("camera", "camera", vec2{0, 0}, 0, 1);
- auto & camera = obj.add_component<Camera>(
- ivec2{100, 100}, vec2{100, 100}, Camera::Data{.bg_color = Color::WHITE, .zoom = 1.0f});
- camera.active = true;
- bool function_triggered = false;
- EventHandler<MouseMoveEvent> on_mouse_move = [&](const MouseMoveEvent & e) {
- function_triggered = true;
- EXPECT_EQ(e.mouse_x, 0);
- EXPECT_EQ(e.mouse_y, 0);
- EXPECT_EQ(e.delta_x, 10);
- EXPECT_EQ(e.delta_y, 10);
- return false;
- };
- event_manager.subscribe<MouseMoveEvent>(on_mouse_move);
-
- SDL_Event event;
- SDL_zero(event);
- event.type = SDL_MOUSEMOTION;
- event.motion.x = 250;
- event.motion.y = 250;
- event.motion.xrel = 10;
- event.motion.yrel = 10;
- SDL_PushEvent(&event);
-
- input_system.update();
- event_manager.dispatch_events();
- EXPECT_TRUE(function_triggered);
-}
-
-TEST_F(InputTest, KeyDown) {
- GameObject obj = mgr.new_object("camera", "camera", vec2{0, 0}, 0, 1);
- auto & camera = obj.add_component<Camera>(
- ivec2{100, 100}, vec2{100, 100}, Camera::Data{.bg_color = Color::WHITE, .zoom = 1.0f});
- camera.active = true;
- bool function_triggered = false;
-
- // Define event handler for KeyPressEvent
- EventHandler<KeyPressEvent> on_key_press = [&](const KeyPressEvent & event) {
- function_triggered = true;
- EXPECT_EQ(event.key, Keycode::B); // Validate the key is 'B'
- EXPECT_EQ(event.repeat, true); // Validate repeat flag
- return false;
- };
-
- event_manager.subscribe<KeyPressEvent>(on_key_press);
-
- // Simulate SDL_KEYDOWN event
- SDL_Event test_event;
- SDL_zero(test_event);
- test_event.type = SDL_KEYDOWN; // Key down event
- test_event.key.keysym.scancode = SDL_SCANCODE_B; // Set scancode for 'B'
- test_event.key.repeat = 1; // Set repeat flag
- SDL_PushEvent(&test_event);
-
- input_system.update(); // Process the event
- event_manager.dispatch_events(); // Dispatch events to handlers
-
- EXPECT_TRUE(function_triggered); // Check if the handler was triggered
-}
-
-TEST_F(InputTest, KeyUp) {
- GameObject obj = mgr.new_object("camera", "camera", vec2{0, 0}, 0, 1);
- auto & camera = obj.add_component<Camera>(
- ivec2{100, 100}, vec2{100, 100}, Camera::Data{.bg_color = Color::WHITE, .zoom = 1.0f});
- camera.active = true;
- bool function_triggered = false;
- EventHandler<KeyReleaseEvent> on_key_release = [&](const KeyReleaseEvent & event) {
- function_triggered = true;
- EXPECT_EQ(event.key, Keycode::B);
- return false;
- };
- event_manager.subscribe<KeyReleaseEvent>(on_key_release);
-
- SDL_Event event;
- SDL_zero(event);
- event.type = SDL_KEYUP;
- event.key.keysym.scancode = SDL_SCANCODE_B;
- SDL_PushEvent(&event);
-
- input_system.update();
- event_manager.dispatch_events();
- EXPECT_TRUE(function_triggered);
-}
-
-TEST_F(InputTest, MouseClick) {
- GameObject obj = mgr.new_object("camera", "camera", vec2{0, 0}, 0, 1);
- auto & camera = obj.add_component<Camera>(
- ivec2{100, 100}, vec2{100, 100}, Camera::Data{.bg_color = Color::WHITE, .zoom = 1.0f});
- camera.active = true;
- bool on_click_triggered = false;
- EventHandler<MouseClickEvent> on_mouse_click = [&](const MouseClickEvent & event) {
- on_click_triggered = true;
- EXPECT_EQ(event.button, MouseButton::LEFT_MOUSE);
- EXPECT_EQ(event.mouse_x, 0);
- EXPECT_EQ(event.mouse_y, 0);
- return false;
- };
- event_manager.subscribe<MouseClickEvent>(on_mouse_click);
-
- this->simulate_mouse_click(250, 250, SDL_BUTTON_LEFT);
- input_system.update();
- event_manager.dispatch_events();
- EXPECT_TRUE(on_click_triggered);
-}
-
-TEST_F(InputTest, testButtonClick) {
- GameObject obj = mgr.new_object("camera", "camera", vec2{0, 0}, 0, 1);
- auto & camera = obj.add_component<Camera>(
- ivec2{100, 100}, vec2{100, 100}, Camera::Data{.bg_color = Color::WHITE, .zoom = 1.0f});
- camera.active = true;
- GameObject button_obj = mgr.new_object("body", "person", vec2{0, 0}, 0, 1);
- bool button_clicked = false;
- std::function<void()> on_click = [&]() { button_clicked = true; };
- auto & button
- = button_obj.add_component<Button>(vec2{100, 100}, vec2{0, 0}, on_click, false);
-
- bool hover = false;
- button.active = true;
-
- button.is_pressed = false;
- button.is_toggle = false;
- this->simulate_mouse_click(999, 999, SDL_BUTTON_LEFT);
- input_system.update();
- event_manager.dispatch_events();
- EXPECT_FALSE(button_clicked);
-
- this->simulate_mouse_click(250, 250, SDL_BUTTON_LEFT);
- input_system.update();
- event_manager.dispatch_events();
- EXPECT_TRUE(button_clicked);
-}
-
-TEST_F(InputTest, testButtonHover) {
- GameObject obj = mgr.new_object("camera", "camera", vec2{0, 0}, 0, 1);
- auto & camera = obj.add_component<Camera>(
- ivec2{100, 100}, vec2{100, 100}, Camera::Data{.bg_color = Color::WHITE, .zoom = 1.0f});
- camera.active = true;
- GameObject button_obj = mgr.new_object("body", "person", vec2{0, 0}, 0, 1);
- bool button_clicked = false;
- std::function<void()> on_click = [&]() { button_clicked = true; };
- auto & button
- = button_obj.add_component<Button>(vec2{100, 100}, vec2{0, 0}, on_click, false);
- button.active = true;
- button.is_pressed = false;
- button.is_toggle = false;
-
- // Mouse not on button
- SDL_Event event;
- SDL_zero(event);
- event.type = SDL_MOUSEMOTION;
- event.motion.x = 700;
- event.motion.y = 700;
- event.motion.xrel = 10;
- event.motion.yrel = 10;
- SDL_PushEvent(&event);
-
- input_system.update();
- event_manager.dispatch_events();
- EXPECT_FALSE(button.hover);
-
- // Mouse on button
- SDL_Event hover_event;
- SDL_zero(hover_event);
- hover_event.type = SDL_MOUSEMOTION;
- hover_event.motion.x = 250;
- hover_event.motion.y = 250;
- hover_event.motion.xrel = 10;
- hover_event.motion.yrel = 10;
- SDL_PushEvent(&hover_event);
-
- input_system.update();
- event_manager.dispatch_events();
- EXPECT_TRUE(button.hover);
-}
+// #include <gtest/gtest.h>
+// #define protected public
+// #define private public
+// #include "api/KeyCodes.h"
+// #include "manager/ComponentManager.h"
+// #include "manager/EventManager.h"
+// #include "manager/Mediator.h"
+// #include "system/InputSystem.h"
+// #include <SDL2/SDL.h>
+// #include <SDL2/SDL_keycode.h>
+// #include <crepe/api/Button.h>
+// #include <crepe/api/Camera.h>
+// #include <crepe/api/GameObject.h>
+// #include <crepe/api/Metadata.h>
+// #include <crepe/api/Transform.h>
+// #include <crepe/api/Vector2.h>
+// #include <gmock/gmock.h>
+
+// using namespace std;
+// using namespace std::chrono_literals;
+// using namespace crepe;
+
+// class InputTest : public ::testing::Test {
+// public:
+// Mediator mediator;
+// ComponentManager mgr{mediator};
+
+// InputSystem input_system{mediator};
+
+// EventManager & event_manager = EventManager::get_instance();
+// //GameObject camera;
+
+// protected:
+// void SetUp() override {
+// mediator.event_manager = event_manager;
+// mediator.component_manager = mgr;
+// event_manager.clear();
+// }
+
+// void simulate_mouse_click(int mouse_x, int mouse_y, Uint8 mouse_button) {
+// SDL_Event event;
+
+// // Simulate Mouse Button Down event
+// SDL_zero(event);
+// event.type = SDL_MOUSEBUTTONDOWN;
+// event.button.x = mouse_x;
+// event.button.y = mouse_y;
+// event.button.button = mouse_button;
+// SDL_PushEvent(&event);
+
+// // Simulate Mouse Button Up event
+// SDL_zero(event);
+// event.type = SDL_MOUSEBUTTONUP;
+// event.button.x = mouse_x;
+// event.button.y = mouse_y;
+// event.button.button = mouse_button;
+// SDL_PushEvent(&event);
+// }
+// };
+
+// TEST_F(InputTest, MouseDown) {
+// GameObject obj = mgr.new_object("camera", "camera", vec2{0, 0}, 0, 1);
+// auto & camera = obj.add_component<Camera>(
+// ivec2{100, 100}, vec2{100, 100}, Camera::Data{.bg_color = Color::WHITE, .zoom = 1.0f});
+// camera.active = true;
+// bool mouse_triggered = false;
+// EventHandler<MousePressEvent> on_mouse_down = [&](const MousePressEvent & event) {
+// mouse_triggered = true;
+// //middle of the screen = 0,0
+// EXPECT_EQ(event.mouse_x, 0);
+// EXPECT_EQ(event.mouse_y, 0);
+// EXPECT_EQ(event.button, MouseButton::LEFT_MOUSE);
+// return false;
+// };
+// event_manager.subscribe<MousePressEvent>(on_mouse_down);
+
+// SDL_Event event;
+// SDL_zero(event);
+// event.type = SDL_MOUSEBUTTONDOWN;
+// // middle of the screen of a 500*500 camera = 250*250
+// event.button.x = 250;
+// event.button.y = 250;
+// event.button.button = SDL_BUTTON_LEFT;
+// SDL_PushEvent(&event);
+
+// input_system.update();
+// event_manager.dispatch_events();
+// EXPECT_TRUE(mouse_triggered);
+// }
+
+// TEST_F(InputTest, MouseUp) {
+// GameObject obj = mgr.new_object("camera", "camera", vec2{0, 0}, 0, 1);
+// auto & camera = obj.add_component<Camera>(
+// ivec2{100, 100}, vec2{100, 100}, Camera::Data{.bg_color = Color::WHITE, .zoom = 1.0f});
+// camera.active = true;
+// bool function_triggered = false;
+// EventHandler<MouseReleaseEvent> on_mouse_release = [&](const MouseReleaseEvent & e) {
+// function_triggered = true;
+// EXPECT_EQ(e.mouse_x, 0);
+// EXPECT_EQ(e.mouse_y, 0);
+// EXPECT_EQ(e.button, MouseButton::LEFT_MOUSE);
+// return false;
+// };
+// event_manager.subscribe<MouseReleaseEvent>(on_mouse_release);
+
+// SDL_Event event;
+// SDL_zero(event);
+// event.type = SDL_MOUSEBUTTONUP;
+// event.button.x = 250;
+// event.button.y = 250;
+// event.button.button = SDL_BUTTON_LEFT;
+// SDL_PushEvent(&event);
+
+// input_system.update();
+// event_manager.dispatch_events();
+// EXPECT_TRUE(function_triggered);
+// }
+
+// TEST_F(InputTest, MouseMove) {
+// GameObject obj = mgr.new_object("camera", "camera", vec2{0, 0}, 0, 1);
+// auto & camera = obj.add_component<Camera>(
+// ivec2{100, 100}, vec2{100, 100}, Camera::Data{.bg_color = Color::WHITE, .zoom = 1.0f});
+// camera.active = true;
+// bool function_triggered = false;
+// EventHandler<MouseMoveEvent> on_mouse_move = [&](const MouseMoveEvent & e) {
+// function_triggered = true;
+// EXPECT_EQ(e.mouse_x, 0);
+// EXPECT_EQ(e.mouse_y, 0);
+// EXPECT_EQ(e.delta_x, 10);
+// EXPECT_EQ(e.delta_y, 10);
+// return false;
+// };
+// event_manager.subscribe<MouseMoveEvent>(on_mouse_move);
+
+// SDL_Event event;
+// SDL_zero(event);
+// event.type = SDL_MOUSEMOTION;
+// event.motion.x = 250;
+// event.motion.y = 250;
+// event.motion.xrel = 10;
+// event.motion.yrel = 10;
+// SDL_PushEvent(&event);
+
+// input_system.update();
+// event_manager.dispatch_events();
+// EXPECT_TRUE(function_triggered);
+// }
+
+// TEST_F(InputTest, KeyDown) {
+// GameObject obj = mgr.new_object("camera", "camera", vec2{0, 0}, 0, 1);
+// auto & camera = obj.add_component<Camera>(
+// ivec2{100, 100}, vec2{100, 100}, Camera::Data{.bg_color = Color::WHITE, .zoom = 1.0f});
+// camera.active = true;
+// bool function_triggered = false;
+
+// // Define event handler for KeyPressEvent
+// EventHandler<KeyPressEvent> on_key_press = [&](const KeyPressEvent & event) {
+// function_triggered = true;
+// EXPECT_EQ(event.key, Keycode::B); // Validate the key is 'B'
+// EXPECT_EQ(event.repeat, true); // Validate repeat flag
+// return false;
+// };
+
+// event_manager.subscribe<KeyPressEvent>(on_key_press);
+
+// // Simulate SDL_KEYDOWN event
+// SDL_Event test_event;
+// SDL_zero(test_event);
+// test_event.type = SDL_KEYDOWN; // Key down event
+// test_event.key.keysym.scancode = SDL_SCANCODE_B; // Set scancode for 'B'
+// test_event.key.repeat = 1; // Set repeat flag
+// SDL_PushEvent(&test_event);
+
+// input_system.update(); // Process the event
+// event_manager.dispatch_events(); // Dispatch events to handlers
+
+// EXPECT_TRUE(function_triggered); // Check if the handler was triggered
+// }
+
+// TEST_F(InputTest, KeyUp) {
+// GameObject obj = mgr.new_object("camera", "camera", vec2{0, 0}, 0, 1);
+// auto & camera = obj.add_component<Camera>(
+// ivec2{100, 100}, vec2{100, 100}, Camera::Data{.bg_color = Color::WHITE, .zoom = 1.0f});
+// camera.active = true;
+// bool function_triggered = false;
+// EventHandler<KeyReleaseEvent> on_key_release = [&](const KeyReleaseEvent & event) {
+// function_triggered = true;
+// EXPECT_EQ(event.key, Keycode::B);
+// return false;
+// };
+// event_manager.subscribe<KeyReleaseEvent>(on_key_release);
+
+// SDL_Event event;
+// SDL_zero(event);
+// event.type = SDL_KEYUP;
+// event.key.keysym.scancode = SDL_SCANCODE_B;
+// SDL_PushEvent(&event);
+
+// input_system.update();
+// event_manager.dispatch_events();
+// EXPECT_TRUE(function_triggered);
+// }
+
+// TEST_F(InputTest, MouseClick) {
+// GameObject obj = mgr.new_object("camera", "camera", vec2{0, 0}, 0, 1);
+// auto & camera = obj.add_component<Camera>(
+// ivec2{100, 100}, vec2{100, 100}, Camera::Data{.bg_color = Color::WHITE, .zoom = 1.0f});
+// camera.active = true;
+// bool on_click_triggered = false;
+// EventHandler<MouseClickEvent> on_mouse_click = [&](const MouseClickEvent & event) {
+// on_click_triggered = true;
+// EXPECT_EQ(event.button, MouseButton::LEFT_MOUSE);
+// EXPECT_EQ(event.mouse_x, 0);
+// EXPECT_EQ(event.mouse_y, 0);
+// return false;
+// };
+// event_manager.subscribe<MouseClickEvent>(on_mouse_click);
+
+// this->simulate_mouse_click(250, 250, SDL_BUTTON_LEFT);
+// input_system.update();
+// event_manager.dispatch_events();
+// EXPECT_TRUE(on_click_triggered);
+// }
+
+// TEST_F(InputTest, testButtonClick) {
+// GameObject obj = mgr.new_object("camera", "camera", vec2{0, 0}, 0, 1);
+// auto & camera = obj.add_component<Camera>(
+// ivec2{100, 100}, vec2{100, 100}, Camera::Data{.bg_color = Color::WHITE, .zoom = 1.0f});
+// camera.active = true;
+// GameObject button_obj = mgr.new_object("body", "person", vec2{0, 0}, 0, 1);
+// bool button_clicked = false;
+// std::function<void()> on_click = [&]() { button_clicked = true; };
+// auto & button
+// = button_obj.add_component<Button>(vec2{100, 100}, vec2{0, 0}, on_click, false);
+
+// bool hover = false;
+// button.active = true;
+
+// button.is_pressed = false;
+// button.is_toggle = false;
+// this->simulate_mouse_click(999, 999, SDL_BUTTON_LEFT);
+// input_system.update();
+// event_manager.dispatch_events();
+// EXPECT_FALSE(button_clicked);
+
+// this->simulate_mouse_click(250, 250, SDL_BUTTON_LEFT);
+// input_system.update();
+// event_manager.dispatch_events();
+// EXPECT_TRUE(button_clicked);
+// }
+
+// TEST_F(InputTest, testButtonHover) {
+// GameObject obj = mgr.new_object("camera", "camera", vec2{0, 0}, 0, 1);
+// auto & camera = obj.add_component<Camera>(
+// ivec2{100, 100}, vec2{100, 100}, Camera::Data{.bg_color = Color::WHITE, .zoom = 1.0f});
+// camera.active = true;
+// GameObject button_obj = mgr.new_object("body", "person", vec2{0, 0}, 0, 1);
+// bool button_clicked = false;
+// std::function<void()> on_click = [&]() { button_clicked = true; };
+// auto & button
+// = button_obj.add_component<Button>(vec2{100, 100}, vec2{0, 0}, on_click, false);
+// button.active = true;
+// button.is_pressed = false;
+// button.is_toggle = false;
+
+// // Mouse not on button
+// SDL_Event event;
+// SDL_zero(event);
+// event.type = SDL_MOUSEMOTION;
+// event.motion.x = 700;
+// event.motion.y = 700;
+// event.motion.xrel = 10;
+// event.motion.yrel = 10;
+// SDL_PushEvent(&event);
+
+// input_system.update();
+// event_manager.dispatch_events();
+// EXPECT_FALSE(button.hover);
+
+// // Mouse on button
+// SDL_Event hover_event;
+// SDL_zero(hover_event);
+// hover_event.type = SDL_MOUSEMOTION;
+// hover_event.motion.x = 250;
+// hover_event.motion.y = 250;
+// hover_event.motion.xrel = 10;
+// hover_event.motion.yrel = 10;
+// SDL_PushEvent(&hover_event);
+
+// input_system.update();
+// event_manager.dispatch_events();
+// EXPECT_TRUE(button.hover);
+// }