Browse Source

Merge pull request #81809 from Rindbee/clean-up-maps-in-Area

Clear monitoring in `Area*` when its space changes to invalid
Yuri Sizov 1 năm trước cách đây
mục cha
commit
f119da59d1

+ 3 - 5
scene/2d/area_2d.cpp

@@ -384,11 +384,9 @@ void Area2D::_clear_monitoring() {
 	}
 }
 
-void Area2D::_notification(int p_what) {
-	switch (p_what) {
-		case NOTIFICATION_EXIT_TREE: {
-			_clear_monitoring();
-		} break;
+void Area2D::_space_changed(const RID &p_new_space) {
+	if (p_new_space.is_null()) {
+		_clear_monitoring();
 	}
 }
 

+ 2 - 1
scene/2d/area_2d.h

@@ -133,10 +133,11 @@ private:
 	StringName audio_bus;
 
 protected:
-	void _notification(int p_what);
 	static void _bind_methods();
 	void _validate_property(PropertyInfo &p_property) const;
 
+	virtual void _space_changed(const RID &p_new_space) override;
+
 public:
 	void set_gravity_space_override_mode(SpaceOverride p_mode);
 	SpaceOverride get_gravity_space_override_mode() const;

+ 8 - 0
scene/2d/collision_object_2d.cpp

@@ -59,6 +59,7 @@ void CollisionObject2D::_notification(int p_what) {
 				} else {
 					PhysicsServer2D::get_singleton()->body_set_space(rid, space);
 				}
+				_space_changed(space);
 			}
 
 			_update_pickable();
@@ -102,6 +103,7 @@ void CollisionObject2D::_notification(int p_what) {
 					} else {
 						PhysicsServer2D::get_singleton()->body_set_space(rid, RID());
 					}
+					_space_changed(RID());
 				}
 			}
 
@@ -125,6 +127,7 @@ void CollisionObject2D::_notification(int p_what) {
 			} else {
 				PhysicsServer2D::get_singleton()->body_set_space(rid, space);
 			}
+			_space_changed(space);
 		} break;
 
 		case NOTIFICATION_DISABLED: {
@@ -246,6 +249,7 @@ void CollisionObject2D::_apply_disabled() {
 					} else {
 						PhysicsServer2D::get_singleton()->body_set_space(rid, RID());
 					}
+					_space_changed(RID());
 				}
 			}
 		} break;
@@ -272,6 +276,7 @@ void CollisionObject2D::_apply_enabled() {
 				} else {
 					PhysicsServer2D::get_singleton()->body_set_space(rid, space);
 				}
+				_space_changed(space);
 			}
 		} break;
 
@@ -569,6 +574,9 @@ void CollisionObject2D::set_body_mode(PhysicsServer2D::BodyMode p_mode) {
 	PhysicsServer2D::get_singleton()->body_set_mode(rid, p_mode);
 }
 
+void CollisionObject2D::_space_changed(const RID &p_new_space) {
+}
+
 void CollisionObject2D::_update_pickable() {
 	if (!is_inside_tree()) {
 		return;

+ 2 - 0
scene/2d/collision_object_2d.h

@@ -109,6 +109,8 @@ protected:
 
 	void set_body_mode(PhysicsServer2D::BodyMode p_mode);
 
+	virtual void _space_changed(const RID &p_new_space);
+
 	GDVIRTUAL3(_input_event, Viewport *, Ref<InputEvent>, int)
 	GDVIRTUAL0(_mouse_enter)
 	GDVIRTUAL0(_mouse_exit)

+ 6 - 4
scene/3d/area_3d.cpp

@@ -347,12 +347,14 @@ void Area3D::_clear_monitoring() {
 	}
 }
 
+void Area3D::_space_changed(const RID &p_new_space) {
+	if (p_new_space.is_null()) {
+		_clear_monitoring();
+	}
+}
+
 void Area3D::_notification(int p_what) {
 	switch (p_what) {
-		case NOTIFICATION_EXIT_TREE: {
-			_clear_monitoring();
-		} break;
-
 		case NOTIFICATION_ENTER_TREE: {
 			_initialize_wind();
 		} break;

+ 2 - 0
scene/3d/area_3d.h

@@ -149,6 +149,8 @@ protected:
 	static void _bind_methods();
 	void _validate_property(PropertyInfo &p_property) const;
 
+	virtual void _space_changed(const RID &p_new_space) override;
+
 public:
 	void set_gravity_space_override_mode(SpaceOverride p_mode);
 	SpaceOverride get_gravity_space_override_mode() const;

+ 7 - 0
scene/3d/collision_object_3d.cpp

@@ -78,6 +78,7 @@ void CollisionObject3D::_notification(int p_what) {
 				} else {
 					PhysicsServer3D::get_singleton()->body_set_space(rid, space);
 				}
+				_space_changed(space);
 			}
 
 			_update_pickable();
@@ -117,6 +118,7 @@ void CollisionObject3D::_notification(int p_what) {
 					} else {
 						PhysicsServer3D::get_singleton()->body_set_space(rid, RID());
 					}
+					_space_changed(RID());
 				}
 			}
 
@@ -244,6 +246,7 @@ void CollisionObject3D::_apply_disabled() {
 					} else {
 						PhysicsServer3D::get_singleton()->body_set_space(rid, RID());
 					}
+					_space_changed(RID());
 				}
 			}
 		} break;
@@ -270,6 +273,7 @@ void CollisionObject3D::_apply_enabled() {
 				} else {
 					PhysicsServer3D::get_singleton()->body_set_space(rid, space);
 				}
+				_space_changed(space);
 			}
 		} break;
 
@@ -320,6 +324,9 @@ void CollisionObject3D::set_body_mode(PhysicsServer3D::BodyMode p_mode) {
 	PhysicsServer3D::get_singleton()->body_set_mode(rid, p_mode);
 }
 
