mirror of https://github.com/PCSX2/pcsx2.git
InputManager: Switch InputEventHandler to std::variant
This commit is contained in:
parent
a524410b0a
commit
f13ad4fcb3
|
@ -25,6 +25,7 @@
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <variant>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
@ -45,102 +46,7 @@ enum : u32
|
||||||
// This class acts as an adapter to convert from normalized values to
|
// This class acts as an adapter to convert from normalized values to
|
||||||
// binary values when the callback is a binary/button handler. That way
|
// binary values when the callback is a binary/button handler. That way
|
||||||
// you don't need to convert float->bool in your callbacks.
|
// you don't need to convert float->bool in your callbacks.
|
||||||
|
using InputEventHandler = std::variant<InputAxisEventHandler, InputButtonEventHandler>;
|
||||||
class InputEventHandler
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
InputEventHandler()
|
|
||||||
{
|
|
||||||
new (&u.button) InputButtonEventHandler;
|
|
||||||
is_axis = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
InputEventHandler(InputButtonEventHandler button)
|
|
||||||
{
|
|
||||||
new (&u.button) InputButtonEventHandler(std::move(button));
|
|
||||||
is_axis = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
InputEventHandler(InputAxisEventHandler axis)
|
|
||||||
{
|
|
||||||
new (&u.axis) InputAxisEventHandler(std::move(axis));
|
|
||||||
is_axis = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
InputEventHandler(const InputEventHandler& copy)
|
|
||||||
{
|
|
||||||
if (copy.is_axis)
|
|
||||||
new (&u.axis) InputAxisEventHandler(copy.u.axis);
|
|
||||||
else
|
|
||||||
new (&u.button) InputButtonEventHandler(copy.u.button);
|
|
||||||
is_axis = copy.is_axis;
|
|
||||||
}
|
|
||||||
|
|
||||||
InputEventHandler(InputEventHandler&& move)
|
|
||||||
{
|
|
||||||
if (move.is_axis)
|
|
||||||
new (&u.axis) InputAxisEventHandler(std::move(move.u.axis));
|
|
||||||
else
|
|
||||||
new (&u.button) InputButtonEventHandler(std::move(move.u.button));
|
|
||||||
is_axis = move.is_axis;
|
|
||||||
}
|
|
||||||
|
|
||||||
~InputEventHandler()
|
|
||||||
{
|
|
||||||
// call the right destructor... :D
|
|
||||||
if (is_axis)
|
|
||||||
u.axis.InputAxisEventHandler::~InputAxisEventHandler();
|
|
||||||
else
|
|
||||||
u.button.InputButtonEventHandler::~InputButtonEventHandler();
|
|
||||||
}
|
|
||||||
|
|
||||||
InputEventHandler& operator=(const InputEventHandler& copy)
|
|
||||||
{
|
|
||||||
InputEventHandler::~InputEventHandler();
|
|
||||||
|
|
||||||
if (copy.is_axis)
|
|
||||||
new (&u.axis) InputAxisEventHandler(copy.u.axis);
|
|
||||||
else
|
|
||||||
new (&u.button) InputButtonEventHandler(copy.u.button);
|
|
||||||
is_axis = copy.is_axis;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
InputEventHandler& operator=(InputEventHandler&& move)
|
|
||||||
{
|
|
||||||
InputEventHandler::~InputEventHandler();
|
|
||||||
|
|
||||||
if (move.is_axis)
|
|
||||||
new (&u.axis) InputAxisEventHandler(std::move(move.u.axis));
|
|
||||||
else
|
|
||||||
new (&u.button) InputButtonEventHandler(std::move(move.u.button));
|
|
||||||
is_axis = move.is_axis;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
__fi bool IsAxis() const { return is_axis; }
|
|
||||||
|
|
||||||
__fi void Invoke(float value) const
|
|
||||||
{
|
|
||||||
if (is_axis)
|
|
||||||
u.axis(value);
|
|
||||||
else
|
|
||||||
u.button(value > 0.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
union HandlerUnion
|
|
||||||
{
|
|
||||||
// constructor/destructor needs to be declared
|
|
||||||
HandlerUnion() {}
|
|
||||||
~HandlerUnion() {}
|
|
||||||
|
|
||||||
InputButtonEventHandler button;
|
|
||||||
InputAxisEventHandler axis;
|
|
||||||
} u;
|
|
||||||
|
|
||||||
bool is_axis;
|
|
||||||
};
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
// Binding Type
|
// Binding Type
|
||||||
|
@ -194,6 +100,8 @@ namespace InputManager
|
||||||
static void AddBindings(const std::vector<std::string>& bindings, const InputEventHandler& handler);
|
static void AddBindings(const std::vector<std::string>& bindings, const InputEventHandler& handler);
|
||||||
static bool ParseBindingAndGetSource(const std::string_view& binding, InputBindingKey* key, InputSource** source);
|
static bool ParseBindingAndGetSource(const std::string_view& binding, InputBindingKey* key, InputSource** source);
|
||||||
|
|
||||||
|
static bool IsAxisHandler(const InputEventHandler& handler);
|
||||||
|
|
||||||
static void AddHotkeyBindings(SettingsInterface& si);
|
static void AddHotkeyBindings(SettingsInterface& si);
|
||||||
static void AddPadBindings(SettingsInterface& si, u32 pad, const char* default_type);
|
static void AddPadBindings(SettingsInterface& si, u32 pad, const char* default_type);
|
||||||
static void UpdateContinuedVibration();
|
static void UpdateContinuedVibration();
|
||||||
|
@ -639,6 +547,11 @@ bool InputManager::HasAnyBindingsForKey(InputBindingKey key)
|
||||||
return (s_binding_map.find(key.MaskDirection()) != s_binding_map.end());
|
return (s_binding_map.find(key.MaskDirection()) != s_binding_map.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool InputManager::IsAxisHandler(const InputEventHandler& handler)
|
||||||
|
{
|
||||||
|
return std::holds_alternative<InputAxisEventHandler>(handler);
|
||||||
|
}
|
||||||
|
|
||||||
bool InputManager::InvokeEvents(InputBindingKey key, float value)
|
bool InputManager::InvokeEvents(InputBindingKey key, float value)
|
||||||
{
|
{
|
||||||
if (DoEventHook(key, value))
|
if (DoEventHook(key, value))
|
||||||
|
@ -658,7 +571,7 @@ bool InputManager::InvokeEvents(InputBindingKey key, float value)
|
||||||
for (auto it = range.first; it != range.second; ++it)
|
for (auto it = range.first; it != range.second; ++it)
|
||||||
{
|
{
|
||||||
InputBinding* binding = it->second.get();
|
InputBinding* binding = it->second.get();
|
||||||
if (binding->handler.IsAxis())
|
if (IsAxisHandler(binding->handler))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// find the key which matches us
|
// find the key which matches us
|
||||||
|
@ -702,7 +615,7 @@ bool InputManager::InvokeEvents(InputBindingKey key, float value)
|
||||||
|
|
||||||
// Don't register the key press when we're part of a longer chord. That way,
|
// Don't register the key press when we're part of a longer chord. That way,
|
||||||
// the state won't change, and it won't get the released event either.
|
// the state won't change, and it won't get the released event either.
|
||||||
if (longest_hotkey_binding && new_state && !binding->handler.IsAxis() &&
|
if (longest_hotkey_binding && new_state && !IsAxisHandler(binding->handler) &&
|
||||||
binding->num_keys != longest_hotkey_binding->num_keys)
|
binding->num_keys != longest_hotkey_binding->num_keys)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
@ -719,11 +632,18 @@ bool InputManager::InvokeEvents(InputBindingKey key, float value)
|
||||||
0.0f);
|
0.0f);
|
||||||
|
|
||||||
// axes are fired regardless of a state change, unless they're zero
|
// axes are fired regardless of a state change, unless they're zero
|
||||||
|
// (but going from not-zero to zero will still fire, because of the full state)
|
||||||
// for buttons, we can use the state of the last chord key, because it'll be 1 on press,
|
// for buttons, we can use the state of the last chord key, because it'll be 1 on press,
|
||||||
// and 0 on release (when the full state changes).
|
// and 0 on release (when the full state changes).
|
||||||
if (prev_full_state != new_full_state || (binding->handler.IsAxis() && value_to_pass > 0.0f))
|
if (IsAxisHandler(binding->handler))
|
||||||
{
|
{
|
||||||
binding->handler.Invoke(value_to_pass);
|
if (prev_full_state != new_full_state || value_to_pass >= 0.0f)
|
||||||
|
std::get<InputAxisEventHandler>(binding->handler)(value_to_pass);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (prev_full_state != new_full_state)
|
||||||
|
std::get<InputButtonEventHandler>(binding->handler)(value_to_pass > 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
// bail out, since we shouldn't have the same key twice in the chord
|
// bail out, since we shouldn't have the same key twice in the chord
|
||||||
|
|
Loading…
Reference in New Issue