-Properly lock and and warn about switching off contact monitoring, fixes #3041
This commit is contained in:
parent
eab1e5b596
commit
a625f7d073
@ -420,13 +420,13 @@ void Area2D::_notification(int p_what) {
|
|||||||
|
|
||||||
void Area2D::set_enable_monitoring(bool p_enable) {
|
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)
|
if (p_enable==monitoring)
|
||||||
return;
|
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;
|
monitoring=p_enable;
|
||||||
|
|
||||||
|
@ -310,14 +310,20 @@ void RigidBody2D::_body_enter_tree(ObjectID p_id) {
|
|||||||
ERR_FAIL_COND(!E);
|
ERR_FAIL_COND(!E);
|
||||||
ERR_FAIL_COND(E->get().in_scene);
|
ERR_FAIL_COND(E->get().in_scene);
|
||||||
|
|
||||||
|
contact_monitor->locked=true;
|
||||||
|
|
||||||
E->get().in_scene=true;
|
E->get().in_scene=true;
|
||||||
emit_signal(SceneStringNames::get_singleton()->body_enter,node);
|
emit_signal(SceneStringNames::get_singleton()->body_enter,node);
|
||||||
|
|
||||||
|
|
||||||
for(int i=0;i<E->get().shapes.size();i++) {
|
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);
|
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) {
|
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);
|
||||||
ERR_FAIL_COND(!E->get().in_scene);
|
ERR_FAIL_COND(!E->get().in_scene);
|
||||||
E->get().in_scene=false;
|
E->get().in_scene=false;
|
||||||
|
|
||||||
|
contact_monitor->locked=true;
|
||||||
|
|
||||||
emit_signal(SceneStringNames::get_singleton()->body_exit,node);
|
emit_signal(SceneStringNames::get_singleton()->body_exit,node);
|
||||||
|
|
||||||
for(int i=0;i<E->get().shapes.size();i++) {
|
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);
|
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) {
|
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) {
|
if (contact_monitor) {
|
||||||
|
|
||||||
|
contact_monitor->locked=true;
|
||||||
|
|
||||||
//untag all
|
//untag all
|
||||||
int rc=0;
|
int rc=0;
|
||||||
for( Map<ObjectID,BodyState>::Element *E=contact_monitor->body_map.front();E;E=E->next()) {
|
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);
|
_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)
|
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 (!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()) {
|
for(Map<ObjectID,BodyState>::Element *E=contact_monitor->body_map.front();E;E=E->next()) {
|
||||||
|
|
||||||
//clean up mess
|
//clean up mess
|
||||||
@ -813,6 +835,7 @@ void RigidBody2D::set_contact_monitor(bool p_enabled) {
|
|||||||
} else {
|
} else {
|
||||||
|
|
||||||
contact_monitor = memnew( ContactMonitor );
|
contact_monitor = memnew( ContactMonitor );
|
||||||
|
contact_monitor->locked=false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -190,7 +190,7 @@ private:
|
|||||||
|
|
||||||
struct ContactMonitor {
|
struct ContactMonitor {
|
||||||
|
|
||||||
|
bool locked;
|
||||||
Map<ObjectID,BodyState> body_map;
|
Map<ObjectID,BodyState> body_map;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -207,6 +207,9 @@ void RigidBody::_body_enter_tree(ObjectID p_id) {
|
|||||||
ERR_FAIL_COND(E->get().in_tree);
|
ERR_FAIL_COND(E->get().in_tree);
|
||||||
|
|
||||||
E->get().in_tree=true;
|
E->get().in_tree=true;
|
||||||
|
|
||||||
|
contact_monitor->locked=true;
|
||||||
|
|
||||||
emit_signal(SceneStringNames::get_singleton()->body_enter,node);
|
emit_signal(SceneStringNames::get_singleton()->body_enter,node);
|
||||||
|
|
||||||
for(int i=0;i<E->get().shapes.size();i++) {
|
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);
|
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) {
|
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);
|
||||||
ERR_FAIL_COND(!E->get().in_tree);
|
ERR_FAIL_COND(!E->get().in_tree);
|
||||||
E->get().in_tree=false;
|
E->get().in_tree=false;
|
||||||
|
|
||||||
|
contact_monitor->locked=true;
|
||||||
|
|
||||||
emit_signal(SceneStringNames::get_singleton()->body_exit,node);
|
emit_signal(SceneStringNames::get_singleton()->body_exit,node);
|
||||||
|
|
||||||
for(int i=0;i<E->get().shapes.size();i++) {
|
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);
|
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) {
|
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) {
|
if (contact_monitor) {
|
||||||
|
|
||||||
|
contact_monitor->locked=true;
|
||||||
|
|
||||||
//untag all
|
//untag all
|
||||||
int rc=0;
|
int rc=0;
|
||||||
for( Map<ObjectID,BodyState>::Element *E=contact_monitor->body_map.front();E;E=E->next()) {
|
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);
|
_body_inout(1,toadd[i].id,toadd[i].shape,toadd[i].local_shape);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
contact_monitor->locked=false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
set_ignore_transform_notification(true);
|
set_ignore_transform_notification(true);
|
||||||
@ -648,6 +665,11 @@ void RigidBody::set_contact_monitor(bool p_enabled) {
|
|||||||
|
|
||||||
if (!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()) {
|
for(Map<ObjectID,BodyState>::Element *E=contact_monitor->body_map.front();E;E=E->next()) {
|
||||||
|
|
||||||
//clean up mess
|
//clean up mess
|
||||||
@ -658,6 +680,8 @@ void RigidBody::set_contact_monitor(bool p_enabled) {
|
|||||||
} else {
|
} else {
|
||||||
|
|
||||||
contact_monitor = memnew( ContactMonitor );
|
contact_monitor = memnew( ContactMonitor );
|
||||||
|
contact_monitor->locked=false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -175,7 +175,7 @@ private:
|
|||||||
|
|
||||||
struct ContactMonitor {
|
struct ContactMonitor {
|
||||||
|
|
||||||
|
bool locked;
|
||||||
Map<ObjectID,BodyState> body_map;
|
Map<ObjectID,BodyState> body_map;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user