summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--scene/2d/area_2d.cpp8
-rw-r--r--scene/2d/physics_body_2d.cpp23
-rw-r--r--scene/2d/physics_body_2d.h2
-rw-r--r--scene/3d/physics_body.cpp24
-rw-r--r--scene/3d/physics_body.h2
5 files changed, 53 insertions, 6 deletions
diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp
index 464553b982..50a115174d 100644
--- a/scene/2d/area_2d.cpp
+++ b/scene/2d/area_2d.cpp
@@ -420,13 +420,13 @@ void Area2D::_notification(int p_what) {
void Area2D::set_enable_monitoring(bool p_enable) {
- if (locked) {
- ERR_EXPLAIN("This function can't be used during the in/out signal.");
- }
- ERR_FAIL_COND(locked);
if (p_enable==monitoring)
return;
+ if (locked) {
+ ERR_EXPLAIN("Function blocked during in/out signal. Use call_deferred(\"set_enable_monitoring\",true/false)");
+ }
+ ERR_FAIL_COND(locked);
monitoring=p_enable;
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index 71a45024c4..cc2e5c0d72 100644
--- a/scene/2d/physics_body_2d.cpp
+++ b/scene/2d/physics_body_2d.cpp
@@ -310,14 +310,20 @@ void RigidBody2D::_body_enter_tree(ObjectID p_id) {
ERR_FAIL_COND(!E);
ERR_FAIL_COND(E->get().in_scene);
+ contact_monitor->locked=true;
+
E->get().in_scene=true;
emit_signal(SceneStringNames::get_singleton()->body_enter,node);
+
for(int i=0;i<E->get().shapes.size();i++) {
emit_signal(SceneStringNames::get_singleton()->body_enter_shape,p_id,node,E->get().shapes[i].body_shape,E->get().shapes[i].local_shape);
}
+ contact_monitor->locked=false;
+
+
}
void RigidBody2D::_body_exit_tree(ObjectID p_id) {
@@ -329,11 +335,18 @@ void RigidBody2D::_body_exit_tree(ObjectID p_id) {
ERR_FAIL_COND(!E);
ERR_FAIL_COND(!E->get().in_scene);
E->get().in_scene=false;
+
+ contact_monitor->locked=true;
+
emit_signal(SceneStringNames::get_singleton()->body_exit,node);
+
for(int i=0;i<E->get().shapes.size();i++) {
emit_signal(SceneStringNames::get_singleton()->body_exit_shape,p_id,node,E->get().shapes[i].body_shape,E->get().shapes[i].local_shape);
}
+
+ contact_monitor->locked=false;
+
}
void RigidBody2D::_body_inout(int p_status, ObjectID p_instance, int p_body_shape,int p_local_shape) {
@@ -439,6 +452,8 @@ void RigidBody2D::_direct_state_changed(Object *p_state) {
if (contact_monitor) {
+ contact_monitor->locked=true;
+
//untag all
int rc=0;
for( Map<ObjectID,BodyState>::Element *E=contact_monitor->body_map.front();E;E=E->next()) {
@@ -520,6 +535,8 @@ void RigidBody2D::_direct_state_changed(Object *p_state) {
_body_inout(1,toadd[i].id,toadd[i].shape,toadd[i].local_shape);
}
+ contact_monitor->locked=false;
+
}
set_block_transform_notify(true); // don't want notify (would feedback loop)
@@ -803,6 +820,11 @@ void RigidBody2D::set_contact_monitor(bool p_enabled) {
if (!p_enabled) {
+ if (contact_monitor->locked) {
+ ERR_EXPLAIN("Can't disable contact monitoring during in/out callback. Use call_deferred(\"set_contact_monitor\",false) instead");
+ }
+ ERR_FAIL_COND(contact_monitor->locked);
+
for(Map<ObjectID,BodyState>::Element *E=contact_monitor->body_map.front();E;E=E->next()) {
//clean up mess
@@ -813,6 +835,7 @@ void RigidBody2D::set_contact_monitor(bool p_enabled) {
} else {
contact_monitor = memnew( ContactMonitor );
+ contact_monitor->locked=false;
}
}
diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h
index fc337915c5..999e63dd5d 100644
--- a/scene/2d/physics_body_2d.h
+++ b/scene/2d/physics_body_2d.h
@@ -190,7 +190,7 @@ private:
struct ContactMonitor {
-
+ bool locked;
Map<ObjectID,BodyState> body_map;
};
diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp
index de777604b0..1a2665b6ad 100644
--- a/scene/3d/physics_body.cpp
+++ b/scene/3d/physics_body.cpp
@@ -207,6 +207,9 @@ void RigidBody::_body_enter_tree(ObjectID p_id) {
ERR_FAIL_COND(E->get().in_tree);
E->get().in_tree=true;
+
+ contact_monitor->locked=true;
+
emit_signal(SceneStringNames::get_singleton()->body_enter,node);
for(int i=0;i<E->get().shapes.size();i++) {
@@ -214,6 +217,9 @@ void RigidBody::_body_enter_tree(ObjectID p_id) {
emit_signal(SceneStringNames::get_singleton()->body_enter_shape,p_id,node,E->get().shapes[i].body_shape,E->get().shapes[i].local_shape);
}
+ contact_monitor->locked=false;
+
+
}
void RigidBody::_body_exit_tree(ObjectID p_id) {
@@ -225,11 +231,18 @@ void RigidBody::_body_exit_tree(ObjectID p_id) {
ERR_FAIL_COND(!E);
ERR_FAIL_COND(!E->get().in_tree);
E->get().in_tree=false;
+
+ contact_monitor->locked=true;
+
emit_signal(SceneStringNames::get_singleton()->body_exit,node);
+
for(int i=0;i<E->get().shapes.size();i++) {
emit_signal(SceneStringNames::get_singleton()->body_exit_shape,p_id,node,E->get().shapes[i].body_shape,E->get().shapes[i].local_shape);
}
+
+ contact_monitor->locked=false;
+
}
void RigidBody::_body_inout(int p_status, ObjectID p_instance, int p_body_shape,int p_local_shape) {
@@ -317,6 +330,8 @@ void RigidBody::_direct_state_changed(Object *p_state) {
if (contact_monitor) {
+ contact_monitor->locked=true;
+
//untag all
int rc=0;
for( Map<ObjectID,BodyState>::Element *E=contact_monitor->body_map.front();E;E=E->next()) {
@@ -396,6 +411,8 @@ void RigidBody::_direct_state_changed(Object *p_state) {
_body_inout(1,toadd[i].id,toadd[i].shape,toadd[i].local_shape);
}
+ contact_monitor->locked=false;
+
}
set_ignore_transform_notification(true);
@@ -648,6 +665,11 @@ void RigidBody::set_contact_monitor(bool p_enabled) {
if (!p_enabled) {
+ if (contact_monitor->locked) {
+ ERR_EXPLAIN("Can't disable contact monitoring during in/out callback. Use call_deferred(\"set_contact_monitor\",false) instead");
+ }
+ ERR_FAIL_COND(contact_monitor->locked);
+
for(Map<ObjectID,BodyState>::Element *E=contact_monitor->body_map.front();E;E=E->next()) {
//clean up mess
@@ -658,6 +680,8 @@ void RigidBody::set_contact_monitor(bool p_enabled) {
} else {
contact_monitor = memnew( ContactMonitor );
+ contact_monitor->locked=false;
+
}
}
diff --git a/scene/3d/physics_body.h b/scene/3d/physics_body.h
index 0d6c358e28..da79d63f00 100644
--- a/scene/3d/physics_body.h
+++ b/scene/3d/physics_body.h
@@ -175,7 +175,7 @@ private:
struct ContactMonitor {
-
+ bool locked;
Map<ObjectID,BodyState> body_map;
};