mirror of
https://github.com/Redot-Engine/redot-engine.git
synced 2025-12-05 23:07:42 -05:00
Add methods to check which event first triggered "just pressed/released" state.
This commit is contained in:
@@ -123,6 +123,8 @@ void Input::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("is_action_pressed", "action", "exact_match"), &Input::is_action_pressed, DEFVAL(false));
|
||||
ClassDB::bind_method(D_METHOD("is_action_just_pressed", "action", "exact_match"), &Input::is_action_just_pressed, DEFVAL(false));
|
||||
ClassDB::bind_method(D_METHOD("is_action_just_released", "action", "exact_match"), &Input::is_action_just_released, DEFVAL(false));
|
||||
ClassDB::bind_method(D_METHOD("is_action_just_pressed_by_event", "action", "event", "exact_match"), &Input::is_action_just_pressed_by_event, DEFVAL(false));
|
||||
ClassDB::bind_method(D_METHOD("is_action_just_released_by_event", "action", "event", "exact_match"), &Input::is_action_just_released_by_event, DEFVAL(false));
|
||||
ClassDB::bind_method(D_METHOD("get_action_strength", "action", "exact_match"), &Input::get_action_strength, DEFVAL(false));
|
||||
ClassDB::bind_method(D_METHOD("get_action_raw_strength", "action", "exact_match"), &Input::get_action_raw_strength, DEFVAL(false));
|
||||
ClassDB::bind_method(D_METHOD("get_axis", "negative_action", "positive_action"), &Input::get_axis);
|
||||
@@ -411,6 +413,37 @@ bool Input::is_action_just_pressed(const StringName &p_action, bool p_exact) con
|
||||
}
|
||||
}
|
||||
|
||||
bool Input::is_action_just_pressed_by_event(const StringName &p_action, const Ref<InputEvent> &p_event, bool p_exact) const {
|
||||
ERR_FAIL_COND_V_MSG(!InputMap::get_singleton()->has_action(p_action), false, InputMap::get_singleton()->suggest_actions(p_action));
|
||||
ERR_FAIL_COND_V(p_event.is_null(), false);
|
||||
|
||||
if (disable_input) {
|
||||
return false;
|
||||
}
|
||||
|
||||
HashMap<StringName, ActionState>::ConstIterator E = action_states.find(p_action);
|
||||
if (!E) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (p_exact && E->value.exact == false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (E->value.pressed_event_id != p_event->get_instance_id()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Backward compatibility for legacy behavior, only return true if currently pressed.
|
||||
bool pressed_requirement = legacy_just_pressed_behavior ? E->value.cache.pressed : true;
|
||||
|
||||
if (Engine::get_singleton()->is_in_physics_frame()) {
|
||||
return pressed_requirement && E->value.pressed_physics_frame == Engine::get_singleton()->get_physics_frames();
|
||||
} else {
|
||||
return pressed_requirement && E->value.pressed_process_frame == Engine::get_singleton()->get_process_frames();
|
||||
}
|
||||
}
|
||||
|
||||
bool Input::is_action_just_released(const StringName &p_action, bool p_exact) const {
|
||||
ERR_FAIL_COND_V_MSG(!InputMap::get_singleton()->has_action(p_action), false, InputMap::get_singleton()->suggest_actions(p_action));
|
||||
|
||||
@@ -437,6 +470,37 @@ bool Input::is_action_just_released(const StringName &p_action, bool p_exact) co
|
||||
}
|
||||
}
|
||||
|
||||
bool Input::is_action_just_released_by_event(const StringName &p_action, const Ref<InputEvent> &p_event, bool p_exact) const {
|
||||
ERR_FAIL_COND_V_MSG(!InputMap::get_singleton()->has_action(p_action), false, InputMap::get_singleton()->suggest_actions(p_action));
|
||||
ERR_FAIL_COND_V(p_event.is_null(), false);
|
||||
|
||||
if (disable_input) {
|
||||
return false;
|
||||
}
|
||||
|
||||
HashMap<StringName, ActionState>::ConstIterator E = action_states.find(p_action);
|
||||
if (!E) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (p_exact && E->value.exact == false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (E->value.released_event_id != p_event->get_instance_id()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Backward compatibility for legacy behavior, only return true if currently released.
|
||||
bool released_requirement = legacy_just_pressed_behavior ? !E->value.cache.pressed : true;
|
||||
|
||||
if (Engine::get_singleton()->is_in_physics_frame()) {
|
||||
return released_requirement && E->value.released_physics_frame == Engine::get_singleton()->get_physics_frames();
|
||||
} else {
|
||||
return released_requirement && E->value.released_process_frame == Engine::get_singleton()->get_process_frames();
|
||||
}
|
||||
}
|
||||
|
||||
float Input::get_action_strength(const StringName &p_action, bool p_exact) const {
|
||||
ERR_FAIL_COND_V_MSG(!InputMap::get_singleton()->has_action(p_action), 0.0, InputMap::get_singleton()->suggest_actions(p_action));
|
||||
|
||||
@@ -895,10 +959,12 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
|
||||
_update_action_cache(E.key, action_state);
|
||||
// As input may come in part way through a physics tick, the earliest we can react to it is the next physics tick.
|
||||
if (action_state.cache.pressed && !was_pressed) {
|
||||
action_state.pressed_event_id = p_event->get_instance_id();
|
||||
action_state.pressed_physics_frame = Engine::get_singleton()->get_physics_frames() + 1;
|
||||
action_state.pressed_process_frame = Engine::get_singleton()->get_process_frames();
|
||||
}
|
||||
if (!action_state.cache.pressed && was_pressed) {
|
||||
action_state.released_event_id = p_event->get_instance_id();
|
||||
action_state.released_physics_frame = Engine::get_singleton()->get_physics_frames() + 1;
|
||||
action_state.released_process_frame = Engine::get_singleton()->get_process_frames();
|
||||
}
|
||||
@@ -1027,6 +1093,7 @@ void Input::action_press(const StringName &p_action, float p_strength) {
|
||||
|
||||
// As input may come in part way through a physics tick, the earliest we can react to it is the next physics tick.
|
||||
if (!action_state.cache.pressed) {
|
||||
action_state.pressed_event_id = ObjectID();
|
||||
action_state.pressed_physics_frame = Engine::get_singleton()->get_physics_frames() + 1;
|
||||
action_state.pressed_process_frame = Engine::get_singleton()->get_process_frames();
|
||||
}
|
||||
@@ -1045,6 +1112,7 @@ void Input::action_release(const StringName &p_action) {
|
||||
action_state.cache.strength = 0.0;
|
||||
action_state.cache.raw_strength = 0.0;
|
||||
// As input may come in part way through a physics tick, the earliest we can react to it is the next physics tick.
|
||||
action_state.released_event_id = ObjectID();
|
||||
action_state.released_physics_frame = Engine::get_singleton()->get_physics_frames() + 1;
|
||||
action_state.released_process_frame = Engine::get_singleton()->get_process_frames();
|
||||
action_state.device_states.clear();
|
||||
|
||||
@@ -109,6 +109,8 @@ private:
|
||||
uint64_t pressed_process_frame = UINT64_MAX;
|
||||
uint64_t released_physics_frame = UINT64_MAX;
|
||||
uint64_t released_process_frame = UINT64_MAX;
|
||||
ObjectID pressed_event_id;
|
||||
ObjectID released_event_id;
|
||||
bool exact = true;
|
||||
|
||||
struct DeviceState {
|
||||
@@ -306,6 +308,8 @@ public:
|
||||
bool is_action_pressed(const StringName &p_action, bool p_exact = false) const;
|
||||
bool is_action_just_pressed(const StringName &p_action, bool p_exact = false) const;
|
||||
bool is_action_just_released(const StringName &p_action, bool p_exact = false) const;
|
||||
bool is_action_just_pressed_by_event(const StringName &p_action, const Ref<InputEvent> &p_event, bool p_exact = false) const;
|
||||
bool is_action_just_released_by_event(const StringName &p_action, const Ref<InputEvent> &p_event, bool p_exact = false) const;
|
||||
float get_action_strength(const StringName &p_action, bool p_exact = false) const;
|
||||
float get_action_raw_strength(const StringName &p_action, bool p_exact = false) const;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user