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 <sstream>
|
||||
#include <unordered_map>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -45,102 +46,7 @@ enum : u32
|
|||
// This class acts as an adapter to convert from normalized values to
|
||||
// binary values when the callback is a binary/button handler. That way
|
||||
// you don't need to convert float->bool in your callbacks.
|
||||
|
||||
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;
|
||||
};
|
||||
using InputEventHandler = std::variant<InputAxisEventHandler, InputButtonEventHandler>;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Binding Type
|
||||
|
@ -194,6 +100,8 @@ namespace InputManager
|
|||
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 IsAxisHandler(const InputEventHandler& handler);
|
||||
|
||||
static void AddHotkeyBindings(SettingsInterface& si);
|
||||
static void AddPadBindings(SettingsInterface& si, u32 pad, const char* default_type);
|
||||
static void UpdateContinuedVibration();
|
||||
|
@ -639,6 +547,11 @@ bool InputManager::HasAnyBindingsForKey(InputBindingKey key)
|
|||
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)
|
||||
{
|
||||
if (DoEventHook(key, value))
|
||||
|
@ -658,7 +571,7 @@ bool InputManager::InvokeEvents(InputBindingKey key, float value)
|
|||
for (auto it = range.first; it != range.second; ++it)
|
||||
{
|
||||
InputBinding* binding = it->second.get();
|
||||
if (binding->handler.IsAxis())
|
||||
if (IsAxisHandler(binding->handler))
|
||||
continue;
|
||||
|
||||
// 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,
|
||||
// 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)
|
||||
{
|
||||
continue;
|
||||
|
@ -719,11 +632,18 @@ bool InputManager::InvokeEvents(InputBindingKey key, float value)
|
|||
0.0f);
|
||||
|
||||
// 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,
|
||||
// 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
|
||||
|
|
Loading…
Reference in New Issue