From 6287d4e9068d8bd27a9e62643f54adb69e84befd Mon Sep 17 00:00:00 2001 From: WBoerenkamps Date: Sun, 24 Nov 2024 22:08:49 +0100 Subject: input facade --- src/crepe/api/LoopManager.cpp | 4 +- src/crepe/facade/SDLContext.cpp | 78 ++++++++++++++++++++++++++++++++++- src/crepe/facade/SDLContext.h | 36 ++++++++++++++--- src/crepe/system/InputSystem.cpp | 87 ++++++++++++++++++++++++++++++++-------- src/crepe/system/InputSystem.h | 7 +++- 5 files changed, 187 insertions(+), 25 deletions(-) (limited to 'src/crepe') diff --git a/src/crepe/api/LoopManager.cpp b/src/crepe/api/LoopManager.cpp index a64366f..af306c0 100644 --- a/src/crepe/api/LoopManager.cpp +++ b/src/crepe/api/LoopManager.cpp @@ -6,6 +6,7 @@ #include "../system/PhysicsSystem.h" #include "../system/RenderSystem.h" #include "../system/ScriptSystem.h" +#include "../system/InputSystem.h" #include "LoopManager.h" #include "LoopTimer.h" @@ -20,10 +21,11 @@ LoopManager::LoopManager() { this->load_system(); this->load_system(); this->load_system(); + this->load_system(); } void LoopManager::process_input() { - SDLContext::get_instance().handle_events(this->game_running); + this->get_system().update(); } void LoopManager::start() { diff --git a/src/crepe/facade/SDLContext.cpp b/src/crepe/facade/SDLContext.cpp index 43ef3f1..3fb7f05 100644 --- a/src/crepe/facade/SDLContext.cpp +++ b/src/crepe/facade/SDLContext.cpp @@ -92,7 +92,6 @@ void SDLContext::handle_events(bool &running) { running = false; event_manager.trigger_event(ShutDownEvent{}); break; - case SDL_KEYDOWN: event_manager.trigger_event(KeyPressEvent{ .repeat = event.key.repeat, @@ -146,7 +145,6 @@ void SDLContext::handle_events(bool &running) { .direction = (event.wheel.direction == SDL_MOUSEWHEEL_FLIPPED ? -1 : 1) }); break; - } } } @@ -365,3 +363,79 @@ int SDLContext::get_height(const Texture & ctx) const { return h; } void SDLContext::delay(int ms) const { SDL_Delay(ms); } + +std::vector SDLContext::get_events(){ + std::vector event_list; + SDL_Event event; + while (SDL_PollEvent(&event)) { + switch (event.type) { + case SDL_QUIT: + event_list.push_back(EventData{ + .event_type = SDLContext::Event::SHUTDOWN, + }); + break; + case SDL_KEYDOWN: + event_list.push_back(EventData{ + .event_type = SDLContext::Event::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::Event::KEYUP, + .key = sdl_to_keycode(event.key.keysym.scancode), + }); + break; + case SDL_MOUSEBUTTONDOWN: + { + int x,y; + SDL_GetMouseState(&x, &y); + event_list.push_back(EventData{ + .event_type = SDLContext::Event::MOUSEDOWN, + .mouse_button = sdl_to_mousebutton(event.button.button), + .mouse_position = {x,y}, + }); + } + break; + case SDL_MOUSEBUTTONUP: + { + int x,y; + SDL_GetMouseState(&x, &y); + event_list.push_back(EventData{ + .event_type = SDLContext::Event::MOUSEUP, + .mouse_button = sdl_to_mousebutton(event.button.button), + .mouse_position = {x,y}, + }); + } + break; + + case SDL_MOUSEMOTION: + { + int x,y; + SDL_GetMouseState(&x, &y); + event_list.push_back(EventData{ + .event_type = SDLContext::Event::MOUSEMOVE, + .mouse_position = {x,y}, + }); + } + break; + + case SDL_MOUSEWHEEL: + { + int x, y; + SDL_GetMouseState(&x, &y); + + event_list.push_back(EventData{ + .event_type = SDLContext::Event::MOUSEWHEEL, + .mouse_position = {event.motion.x,event.motion.y}, + .wheel_delta = event.wheel.y, + .rel_mouse_move {event.motion.yrel,event.motion.xrel}, + }); + } + break; + } + } + return event_list; +} + diff --git a/src/crepe/facade/SDLContext.h b/src/crepe/facade/SDLContext.h index cce2fb6..dcd7440 100644 --- a/src/crepe/facade/SDLContext.h +++ b/src/crepe/facade/SDLContext.h @@ -1,5 +1,5 @@ #pragma once - +#include #include #include #include @@ -10,6 +10,8 @@ #include "../api/Sprite.h" #include "../api/KeyCodes.h" #include "../api/Transform.h" +#include "../api/Vector2.h" +#include "../api/Event.h" #include "api/Camera.h" // FIXME: this needs to be removed @@ -20,11 +22,11 @@ namespace crepe { // TODO: SDL_Keycode is defined in a header not distributed with crepe, which means this // typedef is unusable when crepe is packaged. Wouter will fix this later. -typedef SDL_Keycode CREPE_KEYCODES; +//typedef SDL_Keycode CREPE_KEYCODES; class Texture; class LoopManager; - +class InputSystem; /** * \class SDLContext * \brief Facade for the SDL library @@ -35,6 +37,26 @@ class LoopManager; class SDLContext { public: + enum Event{ + NONE = 0, + MOUSEDOWN, + MOUSEUP, + MOUSEMOVE, + MOUSEWHEEL, + KEYUP, + KEYDOWN, + SHUTDOWN + + }; + struct EventData { + SDLContext::Event event_type = SDLContext::Event::NONE; + Keycode key = Keycode::NONE; + bool key_repeat = false; + MouseButton mouse_button = MouseButton::NONE; + std::pair mouse_position = {-1,-1}; + int wheel_delta = -1; + std::pair rel_mouse_move = {-1,-1}; + }; /** * \brief Gets the singleton instance of SDLContext. * \return Reference to the SDLContext instance. @@ -48,15 +70,18 @@ public: private: //! will only use handle_events - friend class LoopManager; + friend class InputSystem; /** * \brief Handles SDL events such as window close and input. * \param running Reference to a boolean flag that controls the main loop. */ void handle_events(bool & running); + std::vector get_events(); + + Keycode get_key(); + Keycode get_mouse(); Keycode sdl_to_keycode(SDL_Keycode sdlKey); MouseButton sdl_to_mousebutton(Uint8 sdl_button); - private: //! Will only use get_ticks friend class AnimatorSystem; @@ -153,4 +178,5 @@ private: SDL_Rect viewport = {0, 0, 640, 480}; }; + } // namespace crepe diff --git a/src/crepe/system/InputSystem.cpp b/src/crepe/system/InputSystem.cpp index b7a86f4..c61a80f 100644 --- a/src/crepe/system/InputSystem.cpp +++ b/src/crepe/system/InputSystem.cpp @@ -2,26 +2,86 @@ #include "../api/Button.h" #include "../api/EventManager.h" #include "../api/Transform.h" +#include "../facade/SDLContext.h" #include "../api/Event.h" #include "system/InputSystem.h" using namespace crepe; -InputSystem::InputSystem(ComponentManager &component_manager) - : System(component_manager) { - auto &event_manager = EventManager::get_instance(); - event_manager.subscribe([this](const MouseClickEvent &event) { - return this->handle_click(event); - }); - - event_manager.subscribe([this](const MouseMoveEvent &event) { - return this->handle_move(event); - }); -} void InputSystem::update() { + EventManager& event_mgr = EventManager::get_instance(); + std::vector event_list = SDLContext::get_instance().get_events(); + + for (SDLContext::EventData event : event_list) { + switch (event.event_type) { + case SDLContext::Event::KEYDOWN: { + event_mgr.queue_event(KeyPressEvent{ + .key = event.key, + .repeat = event.key_repeat, + }); + break; + } + case SDLContext::Event::KEYUP: { + event_mgr.queue_event(KeyReleaseEvent{ + .key = event.key, + }); + break; + } + case SDLContext::Event::MOUSEDOWN: { + event_mgr.queue_event(MousePressEvent{ + .mouse_x = event.mouse_position.first, + .mouse_y = event.mouse_position.second, + .button = event.mouse_button, + }); + break; + } + case SDLContext::Event::MOUSEMOVE: { + event_mgr.queue_event(MouseMoveEvent{ + .mouse_x = event.mouse_position.first, + .mouse_y = event.mouse_position.second, + .rel_x = event.rel_mouse_move.first, + .rel_y = event.rel_mouse_move.second, + }); + break; + } + case SDLContext::Event::MOUSEUP: { + event_mgr.queue_event(MouseReleaseEvent{ + .mouse_x = event.mouse_position.first, + .mouse_y = event.mouse_position.second, + .button = event.mouse_button, + }); + int delta_x = event.mouse_position.first - last_mouse_down_position.first; + int delta_y = event.mouse_position.second - last_mouse_down_position.second; + if (last_mouse_button == event.mouse_button && + std::abs(delta_x) <= click_tolerance && + std::abs(delta_y) <= click_tolerance) { + event_mgr.queue_event(MouseClickEvent{ + .mouse_x = event.mouse_position.first, + .mouse_y = event.mouse_position.second, + .button = event.mouse_button, + }); + } + break; + } + case SDLContext::Event::MOUSEWHEEL: { + event_mgr.queue_event(MouseScrollEvent{ + .scroll_x = event.mouse_position.first, + .scroll_y = event.mouse_position.second, + .direction = event.wheel_delta, + }); + break; + } + case SDLContext::Event::SHUTDOWN: { + event_mgr.queue_event(ShutDownEvent{}); + break; + } + default: + break; + } + } } bool InputSystem::handle_click(const MouseClickEvent &event) { @@ -45,8 +105,3 @@ bool InputSystem::handle_click(const MouseClickEvent &event) { return false; } -bool InputSystem::handle_move(const MouseMoveEvent &event) { - - ComponentManager &mgr = this->component_manager; - -} diff --git a/src/crepe/system/InputSystem.h b/src/crepe/system/InputSystem.h index c50d928..231aa45 100644 --- a/src/crepe/system/InputSystem.h +++ b/src/crepe/system/InputSystem.h @@ -7,8 +7,13 @@ namespace crepe { class InputSystem : public System { public: using System::System; - InputSystem(ComponentManager & component_manager); void update() override; + void process_events(); + +private: + std::pair last_mouse_down_position{-1, -1}; + MouseButton last_mouse_button = MouseButton::NONE; + const int click_tolerance = 5; bool handle_click(const MouseClickEvent &event); bool handle_move(const MouseMoveEvent &event); bool handle_key_press(const KeyPressEvent &event); -- cgit v1.2.3