diff --git a/doc/classes/PhysicsServer2D.xml b/doc/classes/PhysicsServer2D.xml index 24a20b5613e..e44bf71e8d6 100644 --- a/doc/classes/PhysicsServer2D.xml +++ b/doc/classes/PhysicsServer2D.xml @@ -123,8 +123,7 @@ - - + @@ -147,8 +146,7 @@ - - + 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 034bd555190..0c34cf8092e 100644 --- a/doc/classes/PhysicsServer3D.xml +++ b/doc/classes/PhysicsServer3D.xml @@ -110,8 +110,7 @@ - - + @@ -134,8 +133,7 @@ - - + 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/modules/bullet/area_bullet.cpp b/modules/bullet/area_bullet.cpp index c3bd84c329f..b5a7da0c38c 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(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(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(p_callbackObjectType)].event_callback_id.is_valid(); + return !eventsCallbacks[static_cast(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 c8b516c9514..d96c5500828 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 bb2db49c87e..610d2145cdf 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 7c146de0c30..94635b5bfcf 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 fff9c47d4d6..75a1723e042 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 91799832201..e459c42e8c5 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/servers/physics_2d/godot_area_2d.cpp b/servers/physics_2d/godot_area_2d.cpp index 7cb202dd1fc..6983e288410 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::Element *E = monitored_bodies.front(); E;) { + if (E->get().state == 0) { // Nothing happened + Map::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::Element *E = monitored_bodies.front(); E;) { - if (E->get().state == 0) { // Nothing happened Map::Element *next = E->next(); monitored_bodies.erase(E); E = next; - continue; + + Callable::CallError ce; + Variant ret; + monitor_callback.call((const Variant **)resptr, 5, ret, ce); } - - 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::Element *next = E->next(); - monitored_bodies.erase(E); - E = next; - - Callable::CallError ce; - obj->call(monitor_callback_method, (const Variant **)resptr, 5, 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::Element *E = monitored_areas.front(); E;) { + if (E->get().state == 0) { // Nothing happened + Map::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::Element *E = monitored_areas.front(); E;) { - if (E->get().state == 0) { // Nothing happened Map::Element *next = E->next(); monitored_areas.erase(E); E = next; - continue; + + Callable::CallError ce; + Variant ret; + area_monitor_callback.call((const Variant **)resptr, 5, ret, ce); } - - 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::Element *next = E->next(); - monitored_areas.erase(E); - E = next; - - Callable::CallError ce; - obj->call(area_monitor_callback_method, (const Variant **)resptr, 5, 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 daa03d39e30..13b3ce1bf29 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 monitor_query_list; SelfList 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 c86f87fc030..cf66b800769 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 a8a1e71d134..b03d78a1de0 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 e115e17061f..973fc509685 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::Element *E = monitored_bodies.front(); E;) { + if (E->get().state == 0) { // Nothing happened + Map::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::Element *E = monitored_bodies.front(); E;) { - if (E->get().state == 0) { // Nothing happened Map::Element *next = E->next(); monitored_bodies.erase(E); E = next; - continue; + + Callable::CallError ce; + Variant ret; + monitor_callback.call((const Variant **)resptr, 5, ret, ce); } - - 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::Element *next = E->next(); - monitored_bodies.erase(E); - E = next; - - Callable::CallError ce; - obj->call(monitor_callback_method, (const Variant **)resptr, 5, 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::Element *E = monitored_areas.front(); E;) { + if (E->get().state == 0) { // Nothing happened + Map::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::Element *E = monitored_areas.front(); E;) { - if (E->get().state == 0) { // Nothing happened Map::Element *next = E->next(); monitored_areas.erase(E); E = next; - continue; + + Callable::CallError ce; + Variant ret; + area_monitor_callback.call((const Variant **)resptr, 5, ret, ce); } - - 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::Element *next = E->next(); - monitored_areas.erase(E); - E = next; - - Callable::CallError ce; - obj->call(area_monitor_callback_method, (const Variant **)resptr, 5, 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 e8caa9221b4..b02fa1d5b97 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 monitor_query_list; SelfList 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 79a2e0b0eac..73654939cab 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 3ed9e320dca..4ddd10a4e0c 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 300f9c7d8b1..abe173b0781 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 584da56c669..e6acebd5dd9 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 4a2f07ab1eb..b133fa41aaf 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 c68cd7696be..8f66a207aaa 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 79369bd459f..6e9f8c77043 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 4c88ef26423..df3dc279fed 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 */