diff options
author | reduz <reduzio@gmail.com> | 2021-08-22 12:37:22 -0300 |
---|---|---|
committer | reduz <reduzio@gmail.com> | 2021-08-23 08:10:13 -0300 |
commit | 5cecdfa8afb91a60305b429f5b738e27dadbc83f (patch) | |
tree | 40bf21e1beae1a6883770d2ac0473222ff41ae65 /scene/main | |
parent | 2d446771d6701bb77432b6df5a768e53c9a6c95d (diff) |
Entirely removes BIND_VMETHOD in favor of GDVIRTUAL
* `_gui_input`, `_input`, `_unhandled_input` and `_unhandled_key_input` are now regular C++ virutal functions.
* Everything else converted to GDVIRTUAL
* BIND_VMETHOD is gone, always use the new syntax from now on.
Creating `_gui_input` method and using the binder to register events will no longer work, simply override the virtual function now.
Diffstat (limited to 'scene/main')
-rw-r--r-- | scene/main/node.cpp | 56 | ||||
-rw-r--r-- | scene/main/node.h | 15 | ||||
-rw-r--r-- | scene/main/scene_tree.cpp | 23 | ||||
-rw-r--r-- | scene/main/scene_tree.h | 8 | ||||
-rw-r--r-- | scene/main/viewport.cpp | 59 | ||||
-rw-r--r-- | scene/main/viewport.h | 6 | ||||
-rw-r--r-- | scene/main/window.cpp | 6 |
7 files changed, 102 insertions, 71 deletions
diff --git a/scene/main/node.cpp b/scene/main/node.cpp index 1d617d1ff7..4ea4579bf9 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -123,15 +123,15 @@ void Node::_notification(int p_notification) { } break; case NOTIFICATION_READY: { if (get_script_instance()) { - if (get_script_instance()->has_method(SceneStringNames::get_singleton()->_input)) { + if (GDVIRTUAL_IS_OVERRIDEN(_input)) { set_process_input(true); } - if (get_script_instance()->has_method(SceneStringNames::get_singleton()->_unhandled_input)) { + if (GDVIRTUAL_IS_OVERRIDEN(_unhandled_input)) { set_process_unhandled_input(true); } - if (get_script_instance()->has_method(SceneStringNames::get_singleton()->_unhandled_key_input)) { + if (GDVIRTUAL_IS_OVERRIDEN(_unhandled_key_input)) { set_process_unhandled_key_input(true); } @@ -2487,9 +2487,14 @@ void Node::clear_internal_tree_resource_paths() { } TypedArray<String> Node::get_configuration_warnings() const { - if (get_script_instance() && get_script_instance()->get_script().is_valid() && - get_script_instance()->get_script()->is_tool() && get_script_instance()->has_method("_get_configuration_warnings")) { - return get_script_instance()->call("_get_configuration_warnings"); + Vector<String> warnings; + if (GDVIRTUAL_CALL(_get_configuration_warnings, warnings)) { + TypedArray<String> ret; + ret.resize(warnings.size()); + for (int i = 0; i < warnings.size(); i++) { + ret[i] = warnings[i]; + } + return ret; } return Array(); } @@ -2535,6 +2540,37 @@ void Node::request_ready() { data.ready_first = true; } +void Node::_call_input(const Ref<InputEvent> &p_event) { + GDVIRTUAL_CALL(_input, p_event); + if (!is_inside_tree() || !get_viewport() || get_viewport()->is_input_handled()) { + return; + } + input(p_event); +} +void Node::_call_unhandled_input(const Ref<InputEvent> &p_event) { + GDVIRTUAL_CALL(_unhandled_input, p_event); + if (!is_inside_tree() || !get_viewport() || get_viewport()->is_input_handled()) { + return; + } + unhandled_input(p_event); +} +void Node::_call_unhandled_key_input(const Ref<InputEvent> &p_event) { + GDVIRTUAL_CALL(_unhandled_key_input, p_event); + if (!is_inside_tree() || !get_viewport() || get_viewport()->is_input_handled()) { + return; + } + unhandled_key_input(p_event); +} + +void Node::input(const Ref<InputEvent> &p_event) { +} + +void Node::unhandled_input(const Ref<InputEvent> &p_event) { +} + +void Node::unhandled_key_input(const Ref<InputEvent> &p_key_event) { +} + void Node::_bind_methods() { GLOBAL_DEF("editor/node_naming/name_num_separator", 0); ProjectSettings::get_singleton()->set_custom_property_info("editor/node_naming/name_num_separator", PropertyInfo(Variant::INT, "editor/node_naming/name_num_separator", PROPERTY_HINT_ENUM, "None,Space,Underscore,Dash")); @@ -2734,11 +2770,9 @@ void Node::_bind_methods() { GDVIRTUAL_BIND(_exit_tree); GDVIRTUAL_BIND(_ready); GDVIRTUAL_BIND(_get_configuration_warnings); - - BIND_VMETHOD(MethodInfo("_input", PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"))); - BIND_VMETHOD(MethodInfo("_unhandled_input", PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"))); - BIND_VMETHOD(MethodInfo("_unhandled_key_input", PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEventKey"))); - BIND_VMETHOD(MethodInfo(PropertyInfo(Variant::ARRAY, "", PROPERTY_HINT_ARRAY_TYPE, "String"), "_get_configuration_warnings")); + GDVIRTUAL_BIND(_input, "event"); + GDVIRTUAL_BIND(_unhandled_input, "event"); + GDVIRTUAL_BIND(_unhandled_key_input, "event"); } String Node::_get_name_num_separator() { diff --git a/scene/main/node.h b/scene/main/node.h index 8aa56aa97f..a07accba2f 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -208,12 +208,27 @@ protected: void _set_owner_nocheck(Node *p_owner); void _set_name_nocheck(const StringName &p_name); + //call from SceneTree + void _call_input(const Ref<InputEvent> &p_event); + void _call_unhandled_input(const Ref<InputEvent> &p_event); + void _call_unhandled_key_input(const Ref<InputEvent> &p_event); + +protected: + virtual void input(const Ref<InputEvent> &p_event); + virtual void unhandled_input(const Ref<InputEvent> &p_event); + virtual void unhandled_key_input(const Ref<InputEvent> &p_key_event); + GDVIRTUAL1(_process, double) GDVIRTUAL1(_physics_process, double) GDVIRTUAL0(_enter_tree) GDVIRTUAL0(_exit_tree) GDVIRTUAL0(_ready) GDVIRTUAL0RC(Vector<String>, _get_configuration_warnings) + + GDVIRTUAL1(_input, Ref<InputEvent>) + GDVIRTUAL1(_unhandled_input, Ref<InputEvent>) + GDVIRTUAL1(_unhandled_key_input, Ref<InputEvent>) + public: enum { // you can make your own, but don't use the same numbers as other notifications in other nodes diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index 5b707498a7..8260d0dff5 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -867,7 +867,7 @@ void SceneMainLoop::_update_listener_2d() { */ -void SceneTree::_call_input_pause(const StringName &p_group, const StringName &p_method, const Ref<InputEvent> &p_input, Viewport *p_viewport) { +void SceneTree::_call_input_pause(const StringName &p_group, CallInputType p_call_type, const Ref<InputEvent> &p_input, Viewport *p_viewport) { Map<StringName, Group>::Element *E = group_map.find(p_group); if (!E) { return; @@ -886,9 +886,6 @@ void SceneTree::_call_input_pause(const StringName &p_group, const StringName &p int node_count = nodes_copy.size(); Node **nodes = nodes_copy.ptrw(); - Variant arg = p_input; - const Variant *v[1] = { &arg }; - call_lock++; for (int i = node_count - 1; i >= 0; i--) { @@ -905,14 +902,16 @@ void SceneTree::_call_input_pause(const StringName &p_group, const StringName &p continue; } - Callable::CallError err; - // Call both script and native method. - if (n->get_script_instance()) { - n->get_script_instance()->call(p_method, (const Variant **)v, 1, err); - } - MethodBind *method = ClassDB::get_method(n->get_class_name(), p_method); - if (method) { - method->call(n, (const Variant **)v, 1, err); + switch (p_call_type) { + case CALL_INPUT_TYPE_INPUT: + n->_call_input(p_input); + break; + case CALL_INPUT_TYPE_UNHANDLED_INPUT: + n->_call_unhandled_input(p_input); + break; + case CALL_INPUT_TYPE_UNHANDLED_KEY_INPUT: + n->_call_unhandled_key_input(p_input); + break; } } diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h index cfb95bd6b5..b1b94ae910 100644 --- a/scene/main/scene_tree.h +++ b/scene/main/scene_tree.h @@ -204,8 +204,14 @@ private: void _main_window_close(); void _main_window_go_back(); + enum CallInputType { + CALL_INPUT_TYPE_INPUT, + CALL_INPUT_TYPE_UNHANDLED_INPUT, + CALL_INPUT_TYPE_UNHANDLED_KEY_INPUT, + }; + //used by viewport - void _call_input_pause(const StringName &p_group, const StringName &p_method, const Ref<InputEvent> &p_input, Viewport *p_viewport); + void _call_input_pause(const StringName &p_group, CallInputType p_call_type, const Ref<InputEvent> &p_input, Viewport *p_viewport); protected: void _notification(int p_notification); diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 78fa0985a9..ea2323c651 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -32,6 +32,7 @@ #include "core/core_string_names.h" #include "core/debugger/engine_debugger.h" +#include "core/object/message_queue.h" #include "core/string/translation.h" #include "core/templates/pair.h" #include "scene/2d/camera_2d.h" @@ -662,7 +663,7 @@ void Viewport::_process_picking() { } if (send_event) { - co->_input_event(this, ev, res[i].shape); + co->_input_event_call(this, ev, res[i].shape); } } } @@ -1234,27 +1235,7 @@ void Viewport::_gui_call_input(Control *p_control, const Ref<InputEvent> &p_inpu Control *control = Object::cast_to<Control>(ci); if (control) { if (control->data.mouse_filter != Control::MOUSE_FILTER_IGNORE) { - control->emit_signal(SceneStringNames::get_singleton()->gui_input, ev); //signal should be first, so it's possible to override an event (and then accept it) - } - if (gui.key_event_accepted) { - break; - } - if (!control->is_inside_tree()) { - break; - } - - if (control->data.mouse_filter != Control::MOUSE_FILTER_IGNORE) { - // Call both script and native methods. - Callable::CallError error; - Variant event = ev; - const Variant *args[1] = { &event }; - if (control->get_script_instance()) { - control->get_script_instance()->call(SceneStringNames::get_singleton()->_gui_input, args, 1, error); - } - MethodBind *method = ClassDB::get_method(control->get_class_name(), SceneStringNames::get_singleton()->_gui_input); - if (method) { - method->call(control, args, 1, error); - } + control->_call_gui_input(ev); } if (!control->is_inside_tree() || control->is_set_as_top_level()) { @@ -1982,10 +1963,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { if (gui.key_focus) { gui.key_event_accepted = false; if (gui.key_focus->can_process()) { - gui.key_focus->call(SceneStringNames::get_singleton()->_gui_input, p_event); - if (gui.key_focus) { //maybe lost it - gui.key_focus->emit_signal(SceneStringNames::get_singleton()->gui_input, p_event); - } + gui.key_focus->_call_gui_input(p_event); } if (gui.key_event_accepted) { @@ -2205,7 +2183,7 @@ void Viewport::_drop_mouse_focus() { mb->set_global_position(c->get_local_mouse_position()); mb->set_button_index(MouseButton(i + 1)); mb->set_pressed(false); - c->call(SceneStringNames::get_singleton()->_gui_input, mb); + c->_call_gui_input(mb); } } } @@ -2317,7 +2295,7 @@ void Viewport::_post_gui_grab_click_focus() { mb->set_position(click); mb->set_button_index(MouseButton(i + 1)); mb->set_pressed(false); - gui.mouse_focus->call(SceneStringNames::get_singleton()->_gui_input, mb); + gui.mouse_focus->_call_gui_input(mb); } } @@ -2335,7 +2313,7 @@ void Viewport::_post_gui_grab_click_focus() { mb->set_position(click); mb->set_button_index(MouseButton(i + 1)); mb->set_pressed(true); - gui.mouse_focus->call_deferred(SceneStringNames::get_singleton()->_gui_input, mb); + MessageQueue::get_singleton()->push_callable(callable_mp(gui.mouse_focus, &Control::_call_gui_input), mb); } } } @@ -2343,9 +2321,9 @@ void Viewport::_post_gui_grab_click_focus() { /////////////////////////////// -void Viewport::input_text(const String &p_text) { +void Viewport::push_text_input(const String &p_text) { if (gui.subwindow_focused) { - gui.subwindow_focused->input_text(p_text); + gui.subwindow_focused->push_text_input(p_text); return; } @@ -2665,7 +2643,7 @@ bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) { return true; } -void Viewport::input(const Ref<InputEvent> &p_event, bool p_local_coords) { +void Viewport::push_input(const Ref<InputEvent> &p_event, bool p_local_coords) { ERR_FAIL_COND(!is_inside_tree()); if (disable_input) { @@ -2695,7 +2673,7 @@ void Viewport::input(const Ref<InputEvent> &p_event, bool p_local_coords) { } if (!is_input_handled()) { - get_tree()->_call_input_pause(input_group, "_input", ev, this); //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, ev, this); //not a bug, must happen before GUI, order is _input -> gui input -> _unhandled input } if (!is_input_handled()) { @@ -2703,10 +2681,9 @@ void Viewport::input(const Ref<InputEvent> &p_event, bool p_local_coords) { } event_count++; - //get_tree()->call_group(SceneTree::GROUP_CALL_REVERSE|SceneTree::GROUP_CALL_REALTIME|SceneTree::GROUP_CALL_MULIILEVEL,gui_input_group,"_gui_input",ev); //special one for GUI, as controls use their own process check } -void Viewport::unhandled_input(const Ref<InputEvent> &p_event, bool p_local_coords) { +void Viewport::push_unhandled_input(const Ref<InputEvent> &p_event, bool p_local_coords) { ERR_FAIL_COND(p_event.is_null()); ERR_FAIL_COND(!is_inside_tree()); local_input_handled = false; @@ -2727,11 +2704,11 @@ void Viewport::unhandled_input(const Ref<InputEvent> &p_event, bool p_local_coor } // Unhandled Input - get_tree()->_call_input_pause(unhandled_input_group, "_unhandled_input", ev, this); + get_tree()->_call_input_pause(unhandled_input_group, SceneTree::CALL_INPUT_TYPE_UNHANDLED_INPUT, ev, this); // Unhandled key Input - used for performance reasons - This is called a lot less than _unhandled_input since it ignores MouseMotion, etc if (!is_input_handled() && (Object::cast_to<InputEventKey>(*ev) != nullptr || Object::cast_to<InputEventShortcut>(*ev) != nullptr)) { - get_tree()->_call_input_pause(unhandled_key_input_group, "_unhandled_key_input", ev, this); + get_tree()->_call_input_pause(unhandled_key_input_group, SceneTree::CALL_INPUT_TYPE_UNHANDLED_KEY_INPUT, ev, this); } if (physics_object_picking && !is_input_handled()) { @@ -3159,7 +3136,7 @@ void Viewport::_collision_object_3d_input_event(CollisionObject3D *p_object, Cam return; //discarded } } - p_object->_input_event(camera_3d, p_input_event, p_pos, p_normal, p_shape); + p_object->_input_event_call(camera_3d, p_input_event, p_pos, p_normal, p_shape); physics_last_object_transform = object_transform; physics_last_camera_transform = camera_transform; physics_last_id = id; @@ -3515,9 +3492,9 @@ void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("get_physics_object_picking"), &Viewport::get_physics_object_picking); ClassDB::bind_method(D_METHOD("get_viewport_rid"), &Viewport::get_viewport_rid); - ClassDB::bind_method(D_METHOD("input_text", "text"), &Viewport::input_text); - ClassDB::bind_method(D_METHOD("input", "event", "in_local_coords"), &Viewport::input, DEFVAL(false)); - ClassDB::bind_method(D_METHOD("unhandled_input", "event", "in_local_coords"), &Viewport::unhandled_input, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("push_text_input", "text"), &Viewport::push_text_input); + ClassDB::bind_method(D_METHOD("push_input", "event", "in_local_coords"), &Viewport::push_input, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("push_unhandled_input", "event", "in_local_coords"), &Viewport::push_unhandled_input, DEFVAL(false)); ClassDB::bind_method(D_METHOD("get_camera_2d"), &Viewport::get_camera_2d); ClassDB::bind_method(D_METHOD("set_as_audio_listener_2d", "enable"), &Viewport::set_as_audio_listener_2d); diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 9c51f404d7..b24de77e6b 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -508,9 +508,9 @@ public: Vector2 get_camera_coords(const Vector2 &p_viewport_coords) const; Vector2 get_camera_rect_size() const; - void input_text(const String &p_text); - void input(const Ref<InputEvent> &p_event, bool p_local_coords = false); - void unhandled_input(const Ref<InputEvent> &p_event, bool p_local_coords = false); + void push_text_input(const String &p_text); + void push_input(const Ref<InputEvent> &p_event, bool p_local_coords = false); + void push_unhandled_input(const Ref<InputEvent> &p_event, bool p_local_coords = false); void set_disable_input(bool p_disable); bool is_input_disabled() const; diff --git a/scene/main/window.cpp b/scene/main/window.cpp index 73eec73d75..b9c0ae5a4a 100644 --- a/scene/main/window.cpp +++ b/scene/main/window.cpp @@ -916,14 +916,14 @@ void Window::_window_input(const Ref<InputEvent> &p_ev) { emit_signal(SceneStringNames::get_singleton()->window_input, p_ev); - input(p_ev); + push_input(p_ev); if (!is_input_handled()) { - unhandled_input(p_ev); + push_unhandled_input(p_ev); } } void Window::_window_input_text(const String &p_text) { - input_text(p_text); + push_text_input(p_text); } void Window::_window_drop_files(const Vector<String> &p_files) { |