From 780e02472f5f380e40ece8fb246ad4a3fe9c2268 Mon Sep 17 00:00:00 2001 From: ezveee Date: Tue, 28 Jan 2025 21:28:25 +0100 Subject: [PATCH] another sammelcommit weil ich wirklich ned gut gegittet hab --- include/InputManager.h | 14 ++- src/GameInternal.cpp | 12 +-- src/InputManager.cpp | 228 ++++++++++++++++++++++++++++++++++++++--- src/_Init.cpp | 2 + 4 files changed, 230 insertions(+), 26 deletions(-) diff --git a/include/InputManager.h b/include/InputManager.h index b81ba0f..1af5de8 100644 --- a/include/InputManager.h +++ b/include/InputManager.h @@ -5,6 +5,7 @@ #include #include #include +#include class InputManager { public: @@ -115,12 +116,23 @@ public: void rebindAction(const std::string& actionName, const std::vector& newBindings, const std::string& context); void removeBindings(const std::string& actionName, const std::string& context); std::vector getBindings(const std::string& actionName, const std::string& context) const; + std::vector getActionsByKey(const Key key) const; private: + // TODO: flesh this out to avoid loops in process actions + // additionally to actionsByContext, not instead std::map> actionsByContext; + std::map> actionsByKey; + std::map keyMap; std::string activeContext; void initKeyMap(); void handleEvent(const SDL_Event& event); -}; \ No newline at end of file +}; + +std::ostream& operator<<(std::ostream& os, InputManager::Key key); +std::ostream& operator<<(std::ostream& os, const InputManager::InputAction& action); +std::ostream& operator<<(std::ostream& os, const InputManager::InputAction* action); +std::ostream& operator<<(std::ostream& os, const std::vector& actions); +std::ostream& operator<<(std::ostream& os, const std::vector& actions); diff --git a/src/GameInternal.cpp b/src/GameInternal.cpp index 50908a9..a75c2dd 100644 --- a/src/GameInternal.cpp +++ b/src/GameInternal.cpp @@ -102,18 +102,10 @@ SDL_AppResult GameInternal::init(const char* title, int xpos, int ypos, int widt return SDL_APP_CONTINUE; } +// TODO: rework with InputManager void GameInternal::handleEvents() { - SDL_PollEvent(&event); - - switch (event.type) - { - case SDL_EVENT_QUIT: this->setRunning(false); - break; - - default: - break; - } + inputManager->processEvents(); } void GameInternal::update(Uint64 frameTime) diff --git a/src/InputManager.cpp b/src/InputManager.cpp index 37077f7..3483b49 100644 --- a/src/InputManager.cpp +++ b/src/InputManager.cpp @@ -1,14 +1,165 @@ #include "InputManager.h" #include -InputManager::InputManager() : activeContext("Default") { - initKeyMap(); +std::ostream& operator<<(std::ostream& os, InputManager::Key key) { + static const std::unordered_map keyToString { + {InputManager::Key::UP, "UP"}, + {InputManager::Key::DOWN, "DOWN"}, + {InputManager::Key::LEFT, "LEFT"}, + {InputManager::Key::RIGHT, "RIGHT"}, + {InputManager::Key::SPACE, "SPACE"}, + {InputManager::Key::ENTER, "ENTER"}, + {InputManager::Key::ESCAPE, "ESCAPE"}, + {InputManager::Key::TAB, "TAB"}, + {InputManager::Key::BACKSPACE, "BACKSPACE"}, + {InputManager::Key::DELETE, "DELETE"}, + {InputManager::Key::HOME, "HOME"}, + {InputManager::Key::END, "END"}, + {InputManager::Key::PAGE_UP, "PAGE_UP"}, + {InputManager::Key::PAGE_DOWN, "PAGE_DOWN"}, + {InputManager::Key::INSERT, "INSERT"}, + {InputManager::Key::CAPS_LOCK, "CAPS_LOCK"}, + {InputManager::Key::LEFT_SHIFT, "LEFT_SHIFT"}, + {InputManager::Key::RIGHT_SHIFT, "RIGHT_SHIFT"}, + {InputManager::Key::LEFT_CTRL, "LEFT_CTRL"}, + {InputManager::Key::RIGHT_CTRL, "RIGHT_CTRL"}, + {InputManager::Key::LEFT_ALT, "LEFT_ALT"}, + {InputManager::Key::RIGHT_ALT, "RIGHT_ALT"}, + {InputManager::Key::F1, "F1"}, + {InputManager::Key::F2, "F2"}, + {InputManager::Key::F3, "F3"}, + {InputManager::Key::F4, "F4"}, + {InputManager::Key::F5, "F5"}, + {InputManager::Key::F6, "F6"}, + {InputManager::Key::F7, "F7"}, + {InputManager::Key::F8, "F8"}, + {InputManager::Key::F9, "F9"}, + {InputManager::Key::F10, "F10"}, + {InputManager::Key::F11, "F11"}, + {InputManager::Key::F12, "F12"}, + {InputManager::Key::A, "A"}, + {InputManager::Key::B, "B"}, + {InputManager::Key::C, "C"}, + {InputManager::Key::D, "D"}, + {InputManager::Key::E, "E"}, + {InputManager::Key::F, "F"}, + {InputManager::Key::G, "G"}, + {InputManager::Key::H, "H"}, + {InputManager::Key::I, "I"}, + {InputManager::Key::J, "J"}, + {InputManager::Key::K, "K"}, + {InputManager::Key::L, "L"}, + {InputManager::Key::M, "M"}, + {InputManager::Key::N, "N"}, + {InputManager::Key::O, "O"}, + {InputManager::Key::P, "P"}, + {InputManager::Key::Q, "Q"}, + {InputManager::Key::R, "R"}, + {InputManager::Key::S, "S"}, + {InputManager::Key::T, "T"}, + {InputManager::Key::U, "U"}, + {InputManager::Key::V, "V"}, + {InputManager::Key::W, "W"}, + {InputManager::Key::X, "X"}, + {InputManager::Key::Y, "Y"}, + {InputManager::Key::Z, "Z"}, + {InputManager::Key::NUM_0, "NUM_0"}, + {InputManager::Key::NUM_1, "NUM_1"}, + {InputManager::Key::NUM_2, "NUM_2"}, + {InputManager::Key::NUM_3, "NUM_3"}, + {InputManager::Key::NUM_4, "NUM_4"}, + {InputManager::Key::NUM_5, "NUM_5"}, + {InputManager::Key::NUM_6, "NUM_6"}, + {InputManager::Key::NUM_7, "NUM_7"}, + {InputManager::Key::NUM_8, "NUM_8"}, + {InputManager::Key::NUM_9, "NUM_9"}, + {InputManager::Key::LEFT_BRACKET, "LEFT_BRACKET"}, + {InputManager::Key::RIGHT_BRACKET, "RIGHT_BRACKET"}, + {InputManager::Key::SEMICOLON, "SEMICOLON"}, + {InputManager::Key::APOSTROPHE, "APOSTROPHE"}, + {InputManager::Key::COMMA, "COMMA"}, + {InputManager::Key::PERIOD, "PERIOD"}, + {InputManager::Key::SLASH, "SLASH"}, + {InputManager::Key::BACKSLASH, "BACKSLASH"}, + {InputManager::Key::GRAVE, "GRAVE"} + }; + + auto it = keyToString.find(key); + if (it != keyToString.end()) { + os << it->second; + } else { + os << "UNKNOWN_KEY"; + } + return os; } -InputManager::~InputManager() { - SDL_Quit(); +std::ostream& operator<<(std::ostream& os, const InputManager::InputAction& action) { + os << action.name << " with binding(s): "; + for (size_t i = 0; i < action.bindings.size(); ++i) { + os << action.bindings[i]; + + if (i < action.bindings.size() - 1) { + os << ", "; + } + } + return os; } +std::ostream& operator<<(std::ostream& os, const InputManager::InputAction* action) { + if (action) { + os << *action; + } else { + os << "NULL_ACTION"; + } + return os; +} + +std::ostream& operator<<(std::ostream& os, const std::vector& actions) { + os << "Actions: "; + if (actions.empty()) { + os << "None"; + } else { + for (size_t i = 0; i < actions.size(); ++i) { + os << actions[i]; + if (i < actions.size() - 1) { + os << " | "; + } + } + } + return os; +} + +// TODO: find out why it doesnt work?? +std::ostream& operator<<(std::ostream& os, const std::vector& actions) { + os << "Actions: "; + if (actions.empty()) { + os << "None"; + } else { + for (size_t i = 0; i < actions.size(); ++i) { + if (actions[i]) { + os << *actions[i]; + } else { + os << "NULL_ACTION"; + } + if (i < actions.size() - 1) { + os << " | "; + } + } + } + return os; +} + + + + +// overloads end -------------------------------------------------------------------------------------- + + + + + +InputManager::InputManager() : activeContext("Default") {} + void InputManager::init() { if (SDL_Init(SDL_INIT_EVENTS) != 0) { std::cerr << "Failed to initialize SDL: " << SDL_GetError() << std::endl; @@ -101,8 +252,12 @@ void InputManager::initKeyMap() { } void InputManager::registerAction(const std::string& actionName, const std::vector& keys, std::function callback, const std::string& context) { - actionsByContext[context].push_back({actionName, keys, callback}); - std::cout << "Registered action: " << actionName << " in context: " << context << std::endl; + actionsByContext[context].emplace_back(actionName, keys, callback); + InputAction& storedAction = actionsByContext[context].back(); + for (const auto& key : keys) { + actionsByKey[key].push_back(&storedAction); + } + std::cout << "Registered action: " << storedAction << " in context: " << context << std::endl; } void InputManager::rebindAction(const std::string& actionName, const std::vector& newBindings, const std::string& context) { @@ -110,8 +265,25 @@ void InputManager::rebindAction(const std::string& actionName, const std::vector if (it != actionsByContext.end()) { for (auto& action : it->second) { if (action.name == actionName) { + for (const auto& key : action.bindings) { + auto& keyActions = actionsByKey[key]; + keyActions.erase(std::remove(keyActions.begin(), keyActions.end(), &action), keyActions.end()); + if (keyActions.empty()) { + actionsByKey.erase(key); + } + } + action.bindings = newBindings; - std::cout << "Rebound action: " << actionName << " in context: " << context << " to new bindings.\n"; + + for (const auto& key : newBindings) { + actionsByKey[key].push_back(&action); + } + + std::cout << "Rebound action: " << actionName << " in context: " << context << " to new bindings: "; + for (const auto& key : newBindings) { + std::cout << key << " "; + } + std::cout << std::endl; return; } } @@ -146,6 +318,16 @@ std::vector InputManager::getBindings(const std::string& acti return {}; } +std::vector InputManager::getActionsByKey(const Key key) const { + auto it = actionsByKey.find(key); + if (it != actionsByKey.end()) { + std::cout << "DEBUG: Found " << it->second.size() << " actions for key " << key << std::endl; + return it->second; + } + std::cout << "DEBUG: No actions found for key " << key << std::endl; + return {}; +} + void InputManager::setActiveContext(const std::string& context) { activeContext = context; std::cout << "Active context set to: " << activeContext << std::endl; @@ -164,16 +346,32 @@ void InputManager::processEvents() { } void InputManager::handleEvent(const SDL_Event& event) { - if (event.type != SDL_EVENT_KEY_DOWN) return; // TODO: add other events if necessary + if (event.type != SDL_EVENT_KEY_DOWN) return; // TODO: add other events if necessary // TODO: Controller how?? + std::cout << "in handleEvent" << std::endl; - auto& contextActions = actionsByContext[activeContext]; + auto keyIt = std::ranges::find_if(keyMap, + [&](const auto& pair) { return pair.second == event.key.scancode; }); - for (const auto& action : contextActions) { - for (const auto& binding : action.bindings) { - if (event.key.scancode == keyMap[binding]) { - std::cout << "Action triggered: " << action.name << " in context: " << activeContext << std::endl; - action.callback(); - return; + if (keyIt != keyMap.end()) { + std::cout << "in != keymap.end" << std::endl; + + Key pressedKey = keyIt->first; + auto actionIt = actionsByKey.find(pressedKey); + if (actionIt != actionsByKey.end()) { + std::cout << "in != actionsByKey.end" << std::endl; + + for (auto* action : actionIt->second) { + std::cout << "before if(action)" << std::endl; + if (action) { + std::cout << "after if(action)" << std::endl; + + auto& activeActions = actionsByContext[activeContext]; + if (std::ranges::find_if(activeActions, + [&](const InputAction& act) { return &act == action; }) != activeActions.end()) { + std::cout << "Action triggered: " << action->name << " in context: " << activeContext << std::endl; + action->callback(); + } + } } } } diff --git a/src/_Init.cpp b/src/_Init.cpp index bab9cd3..d9b97b2 100644 --- a/src/_Init.cpp +++ b/src/_Init.cpp @@ -39,7 +39,9 @@ SDL_AppResult SDL_AppIterate(void *appstate) { return SDL_APP_CONTINUE; } +// triggers upon every event SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) { + // TODO: call handleEvents() from gameinternal return SDL_APP_CONTINUE; }