From 69c95f4b4c128a22777af1e155bc24c7033decca Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Wed, 19 Feb 2020 16:27:19 -0300 Subject: [PATCH] Reworked signal connection system, added support for Callable and Signal objects and made them default. --- core/array.cpp | 4 +- core/bind/core_bind.cpp | 12 +- core/callable.cpp | 357 ++++++++++++++++++ core/callable.h | 162 ++++++++ core/class_db.cpp | 20 +- core/core_string_names.cpp | 6 +- core/core_string_names.h | 5 + core/func_ref.cpp | 6 +- core/func_ref.h | 2 +- core/global_constants.cpp | 2 + core/io/dtls_server.cpp | 4 +- core/io/dtls_server.h | 4 +- core/io/marshalls.cpp | 15 + core/io/multiplayer_api.cpp | 34 +- core/io/packet_peer_dtls.cpp | 4 +- core/io/packet_peer_dtls.h | 4 +- core/io/resource_format_binary.cpp | 22 ++ core/io/udp_server.cpp | 4 +- core/io/udp_server.h | 4 +- core/make_binders.py | 24 +- core/math/expression.cpp | 54 +-- core/math/expression.h | 2 +- core/message_queue.cpp | 105 +++--- core/message_queue.h | 6 +- core/method_bind.h | 10 +- core/method_ptrcall.h | 2 + core/object.cpp | 244 ++++++------ core/object.h | 51 +-- core/object_id.h | 30 ++ core/register_core_types.cpp | 3 + core/script_language.cpp | 6 +- core/script_language.h | 8 +- core/type_info.h | 2 + core/undo_redo.cpp | 24 +- core/undo_redo.h | 4 +- core/variant.cpp | 149 +++++++- core/variant.h | 32 +- core/variant_call.cpp | 147 ++++++-- core/variant_op.cpp | 113 ++++-- editor/animation_bezier_editor.cpp | 20 +- editor/animation_track_editor.cpp | 124 +++--- editor/animation_track_editor_plugins.cpp | 4 +- editor/array_property_edit.cpp | 6 +- editor/code_editor.cpp | 54 +-- editor/connections_dialog.cpp | 67 ++-- editor/connections_dialog.h | 36 +- editor/create_dialog.cpp | 24 +- editor/dependency_editor.cpp | 16 +- editor/doc/doc_data.cpp | 13 +- editor/editor_about.cpp | 2 +- editor/editor_asset_installer.cpp | 2 +- editor/editor_audio_buses.cpp | 56 +-- editor/editor_autoload_settings.cpp | 18 +- editor/editor_data.cpp | 4 +- editor/editor_dir_dialog.cpp | 20 +- editor/editor_export.cpp | 2 +- editor/editor_feature_profile.cpp | 30 +- editor/editor_file_dialog.cpp | 62 +-- editor/editor_help.cpp | 18 +- editor/editor_help_search.cpp | 16 +- editor/editor_inspector.cpp | 50 +-- editor/editor_layouts_dialog.cpp | 4 +- editor/editor_log.cpp | 4 +- editor/editor_network_profiler.cpp | 6 +- editor/editor_node.cpp | 164 ++++---- editor/editor_path.cpp | 4 +- editor/editor_plugin_settings.cpp | 10 +- editor/editor_profiler.cpp | 22 +- editor/editor_properties.cpp | 114 +++--- editor/editor_properties_array_dict.cpp | 44 +-- editor/editor_run_native.cpp | 4 +- editor/editor_run_script.cpp | 6 +- editor/editor_sectioned_inspector.cpp | 4 +- editor/editor_spin_slider.cpp | 12 +- editor/editor_sub_scene.cpp | 12 +- editor/editor_visual_profiler.cpp | 24 +- editor/export_template_manager.cpp | 20 +- editor/filesystem_dock.cpp | 66 ++-- editor/find_in_files.cpp | 24 +- editor/groups_editor.cpp | 32 +- editor/import_dock.cpp | 10 +- editor/inspector_dock.cpp | 26 +- editor/node_dock.cpp | 4 +- editor/plugin_config_dialog.cpp | 8 +- editor/plugins/abstract_polygon_2d_editor.cpp | 10 +- .../animation_blend_space_1d_editor.cpp | 32 +- .../animation_blend_space_2d_editor.cpp | 52 +-- .../animation_blend_tree_editor_plugin.cpp | 42 +-- .../animation_player_editor_plugin.cpp | 54 +-- .../animation_state_machine_editor.cpp | 32 +- .../plugins/animation_tree_editor_plugin.cpp | 4 +- .../plugins/asset_library_editor_plugin.cpp | 64 ++-- editor/plugins/audio_stream_editor_plugin.cpp | 14 +- editor/plugins/camera_editor_plugin.cpp | 2 +- editor/plugins/canvas_item_editor_plugin.cpp | 106 +++--- .../collision_polygon_editor_plugin.cpp | 6 +- .../cpu_particles_2d_editor_plugin.cpp | 6 +- .../plugins/cpu_particles_editor_plugin.cpp | 2 +- editor/plugins/curve_editor_plugin.cpp | 12 +- editor/plugins/gi_probe_editor_plugin.cpp | 4 +- editor/plugins/gradient_editor_plugin.cpp | 4 +- editor/plugins/item_list_editor_plugin.cpp | 8 +- editor/plugins/material_editor_plugin.cpp | 8 +- editor/plugins/mesh_editor_plugin.cpp | 4 +- .../plugins/mesh_instance_editor_plugin.cpp | 6 +- editor/plugins/mesh_library_editor_plugin.cpp | 6 +- editor/plugins/multimesh_editor_plugin.cpp | 10 +- editor/plugins/particles_2d_editor_plugin.cpp | 8 +- editor/plugins/particles_editor_plugin.cpp | 12 +- editor/plugins/path_2d_editor_plugin.cpp | 20 +- editor/plugins/path_editor_plugin.cpp | 10 +- editor/plugins/physical_bone_plugin.cpp | 2 +- editor/plugins/polygon_2d_editor_plugin.cpp | 42 +-- .../resource_preloader_editor_plugin.cpp | 10 +- editor/plugins/root_motion_editor_plugin.cpp | 8 +- editor/plugins/script_editor_plugin.cpp | 130 +++---- editor/plugins/script_text_editor.cpp | 74 ++-- editor/plugins/shader_editor_plugin.cpp | 24 +- editor/plugins/skeleton_2d_editor_plugin.cpp | 2 +- editor/plugins/skeleton_editor_plugin.cpp | 4 +- editor/plugins/skeleton_ik_editor_plugin.cpp | 2 +- editor/plugins/spatial_editor_plugin.cpp | 94 ++--- editor/plugins/sprite_editor_plugin.cpp | 8 +- .../plugins/sprite_frames_editor_plugin.cpp | 48 +-- editor/plugins/style_box_editor_plugin.cpp | 6 +- editor/plugins/text_editor.cpp | 22 +- .../plugins/texture_region_editor_plugin.cpp | 30 +- editor/plugins/theme_editor_plugin.cpp | 12 +- editor/plugins/tile_map_editor_plugin.cpp | 56 +-- editor/plugins/tile_set_editor_plugin.cpp | 54 +-- .../plugins/version_control_editor_plugin.cpp | 22 +- .../plugins/visual_shader_editor_plugin.cpp | 106 +++--- editor/progress_dialog.cpp | 2 +- editor/project_export.cpp | 66 ++-- editor/project_manager.cpp | 88 ++--- editor/project_settings_editor.cpp | 78 ++-- editor/property_editor.cpp | 46 +-- editor/property_selector.cpp | 18 +- editor/quick_open.cpp | 10 +- editor/rename_dialog.cpp | 56 +-- editor/reparent_dialog.cpp | 6 +- editor/run_settings_dialog.cpp | 2 +- editor/scene_tree_dock.cpp | 98 ++--- editor/scene_tree_editor.cpp | 66 ++-- editor/script_create_dialog.cpp | 26 +- editor/script_editor_debugger.cpp | 68 ++-- editor/settings_config_dialog.cpp | 22 +- modules/bullet/area_bullet.cpp | 2 +- modules/bullet/rigid_body_bullet.cpp | 2 +- modules/csg/csg_shape.cpp | 16 +- modules/gdnative/gdnative/gdnative.cpp | 2 +- modules/gdnative/gdnative/variant.cpp | 2 +- .../gdnative_library_editor_plugin.cpp | 14 +- .../gdnative_library_singleton_editor.cpp | 4 +- .../gdnative/nativescript/nativescript.cpp | 30 +- modules/gdnative/nativescript/nativescript.h | 4 +- .../pluginscript/pluginscript_instance.cpp | 2 +- .../pluginscript/pluginscript_instance.h | 2 +- .../pluginscript/pluginscript_script.cpp | 16 +- .../pluginscript/pluginscript_script.h | 4 +- .../navigation_mesh_editor_plugin.cpp | 4 +- modules/gdnavigation/rvo_agent.cpp | 2 +- modules/gdscript/gdscript.cpp | 56 +-- modules/gdscript/gdscript.h | 8 +- modules/gdscript/gdscript_compiler.cpp | 4 +- modules/gdscript/gdscript_editor.cpp | 28 +- modules/gdscript/gdscript_function.cpp | 72 ++-- modules/gdscript/gdscript_function.h | 6 +- modules/gdscript/gdscript_functions.cpp | 134 +++---- modules/gdscript/gdscript_functions.h | 2 +- modules/gdscript/gdscript_parser.cpp | 30 +- modules/gdscript/gdscript_tokenizer.cpp | 2 + .../gdscript_language_protocol.cpp | 6 +- modules/gridmap/grid_map_editor_plugin.cpp | 30 +- modules/mbedtls/dtls_server_mbedtls.cpp | 4 +- modules/mbedtls/dtls_server_mbedtls.h | 4 +- modules/mbedtls/packet_peer_mbed_dtls.cpp | 4 +- modules/mbedtls/packet_peer_mbed_dtls.h | 4 +- modules/mono/csharp_script.cpp | 24 +- modules/mono/csharp_script.h | 8 +- modules/mono/editor/bindings_generator.cpp | 2 +- modules/mono/glue/base_object_glue.cpp | 4 +- modules/mono/glue/gd_glue.cpp | 4 +- modules/mono/signal_awaiter_utils.cpp | 8 +- modules/mono/signal_awaiter_utils.h | 2 +- modules/opensimplex/noise_texture.cpp | 4 +- modules/visual_script/visual_script.cpp | 84 ++--- modules/visual_script/visual_script.h | 10 +- .../visual_script_builtin_funcs.cpp | 46 +-- .../visual_script_builtin_funcs.h | 2 +- .../visual_script/visual_script_editor.cpp | 110 +++--- .../visual_script_expression.cpp | 18 +- .../visual_script_flow_control.cpp | 26 +- .../visual_script_func_nodes.cpp | 50 +-- modules/visual_script/visual_script_nodes.cpp | 98 ++--- .../visual_script_property_selector.cpp | 14 +- .../visual_script_yield_nodes.cpp | 12 +- platform/android/api/api.cpp | 4 +- platform/android/api/java_class_wrapper.h | 6 +- platform/android/java_class_wrapper.cpp | 20 +- platform/android/java_godot_lib_jni.cpp | 14 +- scene/2d/animated_sprite.cpp | 4 +- scene/2d/area_2d.cpp | 24 +- scene/2d/audio_stream_player_2d.cpp | 2 +- scene/2d/collision_shape_2d.cpp | 4 +- scene/2d/cpu_particles_2d.cpp | 10 +- scene/2d/light_occluder_2d.cpp | 4 +- scene/2d/line_2d.cpp | 8 +- scene/2d/navigation_polygon.cpp | 4 +- scene/2d/path_2d.cpp | 4 +- scene/2d/physics_body_2d.cpp | 24 +- scene/2d/polygon_2d.cpp | 4 +- scene/2d/sprite.cpp | 4 +- scene/2d/tile_map.cpp | 6 +- scene/2d/touch_screen_button.cpp | 4 +- scene/2d/visibility_notifier_2d.cpp | 4 +- scene/3d/area.cpp | 24 +- scene/3d/audio_stream_player_3d.cpp | 2 +- scene/3d/collision_shape.cpp | 4 +- scene/3d/cpu_particles.cpp | 6 +- scene/3d/mesh_instance.cpp | 4 +- scene/3d/path.cpp | 4 +- scene/3d/physics_body.cpp | 24 +- scene/3d/skeleton.cpp | 2 +- scene/3d/soft_body.cpp | 6 +- scene/3d/sprite_3d.cpp | 8 +- scene/3d/visibility_notifier.cpp | 4 +- scene/animation/animation_blend_space_1d.cpp | 8 +- scene/animation/animation_blend_space_2d.cpp | 8 +- scene/animation/animation_blend_tree.cpp | 12 +- scene/animation/animation_cache.cpp | 12 +- scene/animation/animation_cache.h | 2 +- .../animation_node_state_machine.cpp | 12 +- scene/animation/animation_player.cpp | 8 +- scene/animation/animation_tree.cpp | 16 +- scene/animation/tween.cpp | 28 +- scene/audio/audio_stream_player.cpp | 2 +- scene/gui/color_picker.cpp | 48 +-- scene/gui/container.cpp | 12 +- scene/gui/control.cpp | 60 +-- scene/gui/dialogs.cpp | 10 +- scene/gui/file_dialog.cpp | 38 +- scene/gui/gradient_edit.cpp | 4 +- scene/gui/graph_edit.cpp | 30 +- scene/gui/item_list.cpp | 2 +- scene/gui/line_edit.cpp | 8 +- scene/gui/menu_button.cpp | 4 +- scene/gui/option_button.cpp | 6 +- scene/gui/popup_menu.cpp | 6 +- scene/gui/rich_text_label.cpp | 2 +- scene/gui/scroll_bar.cpp | 18 +- scene/gui/scroll_container.cpp | 6 +- scene/gui/spin_box.cpp | 8 +- scene/gui/tab_container.cpp | 6 +- scene/gui/tabs.cpp | 2 +- scene/gui/text_edit.cpp | 14 +- scene/gui/texture_rect.cpp | 4 +- scene/gui/tree.cpp | 24 +- scene/gui/tree.h | 4 +- scene/main/http_request.cpp | 2 +- scene/main/node.cpp | 50 +-- scene/main/node.h | 8 +- scene/main/scene_tree.cpp | 30 +- scene/main/scene_tree.h | 4 +- scene/main/viewport.cpp | 12 +- scene/resources/material.cpp | 4 +- scene/resources/packed_scene.cpp | 14 +- scene/resources/texture.cpp | 10 +- scene/resources/theme.cpp | 28 +- scene/resources/visual_shader.cpp | 8 +- servers/physics/area_sw.cpp | 4 +- servers/physics/body_sw.cpp | 2 +- servers/physics_2d/area_2d_sw.cpp | 4 +- servers/physics_2d/body_2d_sw.cpp | 2 +- servers/visual/visual_server_raster.cpp | 4 +- 275 files changed, 3831 insertions(+), 2948 deletions(-) create mode 100644 core/callable.cpp create mode 100644 core/callable.h diff --git a/core/array.cpp b/core/array.cpp index 2253d05605ae..7eb15ea934ee 100644 --- a/core/array.cpp +++ b/core/array.cpp @@ -308,9 +308,9 @@ struct _ArrayVariantSortCustom { _FORCE_INLINE_ bool operator()(const Variant &p_l, const Variant &p_r) const { const Variant *args[2] = { &p_l, &p_r }; - Variant::CallError err; + Callable::CallError err; bool res = obj->call(func, args, 2, err); - if (err.error != Variant::CallError::CALL_OK) + if (err.error != Callable::CallError::CALL_OK) res = false; return res; } diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index 583a44846ff2..f5a351f16a29 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -2620,29 +2620,29 @@ void _Thread::_start_func(void *ud) { Ref<_Thread> *tud = (Ref<_Thread> *)ud; Ref<_Thread> t = *tud; memdelete(tud); - Variant::CallError ce; + Callable::CallError ce; const Variant *arg[1] = { &t->userdata }; Thread::set_name(t->target_method); t->ret = t->target_instance->call(t->target_method, arg, 1, ce); - if (ce.error != Variant::CallError::CALL_OK) { + if (ce.error != Callable::CallError::CALL_OK) { String reason; switch (ce.error) { - case Variant::CallError::CALL_ERROR_INVALID_ARGUMENT: { + case Callable::CallError::CALL_ERROR_INVALID_ARGUMENT: { reason = "Invalid Argument #" + itos(ce.argument); } break; - case Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS: { + case Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS: { reason = "Too Many Arguments"; } break; - case Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS: { + case Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS: { reason = "Too Few Arguments"; } break; - case Variant::CallError::CALL_ERROR_INVALID_METHOD: { + case Callable::CallError::CALL_ERROR_INVALID_METHOD: { reason = "Method Not Found"; } break; diff --git a/core/callable.cpp b/core/callable.cpp new file mode 100644 index 000000000000..34b79cea1058 --- /dev/null +++ b/core/callable.cpp @@ -0,0 +1,357 @@ +/*************************************************************************/ +/* callable.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "callable.h" +#include "core/script_language.h" +#include "message_queue.h" +#include "object.h" +#include "reference.h" + +void Callable::call_deferred(const Variant **p_arguments, int p_argcount) const { + MessageQueue::get_singleton()->push_callable(*this, p_arguments, p_argcount); +} + +void Callable::call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, CallError &r_call_error) const { + + if (is_null()) { + r_call_error.error = CallError::CALL_ERROR_INSTANCE_IS_NULL; + r_call_error.argument = 0; + r_call_error.expected = 0; + r_return_value = Variant(); + } else if (is_custom()) { + custom->call(p_arguments, p_argcount, r_return_value, r_call_error); + } else { + Object *obj = ObjectDB::get_instance(ObjectID(object)); + r_return_value = obj->call(method, p_arguments, p_argcount, r_call_error); + } +} + +Object *Callable::get_object() const { + if (is_null()) { + return nullptr; + } else if (is_custom()) { + return ObjectDB::get_instance(custom->get_object()); + } else { + return ObjectDB::get_instance(ObjectID(object)); + } +} + +ObjectID Callable::get_object_id() const { + if (is_null()) { + return ObjectID(); + } else if (is_custom()) { + return custom->get_object(); + } else { + return ObjectID(object); + } +} +StringName Callable::get_method() const { + ERR_FAIL_COND_V(is_custom(), StringName()); + return method; +} +uint32_t Callable::hash() const { + if (is_custom()) { + return custom->hash(); + } else { + uint32_t hash = method.hash(); + return hash_djb2_one_64(object, hash); + } +} + +bool Callable::operator==(const Callable &p_callable) const { + bool custom_a = is_custom(); + bool custom_b = p_callable.is_custom(); + + if (custom_a == custom_b) { + if (custom_a) { + if (custom == p_callable.custom) { + return true; //same pointer, dont even compare + } + + CallableCustom::CompareEqualFunc eq_a = custom->get_compare_equal_func(); + CallableCustom::CompareEqualFunc eq_b = p_callable.custom->get_compare_equal_func(); + if (eq_a == eq_b) { + return eq_a(custom, p_callable.custom); + } else { + return false; + } + } else { + return object == p_callable.object && method == p_callable.method; + } + } else { + return false; + } +} +bool Callable::operator!=(const Callable &p_callable) const { + return !(*this == p_callable); +} +bool Callable::operator<(const Callable &p_callable) const { + bool custom_a = is_custom(); + bool custom_b = p_callable.is_custom(); + + if (custom_a == custom_b) { + if (custom_a) { + if (custom == p_callable.custom) { + return false; //same pointer, dont even compare + } + + CallableCustom::CompareLessFunc less_a = custom->get_compare_less_func(); + CallableCustom::CompareLessFunc less_b = p_callable.custom->get_compare_less_func(); + if (less_a == less_b) { + return less_a(custom, p_callable.custom); + } else { + return less_a < less_b; //it's something.. + } + + } else { + if (object == p_callable.object) { + return method < p_callable.method; + } else { + return object < p_callable.object; + } + } + } else { + return int(custom_a ? 1 : 0) < int(custom_b ? 1 : 0); + } +} + +void Callable::operator=(const Callable &p_callable) { + if (is_custom()) { + if (p_callable.is_custom()) { + if (custom == p_callable.custom) { + return; + } + } + + if (custom->ref_count.unref()) { + memdelete(custom); + } + } + + if (p_callable.is_custom()) { + method = StringName(); + if (!p_callable.custom->ref_count.ref()) { + object = 0; + } else { + object = 0; + custom = p_callable.custom; + } + } else { + method = p_callable.method; + object = p_callable.object; + } +} + +Callable::operator String() const { + + if (is_custom()) { + return custom->get_as_text(); + } else { + if (is_null()) { + return "null::null"; + } + + Object *base = get_object(); + if (base) { + String class_name = base->get_class(); + Ref