浏览代码

Improve cleanup of physics constraints

Don't abort the loop when one is already released
Remove warning on already-released constraint
Clean up area's contraints as well
Clear the constraint data as well
Do the cleanup as soon as the space changes
Pedro J. Estébanez 8 年之前
父节点
当前提交
7264716e86

+ 1 - 0
servers/physics/area_sw.h

@@ -154,6 +154,7 @@ public:
 	_FORCE_INLINE_ void add_constraint(ConstraintSW *p_constraint) { constraints.insert(p_constraint); }
 	_FORCE_INLINE_ void add_constraint(ConstraintSW *p_constraint) { constraints.insert(p_constraint); }
 	_FORCE_INLINE_ void remove_constraint(ConstraintSW *p_constraint) { constraints.erase(p_constraint); }
 	_FORCE_INLINE_ void remove_constraint(ConstraintSW *p_constraint) { constraints.erase(p_constraint); }
 	_FORCE_INLINE_ const Set<ConstraintSW *> &get_constraints() const { return constraints; }
 	_FORCE_INLINE_ const Set<ConstraintSW *> &get_constraints() const { return constraints; }
+	_FORCE_INLINE_ void clear_constraints() { constraints.clear(); }
 
 
 	void set_monitorable(bool p_monitorable);
 	void set_monitorable(bool p_monitorable);
 	_FORCE_INLINE_ bool is_monitorable() const { return monitorable; }
 	_FORCE_INLINE_ bool is_monitorable() const { return monitorable; }

+ 1 - 0
servers/physics/body_sw.h

@@ -194,6 +194,7 @@ public:
 	_FORCE_INLINE_ void add_constraint(ConstraintSW *p_constraint, int p_pos) { constraint_map[p_constraint] = p_pos; }
 	_FORCE_INLINE_ void add_constraint(ConstraintSW *p_constraint, int p_pos) { constraint_map[p_constraint] = p_pos; }
 	_FORCE_INLINE_ void remove_constraint(ConstraintSW *p_constraint) { constraint_map.erase(p_constraint); }
 	_FORCE_INLINE_ void remove_constraint(ConstraintSW *p_constraint) { constraint_map.erase(p_constraint); }
 	const Map<ConstraintSW *, int> &get_constraint_map() const { return constraint_map; }
 	const Map<ConstraintSW *, int> &get_constraint_map() const { return constraint_map; }
+	_FORCE_INLINE_ void clear_constraint_map() { constraint_map.clear(); }
 
 
 	_FORCE_INLINE_ void set_omit_force_integration(bool p_omit_force_integration) { omit_force_integration = p_omit_force_integration; }
 	_FORCE_INLINE_ void set_omit_force_integration(bool p_omit_force_integration) { omit_force_integration = p_omit_force_integration; }
 	_FORCE_INLINE_ bool get_omit_force_integration() const { return omit_force_integration; }
 	_FORCE_INLINE_ bool get_omit_force_integration() const { return omit_force_integration; }

+ 16 - 6
servers/physics/physics_server_sw.cpp

@@ -232,6 +232,14 @@ void PhysicsServerSW::area_set_space(RID p_area, RID p_space) {
 	if (area->get_space() == space)
 	if (area->get_space() == space)
 		return; //pointless
 		return; //pointless
 
 
+	for (Set<ConstraintSW *>::Element *E = area->get_constraints().front(); E; E = E->next()) {
+		RID self = E->get()->get_self();
+		if (!self.is_valid())
+			continue;
+		free(self);
+	}
+	area->clear_constraints();
+
 	area->set_space(space);
 	area->set_space(space);
 };
 };
 
 
@@ -485,6 +493,14 @@ void PhysicsServerSW::body_set_space(RID p_body, RID p_space) {
 	if (body->get_space() == space)
 	if (body->get_space() == space)
 		return; //pointless
 		return; //pointless
 
 
+	while (body->get_constraint_map().size()) {
+		RID self = body->get_constraint_map().front()->key()->get_self();
+		if (!self.is_valid())
+			continue;
+		free(self);
+	}
+	body->clear_constraint_map();
+
 	body->set_space(space);
 	body->set_space(space);
 };
 };
 
 
@@ -1333,12 +1349,6 @@ void PhysicsServerSW::free(RID p_rid) {
 			body->remove_shape(0);
 			body->remove_shape(0);
 		}
 		}
 
 
-		while (body->get_constraint_map().size()) {
-			RID self = body->get_constraint_map().front()->key()->get_self();
-			ERR_FAIL_COND(!self.is_valid());
-			free(self);
-		}
-
 		body_owner.free(p_rid);
 		body_owner.free(p_rid);
 		memdelete(body);
 		memdelete(body);
 
 

+ 1 - 0
servers/physics_2d/area_2d_sw.h

