You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
87 lines
2.1 KiB
87 lines
2.1 KiB
|
5 years ago
|
#pragma once
|
||
|
|
|
||
|
|
#include <cstddef>
|
||
|
|
#include <string>
|
||
|
|
#include <functional>
|
||
|
|
#include <vector>
|
||
|
|
#include <unordered_map>
|
||
|
|
|
||
|
|
namespace devilution {
|
||
|
|
|
||
|
|
/** The Keymapper maps keys to actions. */
|
||
|
|
class Keymapper final {
|
||
|
|
public:
|
||
|
|
using SetConfigKeyFunction = std::function<void(const std::string &key, const std::string &value)>;
|
||
|
|
using GetConfigKeyFunction = std::function<std::string(const std::string &key)>;
|
||
|
|
using ActionIndex = std::size_t;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Action represents an action that can be triggered using a keyboard
|
||
|
|
* shortcut.
|
||
|
|
*/
|
||
|
|
class Action final {
|
||
|
|
public:
|
||
|
|
/** Can this action be triggered while the player is dead? */
|
||
|
|
|
||
|
|
enum class IfDead {
|
||
|
|
Allow,
|
||
|
|
Ignore,
|
||
|
|
};
|
||
|
|
|
||
|
|
Action(const std::string &name, int defaultKey, std::function<void()> action)
|
||
|
|
: name(name)
|
||
|
|
, defaultKey(defaultKey)
|
||
|
|
, action(action)
|
||
|
|
, ifDead(IfDead::Ignore)
|
||
|
|
{
|
||
|
|
}
|
||
|
|
Action(const std::string &name, int defaultKey, std::function<void()> action, IfDead ifDead)
|
||
|
|
: name(name)
|
||
|
|
, defaultKey(defaultKey)
|
||
|
|
, action(action)
|
||
|
|
, ifDead(ifDead)
|
||
|
|
{
|
||
|
|
}
|
||
|
|
|
||
|
|
void operator()() const
|
||
|
|
{
|
||
|
|
action();
|
||
|
|
}
|
||
|
|
|
||
|
|
private:
|
||
|
|
std::string name;
|
||
|
|
int defaultKey;
|
||
|
|
std::function<void()> action;
|
||
|
|
IfDead ifDead;
|
||
|
|
int key {};
|
||
|
|
|
||
|
|
friend class Keymapper;
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Keymapper, for now, uses two function pointers to interact with the
|
||
|
|
* configuration.
|
||
|
|
* This is mostly a workaround and should be replaced later when another INI
|
||
|
|
* library will be used.
|
||
|
|
*/
|
||
|
|
Keymapper(SetConfigKeyFunction setKeyFunction, GetConfigKeyFunction getKeyFunction);
|
||
|
|
|
||
|
|
ActionIndex addAction(const Action &action);
|
||
|
|
void keyPressed(int key, bool isPlayerDead) const;
|
||
|
|
std::string keyNameForAction(ActionIndex actionIndex) const;
|
||
|
|
void save() const;
|
||
|
|
void load();
|
||
|
|
|
||
|
|
private:
|
||
|
|
int getActionKey(const Action &action);
|
||
|
|
|
||
|
|
std::vector<Action> actions;
|
||
|
|
std::unordered_map<int, std::reference_wrapper<Action>> keyIDToAction;
|
||
|
|
std::unordered_map<int, std::string> keyIDToKeyName;
|
||
|
|
std::unordered_map<std::string, int> keyNameToKeyID;
|
||
|
|
SetConfigKeyFunction setKeyFunction;
|
||
|
|
GetConfigKeyFunction getKeyFunction;
|
||
|
|
};
|
||
|
|
|
||
|
|
} // namespace devilution
|