Hello! ;)
I am during my first project in SFML in which I decided to create some kind of game engine that I can use in my future games. I made an action manager which has its members marked as static.
.hpp file:
#include "Input/input.hpp"
#include <unordered_map>
namespace WhitE {
class ActionManager
{
public:
static void addAction(const std::string&, sf::Keyboard::Key);
static void addAction(const std::string&, std::vector<sf::Keyboard::Key>);
static void deleteAction(const std::string& actionName);
static bool isActionPressed(const std::string& actionName);
static bool isMouseButtonPressed(sf::Mouse::Button);
private:
inline static Input mInput;
inline static std::unordered_map<std::string, std::vector<sf::Keyboard::Key>> mKeyboardMap;
};
}
.cpp file:
#include "Input/actionManager.hpp"
#include "Logger/logs.hpp"
namespace WhitE {
void ActionManager::addAction(const std::string& actionName, sf::Keyboard::Key key)
{
mKeyboardMap.insert(std::make_pair(actionName, std::vector<sf::Keyboard::Key> {key}));
WE_LOG_INFO(actionName + " action was added to the manager.");
}
void ActionManager::addAction(const std::string& actionName, std::vector<sf::Keyboard::Key> keys)
{
mKeyboardMap.insert(std::make_pair(actionName, keys));
}
void ActionManager::deleteAction(const std::string& actionName)
{
if (mKeyboardMap.find(actionName) != mKeyboardMap.end())
mKeyboardMap.erase(actionName);
else
WE_LOG_WARNING("WhitE: Key of map cannot be found!");
}
bool ActionManager::isActionPressed(const std::string& actionName)
{
auto keys = mKeyboardMap.at(actionName);
for (const auto& key : keys)
{
if (mInput.isKeyPressed(key))
return true;
}
}
bool ActionManager::isMouseButtonPressed(sf::Mouse::Button button)
{
return mInput.isMouseButtonPressed(button) ? true : false;
}
}
And then I've got a simple class which handles real-time input
#include "Input/actionManager.hpp"
#include <SFML/Window.hpp>
namespace WhitE {
class Input
{
private:
bool isKeyPressed(sf::Keyboard::Key key) { return sf::Keyboard::isKeyPressed(key); }
bool isMouseButtonPressed(sf::Mouse::Button button) { return sf::Mouse::isButtonPressed(button); }
friend class ActionManager;
};
}
My question is if it even makes sense? In case of checking input I'd need to type "if(ActionManager::isActionPressed("someAction")) doSomeStuff" which is not the most convinient style but I have no idea how it could be rearranged. Any help would be appreciated.
The scheme looks okay. You can also report an error if action name that's passed to one of the functions is not correct, so that misspelled actions are easy to spot in code, e.g.
if(ActionManager::isActionPressed("someAction")) doSomeStuff(); // ok
if(ActionManager::isActionPressed("someActoin")) doSomeStuff(); // throws/logs error
Also, I'd strongly advice against using "static" classes which are really Singletons. I prefer Service Locator (https://gameprogrammingpatterns.com/service-locator.html) pattern a lot more.