This commit is contained in:
blueloveTH 2023-08-12 23:21:25 +08:00
parent 31e24ca9bd
commit 18390fc8cf
2 changed files with 25 additions and 8 deletions

View File

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

View File

@ -32,14 +32,7 @@ struct MyBoxCastCallback: b2QueryCallback{
void PyContactListener::_contact_f(b2Contact* contact, StrName name){ void PyContactListener::_contact_f(b2Contact* contact, StrName name){
PyObject* a = get_body_object(contact->GetFixtureA()->GetBody()); PyObject* a = get_body_object(contact->GetFixtureA()->GetBody());
PyObject* b = get_body_object(contact->GetFixtureB()->GetBody()); PyObject* b = get_body_object(contact->GetFixtureB()->GetBody());
PyBody& bodyA = PK_OBJ_GET(PyBody, a); messages.push({a, b, name});
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);
} }
/****************** PyWorld ******************/ /****************** PyWorld ******************/
@ -121,6 +114,20 @@ void PyWorld::_register(VM* vm, PyObject* mod, PyObject* type){
f(vm, self.world.GetBodyList(), on_box2d_pre_step); f(vm, self.world.GetBodyList(), on_box2d_pre_step);
self.world.Step(dt, velocity_iterations, position_iterations); self.world.Step(dt, velocity_iterations, position_iterations);
f(vm, self.world.GetBodyList(), on_box2d_post_step); 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; return vm->None;
}); });