@@ -153,6 +153,7 @@ public:
 	_FORCE_INLINE_ void add_constraint(Constraint2DSW *p_constraint) { constraints.insert(p_constraint); }
 	_FORCE_INLINE_ void add_constraint(Constraint2DSW *p_constraint) { constraints.insert(p_constraint); }
 	_FORCE_INLINE_ void remove_constraint(Constraint2DSW *p_constraint) { constraints.erase(p_constraint); }
 	_FORCE_INLINE_ void remove_constraint(Constraint2DSW *p_constraint) { constraints.erase(p_constraint); }
 	_FORCE_INLINE_ const Set<Constraint2DSW *> &get_constraints() const { return constraints; }
 	_FORCE_INLINE_ const Set<Constraint2DSW *> &get_constraints() const { return constraints; }
+	_FORCE_INLINE_ void clear_constraints() { constraints.clear(); }
 
 
 	void set_monitorable(bool p_monitorable);
 	void set_monitorable(bool p_monitorable);
 	_FORCE_INLINE_ bool is_monitorable() const { return monitorable; }
 	_FORCE_INLINE_ bool is_monitorable() const { return monitorable; }

+ 1 - 0
servers/physics_2d/body_2d_sw.h

@@ -181,6 +181,7 @@ public:
 	_FORCE_INLINE_ void add_constraint(Constraint2DSW *p_constraint, int p_pos) { constraint_map[p_constraint] = p_pos; }
 	_FORCE_INLINE_ void add_constraint(Constraint2DSW *p_constraint, int p_pos) { constraint_map[p_constraint] = p_pos; }
 	_FORCE_INLINE_ void remove_constraint(Constraint2DSW *p_constraint) { constraint_map.erase(p_constraint); }
 	_FORCE_INLINE_ void remove_constraint(Constraint2DSW *p_constraint) { constraint_map.erase(p_constraint); }
 	const Map<Constraint2DSW *, int> &get_constraint_map() const { return constraint_map; }
 	const Map<Constraint2DSW *, int> &get_constraint_map() const { return constraint_map; }
+	_FORCE_INLINE_ void clear_constraint_map() { constraint_map.clear(); }
 
 
 	_FORCE_INLINE_ void set_omit_force_integration(bool p_omit_force_integration) { omit_force_integration = p_omit_force_integration; }
 	_FORCE_INLINE_ void set_omit_force_integration(bool p_omit_force_integration) { omit_force_integration = p_omit_force_integration; }
 	_FORCE_INLINE_ bool get_omit_force_integration() const { return omit_force_integration; }
 	_FORCE_INLINE_ bool get_omit_force_integration() const { return omit_force_integration; }

+ 17 - 7
servers/physics_2d/physics_2d_server_sw.cpp

@@ -296,6 +296,14 @@ void Physics2DServerSW::area_set_space(RID p_area, RID p_space) {
 	if (area->get_space() == space)
 	if (area->get_space() == space)
 		return; //pointless
 		return; //pointless
 
 
+	for (Set<Constraint2DSW *>::Element *E = area->get_constraints().front(); E; E = E->next()) {
+		RID self = E->get()->get_self();
+		if (!self.is_valid())
+			continue;
+		free(self);
+	}
+	area->clear_constraints();
+
 	area->set_space(space);
 	area->set_space(space);
 };
 };
 
 
@@ -540,6 +548,14 @@ void Physics2DServerSW::body_set_space(RID p_body, RID p_space) {
 	if (body->get_space() == space)
 	if (body->get_space() == space)
 		return; //pointless
 		return; //pointless
 
 
+	while (body->get_constraint_map().size()) {
+		RID self = body->get_constraint_map().front()->key()->get_self();
+		if (!self.is_valid())
+			continue;
+		free(self);
+	}
+	body->clear_constraint_map();
+
 	body->set_space(space);
 	body->set_space(space);
 };
 };
 
 
@@ -1080,19 +1096,13 @@ void Physics2DServerSW::free(RID p_rid) {
 			_clear_query(body->get_direct_state_query());
 			_clear_query(body->get_direct_state_query());
 		*/
 		*/
 
 
-		body->set_space(NULL);
+		body_set_space(p_rid, RID());
 
 
 		while (body->get_shape_count()) {
 		while (body->get_shape_count()) {
 
 
 			body->remove_shape(0);
 			body->remove_shape(0);
 		}
 		}
 
 
-		while (body->get_constraint_map().size()) {
-			RID self = body->get_constraint_map().front()->key()->get_self();
-			ERR_FAIL_COND(!self.is_valid());
-			free(self);
-		}
-
 		body_owner.free(p_rid);
 		body_owner.free(p_rid);
 		memdelete(body);
 		memdelete(body);