From dc1c4cfbfa7a5da8e26f21b2a180c68d3e241c50 Mon Sep 17 00:00:00 2001 From: Nathan Franke Date: Sat, 23 Oct 2021 22:38:32 -0500 Subject: [PATCH] Fix action exact match --- core/input/input_event.cpp | 106 +++++++++++++++++++------------------ core/input/input_event.h | 12 ++--- core/input/input_map.cpp | 42 +++++---------- core/input/input_map.h | 4 +- 4 files changed, 77 insertions(+), 87 deletions(-) diff --git a/core/input/input_event.cpp b/core/input/input_event.cpp index c608076a21b..4e18efde811 100644 --- a/core/input/input_event.cpp +++ b/core/input/input_event.cpp @@ -86,7 +86,7 @@ Ref InputEvent::xformed_by(const Transform2D &p_xform, const Vector2 return Ref((InputEvent *)this); } -bool InputEvent::action_match(const Ref &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const { +bool InputEvent::action_match(const Ref &p_event, bool p_exact_match, float p_deadzone, bool *r_pressed, float *r_strength, float *r_raw_strength) const { return false; } @@ -412,35 +412,32 @@ Ref InputEventKey::create_reference(Key p_keycode) { return ie; } -bool InputEventKey::action_match(const Ref &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const { +bool InputEventKey::action_match(const Ref &p_event, bool p_exact_match, float p_deadzone, bool *r_pressed, float *r_strength, float *r_raw_strength) const { Ref key = p_event; if (key.is_null()) { return false; } - bool match = false; - if (get_keycode() == Key::NONE) { - Key code = get_physical_keycode_with_modifiers(); - Key event_code = key->get_physical_keycode_with_modifiers(); - - match = get_physical_keycode() == key->get_physical_keycode() && (!key->is_pressed() || (code & event_code) == code); + bool match; + if (keycode != Key::NONE) { + match = keycode == key->keycode; } else { - Key code = get_keycode_with_modifiers(); - Key event_code = key->get_keycode_with_modifiers(); - - match = get_keycode() == key->get_keycode() && (!key->is_pressed() || (code & event_code) == code); + match = get_physical_keycode() == key->get_physical_keycode(); + } + if (p_exact_match) { + match &= get_modifiers_mask() == key->get_modifiers_mask(); } if (match) { bool pressed = key->is_pressed(); - if (p_pressed != nullptr) { - *p_pressed = pressed; + if (r_pressed != nullptr) { + *r_pressed = pressed; } float strength = pressed ? 1.0f : 0.0f; - if (p_strength != nullptr) { - *p_strength = strength; + if (r_strength != nullptr) { + *r_strength = strength; } - if (p_raw_strength != nullptr) { - *p_raw_strength = strength; + if (r_raw_strength != nullptr) { + *r_raw_strength = strength; } } return match; @@ -585,24 +582,27 @@ Ref InputEventMouseButton::xformed_by(const Transform2D &p_xform, co return mb; } -bool InputEventMouseButton::action_match(const Ref &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const { +bool InputEventMouseButton::action_match(const Ref &p_event, bool p_exact_match, float p_deadzone, bool *r_pressed, float *r_strength, float *r_raw_strength) const { Ref mb = p_event; if (mb.is_null()) { return false; } - bool match = mb->button_index == button_index; + bool match = button_index == mb->button_index; + if (p_exact_match) { + match &= get_modifiers_mask() == mb->get_modifiers_mask(); + } if (match) { bool pressed = mb->is_pressed(); - if (p_pressed != nullptr) { - *p_pressed = pressed; + if (r_pressed != nullptr) { + *r_pressed = pressed; } float strength = pressed ? 1.0f : 0.0f; - if (p_strength != nullptr) { - *p_strength = strength; + if (r_strength != nullptr) { + *r_strength = strength; } - if (p_raw_strength != nullptr) { - *p_raw_strength = strength; + if (r_raw_strength != nullptr) { + *r_raw_strength = strength; } } @@ -887,36 +887,40 @@ bool InputEventJoypadMotion::is_pressed() const { return Math::abs(axis_value) >= 0.5f; } -bool InputEventJoypadMotion::action_match(const Ref &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const { +bool InputEventJoypadMotion::action_match(const Ref &p_event, bool p_exact_match, float p_deadzone, bool *r_pressed, float *r_strength, float *r_raw_strength) const { Ref jm = p_event; if (jm.is_null()) { return false; } - bool match = (axis == jm->axis); // Matches even if not in the same direction, but returns a "not pressed" event. + // Matches even if not in the same direction, but returns a "not pressed" event. + bool match = axis == jm->axis; + if (p_exact_match) { + match &= (axis_value < 0) == (jm->axis_value < 0); + } if (match) { float jm_abs_axis_value = Math::abs(jm->get_axis_value()); bool same_direction = (((axis_value < 0) == (jm->axis_value < 0)) || jm->axis_value == 0); bool pressed = same_direction && jm_abs_axis_value >= p_deadzone; - if (p_pressed != nullptr) { - *p_pressed = pressed; + if (r_pressed != nullptr) { + *r_pressed = pressed; } - if (p_strength != nullptr) { + if (r_strength != nullptr) { if (pressed) { if (p_deadzone == 1.0f) { - *p_strength = 1.0f; + *r_strength = 1.0f; } else { - *p_strength = CLAMP(Math::inverse_lerp(p_deadzone, 1.0f, jm_abs_axis_value), 0.0f, 1.0f); + *r_strength = CLAMP(Math::inverse_lerp(p_deadzone, 1.0f, jm_abs_axis_value), 0.0f, 1.0f); } } else { - *p_strength = 0.0f; + *r_strength = 0.0f; } } - if (p_raw_strength != nullptr) { + if (r_raw_strength != nullptr) { if (same_direction) { // NOT pressed, because we want to ignore the deadzone. - *p_raw_strength = jm_abs_axis_value; + *r_raw_strength = jm_abs_axis_value; } else { - *p_raw_strength = 0.0f; + *r_raw_strength = 0.0f; } } } @@ -994,7 +998,7 @@ float InputEventJoypadButton::get_pressure() const { return pressure; } -bool InputEventJoypadButton::action_match(const Ref &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const { +bool InputEventJoypadButton::action_match(const Ref &p_event, bool p_exact_match, float p_deadzone, bool *r_pressed, float *r_strength, float *r_raw_strength) const { Ref jb = p_event; if (jb.is_null()) { return false; @@ -1003,15 +1007,15 @@ bool InputEventJoypadButton::action_match(const Ref &p_event, bool * bool match = button_index == jb->button_index; if (match) { bool pressed = jb->is_pressed(); - if (p_pressed != nullptr) { - *p_pressed = pressed; + if (r_pressed != nullptr) { + *r_pressed = pressed; } float strength = pressed ? 1.0f : 0.0f; - if (p_strength != nullptr) { - *p_strength = strength; + if (r_strength != nullptr) { + *r_strength = strength; } - if (p_raw_strength != nullptr) { - *p_raw_strength = strength; + if (r_raw_strength != nullptr) { + *r_raw_strength = strength; } } @@ -1288,7 +1292,7 @@ bool InputEventAction::is_action(const StringName &p_action) const { return action == p_action; } -bool InputEventAction::action_match(const Ref &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const { +bool InputEventAction::action_match(const Ref &p_event, bool p_exact_match, float p_deadzone, bool *r_pressed, float *r_strength, float *r_raw_strength) const { Ref act = p_event; if (act.is_null()) { return false; @@ -1297,15 +1301,15 @@ bool InputEventAction::action_match(const Ref &p_event, bool *p_pres bool match = action == act->action; if (match) { bool pressed = act->pressed; - if (p_pressed != nullptr) { - *p_pressed = pressed; + if (r_pressed != nullptr) { + *r_pressed = pressed; } float strength = pressed ? 1.0f : 0.0f; - if (p_strength != nullptr) { - *p_strength = strength; + if (r_strength != nullptr) { + *r_strength = strength; } - if (p_raw_strength != nullptr) { - *p_raw_strength = strength; + if (r_raw_strength != nullptr) { + *r_raw_strength = strength; } } return match; diff --git a/core/input/input_event.h b/core/input/input_event.h index 29450dfc52c..114db466232 100644 --- a/core/input/input_event.h +++ b/core/input/input_event.h @@ -79,7 +79,7 @@ public: virtual Ref xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const; - virtual bool action_match(const Ref &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const; + virtual bool action_match(const Ref &p_event, bool p_exact_match, float p_deadzone, bool *r_pressed, float *r_strength, float *r_raw_strength) const; virtual bool is_match(const Ref &p_event, bool p_exact_match = true) const; virtual bool is_action_type() const; @@ -192,7 +192,7 @@ public: Key get_keycode_with_modifiers() const; Key get_physical_keycode_with_modifiers() const; - virtual bool action_match(const Ref &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const override; + virtual bool action_match(const Ref &p_event, bool p_exact_match, float p_deadzone, bool *r_pressed, float *r_strength, float *r_raw_strength) const override; virtual bool is_match(const Ref &p_event, bool p_exact_match = true) const override; virtual bool is_action_type() const override { return true; } @@ -255,7 +255,7 @@ public: virtual Ref xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const override; - virtual bool action_match(const Ref &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const override; + virtual bool action_match(const Ref &p_event, bool p_exact_match, float p_deadzone, bool *r_pressed, float *r_strength, float *r_raw_strength) const override; virtual bool is_match(const Ref &p_event, bool p_exact_match = true) const override; virtual bool is_action_type() const override { return true; } @@ -315,7 +315,7 @@ public: virtual bool is_pressed() const override; - virtual bool action_match(const Ref &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const override; + virtual bool action_match(const Ref &p_event, bool p_exact_match, float p_deadzone, bool *r_pressed, float *r_strength, float *r_raw_strength) const override; virtual bool is_match(const Ref &p_event, bool p_exact_match = true) const override; virtual bool is_action_type() const override { return true; } @@ -344,7 +344,7 @@ public: void set_pressure(float p_pressure); float get_pressure() const; - virtual bool action_match(const Ref &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const override; + virtual bool action_match(const Ref &p_event, bool p_exact_match, float p_deadzone, bool *r_pressed, float *r_strength, float *r_raw_strength) const override; virtual bool is_match(const Ref &p_event, bool p_exact_match = true) const override; virtual bool is_action_type() const override { return true; } @@ -437,7 +437,7 @@ public: virtual bool is_action(const StringName &p_action) const; - virtual bool action_match(const Ref &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const override; + virtual bool action_match(const Ref &p_event, bool p_exact_match, float p_deadzone, bool *r_pressed, float *r_strength, float *r_raw_strength) const override; virtual bool is_match(const Ref &p_event, bool p_exact_match = true) const override; virtual bool is_action_type() const override { return true; } diff --git a/core/input/input_map.cpp b/core/input/input_map.cpp index 753ac72ab6c..41083b4c473 100644 --- a/core/input/input_map.cpp +++ b/core/input/input_map.cpp @@ -126,15 +126,13 @@ List InputMap::get_actions() const { return actions; } -List>::Element *InputMap::_find_event(Action &p_action, const Ref &p_event, bool p_exact_match, bool *p_pressed, float *p_strength, float *p_raw_strength) const { +List>::Element *InputMap::_find_event(Action &p_action, const Ref &p_event, bool p_exact_match, bool *r_pressed, float *r_strength, float *r_raw_strength) const { ERR_FAIL_COND_V(!p_event.is_valid(), nullptr); for (List>::Element *E = p_action.inputs.front(); E; E = E->next()) { int device = E->get()->get_device(); if (device == ALL_DEVICES || device == p_event->get_device()) { - if (p_exact_match && E->get()->is_match(p_event, true)) { - return E; - } else if (!p_exact_match && E->get()->action_match(p_event, p_pressed, p_strength, p_raw_strength, p_action.deadzone)) { + if (E->get()->action_match(p_event, p_exact_match, p_action.deadzone, r_pressed, r_strength, r_raw_strength)) { return E; } } @@ -217,40 +215,28 @@ bool InputMap::event_is_action(const Ref &p_event, const StringName return event_get_action_status(p_event, p_action, p_exact_match); } -bool InputMap::event_get_action_status(const Ref &p_event, const StringName &p_action, bool p_exact_match, bool *p_pressed, float *p_strength, float *p_raw_strength) const { +bool InputMap::event_get_action_status(const Ref &p_event, const StringName &p_action, bool p_exact_match, bool *r_pressed, float *r_strength, float *r_raw_strength) const { OrderedHashMap::Element E = input_map.find(p_action); ERR_FAIL_COND_V_MSG(!E, false, suggest_actions(p_action)); Ref input_event_action = p_event; if (input_event_action.is_valid()) { - bool pressed = input_event_action->is_pressed(); - if (p_pressed != nullptr) { - *p_pressed = pressed; + const bool pressed = input_event_action->is_pressed(); + if (r_pressed != nullptr) { + *r_pressed = pressed; } - if (p_strength != nullptr) { - *p_strength = pressed ? input_event_action->get_strength() : 0.0f; + const float strength = pressed ? input_event_action->get_strength() : 0.0f; + if (r_strength != nullptr) { + *r_strength = strength; + } + if (r_raw_strength != nullptr) { + *r_raw_strength = strength; } return input_event_action->get_action() == p_action; } - bool pressed; - float strength; - float raw_strength; - List>::Element *event = _find_event(E.get(), p_event, p_exact_match, &pressed, &strength, &raw_strength); - if (event != nullptr) { - if (p_pressed != nullptr) { - *p_pressed = pressed; - } - if (p_strength != nullptr) { - *p_strength = strength; - } - if (p_raw_strength != nullptr) { - *p_raw_strength = raw_strength; - } - return true; - } else { - return false; - } + List>::Element *event = _find_event(E.get(), p_event, p_exact_match, r_pressed, r_strength, r_raw_strength); + return event != nullptr; } const OrderedHashMap &InputMap::get_action_map() const { diff --git a/core/input/input_map.h b/core/input/input_map.h index e896d1f679f..79b4d1038fc 100644 --- a/core/input/input_map.h +++ b/core/input/input_map.h @@ -58,7 +58,7 @@ private: OrderedHashMap>> default_builtin_cache; OrderedHashMap>> default_builtin_with_overrides_cache; - List>::Element *_find_event(Action &p_action, const Ref &p_event, bool p_exact_match = false, bool *p_pressed = nullptr, float *p_strength = nullptr, float *p_raw_strength = nullptr) const; + List>::Element *_find_event(Action &p_action, const Ref &p_event, bool p_exact_match = false, bool *r_pressed = nullptr, float *r_strength = nullptr, float *r_raw_strength = nullptr) const; Array _action_get_events(const StringName &p_action); Array _get_actions(); @@ -83,7 +83,7 @@ public: const List> *action_get_events(const StringName &p_action); bool event_is_action(const Ref &p_event, const StringName &p_action, bool p_exact_match = false) const; - bool event_get_action_status(const Ref &p_event, const StringName &p_action, bool p_exact_match = false, bool *p_pressed = nullptr, float *p_strength = nullptr, float *p_raw_strength = nullptr) const; + bool event_get_action_status(const Ref &p_event, const StringName &p_action, bool p_exact_match = false, bool *r_pressed = nullptr, float *r_strength = nullptr, float *r_raw_strength = nullptr) const; const OrderedHashMap &get_action_map() const; void load_from_project_settings();