blueloveTH 2 years ago
parent
commit
926eafb1c8

+ 2 - 1
3rd/box2d/include/box2d_bindings.hpp

@@ -70,7 +70,8 @@ struct PyBody{
     b2Fixture* fixture;
     PyObject* node_like;
 
-    PyBody(): body(nullptr), fixture(nullptr), node_like(nullptr){}
+    bool _is_destroyed;
+    PyBody(): body(nullptr), fixture(nullptr), node_like(nullptr), _is_destroyed(false){}
 
     void _gc_mark() {
         if(node_like != nullptr){

+ 2 - 4
3rd/box2d/src/box2d_Body.cpp

@@ -16,6 +16,7 @@ void PyBody::_register(VM* vm, PyObject* mod, PyObject* type){
             body.body = world.world.CreateBody(&def);
             body.fixture = nullptr;
             body.node_like = node;
+            body._is_destroyed = false;
             return obj;
         });
 
@@ -129,10 +130,7 @@ void PyBody::_register(VM* vm, PyObject* mod, PyObject* type){
     // destroy
     vm->bind(type, "destroy(self)", [](VM* vm, ArgsView args){
         PyBody& body = CAST(PyBody&, args[0]);
-        body.body->GetWorld()->DestroyBody(body.body);
-        body.body = nullptr;
-        body.fixture = nullptr;
-        body.node_like = nullptr;
+        body._is_destroyed = true;  // mark as destroyed
         return vm->None;
     });
 }

+ 14 - 0
3rd/box2d/src/box2d_World.cpp

@@ -124,6 +124,20 @@ void PyWorld::_register(VM* vm, PyObject* mod, PyObject* type){
             f(vm, self.world.GetBodyList(), on_box2d_pre_step);
             self.world.Step(dt, velocity_iterations, position_iterations);
             f(vm, self.world.GetBodyList(), on_box2d_post_step);
+
+            // destroy bodies which are marked as destroyed
+            b2Body* p = self.world.GetBodyList();
+            while(p != nullptr){
+                b2Body* next = p->GetNext();
+                PyBody& body = _CAST(PyBody&, get_body_object(p));
+                if(body._is_destroyed){
+                    body.body->GetWorld()->DestroyBody(body.body);
+                    body.body = nullptr;
+                    body.fixture = nullptr;
+                    body.node_like = nullptr;
+                }
+                p = next;
+            }
             return vm->None;
         });