+void CollisionObject3D::_space_changed(const RID &p_new_space) {
+}
+
 void CollisionObject3D::set_only_update_transform_changes(bool p_enable) {
 	only_update_transform_changes = p_enable;
 }

+ 2 - 0
scene/3d/collision_object_3d.h

@@ -116,6 +116,8 @@ protected:
 
 	void set_body_mode(PhysicsServer3D::BodyMode p_mode);
 
+	virtual void _space_changed(const RID &p_new_space);
+
 	void set_only_update_transform_changes(bool p_enable);
 	bool is_only_update_transform_changes_enabled() const;
 

+ 2 - 2
servers/physics_2d/godot_area_2d.h

@@ -167,7 +167,7 @@ void GodotArea2D::add_body_to_query(GodotBody2D *p_body, uint32_t p_body_shape,
 void GodotArea2D::remove_body_from_query(GodotBody2D *p_body, uint32_t p_body_shape, uint32_t p_area_shape) {
 	BodyKey bk(p_body, p_body_shape, p_area_shape);
 	monitored_bodies[bk].dec();
-	if (!monitor_query_list.in_list()) {
+	if (get_space() && !monitor_query_list.in_list()) {
 		_queue_monitor_update();
 	}
 }
@@ -183,7 +183,7 @@ void GodotArea2D::add_area_to_query(GodotArea2D *p_area, uint32_t p_area_shape,
 void GodotArea2D::remove_area_from_query(GodotArea2D *p_area, uint32_t p_area_shape, uint32_t p_self_shape) {
 	BodyKey bk(p_area, p_area_shape, p_self_shape);
 	monitored_areas[bk].dec();
-	if (!monitor_query_list.in_list()) {
+	if (get_space() && !monitor_query_list.in_list()) {
 		_queue_monitor_update();
 	}
 }

+ 2 - 1
servers/physics_2d/godot_body_2d.cpp

@@ -407,7 +407,8 @@ void GodotBody2D::set_space(GodotSpace2D *p_space) {
 
 	if (get_space()) {
 		_mass_properties_changed();
-		if (active) {
+
+		if (active && !active_list.in_list()) {
 			get_space()->body_add_to_active_list(&active_list);
 		}
 	}

+ 6 - 5
servers/physics_2d/godot_collision_object_2d.cpp

@@ -212,20 +212,21 @@ void GodotCollisionObject2D::_update_shapes_with_motion(const Vector2 &p_motion)
 }
 
 void GodotCollisionObject2D::_set_space(GodotSpace2D *p_space) {
-	if (space) {
-		space->remove_object(this);
+	GodotSpace2D *old_space = space;
+	space = p_space;
+
+	if (old_space) {
+		old_space->remove_object(this);
 
 		for (int i = 0; i < shapes.size(); i++) {
 			Shape &s = shapes.write[i];
 			if (s.bpid) {
-				space->get_broadphase()->remove(s.bpid);
+				old_space->get_broadphase()->remove(s.bpid);
 				s.bpid = 0;
 			}
 		}
 	}
 
-	space = p_space;
-
 	if (space) {
 		space->add_object(this);
 		_update_shapes();

+ 2 - 2
servers/physics_3d/godot_area_3d.h

@@ -204,7 +204,7 @@ void GodotArea3D::add_body_to_query(GodotBody3D *p_body, uint32_t p_body_shape,
 void GodotArea3D::remove_body_from_query(GodotBody3D *p_body, uint32_t p_body_shape, uint32_t p_area_shape) {
 	BodyKey bk(p_body, p_body_shape, p_area_shape);
 	monitored_bodies[bk].dec();
-	if (!monitor_query_list.in_list()) {
+	if (get_space() && !monitor_query_list.in_list()) {
 		_queue_monitor_update();
 	}
 }
@@ -220,7 +220,7 @@ void GodotArea3D::add_area_to_query(GodotArea3D *p_area, uint32_t p_area_shape,
 void GodotArea3D::remove_area_from_query(GodotArea3D *p_area, uint32_t p_area_shape, uint32_t p_self_shape) {
 	BodyKey bk(p_area, p_area_shape, p_self_shape);
 	monitored_areas[bk].dec();
-	if (!monitor_query_list.in_list()) {
+	if (get_space() && !monitor_query_list.in_list()) {
 		_queue_monitor_update();
 	}
 }

+ 2 - 1
servers/physics_3d/godot_body_3d.cpp

@@ -454,7 +454,8 @@ void GodotBody3D::set_space(GodotSpace3D *p_space) {
 
 	if (get_space()) {
 		_mass_properties_changed();
-		if (active) {
+
+		if (active && !active_list.in_list()) {
 			get_space()->body_add_to_active_list(&active_list);
 		}
 	}

+ 6 - 5
servers/physics_3d/godot_collision_object_3d.cpp

@@ -210,20 +210,21 @@ void GodotCollisionObject3D::_update_shapes_with_motion(const Vector3 &p_motion)
 }
 
 void GodotCollisionObject3D::_set_space(GodotSpace3D *p_space) {
-	if (space) {
-		space->remove_object(this);
+	GodotSpace3D *old_space = space;
+	space = p_space;
+
+	if (old_space) {
+		old_space->remove_object(this);
 
 		for (int i = 0; i < shapes.size(); i++) {
 			Shape &s = shapes.write[i];
 			if (s.bpid) {
-				space->get_broadphase()->remove(s.bpid);
+				old_space->get_broadphase()->remove(s.bpid);
 				s.bpid = 0;
 			}
 		}
 	}
 
-	space = p_space;
-
 	if (space) {
 		space->add_object(this);
 		_update_shapes();