Use Callable
in Area monitor callback
This commit is contained in:
parent
455e027725
commit
770e3a8e51
22 changed files with 194 additions and 214 deletions
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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")));
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
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<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);
|
||||
} 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;
|
||||
|
||||
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<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);
|
||||
} else {
|
||||
monitored_areas.clear();
|
||||
area_monitor_callback = Callable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
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<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);
|
||||
} 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;
|
||||
|
||||
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<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);
|
||||
} else {
|
||||
monitored_areas.clear();
|
||||
area_monitor_callback = Callable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
Loading…
Reference in a new issue