diff --git a/3rd/box2d/include/box2d_bindings.hpp b/3rd/box2d/include/box2d_bindings.hpp index 4f455f8b..37f7e3cf 100644 --- a/3rd/box2d/include/box2d_bindings.hpp +++ b/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){ diff --git a/3rd/box2d/src/box2d_Body.cpp b/3rd/box2d/src/box2d_Body.cpp index 2797913c..89dba3e2 100644 --- a/3rd/box2d/src/box2d_Body.cpp +++ b/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; }); } diff --git a/3rd/box2d/src/box2d_World.cpp b/3rd/box2d/src/box2d_World.cpp index 5d477ec1..068dd248 100644 --- a/3rd/box2d/src/box2d_World.cpp +++ b/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; });