Files
OpenVulkano/openVulkanoCpp/Input/InputManager.hpp
2023-10-03 19:52:23 +02:00

183 lines
3.7 KiB
C++

#pragma once
#include "InputKey.hpp"
#include "InputDevice.hpp"
#include "Base/Utils.hpp"
#include <functional>
#include <unordered_map>
#include <vector>
namespace OpenVulkano
{
namespace Input
{
class BaseInputAction
{
std::string name;
std::vector<InputDevice*> devices;
bool enabled;
protected:
BaseInputAction(const std::string& name) : name(name), enabled(true) {}
public:
virtual ~BaseInputAction() = default;
const std::string& GetName() const
{
return name;
}
const std::vector<InputDevice*>& GetDevices() const
{
return devices;
}
bool IsEnabled() const
{
return enabled;
}
void SetEnabled(bool enabled)
{
this->enabled = enabled;
}
};
class InputAction : public BaseInputAction
{
std::vector<InputKey> keys;
std::vector<std::pair<InputKey, InputKey>> axisButtons;
public:
InputAction(const std::string& name) : BaseInputAction(name)
{}
const std::vector<InputKey>& GetKeys() const
{
return keys;
}
const std::vector<std::pair<InputKey, InputKey>>& GetAxisButtons() const
{
return axisButtons;
}
void BindKey(InputKey key)
{
keys.push_back(key);
}
void BindAxisButtons(InputKey keyPositive, InputKey keyNegative)
{
axisButtons.emplace_back(keyPositive, keyNegative);
}
};
class InputShortcut : public BaseInputAction
{
std::string name;
std::vector<InputDevice*> devices;
std::vector<std::vector<InputKey>> buttonBindings;
public:
InputShortcut(const std::string& name) : BaseInputAction(name)
{}
};
class InputManager
{
InputManager() = default;
public:
static InputManager* GetInstance()
{
static InputManager* instance = new InputManager();
return instance;
}
void RegisterInputDevice(InputDevice* device)
{
devices.push_back(device);
if (!lastActiveDevice) lastActiveDevice = device;
}
void UnregisterInputDevice(InputDevice* device)
{
Utils::Remove(devices, device);
}
InputAction* GetAction(const std::string& actionName)
{
InputAction*& action = actionNameMapping[actionName];
if(!action)
{
action = new InputAction(actionName);
}
return action;
}
float GetAxis(const InputAction* action) const
{
float value = 0;
const std::vector<InputDevice*>& testDevices = action->GetDevices().empty() ? devices : action->GetDevices();
for (const InputDevice* device : testDevices)
{
for(InputKey key : action->GetKeys())
{
value += device->GetAxis(key);
}
for(const auto& keys : action->GetAxisButtons())
{
value += GetAxis(keys.first) - GetAxis(keys.second);
}
}
return value;
}
float GetAxis(InputKey key) const
{
float value = 0;
for (const InputDevice* device : devices)
{
value += device->GetAxis(key);
}
return value;
}
bool GetButton(InputAction* action) const
{
const std::vector<InputDevice*>& testDevices = action->GetDevices().empty() ? devices : action->GetDevices();
for (const InputDevice* device : testDevices)
{
for (const InputKey key : action->GetKeys())
{
if (device->GetButton(key)) return true;
}
}
return false;
}
bool GetButton(InputKey key) const
{
for(const InputDevice* device : devices)
{
if (device->GetButton(key)) return true;
}
return false;
}
InputDevice* GetLastActiveDevice() const
{
return lastActiveDevice;
}
private:
//std::unordered_map<InputKey, std::vector<InputAction*>> inputActionMapping;
std::unordered_map<std::string, InputAction*> actionNameMapping;
std::vector<InputDevice*> devices;
InputDevice* lastActiveDevice = nullptr;
};
}
}