Files
spacetris/src/core/InputManager.h

105 lines
3.7 KiB
C++

#pragma once
#include <SDL3/SDL.h>
#include <unordered_map>
#include <functional>
#include <vector>
/**
* InputManager - Centralized input handling system
*
* Responsibilities:
* - Process SDL events and maintain input state
* - Provide clean interface for input queries
* - Handle keyboard and mouse input
* - Support event handler registration
* - Implement game-specific input logic (DAS/ARR)
*/
class InputManager {
public:
// Event handler types
using KeyHandler = std::function<void(SDL_Scancode key, bool pressed)>;
using MouseButtonHandler = std::function<void(int button, bool pressed, float x, float y)>;
using MouseMotionHandler = std::function<void(float x, float y, float deltaX, float deltaY)>;
using WindowEventHandler = std::function<void(const SDL_WindowEvent& event)>;
using QuitHandler = std::function<void()>;
InputManager();
~InputManager() = default;
// Core input processing
void processEvents();
void update(float deltaTime);
// Keyboard state queries
bool isKeyPressed(SDL_Scancode key) const; // True only on the frame key was pressed
bool isKeyReleased(SDL_Scancode key) const; // True only on the frame key was released
bool isKeyHeld(SDL_Scancode key) const; // True while key is down
// Mouse state queries
bool isMouseButtonPressed(int button) const;
bool isMouseButtonReleased(int button) const;
bool isMouseButtonHeld(int button) const;
void getMousePosition(float& x, float& y) const;
void getMouseDelta(float& deltaX, float& deltaY) const;
// Event handler registration
void registerKeyHandler(KeyHandler handler);
void registerMouseButtonHandler(MouseButtonHandler handler);
void registerMouseMotionHandler(MouseMotionHandler handler);
void registerWindowEventHandler(WindowEventHandler handler);
void registerQuitHandler(QuitHandler handler);
// Game-specific input utilities (DAS/ARR system for Tetris)
struct DASState {
bool isActive = false;
float delayTimer = 0.0f;
float repeatTimer = 0.0f;
SDL_Scancode activeKey = SDL_SCANCODE_UNKNOWN;
};
void configureDAS(float delayMs, float repeatMs);
bool checkDASMovement(SDL_Scancode leftKey, SDL_Scancode rightKey, int& direction);
// Application control
bool shouldQuit() const { return m_shouldQuit; }
void requestQuit() { m_shouldQuit = true; }
private:
// Input state tracking
std::unordered_map<SDL_Scancode, bool> m_currentKeyState;
std::unordered_map<SDL_Scancode, bool> m_previousKeyState;
std::unordered_map<int, bool> m_currentMouseState;
std::unordered_map<int, bool> m_previousMouseState;
// Mouse position tracking
float m_mouseX = 0.0f;
float m_mouseY = 0.0f;
float m_mouseDeltaX = 0.0f;
float m_mouseDeltaY = 0.0f;
// Event handlers
std::vector<KeyHandler> m_keyHandlers;
std::vector<MouseButtonHandler> m_mouseButtonHandlers;
std::vector<MouseMotionHandler> m_mouseMotionHandlers;
std::vector<WindowEventHandler> m_windowEventHandlers;
std::vector<QuitHandler> m_quitHandlers;
// Application state
bool m_shouldQuit = false;
// DAS/ARR system for Tetris-style movement
DASState m_dasState;
float m_dasDelay = 170.0f; // Default DAS delay in ms
float m_dasRepeat = 40.0f; // Default ARR (Auto Repeat Rate) in ms
// Helper methods
void handleKeyEvent(const SDL_KeyboardEvent& event);
void handleMouseButtonEvent(const SDL_MouseButtonEvent& event);
void handleMouseMotionEvent(const SDL_MouseMotionEvent& event);
void handleWindowEvent(const SDL_WindowEvent& event);
void updateInputState();
void updateDAS(float deltaTime);
void resetDAS();
};