Backported the CallInputType parameter for SceneTree::_call_input_pause() from godot4.

This commit is contained in:
Relintai 2023-09-07 07:40:45 +02:00
parent 448825acc1
commit 7fcc653a0e
3 changed files with 83 additions and 62 deletions

View File

@ -1142,64 +1142,6 @@ bool SceneTree::is_paused() const {
return pause;
}
void SceneTree::_call_input_pause(const StringName &p_group, const StringName &p_method, const Ref<InputEvent> &p_input) {
Vector<Node *> nodes_copy;
{
_THREAD_SAFE_METHOD_
RBMap<StringName, Group>::Element *E = group_map.find(p_group);
if (!E) {
return;
}
Group &g = E->get();
if (g.nodes.empty()) {
return;
}
_update_group_order(g);
//copy, so copy on write happens in case something is removed from process while being called
//performance is not lost because only if something is added/removed the vector is copied.
nodes_copy = g.nodes;
}
int node_count = nodes_copy.size();
Node **nodes = nodes_copy.ptrw();
Variant arg = p_input;
const Variant *v[1] = { &arg };
_THREAD_SAFE_LOCK_
call_lock++;
_THREAD_SAFE_UNLOCK_
for (int i = node_count - 1; i >= 0; i--) {
if (input_handled) {
break;
}
Node *n = nodes[i];
if (call_lock && call_skip.has(n)) {
continue;
}
if (!n->can_process()) {
continue;
}
n->call_multilevel(p_method, (const Variant **)v, 1);
//ERR_FAIL_COND(node_count != g.nodes.size());
}
_THREAD_SAFE_LOCK_
call_lock--;
if (call_lock == 0) {
call_skip.clear();
}
_THREAD_SAFE_UNLOCK_
}
void SceneTree::_notify_group_pause(const StringName &p_group, int p_notification) {
Vector<Node *> nodes_copy;
@ -1305,6 +1247,78 @@ Variant SceneTree::_call_group(const Variant **p_args, int p_argcount, Variant::
return Variant();
}
void SceneTree::_call_input_pause(const StringName &p_group, const CallInputType p_call_type, const Ref<InputEvent> &p_input) {
Vector<Node *> nodes_copy;
{
_THREAD_SAFE_METHOD_
RBMap<StringName, Group>::Element *E = group_map.find(p_group);
if (!E) {
return;
}
Group &g = E->get();
if (g.nodes.empty()) {
return;
}
_update_group_order(g);
//copy, so copy on write happens in case something is removed from process while being called
//performance is not lost because only if something is added/removed the vector is copied.
nodes_copy = g.nodes;
}
int node_count = nodes_copy.size();
Node **nodes = nodes_copy.ptrw();
Variant arg = p_input;
const Variant *v[1] = { &arg };
_THREAD_SAFE_LOCK_
call_lock++;
_THREAD_SAFE_UNLOCK_
StringName method;
switch (p_call_type) {
case CALL_INPUT_TYPE_INPUT:
method = SceneStringNames::get_singleton()->_input;
break;
case CALL_INPUT_TYPE_UNHANDLED_INPUT:
method = SceneStringNames::get_singleton()->_unhandled_input;
break;
case CALL_INPUT_TYPE_UNHANDLED_KEY_INPUT:
method = SceneStringNames::get_singleton()->_unhandled_input;
break;
}
for (int i = node_count - 1; i >= 0; i--) {
if (input_handled) {
break;
}
Node *n = nodes[i];
if (call_lock && call_skip.has(n)) {
continue;
}
if (!n->can_process()) {
continue;
}
n->call_multilevel(method, (const Variant **)v, 1);
//ERR_FAIL_COND(node_count != g.nodes.size());
}
_THREAD_SAFE_LOCK_
call_lock--;
if (call_lock == 0) {
call_skip.clear();
}
_THREAD_SAFE_UNLOCK_
}
int64_t SceneTree::get_frame() const {
return current_frame;
}

View File

@ -219,10 +219,17 @@ private:
void make_group_changed(const StringName &p_group);
void _notify_group_pause(const StringName &p_group, int p_notification);
void _call_input_pause(const StringName &p_group, const StringName &p_method, const Ref<InputEvent> &p_input);
Variant _call_group_flags(const Variant **p_args, int p_argcount, Variant::CallError &r_error);
Variant _call_group(const Variant **p_args, int p_argcount, Variant::CallError &r_error);
enum CallInputType {
CALL_INPUT_TYPE_INPUT,
CALL_INPUT_TYPE_UNHANDLED_INPUT,
CALL_INPUT_TYPE_UNHANDLED_KEY_INPUT,
};
void _call_input_pause(const StringName &p_group, const CallInputType p_call_type, const Ref<InputEvent> &p_input);
void _flush_delete_queue();
//optimization
friend class CanvasItem;

View File

@ -2812,7 +2812,7 @@ void Viewport::input(const Ref<InputEvent> &p_event) {
local_input_handled = false;
if (!is_input_handled()) {
get_tree()->_call_input_pause(input_group, "_input", p_event); //not a bug, must happen before GUI, order is _input -> gui input -> _unhandled input
get_tree()->_call_input_pause(input_group, SceneTree::CALL_INPUT_TYPE_INPUT, p_event); //not a bug, must happen before GUI, order is _input -> gui input -> _unhandled input
}
if (!is_input_handled()) {
@ -2827,10 +2827,10 @@ void Viewport::input(const Ref<InputEvent> &p_event) {
void Viewport::unhandled_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(!is_inside_tree());
get_tree()->_call_input_pause(unhandled_input_group, "_unhandled_input", p_event);
get_tree()->_call_input_pause(unhandled_input_group, SceneTree::CALL_INPUT_TYPE_UNHANDLED_INPUT, p_event);
//call_group(GROUP_CALL_REVERSE|GROUP_CALL_REALTIME|GROUP_CALL_MULIILEVEL,"unhandled_input","_unhandled_input",ev);
if (!get_tree()->input_handled && Object::cast_to<InputEventKey>(*p_event) != nullptr) {
get_tree()->_call_input_pause(unhandled_key_input_group, "_unhandled_key_input", p_event);
get_tree()->_call_input_pause(unhandled_key_input_group, SceneTree::CALL_INPUT_TYPE_UNHANDLED_KEY_INPUT, p_event);
//call_group(GROUP_CALL_REVERSE|GROUP_CALL_REALTIME|GROUP_CALL_MULIILEVEL,"unhandled_key_input","_unhandled_key_input",ev);
}