diff options
31 files changed, 221 insertions, 223 deletions
diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp index ec3a6a5ca8..2b1d330942 100644 --- a/core/variant/variant_call.cpp +++ b/core/variant/variant_call.cpp @@ -1366,6 +1366,7 @@ static void _register_variant_builtin_methods() { bind_method(String, naturalnocasecmp_to, sarray("to"), varray()); bind_method(String, length, sarray(), varray()); bind_method(String, substr, sarray("from", "len"), varray(-1)); + bind_method(String, get_slice, sarray("delimiter", "slice"), varray()); bind_methodv(String, find, static_cast<int (String::*)(const String &, int) const>(&String::find), sarray("what", "from"), varray(0)); bind_method(String, count, sarray("what", "from", "to"), varray(0, 0)); bind_method(String, countn, sarray("what", "from", "to"), varray(0, 0)); diff --git a/doc/classes/EditorResourcePicker.xml b/doc/classes/EditorResourcePicker.xml index 9c490cbb3e..b26b6f9527 100644 --- a/doc/classes/EditorResourcePicker.xml +++ b/doc/classes/EditorResourcePicker.xml @@ -62,8 +62,9 @@ </signal> <signal name="resource_selected"> <argument index="0" name="resource" type="Resource" /> + <argument index="1" name="edit" type="bool" /> <description> - Emitted when the resource value was set and user clicked to edit it. + Emitted when the resource value was set and user clicked to edit it. When [code]edit[/code] is [code]true[/code], the signal was caused by the context menu "Edit" option. </description> </signal> </signals> diff --git a/doc/classes/PhysicsServer2D.xml b/doc/classes/PhysicsServer2D.xml index 24a20b5613..e44bf71e8d 100644 --- a/doc/classes/PhysicsServer2D.xml +++ b/doc/classes/PhysicsServer2D.xml @@ -123,8 +123,7 @@ <method name="area_set_area_monitor_callback"> <return type="void" /> <argument index="0" name="area" type="RID" /> - <argument index="1" name="receiver" type="Object" /> - <argument index="2" name="method" type="StringName" /> + <argument index="1" name="callback" type="Callable" /> <description> </description> </method> @@ -147,8 +146,7 @@ <method name="area_set_monitor_callback"> <return type="void" /> <argument index="0" name="area" type="RID" /> - <argument index="1" name="receiver" type="Object" /> - <argument index="2" name="method" type="StringName" /> + <argument index="1" name="callback" type="Callable" /> <description> Sets the function to call when any body/area enters or exits the area. This callback will be called for any object interacting with the area, and takes five parameters: 1: [constant AREA_BODY_ADDED] or [constant AREA_BODY_REMOVED], depending on whether the object entered or exited the area. diff --git a/doc/classes/PhysicsServer3D.xml b/doc/classes/PhysicsServer3D.xml index 034bd55519..0c34cf8092 100644 --- a/doc/classes/PhysicsServer3D.xml +++ b/doc/classes/PhysicsServer3D.xml @@ -110,8 +110,7 @@ <method name="area_set_area_monitor_callback"> <return type="void" /> <argument index="0" name="area" type="RID" /> - <argument index="1" name="receiver" type="Object" /> - <argument index="2" name="method" type="StringName" /> + <argument index="1" name="callback" type="Callable" /> <description> </description> </method> @@ -134,8 +133,7 @@ <method name="area_set_monitor_callback"> <return type="void" /> <argument index="0" name="area" type="RID" /> - <argument index="1" name="receiver" type="Object" /> - <argument index="2" name="method" type="StringName" /> + <argument index="1" name="callback" type="Callable" /> <description> Sets the function to call when any body/area enters or exits the area. This callback will be called for any object interacting with the area, and takes five parameters: 1: [constant AREA_BODY_ADDED] or [constant AREA_BODY_REMOVED], depending on whether the object entered or exited the area. diff --git a/doc/classes/String.xml b/doc/classes/String.xml index 1190d90190..a58bfd5c15 100644 --- a/doc/classes/String.xml +++ b/doc/classes/String.xml @@ -202,6 +202,19 @@ If the string is a valid file path, returns the filename. </description> </method> + <method name="get_slice" qualifiers="const"> + <return type="String" /> + <argument index="0" name="delimiter" type="String" /> + <argument index="1" name="slice" type="int" /> + <description> + Splits a string using a [code]delimiter[/code] and returns a substring at index [code]slice[/code]. Returns an empty string if the index doesn't exist. + This is a more performant alternative to [method split] for cases when you need only one element from the array at a fixed index. + Example: + [codeblock] + print("i/am/example/string".get_slice("/", 2)) # Prints 'example'. + [/codeblock] + </description> + </method> <method name="hash" qualifiers="const"> <return type="int" /> <description> @@ -602,6 +615,7 @@ <description> Splits the string by a [code]delimiter[/code] string and returns an array of the substrings. The [code]delimiter[/code] can be of any length. If [code]maxsplit[/code] is specified, it defines the number of splits to do from the left up to [code]maxsplit[/code]. The default value of [code]0[/code] means that all items are split. + If you need only one element from the array at a specific index, [method get_slice] is a more performant option. Example: [codeblocks] [gdscript] diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index e679222567..fbf80fef2e 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -2821,8 +2821,8 @@ void EditorPropertyResource::_set_read_only(bool p_read_only) { resource_picker->set_editable(!p_read_only); }; -void EditorPropertyResource::_resource_selected(const RES &p_resource) { - if (use_sub_inspector) { +void EditorPropertyResource::_resource_selected(const RES &p_resource, bool p_edit) { + if (!p_edit && use_sub_inspector) { bool unfold = !get_edited_object()->editor_is_section_unfolded(get_edited_property()); get_edited_object()->editor_set_section_unfold(get_edited_property(), unfold); update_property(); diff --git a/editor/editor_properties.h b/editor/editor_properties.h index 9a687f1a72..6b07efb068 100644 --- a/editor/editor_properties.h +++ b/editor/editor_properties.h @@ -657,7 +657,7 @@ class EditorPropertyResource : public EditorProperty { bool updating_theme = false; bool opened_editor = false; - void _resource_selected(const RES &p_resource); + void _resource_selected(const RES &p_resource, bool p_edit); void _resource_changed(const RES &p_resource); void _viewport_selected(const NodePath &p_path); diff --git a/editor/editor_resource_picker.cpp b/editor/editor_resource_picker.cpp index 9dbf69a779..a2d11c4b1f 100644 --- a/editor/editor_resource_picker.cpp +++ b/editor/editor_resource_picker.cpp @@ -106,7 +106,7 @@ void EditorResourcePicker::_resource_selected() { return; } - emit_signal(SNAME("resource_selected"), edited_resource); + emit_signal(SNAME("resource_selected"), edited_resource, false); } void EditorResourcePicker::_file_selected(const String &p_path) { @@ -266,7 +266,7 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) { case OBJ_MENU_EDIT: { if (edited_resource.is_valid()) { - emit_signal(SNAME("resource_selected"), edited_resource); + emit_signal(SNAME("resource_selected"), edited_resource, true); } } break; @@ -690,7 +690,7 @@ void EditorResourcePicker::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editable"), "set_editable", "is_editable"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "toggle_mode"), "set_toggle_mode", "is_toggle_mode"); - ADD_SIGNAL(MethodInfo("resource_selected", PropertyInfo(Variant::OBJECT, "resource", PROPERTY_HINT_RESOURCE_TYPE, "Resource"))); + ADD_SIGNAL(MethodInfo("resource_selected", PropertyInfo(Variant::OBJECT, "resource", PROPERTY_HINT_RESOURCE_TYPE, "Resource"), PropertyInfo(Variant::BOOL, "edit"))); ADD_SIGNAL(MethodInfo("resource_changed", PropertyInfo(Variant::OBJECT, "resource", PROPERTY_HINT_RESOURCE_TYPE, "Resource"))); } diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp index 127219546d..b1ef85b4f4 100644 --- a/editor/plugins/theme_editor_plugin.cpp +++ b/editor/plugins/theme_editor_plugin.cpp @@ -2848,7 +2848,7 @@ void ThemeTypeEditor::_font_size_item_changed(float p_value, String p_item_name) edited_theme->set_font_size(p_item_name, edited_type, int(p_value)); } -void ThemeTypeEditor::_edit_resource_item(RES p_resource) { +void ThemeTypeEditor::_edit_resource_item(RES p_resource, bool p_edit) { EditorNode::get_singleton()->edit_resource(p_resource); } diff --git a/editor/plugins/theme_editor_plugin.h b/editor/plugins/theme_editor_plugin.h index b6becbb1c7..f5ad577aff 100644 --- a/editor/plugins/theme_editor_plugin.h +++ b/editor/plugins/theme_editor_plugin.h @@ -362,7 +362,7 @@ class ThemeTypeEditor : public MarginContainer { void _color_item_changed(Color p_value, String p_item_name); void _constant_item_changed(float p_value, String p_item_name); void _font_size_item_changed(float p_value, String p_item_name); - void _edit_resource_item(RES p_resource); + void _edit_resource_item(RES p_resource, bool p_edit); void _font_item_changed(Ref<Font> p_value, String p_item_name); void _icon_item_changed(Ref<Texture2D> p_value, String p_item_name); void _stylebox_item_changed(Ref<StyleBox> p_value, String p_item_name); diff --git a/modules/bullet/area_bullet.cpp b/modules/bullet/area_bullet.cpp index c3bd84c329..b5a7da0c38 100644 --- a/modules/bullet/area_bullet.cpp +++ b/modules/bullet/area_bullet.cpp @@ -94,10 +94,9 @@ void AreaBullet::dispatch_callbacks() { void AreaBullet::call_event(CollisionObjectBullet *p_otherObject, PhysicsServer3D::AreaBodyStatus p_status) { InOutEventCallback &event = eventsCallbacks[static_cast<int>(p_otherObject->getType())]; - Object *areaGodoObject = ObjectDB::get_instance(event.event_callback_id); - if (!areaGodoObject) { - event.event_callback_id = ObjectID(); + if (!event.event_callback.is_valid()) { + event.event_callback = Callable(); return; } @@ -108,7 +107,8 @@ void AreaBullet::call_event(CollisionObjectBullet *p_otherObject, PhysicsServer3 call_event_res[4] = 0; // self_shape ID Callable::CallError outResp; - areaGodoObject->call(event.event_callback_method, (const Variant **)call_event_res_ptr, 5, outResp); + Variant ret; + event.event_callback.call((const Variant **)call_event_res, 5, ret, outResp); } void AreaBullet::scratch() { @@ -267,13 +267,12 @@ Variant AreaBullet::get_param(PhysicsServer3D::AreaParameter p_param) const { } } -void AreaBullet::set_event_callback(Type p_callbackObjectType, ObjectID p_id, const StringName &p_method) { +void AreaBullet::set_event_callback(Type p_callbackObjectType, const Callable &p_callback) { InOutEventCallback &ev = eventsCallbacks[static_cast<int>(p_callbackObjectType)]; - ev.event_callback_id = p_id; - ev.event_callback_method = p_method; + ev.event_callback = p_callback; /// Set if monitoring - if (eventsCallbacks[0].event_callback_id.is_valid() || eventsCallbacks[1].event_callback_id.is_valid()) { + if (!eventsCallbacks[0].event_callback.is_null() || !eventsCallbacks[1].event_callback.is_null()) { set_godot_object_flags(get_godot_object_flags() | GOF_IS_MONITORING_AREA); } else { set_godot_object_flags(get_godot_object_flags() & (~GOF_IS_MONITORING_AREA)); @@ -281,7 +280,7 @@ void AreaBullet::set_event_callback(Type p_callbackObjectType, ObjectID p_id, co } bool AreaBullet::has_event_callback(Type p_callbackObjectType) { - return eventsCallbacks[static_cast<int>(p_callbackObjectType)].event_callback_id.is_valid(); + return !eventsCallbacks[static_cast<int>(p_callbackObjectType)].event_callback.is_null(); } void AreaBullet::on_enter_area(AreaBullet *p_area) { diff --git a/modules/bullet/area_bullet.h b/modules/bullet/area_bullet.h index c8b516c951..d96c550082 100644 --- a/modules/bullet/area_bullet.h +++ b/modules/bullet/area_bullet.h @@ -47,8 +47,7 @@ class AreaBullet : public RigidCollisionObjectBullet { public: struct InOutEventCallback { - ObjectID event_callback_id; - StringName event_callback_method; + Callable event_callback; InOutEventCallback() {} }; @@ -162,7 +161,7 @@ public: void set_param(PhysicsServer3D::AreaParameter p_param, const Variant &p_value); Variant get_param(PhysicsServer3D::AreaParameter p_param) const; - void set_event_callback(Type p_callbackObjectType, ObjectID p_id, const StringName &p_method); + void set_event_callback(Type p_callbackObjectType, const Callable &p_callback); bool has_event_callback(Type p_callbackObjectType); virtual void on_enter_area(AreaBullet *p_area); diff --git a/modules/bullet/bullet_physics_server.cpp b/modules/bullet/bullet_physics_server.cpp index bb2db49c87..610d2145cd 100644 --- a/modules/bullet/bullet_physics_server.cpp +++ b/modules/bullet/bullet_physics_server.cpp @@ -413,18 +413,18 @@ void BulletPhysicsServer3D::area_set_monitorable(RID p_area, bool p_monitorable) area->set_monitorable(p_monitorable); } -void BulletPhysicsServer3D::area_set_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) { +void BulletPhysicsServer3D::area_set_monitor_callback(RID p_area, const Callable &p_callback) { AreaBullet *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); - area->set_event_callback(CollisionObjectBullet::TYPE_RIGID_BODY, p_receiver ? p_receiver->get_instance_id() : ObjectID(), p_method); + area->set_event_callback(CollisionObjectBullet::TYPE_RIGID_BODY, p_callback.is_valid() ? p_callback : Callable()); } -void BulletPhysicsServer3D::area_set_area_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) { +void BulletPhysicsServer3D::area_set_area_monitor_callback(RID p_area, const Callable &p_callback) { AreaBullet *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); - area->set_event_callback(CollisionObjectBullet::TYPE_AREA, p_receiver ? p_receiver->get_instance_id() : ObjectID(), p_method); + area->set_event_callback(CollisionObjectBullet::TYPE_AREA, p_callback.is_valid() ? p_callback : Callable()); } void BulletPhysicsServer3D::area_set_ray_pickable(RID p_area, bool p_enable) { diff --git a/modules/bullet/bullet_physics_server.h b/modules/bullet/bullet_physics_server.h index 7c146de0c3..94635b5bfc 100644 --- a/modules/bullet/bullet_physics_server.h +++ b/modules/bullet/bullet_physics_server.h @@ -160,8 +160,8 @@ public: virtual void area_set_collision_layer(RID p_area, uint32_t p_layer) override; virtual void area_set_monitorable(RID p_area, bool p_monitorable) override; - virtual void area_set_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) override; - virtual void area_set_area_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) override; + virtual void area_set_monitor_callback(RID p_area, const Callable &p_callback) override; + virtual void area_set_area_monitor_callback(RID p_area, const Callable &p_callback) override; virtual void area_set_ray_pickable(RID p_area, bool p_enable) override; /* RIGID BODY API */ diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp index fff9c47d4d..75a1723e04 100644 --- a/scene/2d/area_2d.cpp +++ b/scene/2d/area_2d.cpp @@ -369,12 +369,11 @@ void Area2D::set_monitoring(bool p_enable) { monitoring = p_enable; if (monitoring) { - PhysicsServer2D::get_singleton()->area_set_monitor_callback(get_rid(), this, SceneStringNames::get_singleton()->_body_inout); - PhysicsServer2D::get_singleton()->area_set_area_monitor_callback(get_rid(), this, SceneStringNames::get_singleton()->_area_inout); - + PhysicsServer2D::get_singleton()->area_set_monitor_callback(get_rid(), callable_mp(this, &Area2D::_body_inout)); + PhysicsServer2D::get_singleton()->area_set_area_monitor_callback(get_rid(), callable_mp(this, &Area2D::_area_inout)); } else { - PhysicsServer2D::get_singleton()->area_set_monitor_callback(get_rid(), nullptr, StringName()); - PhysicsServer2D::get_singleton()->area_set_area_monitor_callback(get_rid(), nullptr, StringName()); + PhysicsServer2D::get_singleton()->area_set_monitor_callback(get_rid(), Callable()); + PhysicsServer2D::get_singleton()->area_set_area_monitor_callback(get_rid(), Callable()); _clear_monitoring(); } } @@ -530,9 +529,6 @@ void Area2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_audio_bus_override", "enable"), &Area2D::set_audio_bus_override); ClassDB::bind_method(D_METHOD("is_overriding_audio_bus"), &Area2D::is_overriding_audio_bus); - ClassDB::bind_method(D_METHOD("_body_inout"), &Area2D::_body_inout); - ClassDB::bind_method(D_METHOD("_area_inout"), &Area2D::_area_inout); - ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::RID, "body_rid"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node2D"), PropertyInfo(Variant::INT, "body_shape_index"), PropertyInfo(Variant::INT, "local_shape_index"))); ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::RID, "body_rid"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node2D"), PropertyInfo(Variant::INT, "body_shape_index"), PropertyInfo(Variant::INT, "local_shape_index"))); ADD_SIGNAL(MethodInfo("body_entered", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node2D"))); diff --git a/scene/3d/area_3d.cpp b/scene/3d/area_3d.cpp index 9179983220..e459c42e8c 100644 --- a/scene/3d/area_3d.cpp +++ b/scene/3d/area_3d.cpp @@ -334,11 +334,11 @@ void Area3D::set_monitoring(bool p_enable) { monitoring = p_enable; if (monitoring) { - PhysicsServer3D::get_singleton()->area_set_monitor_callback(get_rid(), this, SceneStringNames::get_singleton()->_body_inout); - PhysicsServer3D::get_singleton()->area_set_area_monitor_callback(get_rid(), this, SceneStringNames::get_singleton()->_area_inout); + PhysicsServer3D::get_singleton()->area_set_monitor_callback(get_rid(), callable_mp(this, &Area3D::_body_inout)); + PhysicsServer3D::get_singleton()->area_set_area_monitor_callback(get_rid(), callable_mp(this, &Area3D::_area_inout)); } else { - PhysicsServer3D::get_singleton()->area_set_monitor_callback(get_rid(), nullptr, StringName()); - PhysicsServer3D::get_singleton()->area_set_area_monitor_callback(get_rid(), nullptr, StringName()); + PhysicsServer3D::get_singleton()->area_set_monitor_callback(get_rid(), Callable()); + PhysicsServer3D::get_singleton()->area_set_area_monitor_callback(get_rid(), Callable()); _clear_monitoring(); } } @@ -630,9 +630,6 @@ void Area3D::_bind_methods() { ClassDB::bind_method(D_METHOD("overlaps_body", "body"), &Area3D::overlaps_body); ClassDB::bind_method(D_METHOD("overlaps_area", "area"), &Area3D::overlaps_area); - ClassDB::bind_method(D_METHOD("_body_inout"), &Area3D::_body_inout); - ClassDB::bind_method(D_METHOD("_area_inout"), &Area3D::_area_inout); - ClassDB::bind_method(D_METHOD("set_audio_bus_override", "enable"), &Area3D::set_audio_bus_override); ClassDB::bind_method(D_METHOD("is_overriding_audio_bus"), &Area3D::is_overriding_audio_bus); diff --git a/scene/resources/mesh_data_tool.cpp b/scene/resources/mesh_data_tool.cpp index 04b2437ae8..9ecd8ec2f3 100644 --- a/scene/resources/mesh_data_tool.cpp +++ b/scene/resources/mesh_data_tool.cpp @@ -421,6 +421,7 @@ Vector<int> MeshDataTool::get_vertex_bones(int p_idx) const { void MeshDataTool::set_vertex_bones(int p_idx, const Vector<int> &p_bones) { ERR_FAIL_INDEX(p_idx, vertices.size()); + ERR_FAIL_COND(p_bones.size() != 4); vertices.write[p_idx].bones = p_bones; format |= Mesh::ARRAY_FORMAT_BONES; } @@ -432,6 +433,7 @@ Vector<float> MeshDataTool::get_vertex_weights(int p_idx) const { void MeshDataTool::set_vertex_weights(int p_idx, const Vector<float> &p_weights) { ERR_FAIL_INDEX(p_idx, vertices.size()); + ERR_FAIL_COND(p_weights.size() != 4); vertices.write[p_idx].weights = p_weights; format |= Mesh::ARRAY_FORMAT_WEIGHTS; } diff --git a/servers/physics_2d/godot_area_2d.cpp b/servers/physics_2d/godot_area_2d.cpp index 7cb202dd1f..6983e28841 100644 --- a/servers/physics_2d/godot_area_2d.cpp +++ b/servers/physics_2d/godot_area_2d.cpp @@ -77,16 +77,17 @@ void GodotArea2D::set_space(GodotSpace2D *p_space) { _set_space(p_space); } -void GodotArea2D::set_monitor_callback(ObjectID p_id, const StringName &p_method) { - if (p_id == monitor_callback_id) { - monitor_callback_method = p_method; +void GodotArea2D::set_monitor_callback(const Callable &p_callback) { + ObjectID id = p_callback.get_object_id(); + + if (id == monitor_callback.get_object_id()) { + monitor_callback = p_callback; return; } _unregister_shapes(); - monitor_callback_id = p_id; - monitor_callback_method = p_method; + monitor_callback = p_callback; monitored_bodies.clear(); monitored_areas.clear(); @@ -98,16 +99,17 @@ void GodotArea2D::set_monitor_callback(ObjectID p_id, const StringName &p_method } } -void GodotArea2D::set_area_monitor_callback(ObjectID p_id, const StringName &p_method) { - if (p_id == area_monitor_callback_id) { - area_monitor_callback_method = p_method; +void GodotArea2D::set_area_monitor_callback(const Callable &p_callback) { + ObjectID id = p_callback.get_object_id(); + + if (id == area_monitor_callback.get_object_id()) { + area_monitor_callback = p_callback; return; } _unregister_shapes(); - area_monitor_callback_id = p_id; - area_monitor_callback_method = p_method; + area_monitor_callback = p_callback; monitored_bodies.clear(); monitored_areas.clear(); @@ -199,77 +201,75 @@ void GodotArea2D::set_monitorable(bool p_monitorable) { } void GodotArea2D::call_queries() { - if (monitor_callback_id.is_valid() && !monitored_bodies.is_empty()) { - Variant res[5]; - Variant *resptr[5]; - for (int i = 0; i < 5; i++) { - resptr[i] = &res[i]; - } + if (!monitor_callback.is_null() && !monitored_bodies.is_empty()) { + if (monitor_callback.is_valid()) { + Variant res[5]; + Variant *resptr[5]; + for (int i = 0; i < 5; i++) { + resptr[i] = &res[i]; + } - Object *obj = ObjectDB::get_instance(monitor_callback_id); - if (!obj) { - monitored_bodies.clear(); - monitor_callback_id = ObjectID(); - return; - } + for (Map<BodyKey, BodyState>::Element *E = monitored_bodies.front(); E;) { + if (E->get().state == 0) { // Nothing happened + Map<BodyKey, BodyState>::Element *next = E->next(); + monitored_bodies.erase(E); + E = next; + continue; + } + + res[0] = E->get().state > 0 ? PhysicsServer2D::AREA_BODY_ADDED : PhysicsServer2D::AREA_BODY_REMOVED; + res[1] = E->key().rid; + res[2] = E->key().instance_id; + res[3] = E->key().body_shape; + res[4] = E->key().area_shape; - for (Map<BodyKey, BodyState>::Element *E = monitored_bodies.front(); E;) { - if (E->get().state == 0) { // Nothing happened Map<BodyKey, BodyState>::Element *next = E->next(); monitored_bodies.erase(E); E = next; - continue; - } - - res[0] = E->get().state > 0 ? PhysicsServer2D::AREA_BODY_ADDED : PhysicsServer2D::AREA_BODY_REMOVED; - res[1] = E->key().rid; - res[2] = E->key().instance_id; - res[3] = E->key().body_shape; - res[4] = E->key().area_shape; - Map<BodyKey, BodyState>::Element *next = E->next(); - monitored_bodies.erase(E); - E = next; - - Callable::CallError ce; - obj->call(monitor_callback_method, (const Variant **)resptr, 5, ce); + Callable::CallError ce; + Variant ret; + monitor_callback.call((const Variant **)resptr, 5, ret, ce); + } + } else { + monitored_bodies.clear(); + monitor_callback = Callable(); } } - if (area_monitor_callback_id.is_valid() && !monitored_areas.is_empty()) { - Variant res[5]; - Variant *resptr[5]; - for (int i = 0; i < 5; i++) { - resptr[i] = &res[i]; - } + if (!area_monitor_callback.is_null() && !monitored_areas.is_empty()) { + if (area_monitor_callback.is_valid()) { + Variant res[5]; + Variant *resptr[5]; + for (int i = 0; i < 5; i++) { + resptr[i] = &res[i]; + } - Object *obj = ObjectDB::get_instance(area_monitor_callback_id); - if (!obj) { - monitored_areas.clear(); - area_monitor_callback_id = ObjectID(); - return; - } + for (Map<BodyKey, BodyState>::Element *E = monitored_areas.front(); E;) { + if (E->get().state == 0) { // Nothing happened + Map<BodyKey, BodyState>::Element *next = E->next(); + monitored_areas.erase(E); + E = next; + continue; + } + + res[0] = E->get().state > 0 ? PhysicsServer2D::AREA_BODY_ADDED : PhysicsServer2D::AREA_BODY_REMOVED; + res[1] = E->key().rid; + res[2] = E->key().instance_id; + res[3] = E->key().body_shape; + res[4] = E->key().area_shape; - for (Map<BodyKey, BodyState>::Element *E = monitored_areas.front(); E;) { - if (E->get().state == 0) { // Nothing happened Map<BodyKey, BodyState>::Element *next = E->next(); monitored_areas.erase(E); E = next; - continue; - } - - res[0] = E->get().state > 0 ? PhysicsServer2D::AREA_BODY_ADDED : PhysicsServer2D::AREA_BODY_REMOVED; - res[1] = E->key().rid; - res[2] = E->key().instance_id; - res[3] = E->key().body_shape; - res[4] = E->key().area_shape; - - Map<BodyKey, BodyState>::Element *next = E->next(); - monitored_areas.erase(E); - E = next; - Callable::CallError ce; - obj->call(area_monitor_callback_method, (const Variant **)resptr, 5, ce); + Callable::CallError ce; + Variant ret; + area_monitor_callback.call((const Variant **)resptr, 5, ret, ce); + } + } else { + monitored_areas.clear(); + area_monitor_callback = Callable(); } } } diff --git a/servers/physics_2d/godot_area_2d.h b/servers/physics_2d/godot_area_2d.h index daa03d39e3..13b3ce1bf2 100644 --- a/servers/physics_2d/godot_area_2d.h +++ b/servers/physics_2d/godot_area_2d.h @@ -52,11 +52,9 @@ class GodotArea2D : public GodotCollisionObject2D { int priority = 0; bool monitorable = false; - ObjectID monitor_callback_id; - StringName monitor_callback_method; + Callable monitor_callback; - ObjectID area_monitor_callback_id; - StringName area_monitor_callback_method; + Callable area_monitor_callback; SelfList<GodotArea2D> monitor_query_list; SelfList<GodotArea2D> moved_list; @@ -99,11 +97,11 @@ class GodotArea2D : public GodotCollisionObject2D { void _queue_monitor_update(); public: - void set_monitor_callback(ObjectID p_id, const StringName &p_method); - _FORCE_INLINE_ bool has_monitor_callback() const { return monitor_callback_id.is_valid(); } + void set_monitor_callback(const Callable &p_callback); + _FORCE_INLINE_ bool has_monitor_callback() const { return !monitor_callback.is_null(); } - void set_area_monitor_callback(ObjectID p_id, const StringName &p_method); - _FORCE_INLINE_ bool has_area_monitor_callback() const { return area_monitor_callback_id.is_valid(); } + void set_area_monitor_callback(const Callable &p_callback); + _FORCE_INLINE_ bool has_area_monitor_callback() const { return !area_monitor_callback.is_null(); } _FORCE_INLINE_ void add_body_to_query(GodotBody2D *p_body, uint32_t p_body_shape, uint32_t p_area_shape); _FORCE_INLINE_ void remove_body_from_query(GodotBody2D *p_body, uint32_t p_body_shape, uint32_t p_area_shape); diff --git a/servers/physics_2d/godot_physics_server_2d.cpp b/servers/physics_2d/godot_physics_server_2d.cpp index c86f87fc03..cf66b80076 100644 --- a/servers/physics_2d/godot_physics_server_2d.cpp +++ b/servers/physics_2d/godot_physics_server_2d.cpp @@ -513,18 +513,18 @@ void GodotPhysicsServer2D::area_set_collision_layer(RID p_area, uint32_t p_layer area->set_collision_layer(p_layer); } -void GodotPhysicsServer2D::area_set_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) { +void GodotPhysicsServer2D::area_set_monitor_callback(RID p_area, const Callable &p_callback) { GodotArea2D *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); - area->set_monitor_callback(p_receiver ? p_receiver->get_instance_id() : ObjectID(), p_method); + area->set_monitor_callback(p_callback.is_valid() ? p_callback : Callable()); } -void GodotPhysicsServer2D::area_set_area_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) { +void GodotPhysicsServer2D::area_set_area_monitor_callback(RID p_area, const Callable &p_callback) { GodotArea2D *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); - area->set_area_monitor_callback(p_receiver ? p_receiver->get_instance_id() : ObjectID(), p_method); + area->set_area_monitor_callback(p_callback.is_valid() ? p_callback : Callable()); } /* BODY API */ diff --git a/servers/physics_2d/godot_physics_server_2d.h b/servers/physics_2d/godot_physics_server_2d.h index a8a1e71d13..b03d78a1de 100644 --- a/servers/physics_2d/godot_physics_server_2d.h +++ b/servers/physics_2d/godot_physics_server_2d.h @@ -158,8 +158,8 @@ public: virtual void area_set_collision_mask(RID p_area, uint32_t p_mask) override; virtual void area_set_collision_layer(RID p_area, uint32_t p_layer) override; - virtual void area_set_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) override; - virtual void area_set_area_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) override; + virtual void area_set_monitor_callback(RID p_area, const Callable &p_callback) override; + virtual void area_set_area_monitor_callback(RID p_area, const Callable &p_callback) override; virtual void area_set_pickable(RID p_area, bool p_pickable) override; diff --git a/servers/physics_3d/godot_area_3d.cpp b/servers/physics_3d/godot_area_3d.cpp index e115e17061..973fc50968 100644 --- a/servers/physics_3d/godot_area_3d.cpp +++ b/servers/physics_3d/godot_area_3d.cpp @@ -86,16 +86,16 @@ void GodotArea3D::set_space(GodotSpace3D *p_space) { _set_space(p_space); } -void GodotArea3D::set_monitor_callback(ObjectID p_id, const StringName &p_method) { - if (p_id == monitor_callback_id) { - monitor_callback_method = p_method; +void GodotArea3D::set_monitor_callback(const Callable &p_callback) { + ObjectID id = p_callback.get_object_id(); + if (id == monitor_callback.get_object_id()) { + monitor_callback = p_callback; return; } _unregister_shapes(); - monitor_callback_id = p_id; - monitor_callback_method = p_method; + monitor_callback = p_callback; monitored_bodies.clear(); monitored_areas.clear(); @@ -107,16 +107,16 @@ void GodotArea3D::set_monitor_callback(ObjectID p_id, const StringName &p_method } } -void GodotArea3D::set_area_monitor_callback(ObjectID p_id, const StringName &p_method) { - if (p_id == area_monitor_callback_id) { - area_monitor_callback_method = p_method; +void GodotArea3D::set_area_monitor_callback(const Callable &p_callback) { + ObjectID id = p_callback.get_object_id(); + if (id == area_monitor_callback.get_object_id()) { + area_monitor_callback = p_callback; return; } _unregister_shapes(); - area_monitor_callback_id = p_id; - area_monitor_callback_method = p_method; + area_monitor_callback = p_callback; monitored_bodies.clear(); monitored_areas.clear(); @@ -230,77 +230,75 @@ void GodotArea3D::set_monitorable(bool p_monitorable) { } void GodotArea3D::call_queries() { - if (monitor_callback_id.is_valid() && !monitored_bodies.is_empty()) { - Variant res[5]; - Variant *resptr[5]; - for (int i = 0; i < 5; i++) { - resptr[i] = &res[i]; - } + if (!monitor_callback.is_null() && !monitored_bodies.is_empty()) { + if (monitor_callback.is_valid()) { + Variant res[5]; + Variant *resptr[5]; + for (int i = 0; i < 5; i++) { + resptr[i] = &res[i]; + } - Object *obj = ObjectDB::get_instance(monitor_callback_id); - if (!obj) { - monitored_bodies.clear(); - monitor_callback_id = ObjectID(); - return; - } + for (Map<BodyKey, BodyState>::Element *E = monitored_bodies.front(); E;) { + if (E->get().state == 0) { // Nothing happened + Map<BodyKey, BodyState>::Element *next = E->next(); + monitored_bodies.erase(E); + E = next; + continue; + } + + res[0] = E->get().state > 0 ? PhysicsServer3D::AREA_BODY_ADDED : PhysicsServer3D::AREA_BODY_REMOVED; + res[1] = E->key().rid; + res[2] = E->key().instance_id; + res[3] = E->key().body_shape; + res[4] = E->key().area_shape; - for (Map<BodyKey, BodyState>::Element *E = monitored_bodies.front(); E;) { - if (E->get().state == 0) { // Nothing happened Map<BodyKey, BodyState>::Element *next = E->next(); monitored_bodies.erase(E); E = next; - continue; - } - res[0] = E->get().state > 0 ? PhysicsServer3D::AREA_BODY_ADDED : PhysicsServer3D::AREA_BODY_REMOVED; - res[1] = E->key().rid; - res[2] = E->key().instance_id; - res[3] = E->key().body_shape; - res[4] = E->key().area_shape; - - Map<BodyKey, BodyState>::Element *next = E->next(); - monitored_bodies.erase(E); - E = next; - - Callable::CallError ce; - obj->call(monitor_callback_method, (const Variant **)resptr, 5, ce); + Callable::CallError ce; + Variant ret; + monitor_callback.call((const Variant **)resptr, 5, ret, ce); + } + } else { + monitored_bodies.clear(); + monitor_callback = Callable(); } } - if (area_monitor_callback_id.is_valid() && !monitored_areas.is_empty()) { - Variant res[5]; - Variant *resptr[5]; - for (int i = 0; i < 5; i++) { - resptr[i] = &res[i]; - } + if (!area_monitor_callback.is_null() && !monitored_areas.is_empty()) { + if (area_monitor_callback.is_valid()) { + Variant res[5]; + Variant *resptr[5]; + for (int i = 0; i < 5; i++) { + resptr[i] = &res[i]; + } - Object *obj = ObjectDB::get_instance(area_monitor_callback_id); - if (!obj) { - monitored_areas.clear(); - area_monitor_callback_id = ObjectID(); - return; - } + for (Map<BodyKey, BodyState>::Element *E = monitored_areas.front(); E;) { + if (E->get().state == 0) { // Nothing happened + Map<BodyKey, BodyState>::Element *next = E->next(); + monitored_areas.erase(E); + E = next; + continue; + } + + res[0] = E->get().state > 0 ? PhysicsServer3D::AREA_BODY_ADDED : PhysicsServer3D::AREA_BODY_REMOVED; + res[1] = E->key().rid; + res[2] = E->key().instance_id; + res[3] = E->key().body_shape; + res[4] = E->key().area_shape; - for (Map<BodyKey, BodyState>::Element *E = monitored_areas.front(); E;) { - if (E->get().state == 0) { // Nothing happened Map<BodyKey, BodyState>::Element *next = E->next(); monitored_areas.erase(E); E = next; - continue; - } - res[0] = E->get().state > 0 ? PhysicsServer3D::AREA_BODY_ADDED : PhysicsServer3D::AREA_BODY_REMOVED; - res[1] = E->key().rid; - res[2] = E->key().instance_id; - res[3] = E->key().body_shape; - res[4] = E->key().area_shape; - - Map<BodyKey, BodyState>::Element *next = E->next(); - monitored_areas.erase(E); - E = next; - - Callable::CallError ce; - obj->call(area_monitor_callback_method, (const Variant **)resptr, 5, ce); + Callable::CallError ce; + Variant ret; + area_monitor_callback.call((const Variant **)resptr, 5, ret, ce); + } + } else { + monitored_areas.clear(); + area_monitor_callback = Callable(); } } } diff --git a/servers/physics_3d/godot_area_3d.h b/servers/physics_3d/godot_area_3d.h index e8caa9221b..b02fa1d5b9 100644 --- a/servers/physics_3d/godot_area_3d.h +++ b/servers/physics_3d/godot_area_3d.h @@ -57,11 +57,8 @@ class GodotArea3D : public GodotCollisionObject3D { int priority = 0; bool monitorable = false; - ObjectID monitor_callback_id; - StringName monitor_callback_method; - - ObjectID area_monitor_callback_id; - StringName area_monitor_callback_method; + Callable monitor_callback; + Callable area_monitor_callback; SelfList<GodotArea3D> monitor_query_list; SelfList<GodotArea3D> moved_list; @@ -106,11 +103,11 @@ class GodotArea3D : public GodotCollisionObject3D { void _queue_monitor_update(); public: - void set_monitor_callback(ObjectID p_id, const StringName &p_method); - _FORCE_INLINE_ bool has_monitor_callback() const { return monitor_callback_id.is_valid(); } + void set_monitor_callback(const Callable &p_callback); + _FORCE_INLINE_ bool has_monitor_callback() const { return !monitor_callback.is_null(); } - void set_area_monitor_callback(ObjectID p_id, const StringName &p_method); - _FORCE_INLINE_ bool has_area_monitor_callback() const { return area_monitor_callback_id.is_valid(); } + void set_area_monitor_callback(const Callable &p_callback); + _FORCE_INLINE_ bool has_area_monitor_callback() const { return !area_monitor_callback.is_null(); } _FORCE_INLINE_ void add_body_to_query(GodotBody3D *p_body, uint32_t p_body_shape, uint32_t p_area_shape); _FORCE_INLINE_ void remove_body_from_query(GodotBody3D *p_body, uint32_t p_body_shape, uint32_t p_area_shape); diff --git a/servers/physics_3d/godot_physics_server_3d.cpp b/servers/physics_3d/godot_physics_server_3d.cpp index 79a2e0b0ea..73654939ca 100644 --- a/servers/physics_3d/godot_physics_server_3d.cpp +++ b/servers/physics_3d/godot_physics_server_3d.cpp @@ -416,11 +416,11 @@ void GodotPhysicsServer3D::area_set_monitorable(RID p_area, bool p_monitorable) area->set_monitorable(p_monitorable); } -void GodotPhysicsServer3D::area_set_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) { +void GodotPhysicsServer3D::area_set_monitor_callback(RID p_area, const Callable &p_callback) { GodotArea3D *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); - area->set_monitor_callback(p_receiver ? p_receiver->get_instance_id() : ObjectID(), p_method); + area->set_monitor_callback(p_callback.is_valid() ? p_callback : Callable()); } void GodotPhysicsServer3D::area_set_ray_pickable(RID p_area, bool p_enable) { @@ -430,11 +430,11 @@ void GodotPhysicsServer3D::area_set_ray_pickable(RID p_area, bool p_enable) { area->set_ray_pickable(p_enable); } -void GodotPhysicsServer3D::area_set_area_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) { +void GodotPhysicsServer3D::area_set_area_monitor_callback(RID p_area, const Callable &p_callback) { GodotArea3D *area = area_owner.get_or_null(p_area); ERR_FAIL_COND(!area); - area->set_area_monitor_callback(p_receiver ? p_receiver->get_instance_id() : ObjectID(), p_method); + area->set_area_monitor_callback(p_callback.is_valid() ? p_callback : Callable()); } /* BODY API */ diff --git a/servers/physics_3d/godot_physics_server_3d.h b/servers/physics_3d/godot_physics_server_3d.h index 3ed9e320dc..4ddd10a4e0 100644 --- a/servers/physics_3d/godot_physics_server_3d.h +++ b/servers/physics_3d/godot_physics_server_3d.h @@ -157,8 +157,8 @@ public: virtual void area_set_monitorable(RID p_area, bool p_monitorable) override; - virtual void area_set_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) override; - virtual void area_set_area_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) override; + virtual void area_set_monitor_callback(RID p_area, const Callable &p_callback) override; + virtual void area_set_area_monitor_callback(RID p_area, const Callable &p_callback) override; /* BODY API */ diff --git a/servers/physics_server_2d.cpp b/servers/physics_server_2d.cpp index 300f9c7d8b..abe173b078 100644 --- a/servers/physics_server_2d.cpp +++ b/servers/physics_server_2d.cpp @@ -616,8 +616,8 @@ void PhysicsServer2D::_bind_methods() { ClassDB::bind_method(D_METHOD("area_attach_canvas_instance_id", "area", "id"), &PhysicsServer2D::area_attach_canvas_instance_id); ClassDB::bind_method(D_METHOD("area_get_canvas_instance_id", "area"), &PhysicsServer2D::area_get_canvas_instance_id); - ClassDB::bind_method(D_METHOD("area_set_monitor_callback", "area", "receiver", "method"), &PhysicsServer2D::area_set_monitor_callback); - ClassDB::bind_method(D_METHOD("area_set_area_monitor_callback", "area", "receiver", "method"), &PhysicsServer2D::area_set_area_monitor_callback); + ClassDB::bind_method(D_METHOD("area_set_monitor_callback", "area", "callback"), &PhysicsServer2D::area_set_monitor_callback); + ClassDB::bind_method(D_METHOD("area_set_area_monitor_callback", "area", "callback"), &PhysicsServer2D::area_set_area_monitor_callback); ClassDB::bind_method(D_METHOD("area_set_monitorable", "area", "monitorable"), &PhysicsServer2D::area_set_monitorable); ClassDB::bind_method(D_METHOD("body_create"), &PhysicsServer2D::body_create); diff --git a/servers/physics_server_2d.h b/servers/physics_server_2d.h index 584da56c66..e6acebd5dd 100644 --- a/servers/physics_server_2d.h +++ b/servers/physics_server_2d.h @@ -335,8 +335,8 @@ public: virtual void area_set_monitorable(RID p_area, bool p_monitorable) = 0; virtual void area_set_pickable(RID p_area, bool p_pickable) = 0; - virtual void area_set_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) = 0; - virtual void area_set_area_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) = 0; + virtual void area_set_monitor_callback(RID p_area, const Callable &p_callback) = 0; + virtual void area_set_area_monitor_callback(RID p_area, const Callable &p_callback) = 0; /* BODY API */ diff --git a/servers/physics_server_2d_wrap_mt.h b/servers/physics_server_2d_wrap_mt.h index 4a2f07ab1e..b133fa41aa 100644 --- a/servers/physics_server_2d_wrap_mt.h +++ b/servers/physics_server_2d_wrap_mt.h @@ -165,8 +165,8 @@ public: FUNC2(area_set_monitorable, RID, bool); FUNC2(area_set_pickable, RID, bool); - FUNC3(area_set_monitor_callback, RID, Object *, const StringName &); - FUNC3(area_set_area_monitor_callback, RID, Object *, const StringName &); + FUNC2(area_set_monitor_callback, RID, const Callable &); + FUNC2(area_set_area_monitor_callback, RID, const Callable &); /* BODY API */ diff --git a/servers/physics_server_3d.cpp b/servers/physics_server_3d.cpp index c68cd7696b..8f66a207aa 100644 --- a/servers/physics_server_3d.cpp +++ b/servers/physics_server_3d.cpp @@ -612,8 +612,8 @@ void PhysicsServer3D::_bind_methods() { ClassDB::bind_method(D_METHOD("area_attach_object_instance_id", "area", "id"), &PhysicsServer3D::area_attach_object_instance_id); ClassDB::bind_method(D_METHOD("area_get_object_instance_id", "area"), &PhysicsServer3D::area_get_object_instance_id); - ClassDB::bind_method(D_METHOD("area_set_monitor_callback", "area", "receiver", "method"), &PhysicsServer3D::area_set_monitor_callback); - ClassDB::bind_method(D_METHOD("area_set_area_monitor_callback", "area", "receiver", "method"), &PhysicsServer3D::area_set_area_monitor_callback); + ClassDB::bind_method(D_METHOD("area_set_monitor_callback", "area", "callback"), &PhysicsServer3D::area_set_monitor_callback); + ClassDB::bind_method(D_METHOD("area_set_area_monitor_callback", "area", "callback"), &PhysicsServer3D::area_set_area_monitor_callback); ClassDB::bind_method(D_METHOD("area_set_monitorable", "area", "monitorable"), &PhysicsServer3D::area_set_monitorable); ClassDB::bind_method(D_METHOD("area_set_ray_pickable", "area", "enable"), &PhysicsServer3D::area_set_ray_pickable); diff --git a/servers/physics_server_3d.h b/servers/physics_server_3d.h index 79369bd459..6e9f8c7704 100644 --- a/servers/physics_server_3d.h +++ b/servers/physics_server_3d.h @@ -348,8 +348,8 @@ public: virtual void area_set_monitorable(RID p_area, bool p_monitorable) = 0; - virtual void area_set_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) = 0; - virtual void area_set_area_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) = 0; + virtual void area_set_monitor_callback(RID p_area, const Callable &p_callback) = 0; + virtual void area_set_area_monitor_callback(RID p_area, const Callable &p_callback) = 0; virtual void area_set_ray_pickable(RID p_area, bool p_enable) = 0; diff --git a/servers/physics_server_3d_wrap_mt.h b/servers/physics_server_3d_wrap_mt.h index 4c88ef2642..df3dc279fe 100644 --- a/servers/physics_server_3d_wrap_mt.h +++ b/servers/physics_server_3d_wrap_mt.h @@ -166,8 +166,8 @@ public: FUNC2(area_set_monitorable, RID, bool); FUNC2(area_set_ray_pickable, RID, bool); - FUNC3(area_set_monitor_callback, RID, Object *, const StringName &); - FUNC3(area_set_area_monitor_callback, RID, Object *, const StringName &); + FUNC2(area_set_monitor_callback, RID, const Callable &); + FUNC2(area_set_area_monitor_callback, RID, const Callable &); /* BODY API */ |