InputProxy with a KeyboardInputHandler to translate keyboard keys to input commands. Input origins are bound to commands through the BindOrigin event, or through loading them from a config file.

This commit is contained in:
2015-12-11 11:39:20 +01:00
parent 5d46a10a4e
commit 35624008e7
13 changed files with 328 additions and 509 deletions
+78 -219
View File
@@ -1,221 +1,80 @@
#include "Input/InputProxy.h"
#include "Core/World.h"
#include "Input/InputHandler.h"
//InputProxy::InputProxy(EventBroker* eventBroker)
// : m_EventBroker(eventBroker)
//{
// // Subscribe to events
// EVENT_SUBSCRIBE_MEMBER(m_EMousePress, &InputProxy::OnMousePress);
// EVENT_SUBSCRIBE_MEMBER(m_EMouseRelease, &InputProxy::OnMouseRelease);
// EVENT_SUBSCRIBE_MEMBER(m_EGamepadAxis, &InputProxy::OnGamepadAxis);
// EVENT_SUBSCRIBE_MEMBER(m_EGamepadButtonDown, &InputProxy::OnGamepadButtonDown);
// EVENT_SUBSCRIBE_MEMBER(m_EGamepadButtonUp, &InputProxy::OnGamepadButtonUp);
// EVENT_SUBSCRIBE_MEMBER(m_EBindKey, &InputProxy::OnBindKey);
// EVENT_SUBSCRIBE_MEMBER(m_EBindMouseButton, &InputProxy::OnBindMouseButton);
// EVENT_SUBSCRIBE_MEMBER(m_EBindGamepadAxis, &InputProxy::OnBindGamepadAxis);
// EVENT_SUBSCRIBE_MEMBER(m_EBindGamepadButton, &InputProxy::OnBindGamepadButton);
//
// SteamController()->Init();
//
//}
//
//void InputProxy::Update(double dt)
//{
// std::array<ControllerHandle_t, STEAM_CONTROLLER_MAX_COUNT> controllers;
// int numControllers = SteamController()->GetConnectedControllers(controllers.data());
//
// ControllerDigitalActionHandle_t debug_reload_handle = SteamController()->GetDigitalActionHandle("debug_reload");
// SteamController()->
//}
//
//bool InputProxy::OnKeyDown(const Events::KeyDown &event)
//{
// auto range = m_KeyBindings.equal_range(event.KeyCode);
// for (auto bindingIt = range.first; bindingIt != range.second; bindingIt++) {
// std::string command;
// float value;
// std::tie(command, value) = bindingIt->second;
// m_CommandKeyboardValues[command][event.KeyCode] = value;
// PublishCommand(1, command, GetCommandTotalValue(command));
// }
//
// return true;
//}
//
//bool InputProxy::OnKeyUp(const Events::KeyUp &event)
//{
// auto range = m_KeyBindings.equal_range(event.KeyCode);
// for (auto bindingIt = range.first; bindingIt != range.second; bindingIt++) {
// std::string command;
// float value;
// std::tie(command, value) = bindingIt->second;
// m_CommandKeyboardValues[command][event.KeyCode] = 0;
// PublishCommand(1, command, GetCommandTotalValue(command));;
// }
//
// return true;
//}
//
//bool InputProxy::OnMousePress(const Events::MousePress &event)
//{
// auto range = m_MouseButtonBindings.equal_range(event.Button);
// for (auto bindingIt = range.first; bindingIt != range.second; bindingIt++) {
// std::string command;
// float value;
// std::tie(command, value) = bindingIt->second;
// m_CommandMouseButtonValues[command][event.Button] = value;
// PublishCommand(1, command, GetCommandTotalValue(command));
// }
//
// return true;
//}
//
//bool InputProxy::OnMouseRelease(const Events::MouseRelease &event)
//{
// auto range = m_MouseButtonBindings.equal_range(event.Button);
// for (auto bindingIt = range.first; bindingIt != range.second; bindingIt++) {
// std::string command;
// float value;
// std::tie(command, value) = bindingIt->second;
// m_CommandMouseButtonValues[command][event.Button] = 0;
// PublishCommand(1, command, GetCommandTotalValue(command));
// }
//
// return true;
//}
//
//bool InputProxy::OnGamepadAxis(const Events::GamepadAxis &event)
//{
// auto range = m_GamepadAxisBindings.equal_range(event.Axis);
// for (auto bindingIt = range.first; bindingIt != range.second; bindingIt++) {
// std::string command;
// float value;
// std::tie(command, value) = bindingIt->second;
// m_CommandGamepadAxisValues[command][event.Axis] = event.Value * value;
// PublishCommand(event.GamepadID + 1, command, GetCommandTotalValue(command));
// }
//
// return true;
//}
//
//bool InputProxy::OnGamepadButtonDown(const Events::GamepadButtonDown &event)
//{
// auto range = m_GamepadButtonBindings.equal_range(event.Button);
// for (auto bindingIt = range.first; bindingIt != range.second; bindingIt++) {
// std::string command;
// float value;
// std::tie(command, value) = bindingIt->second;
// m_CommandGamepadButtonValues[command][event.Button] = value;
// PublishCommand(event.GamepadID + 1, command, GetCommandTotalValue(command));
// }
//
// return true;
//}
//
//bool InputProxy::OnGamepadButtonUp(const Events::GamepadButtonUp &event)
//{
// auto range = m_GamepadButtonBindings.equal_range(event.Button);
// for (auto bindingIt = range.first; bindingIt != range.second; bindingIt++) {
// std::string command;
// float value;
// std::tie(command, value) = bindingIt->second;
// m_CommandGamepadButtonValues[command][event.Button] = 0;
// PublishCommand(event.GamepadID + 1, command, GetCommandTotalValue(command));
// }
//
// return true;
//}
//
//bool InputProxy::OnBindKey(const Events::BindKey &event)
//{
// if (event.Command.empty()) {
// return false;
// }
//
// m_KeyBindings.insert(std::make_pair(event.KeyCode, std::make_tuple(event.Command, event.Value)));
// LOG_DEBUG("Input: Bound key %i to %s", event.KeyCode, event.Command.c_str());
//
// return true;
//}
//
//bool InputProxy::OnBindMouseButton(const Events::BindMouseButton &event)
//{
// if (event.Command.empty()) {
// return false;
// }
//
// m_MouseButtonBindings.insert(std::make_pair(event.Button, std::make_tuple(event.Command, event.Value)));
// LOG_DEBUG("Input: Bound mouse button %i to %s", event.Button, event.Command.c_str());
//
// return true;
//}
//
//bool InputProxy::OnBindGamepadAxis(const Events::BindGamepadAxis &event)
//{
// if (event.Command.empty()) {
// return false;
// }
//
// m_GamepadAxisBindings.insert(std::make_pair(event.Axis, std::make_tuple(event.Command, event.Value)));
// LOG_DEBUG("Input: Bound gamepad axis %i to %s", event.Axis, event.Command.c_str());
//
// return true;
//}
//
//bool InputProxy::OnBindGamepadButton(const Events::BindGamepadButton &event)
//{
// if (event.Command.empty()) {
// return false;
// }
//
// m_GamepadButtonBindings.insert(std::make_pair(event.Button, std::make_tuple(event.Command, event.Value)));
// LOG_DEBUG("Input: Bound gamepad axis %i to %s", event.Button, event.Command.c_str());
//
// return true;
//}
//
//float InputProxy::GetCommandTotalValue(std::string command)
//{
// float value = 0.f;
//
// auto keyboardIt = m_CommandKeyboardValues.find(command);
// if (keyboardIt != m_CommandKeyboardValues.end()) {
// for (auto &key : keyboardIt->second) {
// value += key.second;
// }
// }
//
// auto mouseButtonIt = m_CommandMouseButtonValues.find(command);
// if (mouseButtonIt != m_CommandMouseButtonValues.end()) {
// for (auto &button : mouseButtonIt->second) {
// value += button.second;
// }
// }
//
// auto gamepadAxisIt = m_CommandGamepadAxisValues.find(command);
// if (gamepadAxisIt != m_CommandGamepadAxisValues.end()) {
// for (auto &axis : gamepadAxisIt->second) {
// value += axis.second;
// }
// }
//
// auto gamepadButtonIt = m_CommandGamepadButtonValues.find(command);
// if (gamepadButtonIt != m_CommandGamepadButtonValues.end()) {
// for (auto &button : gamepadButtonIt->second) {
// value += button.second;
// }
// }
//
// return std::max(-1.f, std::min(value, 1.f));
//}
//
//void InputProxy::PublishCommand(int playerID, std::string command, float value)
//{
// Events::InputCommand e;
// e.PlayerID = playerID;
// e.Command = command;
// e.Value = value;
// m_EventBroker->Publish(e);
//
// LOG_DEBUG("Input: Published command %s=%f for player %i", e.Command.c_str(), e.Value, playerID);
//}
InputProxy::InputProxy(EventBroker* eventBroker)
: m_EventBroker(eventBroker)
{
EVENT_SUBSCRIBE_MEMBER(m_EBindOrigin, &InputProxy::OnBindOrigin);
}
InputProxy::~InputProxy()
{
for (auto& handler : m_Handlers) {
delete handler;
}
}
void InputProxy::LoadBindings(std::string file)
{
auto config = ResourceManager::Load<ConfigFile>(file);
for (auto& origin : config->GetAll<std::string>("Bindings")) {
Events::BindOrigin e;
e.Origin = origin.first;
e.Command = origin.second;
e.Value = 1.f;
OnBindOrigin(e);
}
}
void InputProxy::Update(double dt)
{
m_EventBroker->Process<InputProxy>();
m_EventBroker->Process<InputHandler>();
for (auto& handler : m_Handlers) {
handler->Update(dt);
}
}
void InputProxy::Process()
{
// Accumulate the input values of all unique commands published by input handlers
for (auto& pair : m_CommandQueue) {
Events::InputCommand e;
e.PlayerID = pair.first.first;
e.Command = pair.first.second;
e.Value = 0;
for (auto& value : pair.second) {
e.Value += value;
}
e.Value = std::max(-1.f, std::min(e.Value, 1.f));
m_EventBroker->Publish(e);
LOG_DEBUG("Input: Published command %s=%f for player %i", e.Command.c_str(), e.Value, e.PlayerID);
}
m_CommandQueue.clear();
}
void InputProxy::Publish(const Events::InputCommand& e)
{
auto key = std::make_pair(e.PlayerID, e.Command);
m_CommandQueue[key].push_back(e.Value);
}
bool InputProxy::OnBindOrigin(const Events::BindOrigin& e)
{
bool originBound = false;
for (auto& handler : m_Handlers) {
bool result = handler->BindOrigin(e.Origin, e.Command, e.Value);
if (result) {
if (originBound) {
LOG_WARNING("Multiple handlers responded to binding input origin \"%s\"!", e.Origin.c_str());
}
originBound = true;
}
}
if (!originBound) {
LOG_ERROR("No input handler responded to binding input origin \"%s\"!", e.Origin.c_str());
}
return originBound;
}
+172
View File
@@ -0,0 +1,172 @@
#include "Input/KeyboardInputHandler.h"
KeyboardInputHandler::KeyboardInputHandler(EventBroker* eventBroker, InputProxy* inputProxy) : InputHandler(eventBroker, inputProxy)
{
EVENT_SUBSCRIBE_MEMBER(m_EKeyDown, &KeyboardInputHandler::OnKeyDown);
EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &KeyboardInputHandler::OnKeyUp);
m_OriginKeyCodes["Space"] = GLFW_KEY_SPACE;
m_OriginKeyCodes["Apostrophe"] = GLFW_KEY_APOSTROPHE;
m_OriginKeyCodes["Comma"] = GLFW_KEY_COMMA;
m_OriginKeyCodes["Minus"] = GLFW_KEY_MINUS;
m_OriginKeyCodes["Period"] = GLFW_KEY_PERIOD;
m_OriginKeyCodes["Slash"] = GLFW_KEY_SLASH;
m_OriginKeyCodes["0"] = GLFW_KEY_0;
m_OriginKeyCodes["1"] = GLFW_KEY_1;
m_OriginKeyCodes["2"] = GLFW_KEY_2;
m_OriginKeyCodes["3"] = GLFW_KEY_3;
m_OriginKeyCodes["4"] = GLFW_KEY_4;
m_OriginKeyCodes["5"] = GLFW_KEY_5;
m_OriginKeyCodes["6"] = GLFW_KEY_6;
m_OriginKeyCodes["7"] = GLFW_KEY_7;
m_OriginKeyCodes["8"] = GLFW_KEY_8;
m_OriginKeyCodes["9"] = GLFW_KEY_9;
m_OriginKeyCodes["Semicolon"] = GLFW_KEY_SEMICOLON;
m_OriginKeyCodes["Equal"] = GLFW_KEY_EQUAL;
m_OriginKeyCodes["A"] = GLFW_KEY_A;
m_OriginKeyCodes["B"] = GLFW_KEY_B;
m_OriginKeyCodes["C"] = GLFW_KEY_C;
m_OriginKeyCodes["D"] = GLFW_KEY_D;
m_OriginKeyCodes["E"] = GLFW_KEY_E;
m_OriginKeyCodes["F"] = GLFW_KEY_F;
m_OriginKeyCodes["G"] = GLFW_KEY_G;
m_OriginKeyCodes["H"] = GLFW_KEY_H;
m_OriginKeyCodes["I"] = GLFW_KEY_I;
m_OriginKeyCodes["J"] = GLFW_KEY_J;
m_OriginKeyCodes["K"] = GLFW_KEY_K;
m_OriginKeyCodes["L"] = GLFW_KEY_L;
m_OriginKeyCodes["M"] = GLFW_KEY_M;
m_OriginKeyCodes["N"] = GLFW_KEY_N;
m_OriginKeyCodes["O"] = GLFW_KEY_O;
m_OriginKeyCodes["P"] = GLFW_KEY_P;
m_OriginKeyCodes["Q"] = GLFW_KEY_Q;
m_OriginKeyCodes["R"] = GLFW_KEY_R;
m_OriginKeyCodes["S"] = GLFW_KEY_S;
m_OriginKeyCodes["T"] = GLFW_KEY_T;
m_OriginKeyCodes["U"] = GLFW_KEY_U;
m_OriginKeyCodes["V"] = GLFW_KEY_V;
m_OriginKeyCodes["W"] = GLFW_KEY_W;
m_OriginKeyCodes["X"] = GLFW_KEY_X;
m_OriginKeyCodes["Y"] = GLFW_KEY_Y;
m_OriginKeyCodes["Z"] = GLFW_KEY_Z;
m_OriginKeyCodes["LeftBracket"] = GLFW_KEY_LEFT_BRACKET;
m_OriginKeyCodes["Backslash"] = GLFW_KEY_BACKSLASH;
m_OriginKeyCodes["RightBracket"] = GLFW_KEY_RIGHT_BRACKET;
m_OriginKeyCodes["Accent"] = GLFW_KEY_GRAVE_ACCENT;
m_OriginKeyCodes["W1"] = GLFW_KEY_WORLD_1;
m_OriginKeyCodes["W2"] = GLFW_KEY_WORLD_2;
m_OriginKeyCodes["Escape"] = GLFW_KEY_ESCAPE;
m_OriginKeyCodes["Enter"] = GLFW_KEY_ENTER;
m_OriginKeyCodes["Tab"] = GLFW_KEY_TAB;
m_OriginKeyCodes["Backspace"] = GLFW_KEY_BACKSPACE;
m_OriginKeyCodes["Insert"] = GLFW_KEY_INSERT;
m_OriginKeyCodes["Delete"] = GLFW_KEY_DELETE;
m_OriginKeyCodes["Right"] = GLFW_KEY_RIGHT;
m_OriginKeyCodes["Left"] = GLFW_KEY_LEFT;
m_OriginKeyCodes["Down"] = GLFW_KEY_DOWN;
m_OriginKeyCodes["Up"] = GLFW_KEY_UP;
m_OriginKeyCodes["PgUp"] = GLFW_KEY_PAGE_UP;
m_OriginKeyCodes["PgDn"] = GLFW_KEY_PAGE_DOWN;
m_OriginKeyCodes["Home"] = GLFW_KEY_HOME;
m_OriginKeyCodes["End"] = GLFW_KEY_END;
m_OriginKeyCodes["CapsLock"] = GLFW_KEY_CAPS_LOCK;
m_OriginKeyCodes["ScrollLock"] = GLFW_KEY_SCROLL_LOCK;
m_OriginKeyCodes["NumLock"] = GLFW_KEY_NUM_LOCK;
m_OriginKeyCodes["PrintScreen"] = GLFW_KEY_PRINT_SCREEN;
m_OriginKeyCodes["Pause"] = GLFW_KEY_PAUSE;
m_OriginKeyCodes["F1"] = GLFW_KEY_F1;
m_OriginKeyCodes["F2"] = GLFW_KEY_F2;
m_OriginKeyCodes["F3"] = GLFW_KEY_F3;
m_OriginKeyCodes["F4"] = GLFW_KEY_F4;
m_OriginKeyCodes["F5"] = GLFW_KEY_F5;
m_OriginKeyCodes["F6"] = GLFW_KEY_F6;
m_OriginKeyCodes["F7"] = GLFW_KEY_F7;
m_OriginKeyCodes["F8"] = GLFW_KEY_F8;
m_OriginKeyCodes["F9"] = GLFW_KEY_F9;
m_OriginKeyCodes["F10"] = GLFW_KEY_F10;
m_OriginKeyCodes["F11"] = GLFW_KEY_F11;
m_OriginKeyCodes["F12"] = GLFW_KEY_F12;
m_OriginKeyCodes["F13"] = GLFW_KEY_F13;
m_OriginKeyCodes["F14"] = GLFW_KEY_F14;
m_OriginKeyCodes["F15"] = GLFW_KEY_F15;
m_OriginKeyCodes["F16"] = GLFW_KEY_F16;
m_OriginKeyCodes["F17"] = GLFW_KEY_F17;
m_OriginKeyCodes["F18"] = GLFW_KEY_F18;
m_OriginKeyCodes["F19"] = GLFW_KEY_F19;
m_OriginKeyCodes["F20"] = GLFW_KEY_F20;
m_OriginKeyCodes["F21"] = GLFW_KEY_F21;
m_OriginKeyCodes["F22"] = GLFW_KEY_F22;
m_OriginKeyCodes["F23"] = GLFW_KEY_F23;
m_OriginKeyCodes["F24"] = GLFW_KEY_F24;
m_OriginKeyCodes["F25"] = GLFW_KEY_F25;
m_OriginKeyCodes["KP0"] = GLFW_KEY_KP_0;
m_OriginKeyCodes["KP1"] = GLFW_KEY_KP_1;
m_OriginKeyCodes["KP2"] = GLFW_KEY_KP_2;
m_OriginKeyCodes["KP3"] = GLFW_KEY_KP_3;
m_OriginKeyCodes["KP4"] = GLFW_KEY_KP_4;
m_OriginKeyCodes["KP5"] = GLFW_KEY_KP_5;
m_OriginKeyCodes["KP6"] = GLFW_KEY_KP_6;
m_OriginKeyCodes["KP7"] = GLFW_KEY_KP_7;
m_OriginKeyCodes["KP8"] = GLFW_KEY_KP_8;
m_OriginKeyCodes["KP9"] = GLFW_KEY_KP_9;
m_OriginKeyCodes["KPDecimal"] = GLFW_KEY_KP_DECIMAL;
m_OriginKeyCodes["KPDivide"] = GLFW_KEY_KP_DIVIDE;
m_OriginKeyCodes["KPMultiply"] = GLFW_KEY_KP_MULTIPLY;
m_OriginKeyCodes["KPSubtract"] = GLFW_KEY_KP_SUBTRACT;
m_OriginKeyCodes["KPAdd"] = GLFW_KEY_KP_ADD;
m_OriginKeyCodes["KPEnter"] = GLFW_KEY_KP_ENTER;
m_OriginKeyCodes["KPEqual"] = GLFW_KEY_KP_EQUAL;
m_OriginKeyCodes["LeftShift"] = GLFW_KEY_LEFT_SHIFT;
m_OriginKeyCodes["LeftControl"] = GLFW_KEY_LEFT_CONTROL;
m_OriginKeyCodes["LeftAlt"] = GLFW_KEY_LEFT_ALT;
m_OriginKeyCodes["LeftSuper"] = GLFW_KEY_LEFT_SUPER;
m_OriginKeyCodes["RightShift"] = GLFW_KEY_RIGHT_SHIFT;
m_OriginKeyCodes["RightControl"] = GLFW_KEY_RIGHT_CONTROL;
m_OriginKeyCodes["RightAlt"] = GLFW_KEY_RIGHT_ALT;
m_OriginKeyCodes["RightSuper"] = GLFW_KEY_RIGHT_SUPER;
m_OriginKeyCodes["Menu"] = GLFW_KEY_MENU;
}
bool KeyboardInputHandler::BindOrigin(std::string origin, std::string command, float value)
{
auto originIt = m_OriginKeyCodes.find(origin);
if (originIt == m_OriginKeyCodes.end()) {
return false;
}
int keyCode = originIt->second;
m_KeyBindings[keyCode] = std::make_tuple(command, value);
return true;
}
bool KeyboardInputHandler::OnKeyDown(const Events::KeyDown& e)
{
auto it = m_KeyBindings.find(e.KeyCode);
if (it == m_KeyBindings.end()) {
return false;
}
Events::InputCommand ic;
ic.PlayerID = 0;
std::tie(ic.Command, ic.Value) = it->second;
m_InputProxy->Publish(ic);
return true;
}
bool KeyboardInputHandler::OnKeyUp(const Events::KeyUp& e)
{
auto it = m_KeyBindings.find(e.KeyCode);
if (it == m_KeyBindings.end()) {
return false;
}
Events::InputCommand ic;
ic.PlayerID = 0;
std::tie(ic.Command, std::ignore) = it->second;
ic.Value = 0;
m_InputProxy->Publish(ic);
return true;
}