diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/crepe/api/LoopManager.cpp | 4 | ||||
| -rw-r--r-- | src/crepe/facade/SDLContext.cpp | 78 | ||||
| -rw-r--r-- | src/crepe/facade/SDLContext.h | 36 | ||||
| -rw-r--r-- | src/crepe/system/InputSystem.cpp | 87 | ||||
| -rw-r--r-- | src/crepe/system/InputSystem.h | 7 | ||||
| -rw-r--r-- | src/test/inputTest.cpp | 53 | ||||
| -rw-r--r-- | src/test/loopTimerTest.cpp | 32 | 
7 files changed, 272 insertions, 25 deletions
| 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<PhysicsSystem>();  	this->load_system<RenderSystem>();  	this->load_system<ScriptSystem>(); +	this->load_system<InputSystem>();  }  void LoopManager::process_input() { -	SDLContext::get_instance().handle_events(this->game_running); +	this->get_system<InputSystem>().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>(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::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::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 <SDL2/SDL.h>  #include <SDL2/SDL_keycode.h>  #include <SDL2/SDL_render.h>  #include <SDL2/SDL_video.h> @@ -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<int,int> mouse_position = {-1,-1}; +		int wheel_delta = -1; +		std::pair<int,int> 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<SDLContext::EventData> 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<MouseClickEvent>([this](const MouseClickEvent &event) { -        return this->handle_click(event); -    }); - -    event_manager.subscribe<MouseMoveEvent>([this](const MouseMoveEvent &event) { -        return this->handle_move(event); -    }); -}  void InputSystem::update() { +	EventManager& event_mgr = EventManager::get_instance(); +    std::vector<SDLContext::EventData> 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<int, int> 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); diff --git a/src/test/inputTest.cpp b/src/test/inputTest.cpp new file mode 100644 index 0000000..0f02410 --- /dev/null +++ b/src/test/inputTest.cpp @@ -0,0 +1,53 @@ +#include <SDL2/SDL.h> +#include <SDL2/SDL_keycode.h> +#include "system/InputSystem.h" +#include "api/EventManager.h" +#include "api/KeyCodes.h" +#include <gmock/gmock.h> +#include <gtest/gtest.h> + +using namespace std; +using namespace std::chrono_literals; +using namespace crepe; + +class InputTest : public ::testing::Test { +public: +InputSystem input_system; +EventManager& event_manager = EventManager::get_instance(); +protected: +	void SetUp() override { +	} + +	void TearDown() override { +		 +	} +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); +    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, KeyDown) { + +	SDL_Event event; +	SDL_zero(event); +    event.type = SDL_MOUSEBUTTONDOWN; +    event.button.x = 10; +    event.button.y = 10; +    event.button.button = mouse_bu; +    SDL_PushEvent(&event);  // Push event into the SDL event queue +} diff --git a/src/test/loopTimerTest.cpp b/src/test/loopTimerTest.cpp new file mode 100644 index 0000000..a3b1646 --- /dev/null +++ b/src/test/loopTimerTest.cpp @@ -0,0 +1,32 @@ +#define private public +#define protected public +#include "api/LoopManager.h" +#include "api/LoopTimer.h" +#include <gmock/gmock.h> +#include <gtest/gtest.h> + +using namespace std; +using namespace std::chrono_literals; +using namespace crepe; + +class LoopTimerTest : public ::testing::Test { +public: +LoopTimer loop_timer = LoopTimer::get_instance(); +protected: +	void SetUp() override { +		loop_timer.start(); +	} + +	void TearDown() override { +		 +	} +}; +TEST_F(LoopTimerTest, TestDeltaTime) { +    auto start_time = std::chrono::steady_clock::now(); +     +    loop_timer.update();   +    double delta_time = loop_timer.get_delta_time(); + +    auto elapsed_time = std::chrono::steady_clock::now() - start_time; +    EXPECT_LE(delta_time, std::chrono::duration<double>(elapsed_time).count()); +} |