mirror of
https://github.com/love2d/love.git
synced 2026-08-21 21:15:09 +02:00
Import box2d-contacts branch from love-experiments
Fix issues with Contact lifetime, based on the work of Matteo "teomat" Goggi
This commit is contained in:
@@ -38,8 +38,22 @@ Contact::Contact(b2Contact *contact)
|
||||
}
|
||||
|
||||
Contact::~Contact()
|
||||
{
|
||||
invalidate();
|
||||
}
|
||||
|
||||
void Contact::invalidate()
|
||||
{
|
||||
if (contact != NULL)
|
||||
{
|
||||
Memoizer::remove(contact);
|
||||
contact = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool Contact::isValid()
|
||||
{
|
||||
return contact != NULL ? true : false;
|
||||
}
|
||||
|
||||
int Contact::getPositions(lua_State *L)
|
||||
|
||||
@@ -59,6 +59,18 @@ public:
|
||||
|
||||
virtual ~Contact();
|
||||
|
||||
/**
|
||||
* Removes the b2Contact pointer from Memoizer and sets it
|
||||
* to null on the Contact.
|
||||
**/
|
||||
void invalidate();
|
||||
|
||||
/**
|
||||
* Returns if the Contact still points to a valid b2Contact.
|
||||
* @return True if the contact is still valid or false if it has been destroyed.
|
||||
**/
|
||||
bool isValid();
|
||||
|
||||
/**
|
||||
* Gets the position of each point of contact.
|
||||
* @return The position along the x-axis.
|
||||
|
||||
@@ -77,9 +77,13 @@ void World::ContactCallback::process(b2Contact *contact, const b2ContactImpulse
|
||||
throw love::Exception("A fixture has escaped Memoizer!");
|
||||
}
|
||||
|
||||
Contact *c = new Contact(contact);
|
||||
Contact *cobj = (Contact *)Memoizer::find(contact);
|
||||
if (!cobj)
|
||||
cobj = new Contact(contact);
|
||||
else
|
||||
cobj->retain();
|
||||
|
||||
luax_newtype(L, "Contact", (PHYSICS_CONTACT_T), (void *)c);
|
||||
luax_newtype(L, "Contact", (PHYSICS_CONTACT_T), (void *)cobj);
|
||||
|
||||
int args = 3;
|
||||
if (impulse)
|
||||
@@ -290,6 +294,11 @@ void World::BeginContact(b2Contact *contact)
|
||||
void World::EndContact(b2Contact *contact)
|
||||
{
|
||||
end.process(contact);
|
||||
|
||||
// Letting the Contact know that the b2Contact will be destroyed any second.
|
||||
Contact *c = (Contact *)Memoizer::find(contact);
|
||||
if (c != NULL)
|
||||
c->invalidate();
|
||||
}
|
||||
|
||||
void World::PreSolve(b2Contact *contact, const b2Manifold *oldManifold)
|
||||
@@ -468,7 +477,9 @@ int World::getContactList(lua_State *L) const
|
||||
{
|
||||
if (!c) break;
|
||||
Contact *contact = (Contact *)Memoizer::find(c);
|
||||
if (!contact) throw love::Exception("A contact has escaped Memoizer!");
|
||||
if (!contact)
|
||||
contact = new Contact(c);
|
||||
else
|
||||
contact->retain();
|
||||
luax_newtype(L, "Contact", PHYSICS_CONTACT_T, (void *)contact);
|
||||
lua_rawseti(L, -2, i);
|
||||
|
||||
@@ -29,7 +29,10 @@ namespace box2d
|
||||
|
||||
Contact *luax_checkcontact(lua_State *L, int idx)
|
||||
{
|
||||
return luax_checktype<Contact>(L, idx, "Contact", PHYSICS_CONTACT_T);
|
||||
Contact *c = luax_checktype<Contact>(L, idx, "Contact", PHYSICS_CONTACT_T);
|
||||
if (!c->isValid())
|
||||
luaL_error(L, "Attempt to use destroyed contact.");
|
||||
return c;
|
||||
}
|
||||
|
||||
int w_Contact_getPositions(lua_State *L)
|
||||
|
||||
Reference in New Issue
Block a user