blueloveTH 2 лет назад
Родитель
Сommit
18390fc8cf
2 измененных файлов с 25 добавлено и 8 удалено
  1. 10 0
      3rd/box2d/include/box2d_bindings.hpp
  2. 15 8
      3rd/box2d/src/box2d_World.cpp

+ 10 - 0
3rd/box2d/include/box2d_bindings.hpp

@@ -3,6 +3,8 @@
 #include "box2d/box2d.h"
 #include "pocketpy/pocketpy.h"
 
+#include <queue>
+
 namespace pkpy{
 
 template<>
@@ -44,9 +46,17 @@ struct PyDebugDraw: b2Draw{
     void DrawPoint(const b2Vec2& p, float size, const b2Color& color) override;
 };
 
+struct PyContactMessage{
+    PyObject* a;
+    PyObject* b;
+    StrName name;
+};
+
 struct PyContactListener: b2ContactListener{
     PK_ALWAYS_PASS_BY_POINTER(PyContactListener)
     VM* vm;
+    std::queue<PyContactMessage> messages;
+
     PyContactListener(VM* vm): vm(vm){}
 
     void _contact_f(b2Contact* contact, StrName name);

+ 15 - 8
3rd/box2d/src/box2d_World.cpp

@@ -32,14 +32,7 @@ struct MyBoxCastCallback: b2QueryCallback{
 void PyContactListener::_contact_f(b2Contact* contact, StrName name){
     PyObject* a = get_body_object(contact->GetFixtureA()->GetBody());
     PyObject* b = get_body_object(contact->GetFixtureB()->GetBody());
-    PyBody& bodyA = PK_OBJ_GET(PyBody, a);
-    PyBody& bodyB = PK_OBJ_GET(PyBody, b);
-    PyObject* self;
-    PyObject* f;
-    f = vm->get_unbound_method(bodyA.node_like, name, &self, false);
-    if(f != nullptr) vm->call_method(self, f, b);
-    f = vm->get_unbound_method(bodyB.node_like, name, &self, false);
-    if(f != nullptr) vm->call_method(self, f, a);
+    messages.push({a, b, name});
 }
 
 /****************** PyWorld ******************/
@@ -121,6 +114,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);
+
+            // clear contact messages
+            while(!self._contact_listener.messages.empty()){
+                PyContactMessage& msg = self._contact_listener.messages.front();
+                PyBody& bodyA = PK_OBJ_GET(PyBody, msg.a);
+                PyBody& bodyB = PK_OBJ_GET(PyBody, msg.b);
+                PyObject* f_self;
+                PyObject* f;
+                f = vm->get_unbound_method(bodyA.node_like, msg.name, &f_self, false);
+                if(f != nullptr) vm->call_method(f_self, f, msg.b);
+                f = vm->get_unbound_method(bodyB.node_like, msg.name, &f_self, false);
+                if(f != nullptr) vm->call_method(f_self, f, msg.a);
+                self._contact_listener.messages.pop();
+            }
             return vm->None;
         });