Browse Source

love.physics: move internal box2d->love object map to World instances, and clean up some physics object code. Resolves issue #1465.

Alex Szpakowski 6 years ago
parent
commit
3ad16a70da

+ 0 - 2
CMakeLists.txt

@@ -285,8 +285,6 @@ set(LOVE_SRC_COMMON
 	src/common/math.h
 	src/common/math.h
 	src/common/Matrix.cpp
 	src/common/Matrix.cpp
 	src/common/Matrix.h
 	src/common/Matrix.h
-	src/common/Memoizer.cpp
-	src/common/Memoizer.h
 	src/common/memory.cpp
 	src/common/memory.cpp
 	src/common/memory.h
 	src/common/memory.h
 	src/common/Module.cpp
 	src/common/Module.cpp

+ 0 - 10
platform/xcode/liblove.xcodeproj/project.pbxproj

@@ -81,9 +81,6 @@
 		FA0B79291A958E3B000E1D17 /* Matrix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79021A958E3B000E1D17 /* Matrix.cpp */; };
 		FA0B79291A958E3B000E1D17 /* Matrix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79021A958E3B000E1D17 /* Matrix.cpp */; };
 		FA0B792A1A958E3B000E1D17 /* Matrix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79021A958E3B000E1D17 /* Matrix.cpp */; };
 		FA0B792A1A958E3B000E1D17 /* Matrix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79021A958E3B000E1D17 /* Matrix.cpp */; };
 		FA0B792B1A958E3B000E1D17 /* Matrix.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B79031A958E3B000E1D17 /* Matrix.h */; };
 		FA0B792B1A958E3B000E1D17 /* Matrix.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B79031A958E3B000E1D17 /* Matrix.h */; };
-		FA0B792C1A958E3B000E1D17 /* Memoizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79041A958E3B000E1D17 /* Memoizer.cpp */; };
-		FA0B792D1A958E3B000E1D17 /* Memoizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79041A958E3B000E1D17 /* Memoizer.cpp */; };
-		FA0B792E1A958E3B000E1D17 /* Memoizer.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B79051A958E3B000E1D17 /* Memoizer.h */; };
 		FA0B792F1A958E3B000E1D17 /* Module.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79061A958E3B000E1D17 /* Module.cpp */; };
 		FA0B792F1A958E3B000E1D17 /* Module.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79061A958E3B000E1D17 /* Module.cpp */; };
 		FA0B79301A958E3B000E1D17 /* Module.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79061A958E3B000E1D17 /* Module.cpp */; };
 		FA0B79301A958E3B000E1D17 /* Module.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B79061A958E3B000E1D17 /* Module.cpp */; };
 		FA0B79311A958E3B000E1D17 /* Module.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B79071A958E3B000E1D17 /* Module.h */; };
 		FA0B79311A958E3B000E1D17 /* Module.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B79071A958E3B000E1D17 /* Module.h */; };
@@ -1297,8 +1294,6 @@
 		FA0B79011A958E3B000E1D17 /* math.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = math.h; sourceTree = "<group>"; };
 		FA0B79011A958E3B000E1D17 /* math.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = math.h; sourceTree = "<group>"; };
 		FA0B79021A958E3B000E1D17 /* Matrix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Matrix.cpp; sourceTree = "<group>"; };
 		FA0B79021A958E3B000E1D17 /* Matrix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Matrix.cpp; sourceTree = "<group>"; };
 		FA0B79031A958E3B000E1D17 /* Matrix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Matrix.h; sourceTree = "<group>"; };
 		FA0B79031A958E3B000E1D17 /* Matrix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Matrix.h; sourceTree = "<group>"; };
-		FA0B79041A958E3B000E1D17 /* Memoizer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Memoizer.cpp; sourceTree = "<group>"; };
-		FA0B79051A958E3B000E1D17 /* Memoizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Memoizer.h; sourceTree = "<group>"; };
 		FA0B79061A958E3B000E1D17 /* Module.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Module.cpp; sourceTree = "<group>"; };
 		FA0B79061A958E3B000E1D17 /* Module.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Module.cpp; sourceTree = "<group>"; };
 		FA0B79071A958E3B000E1D17 /* Module.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Module.h; sourceTree = "<group>"; };
 		FA0B79071A958E3B000E1D17 /* Module.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Module.h; sourceTree = "<group>"; };
 		FA0B79081A958E3B000E1D17 /* Object.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Object.cpp; sourceTree = "<group>"; };
 		FA0B79081A958E3B000E1D17 /* Object.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Object.cpp; sourceTree = "<group>"; };
@@ -2176,8 +2171,6 @@
 				FA0B79011A958E3B000E1D17 /* math.h */,
 				FA0B79011A958E3B000E1D17 /* math.h */,
 				FA0B79021A958E3B000E1D17 /* Matrix.cpp */,
 				FA0B79021A958E3B000E1D17 /* Matrix.cpp */,
 				FA0B79031A958E3B000E1D17 /* Matrix.h */,
 				FA0B79031A958E3B000E1D17 /* Matrix.h */,
-				FA0B79041A958E3B000E1D17 /* Memoizer.cpp */,
-				FA0B79051A958E3B000E1D17 /* Memoizer.h */,
 				FA56AA361FAFF02000A43D5F /* memory.cpp */,
 				FA56AA361FAFF02000A43D5F /* memory.cpp */,
 				FA56AA371FAFF02000A43D5F /* memory.h */,
 				FA56AA371FAFF02000A43D5F /* memory.h */,
 				FA0B79061A958E3B000E1D17 /* Module.cpp */,
 				FA0B79061A958E3B000E1D17 /* Module.cpp */,
@@ -4000,7 +3993,6 @@
 				FA0B7E321A95902C000E1D17 /* Shape.h in Headers */,
 				FA0B7E321A95902C000E1D17 /* Shape.h in Headers */,
 				FA620A371AA2F8DB005DB4C2 /* wrap_Texture.h in Headers */,
 				FA620A371AA2F8DB005DB4C2 /* wrap_Texture.h in Headers */,
 				FA0B7DBA1A95902C000E1D17 /* JoystickModule.h in Headers */,
 				FA0B7DBA1A95902C000E1D17 /* JoystickModule.h in Headers */,
-				FA0B792E1A958E3B000E1D17 /* Memoizer.h in Headers */,
 				FA0B7A731A958EA3000E1D17 /* b2ChainAndCircleContact.h in Headers */,
 				FA0B7A731A958EA3000E1D17 /* b2ChainAndCircleContact.h in Headers */,
 				FA0B7AA01A958EA3000E1D17 /* b2PrismaticJoint.h in Headers */,
 				FA0B7AA01A958EA3000E1D17 /* b2PrismaticJoint.h in Headers */,
 				FA0B7DEA1A95902C000E1D17 /* Mouse.h in Headers */,
 				FA0B7DEA1A95902C000E1D17 /* Mouse.h in Headers */,
@@ -4368,7 +4360,6 @@
 				FAF140561E20934C00F898D2 /* Link.cpp in Sources */,
 				FAF140561E20934C00F898D2 /* Link.cpp in Sources */,
 				FAF140851E20934C00F898D2 /* ParseHelper.cpp in Sources */,
 				FAF140851E20934C00F898D2 /* ParseHelper.cpp in Sources */,
 				FA0B7D801A95902C000E1D17 /* Volatile.cpp in Sources */,
 				FA0B7D801A95902C000E1D17 /* Volatile.cpp in Sources */,
-				FA0B792D1A958E3B000E1D17 /* Memoizer.cpp in Sources */,
 				FA1BA0B21E16FD0800AA2803 /* Shader.cpp in Sources */,
 				FA1BA0B21E16FD0800AA2803 /* Shader.cpp in Sources */,
 				FA0B7EBC1A95902C000E1D17 /* LuaThread.cpp in Sources */,
 				FA0B7EBC1A95902C000E1D17 /* LuaThread.cpp in Sources */,
 				FA0B7A871A958EA3000E1D17 /* b2PolygonAndCircleContact.cpp in Sources */,
 				FA0B7A871A958EA3000E1D17 /* b2PolygonAndCircleContact.cpp in Sources */,
@@ -4694,7 +4685,6 @@
 				FA0B7E421A95902C000E1D17 /* wrap_CircleShape.cpp in Sources */,
 				FA0B7E421A95902C000E1D17 /* wrap_CircleShape.cpp in Sources */,
 				FA0B7CE51A95902C000E1D17 /* wrap_Source.cpp in Sources */,
 				FA0B7CE51A95902C000E1D17 /* wrap_Source.cpp in Sources */,
 				FAC7CD921FE35E95006A60C7 /* physfs_archiver_hog.c in Sources */,
 				FAC7CD921FE35E95006A60C7 /* physfs_archiver_hog.c in Sources */,
-				FA0B792C1A958E3B000E1D17 /* Memoizer.cpp in Sources */,
 				FAF140931E20934C00F898D2 /* PpScanner.cpp in Sources */,
 				FAF140931E20934C00F898D2 /* PpScanner.cpp in Sources */,
 				FA9D53AC1F5307E900125C6B /* Deprecations.cpp in Sources */,
 				FA9D53AC1F5307E900125C6B /* Deprecations.cpp in Sources */,
 				FA0B7CCD1A95902C000E1D17 /* Audio.cpp in Sources */,
 				FA0B7CCD1A95902C000E1D17 /* Audio.cpp in Sources */,

+ 0 - 50
src/common/Memoizer.cpp

@@ -1,50 +0,0 @@
-/**
- * Copyright (c) 2006-2019 LOVE Development Team
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.  In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- *    claim that you wrote the original software. If you use this software
- *    in a product, an acknowledgment in the product documentation would be
- *    appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- *    misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- **/
- 
-#include "Memoizer.h"
-
-#include <unordered_map>
-
-namespace love
-{
-
-static std::unordered_map<void *, void *> objectMap;
-
-void Memoizer::add(void *key, void *val)
-{
-	objectMap[key] = val;
-}
-
-void Memoizer::remove(void *key)
-{
-	objectMap.erase(key);
-}
-
-void *Memoizer::find(void *key)
-{
-	auto it = objectMap.find(key);
-
-	if (it != objectMap.end())
-		return it->second;
-	else
-		return nullptr;
-}
-
-} // love

+ 0 - 39
src/common/Memoizer.h

@@ -1,39 +0,0 @@
-/**
- * Copyright (c) 2006-2019 LOVE Development Team
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.  In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- *    claim that you wrote the original software. If you use this software
- *    in a product, an acknowledgment in the product documentation would be
- *    appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- *    misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- **/
-
-#ifndef LOVE_MEMOIZER_H
-#define LOVE_MEMOIZER_H
-
-namespace love
-{
-
-class Memoizer
-{
-public:
-
-	static void add(void *key, void *val);
-	static void remove(void *key);
-	static void *find(void *key);
-
-}; // Memoizer
-
-} // love
-
-#endif // LOVE_MEMOIZER_H

+ 6 - 18
src/modules/physics/box2d/Body.cpp

@@ -21,7 +21,6 @@
 #include "Body.h"
 #include "Body.h"
 
 
 #include "common/math.h"
 #include "common/math.h"
-#include "common/Memoizer.h"
 
 
 #include "Shape.h"
 #include "Shape.h"
 #include "Fixture.h"
 #include "Fixture.h"
@@ -51,18 +50,7 @@ Body::Body(World *world, b2Vec2 p, Body::Type type)
 	// Box2D body holds a reference to the love Body.
 	// Box2D body holds a reference to the love Body.
 	this->retain();
 	this->retain();
 	this->setType(type);
 	this->setType(type);
-	Memoizer::add(body, this);
-}
-
-Body::Body(b2Body *b)
-	: body(b)
-	, udata(nullptr)
-{
-	udata = (bodyudata *) b->GetUserData();
-	world = (World *) Memoizer::find(b->GetWorld());
-	// Box2D body holds a reference to the love Body.
-	this->retain();
-	Memoizer::add(body, this);
+	world->registerObject(body, this);
 }
 }
 
 
 Body::~Body()
 Body::~Body()
@@ -452,7 +440,7 @@ int Body::getFixtures(lua_State *L) const
 	{
 	{
 		if (!f)
 		if (!f)
 			break;
 			break;
-		Fixture *fixture = (Fixture *)Memoizer::find(f);
+		Fixture *fixture = (Fixture *)world->findObject(f);
 		if (!fixture)
 		if (!fixture)
 			throw love::Exception("A fixture has escaped Memoizer!");
 			throw love::Exception("A fixture has escaped Memoizer!");
 		luax_pushtype(L, fixture);
 		luax_pushtype(L, fixture);
@@ -474,7 +462,7 @@ int Body::getJoints(lua_State *L) const
 		if (!je)
 		if (!je)
 			break;
 			break;
 
 
-		Joint *joint = (Joint *) Memoizer::find(je->joint);
+		Joint *joint = (Joint *) world->findObject(je->joint);
 		if (!joint)
 		if (!joint)
 			throw love::Exception("A joint has escaped Memoizer!");
 			throw love::Exception("A joint has escaped Memoizer!");
 
 
@@ -497,9 +485,9 @@ int Body::getContacts(lua_State *L) const
 		if (!ce)
 		if (!ce)
 			break;
 			break;
 
 
-		Contact *contact = (Contact *) Memoizer::find(ce->contact);
+		Contact *contact = (Contact *) world->findObject(ce->contact);
 		if (!contact)
 		if (!contact)
-			contact = new Contact(ce->contact);
+			contact = new Contact(world, ce->contact);
 		else
 		else
 			contact->retain();
 			contact->retain();
 
 
@@ -523,7 +511,7 @@ void Body::destroy()
 	}
 	}
 
 
 	world->world->DestroyBody(body);
 	world->world->DestroyBody(body);
-	Memoizer::remove(body);
+	world->unregisterObject(body);
 	body = NULL;
 	body = NULL;
 
 
 	// Remove userdata reference to avoid it sticking around after GC
 	// Remove userdata reference to avoid it sticking around after GC

+ 0 - 5
src/modules/physics/box2d/Body.h

@@ -77,11 +77,6 @@ public:
 	 **/
 	 **/
 	Body(World *world, b2Vec2 p, Type type);
 	Body(World *world, b2Vec2 p, Type type);
 
 
-	/**
-	 * Create a Body from an extant b2Body.
-	 **/
-	Body(b2Body *b);
-
 	virtual ~Body();
 	virtual ~Body();
 
 
 	/**
 	/**

+ 0 - 2
src/modules/physics/box2d/ChainShape.cpp

@@ -25,8 +25,6 @@
 #include "World.h"
 #include "World.h"
 #include "Physics.h"
 #include "Physics.h"
 
 
-#include "common/Memoizer.h"
-
 namespace love
 namespace love
 {
 {
 namespace physics
 namespace physics

+ 0 - 2
src/modules/physics/box2d/CircleShape.cpp

@@ -25,8 +25,6 @@
 #include "World.h"
 #include "World.h"
 #include "Physics.h"
 #include "Physics.h"
 
 
-#include "common/Memoizer.h"
-
 namespace love
 namespace love
 {
 {
 namespace physics
 namespace physics

+ 7 - 8
src/modules/physics/box2d/Contact.cpp

@@ -22,8 +22,6 @@
 #include "World.h"
 #include "World.h"
 #include "Physics.h"
 #include "Physics.h"
 
 
-#include "common/Memoizer.h"
-
 namespace love
 namespace love
 {
 {
 namespace physics
 namespace physics
@@ -33,10 +31,11 @@ namespace box2d
 
 
 love::Type Contact::type("Contact", &Object::type);
 love::Type Contact::type("Contact", &Object::type);
 
 
-Contact::Contact(b2Contact *contact)
+Contact::Contact(World *world, b2Contact *contact)
 	: contact(contact)
 	: contact(contact)
+	, world(world)
 {
 {
-	Memoizer::add(contact, this);
+	world->registerObject(contact, this);
 }
 }
 
 
 Contact::~Contact()
 Contact::~Contact()
@@ -48,14 +47,14 @@ void Contact::invalidate()
 {
 {
 	if (contact != NULL)
 	if (contact != NULL)
 	{
 	{
-		Memoizer::remove(contact);
+		world->unregisterObject(contact);
 		contact = NULL;
 		contact = NULL;
 	}
 	}
 }
 }
 
 
 bool Contact::isValid()
 bool Contact::isValid()
 {
 {
-	return contact != NULL ? true : false;
+	return contact != NULL;
 }
 }
 
 
 int Contact::getPositions(lua_State *L)
 int Contact::getPositions(lua_State *L)
@@ -146,8 +145,8 @@ void Contact::getChildren(int &childA, int &childB)
 
 
 void Contact::getFixtures(Fixture *&fixtureA, Fixture *&fixtureB)
 void Contact::getFixtures(Fixture *&fixtureA, Fixture *&fixtureB)
 {
 {
-	fixtureA = (Fixture *) Memoizer::find(contact->GetFixtureA());
-	fixtureB = (Fixture *) Memoizer::find(contact->GetFixtureB());
+	fixtureA = (Fixture *) world->findObject(contact->GetFixtureA());
+	fixtureB = (Fixture *) world->findObject(contact->GetFixtureB());
 
 
 	if (!fixtureA || !fixtureB)
 	if (!fixtureA || !fixtureB)
 		throw love::Exception("A fixture has escaped Memoizer!");
 		throw love::Exception("A fixture has escaped Memoizer!");

+ 3 - 1
src/modules/physics/box2d/Contact.h

@@ -57,7 +57,7 @@ public:
 	 * data pointed to.
 	 * data pointed to.
 	 * @param contact Pointer to the Box2D contact.
 	 * @param contact Pointer to the Box2D contact.
 	 **/
 	 **/
-	Contact(b2Contact *contact);
+	Contact(World *world, b2Contact *contact);
 
 
 	virtual ~Contact();
 	virtual ~Contact();
 
 
@@ -159,6 +159,8 @@ private:
 
 
 	// The Box2D contact.
 	// The Box2D contact.
 	b2Contact *contact;
 	b2Contact *contact;
+
+	World *world;
 };
 };
 
 
 } // box2d
 } // box2d

+ 0 - 2
src/modules/physics/box2d/EdgeShape.cpp

@@ -25,8 +25,6 @@
 #include "World.h"
 #include "World.h"
 #include "Physics.h"
 #include "Physics.h"
 
 
-#include "common/Memoizer.h"
-
 namespace love
 namespace love
 {
 {
 namespace physics
 namespace physics

+ 2 - 15
src/modules/physics/box2d/Fixture.cpp

@@ -25,8 +25,6 @@
 #include "World.h"
 #include "World.h"
 #include "Physics.h"
 #include "Physics.h"
 
 
-#include "common/Memoizer.h"
-
 // STD
 // STD
 #include <bitset>
 #include <bitset>
 
 
@@ -51,18 +49,7 @@ Fixture::Fixture(Body *body, Shape *shape, float density)
 	def.density = density;
 	def.density = density;
 	fixture = body->body->CreateFixture(&def);
 	fixture = body->body->CreateFixture(&def);
 	this->retain();
 	this->retain();
-	Memoizer::add(fixture, this);
-}
-
-Fixture::Fixture(b2Fixture *f)
-	: fixture(f)
-{
-	udata = (fixtureudata *)f->GetUserData();
-	body = (Body *)Memoizer::find(f->GetBody());
-	if (!body)
-		body = new Body(f->GetBody());
-	this->retain();
-	Memoizer::add(fixture, this);
+	body->world->registerObject(fixture, this);
 }
 }
 
 
 Fixture::~Fixture()
 Fixture::~Fixture()
@@ -361,7 +348,7 @@ void Fixture::destroy(bool implicit)
 
 
 	if (!implicit && fixture != nullptr)
 	if (!implicit && fixture != nullptr)
 		body->body->DestroyFixture(fixture);
 		body->body->DestroyFixture(fixture);
-	Memoizer::remove(fixture);
+	body->world->unregisterObject(fixture);
 	fixture = nullptr;
 	fixture = nullptr;
 
 
 	// Remove userdata reference to avoid it sticking around after GC
 	// Remove userdata reference to avoid it sticking around after GC

+ 2 - 5
src/modules/physics/box2d/Fixture.h

@@ -38,6 +38,8 @@ namespace physics
 namespace box2d
 namespace box2d
 {
 {
 
 
+class World;
+
 /**
 /**
  * This struct is stored in a void pointer
  * This struct is stored in a void pointer
  * in the Box2D Fixture class. For now, all we
  * in the Box2D Fixture class. For now, all we
@@ -68,11 +70,6 @@ public:
 	 **/
 	 **/
 	Fixture(Body *body, Shape *shape, float density);
 	Fixture(Body *body, Shape *shape, float density);
 
 
-	/**
-	 * Creates a Fixture.
-	 **/
-	Fixture(b2Fixture *f);
-
 	virtual ~Fixture();
 	virtual ~Fixture();
 
 
 	/**
 	/**

+ 2 - 3
src/modules/physics/box2d/GearJoint.cpp

@@ -23,7 +23,6 @@
 // Module
 // Module
 #include "Body.h"
 #include "Body.h"
 #include "World.h"
 #include "World.h"
-#include "common/Memoizer.h"
 
 
 namespace love
 namespace love
 {
 {
@@ -69,7 +68,7 @@ Joint *GearJoint::getJointA() const
 	if (b2joint == nullptr)
 	if (b2joint == nullptr)
 		return nullptr;
 		return nullptr;
 
 
-	Joint *j = (Joint *) Memoizer::find(b2joint);
+	Joint *j = (Joint *) world->findObject(b2joint);
 	if (j == nullptr)
 	if (j == nullptr)
 		throw love::Exception("A joint has escaped Memoizer!");
 		throw love::Exception("A joint has escaped Memoizer!");
 
 
@@ -82,7 +81,7 @@ Joint *GearJoint::getJointB() const
 	if (b2joint == nullptr)
 	if (b2joint == nullptr)
 		return nullptr;
 		return nullptr;
 
 
-	Joint *j = (Joint *) Memoizer::find(b2joint);
+	Joint *j = (Joint *) world->findObject(b2joint);
 	if (j == nullptr)
 	if (j == nullptr)
 		throw love::Exception("A joint has escaped Memoizer!");
 		throw love::Exception("A joint has escaped Memoizer!");
 
 

+ 6 - 9
src/modules/physics/box2d/Joint.cpp

@@ -23,9 +23,6 @@
 // STD
 // STD
 #include <bitset>
 #include <bitset>
 
 
-// LOVE
-#include "common/Memoizer.h"
-
 // Module
 // Module
 #include "Body.h"
 #include "Body.h"
 #include "World.h"
 #include "World.h"
@@ -107,7 +104,7 @@ Body *Joint::getBodyA() const
 	if (b2body == nullptr)
 	if (b2body == nullptr)
 		return nullptr;
 		return nullptr;
 
 
-	Body *body = (Body *) Memoizer::find(b2body);
+	Body *body = (Body *) world->findObject(b2body);
 	if (body == nullptr)
 	if (body == nullptr)
 		throw love::Exception("A body has escaped Memoizer!");
 		throw love::Exception("A body has escaped Memoizer!");
 
 
@@ -120,7 +117,7 @@ Body *Joint::getBodyB() const
 	if (b2body == nullptr)
 	if (b2body == nullptr)
 		return nullptr;
 		return nullptr;
 
 
-	Body *body = (Body *) Memoizer::find(b2body);
+	Body *body = (Body *) world->findObject(b2body);
 	if (body == nullptr)
 	if (body == nullptr)
 		throw love::Exception("A body has escaped Memoizer!");
 		throw love::Exception("A body has escaped Memoizer!");
 
 
@@ -129,7 +126,7 @@ Body *Joint::getBodyB() const
 
 
 bool Joint::isValid() const
 bool Joint::isValid() const
 {
 {
-	return joint != 0;
+	return joint != nullptr;
 }
 }
 
 
 int Joint::getAnchors(lua_State *L)
 int Joint::getAnchors(lua_State *L)
@@ -159,7 +156,7 @@ b2Joint *Joint::createJoint(b2JointDef *def)
 {
 {
 	def->userData = udata;
 	def->userData = udata;
 	joint = world->world->CreateJoint(def);
 	joint = world->world->CreateJoint(def);
-	Memoizer::add(joint, this);
+	world->registerObject(joint, this);
 	// Box2D joint has a reference to this love Joint.
 	// Box2D joint has a reference to this love Joint.
 	this->retain();
 	this->retain();
 	return joint;
 	return joint;
@@ -175,9 +172,9 @@ void Joint::destroyJoint(bool implicit)
 		return;
 		return;
 	}
 	}
 
 
-	if (!implicit && joint != 0)
+	if (!implicit && joint != nullptr)
 		world->world->DestroyJoint(joint);
 		world->world->DestroyJoint(joint);
-	Memoizer::remove(joint);
+	world->unregisterObject(joint);
 	joint = NULL;
 	joint = NULL;
 
 
 	// Remove userdata reference to avoid it sticking around after GC
 	// Remove userdata reference to avoid it sticking around after GC

+ 1 - 1
src/modules/physics/box2d/Joint.h

@@ -153,7 +153,7 @@ private:
 	// The Box2D joint object.
 	// The Box2D joint object.
 	b2Joint *joint;
 	b2Joint *joint;
 
 
-};
+}; // Joint
 
 
 } // box2d
 } // box2d
 } // physics
 } // physics

+ 0 - 2
src/modules/physics/box2d/PolygonShape.cpp

@@ -25,8 +25,6 @@
 #include "World.h"
 #include "World.h"
 #include "Physics.h"
 #include "Physics.h"
 
 
-#include "common/Memoizer.h"
-
 namespace love
 namespace love
 {
 {
 namespace physics
 namespace physics

+ 0 - 7
src/modules/physics/box2d/Shape.cpp

@@ -25,8 +25,6 @@
 #include "World.h"
 #include "World.h"
 #include "Physics.h"
 #include "Physics.h"
 
 
-#include "common/Memoizer.h"
-
 // STD
 // STD
 #include <bitset>
 #include <bitset>
 
 
@@ -47,17 +45,12 @@ Shape::Shape(b2Shape *shape, bool own)
 	: shape(shape)
 	: shape(shape)
 	, own(own)
 	, own(own)
 {
 {
-	if (own)
-		Memoizer::add(shape, this);
 }
 }
 
 
 Shape::~Shape()
 Shape::~Shape()
 {
 {
 	if (shape && own)
 	if (shape && own)
-	{
-		Memoizer::remove(shape);
 		delete shape;
 		delete shape;
-	}
 	shape = nullptr;
 	shape = nullptr;
 }
 }
 
 

+ 58 - 29
src/modules/physics/box2d/World.cpp

@@ -24,7 +24,6 @@
 #include "Shape.h"
 #include "Shape.h"
 #include "Contact.h"
 #include "Contact.h"
 #include "Physics.h"
 #include "Physics.h"
-#include "common/Memoizer.h"
 #include "common/Reference.h"
 #include "common/Reference.h"
 
 
 namespace love
 namespace love
@@ -36,9 +35,10 @@ namespace box2d
 
 
 love::Type World::type("World", &Object::type);
 love::Type World::type("World", &Object::type);
 
 
-World::ContactCallback::ContactCallback()
+World::ContactCallback::ContactCallback(World *world)
 	: ref(nullptr)
 	: ref(nullptr)
 	, L(nullptr)
 	, L(nullptr)
+	, world(world)
 {
 {
 }
 }
 
 
@@ -57,7 +57,7 @@ void World::ContactCallback::process(b2Contact *contact, const b2ContactImpulse
 
 
 		// Push first fixture.
 		// Push first fixture.
 		{
 		{
-			Fixture *a = (Fixture *)Memoizer::find(contact->GetFixtureA());
+			Fixture *a = (Fixture *)world->findObject(contact->GetFixtureA());
 			if (a != nullptr)
 			if (a != nullptr)
 				luax_pushtype(L, a);
 				luax_pushtype(L, a);
 			else
 			else
@@ -66,16 +66,16 @@ void World::ContactCallback::process(b2Contact *contact, const b2ContactImpulse
 
 
 		// Push second fixture.
 		// Push second fixture.
 		{
 		{
-			Fixture *b = (Fixture *)Memoizer::find(contact->GetFixtureB());
+			Fixture *b = (Fixture *)world->findObject(contact->GetFixtureB());
 			if (b != nullptr)
 			if (b != nullptr)
 				luax_pushtype(L, b);
 				luax_pushtype(L, b);
 			else
 			else
 				throw love::Exception("A fixture has escaped Memoizer!");
 				throw love::Exception("A fixture has escaped Memoizer!");
 		}
 		}
 
 
-		Contact *cobj = (Contact *)Memoizer::find(contact);
+		Contact *cobj = (Contact *)world->findObject(contact);
 		if (!cobj)
 		if (!cobj)
-			cobj = new Contact(contact);
+			cobj = new Contact(world, contact);
 		else
 		else
 			cobj->retain();
 			cobj->retain();
 
 
@@ -138,8 +138,9 @@ bool World::ContactFilter::process(Fixture *a, Fixture *b)
 	return true;
 	return true;
 }
 }
 
 
-World::QueryCallback::QueryCallback(lua_State *L, int idx)
-	: L(L)
+World::QueryCallback::QueryCallback(World *world, lua_State *L, int idx)
+	: world(world)
+	, L(L)
 	, funcidx(idx)
 	, funcidx(idx)
 {
 {
 	luaL_checktype(L, funcidx, LUA_TFUNCTION);
 	luaL_checktype(L, funcidx, LUA_TFUNCTION);
@@ -154,7 +155,7 @@ bool World::QueryCallback::ReportFixture(b2Fixture *fixture)
 	if (L != nullptr)
 	if (L != nullptr)
 	{
 	{
 		lua_pushvalue(L, funcidx);
 		lua_pushvalue(L, funcidx);
-		Fixture *f = (Fixture *)Memoizer::find(fixture);
+		Fixture *f = (Fixture *)world->findObject(fixture);
 		if (!f)
 		if (!f)
 			throw love::Exception("A fixture has escaped Memoizer!");
 			throw love::Exception("A fixture has escaped Memoizer!");
 		luax_pushtype(L, f);
 		luax_pushtype(L, f);
@@ -167,8 +168,9 @@ bool World::QueryCallback::ReportFixture(b2Fixture *fixture)
 	return true;
 	return true;
 }
 }
 
 
-World::RayCastCallback::RayCastCallback(lua_State *L, int idx)
-	: L(L)
+World::RayCastCallback::RayCastCallback(World *world, lua_State *L, int idx)
+	: world(world)
+	, L(L)
 	, funcidx(idx)
 	, funcidx(idx)
 {
 {
 	luaL_checktype(L, funcidx, LUA_TFUNCTION);
 	luaL_checktype(L, funcidx, LUA_TFUNCTION);
@@ -183,7 +185,7 @@ float32 World::RayCastCallback::ReportFixture(b2Fixture *fixture, const b2Vec2 &
 	if (L != nullptr)
 	if (L != nullptr)
 	{
 	{
 		lua_pushvalue(L, funcidx);
 		lua_pushvalue(L, funcidx);
-		Fixture *f = (Fixture *)Memoizer::find(fixture);
+		Fixture *f = (Fixture *)world->findObject(fixture);
 		if (!f)
 		if (!f)
 			throw love::Exception("A fixture has escaped Memoizer!");
 			throw love::Exception("A fixture has escaped Memoizer!");
 		luax_pushtype(L, f);
 		luax_pushtype(L, f);
@@ -206,14 +208,14 @@ float32 World::RayCastCallback::ReportFixture(b2Fixture *fixture, const b2Vec2 &
 
 
 void World::SayGoodbye(b2Fixture *fixture)
 void World::SayGoodbye(b2Fixture *fixture)
 {
 {
-	Fixture *f = (Fixture *)Memoizer::find(fixture);
+	Fixture *f = (Fixture *)findObject(fixture);
 	// Hint implicit destruction with true.
 	// Hint implicit destruction with true.
 	if (f) f->destroy(true);
 	if (f) f->destroy(true);
 }
 }
 
 
 void World::SayGoodbye(b2Joint *joint)
 void World::SayGoodbye(b2Joint *joint)
 {
 {
-	Joint *j = (Joint *)Memoizer::find(joint);
+	Joint *j = (Joint *)findObject(joint);
 	// Hint implicit destruction with true.
 	// Hint implicit destruction with true.
 	if (j) j->destroyJoint(true);
 	if (j) j->destroyJoint(true);
 }
 }
@@ -221,6 +223,10 @@ void World::SayGoodbye(b2Joint *joint)
 World::World()
 World::World()
 	: world(nullptr)
 	: world(nullptr)
 	, destructWorld(false)
 	, destructWorld(false)
+	, begin(this)
+	, end(this)
+	, presolve(this)
+	, postsolve(this)
 {
 {
 	world = new b2World(b2Vec2(0,0));
 	world = new b2World(b2Vec2(0,0));
 	world->SetAllowSleeping(true);
 	world->SetAllowSleeping(true);
@@ -229,12 +235,16 @@ World::World()
 	world->SetDestructionListener(this);
 	world->SetDestructionListener(this);
 	b2BodyDef def;
 	b2BodyDef def;
 	groundBody = world->CreateBody(&def);
 	groundBody = world->CreateBody(&def);
-	Memoizer::add(world, this);
+	registerObject(world, this);
 }
 }
 
 
 World::World(b2Vec2 gravity, bool sleep)
 World::World(b2Vec2 gravity, bool sleep)
 	: world(nullptr)
 	: world(nullptr)
 	, destructWorld(false)
 	, destructWorld(false)
+	, begin(this)
+	, end(this)
+	, presolve(this)
+	, postsolve(this)
 {
 {
 	world = new b2World(Physics::scaleDown(gravity));
 	world = new b2World(Physics::scaleDown(gravity));
 	world->SetAllowSleeping(sleep);
 	world->SetAllowSleeping(sleep);
@@ -243,7 +253,7 @@ World::World(b2Vec2 gravity, bool sleep)
 	world->SetDestructionListener(this);
 	world->SetDestructionListener(this);
 	b2BodyDef def;
 	b2BodyDef def;
 	groundBody = world->CreateBody(&def);
 	groundBody = world->CreateBody(&def);
-	Memoizer::add(world, this);
+	registerObject(world, this);
 }
 }
 
 
 World::~World()
 World::~World()
@@ -297,8 +307,8 @@ void World::EndContact(b2Contact *contact)
 	end.process(contact);
 	end.process(contact);
 
 
 	// Letting the Contact know that the b2Contact will be destroyed any second.
 	// Letting the Contact know that the b2Contact will be destroyed any second.
-	Contact *c = (Contact *)Memoizer::find(contact);
-	if (c != NULL)
+	Contact *c = (Contact *)findObject(contact);
+	if (c != nullptr)
 		c->invalidate();
 		c->invalidate();
 }
 }
 
 
@@ -316,8 +326,8 @@ void World::PostSolve(b2Contact *contact, const b2ContactImpulse *impulse)
 bool World::ShouldCollide(b2Fixture *fixtureA, b2Fixture *fixtureB)
 bool World::ShouldCollide(b2Fixture *fixtureA, b2Fixture *fixtureB)
 {
 {
 	// Fixtures should be memoized, if we created them
 	// Fixtures should be memoized, if we created them
-	Fixture *a = (Fixture *)Memoizer::find(fixtureA);
-	Fixture *b = (Fixture *)Memoizer::find(fixtureB);
+	Fixture *a = (Fixture *)findObject(fixtureA);
+	Fixture *b = (Fixture *)findObject(fixtureB);
 	if (!a || !b)
 	if (!a || !b)
 		throw love::Exception("A fixture has escaped Memoizer!");
 		throw love::Exception("A fixture has escaped Memoizer!");
 	return filter.process(a, b);
 	return filter.process(a, b);
@@ -472,7 +482,7 @@ int World::getBodies(lua_State *L) const
 			break;
 			break;
 		if (b == groundBody)
 		if (b == groundBody)
 			continue;
 			continue;
-		Body *body = (Body *)Memoizer::find(b);
+		Body *body = (Body *)findObject(b);
 		if (!body)
 		if (!body)
 			throw love::Exception("A body has escaped Memoizer!");
 			throw love::Exception("A body has escaped Memoizer!");
 		luax_pushtype(L, body);
 		luax_pushtype(L, body);
@@ -491,7 +501,7 @@ int World::getJoints(lua_State *L) const
 	do
 	do
 	{
 	{
 		if (!j) break;
 		if (!j) break;
-		Joint *joint = (Joint *)Memoizer::find(j);
+		Joint *joint = (Joint *)findObject(j);
 		if (!joint) throw love::Exception("A joint has escaped Memoizer!");
 		if (!joint) throw love::Exception("A joint has escaped Memoizer!");
 		luax_pushtype(L, joint);
 		luax_pushtype(L, joint);
 		lua_rawseti(L, -2, i);
 		lua_rawseti(L, -2, i);
@@ -501,7 +511,7 @@ int World::getJoints(lua_State *L) const
 	return 1;
 	return 1;
 }
 }
 
 
-int World::getContacts(lua_State *L) const
+int World::getContacts(lua_State *L)
 {
 {
 	lua_newtable(L);
 	lua_newtable(L);
 	b2Contact *c = world->GetContactList();
 	b2Contact *c = world->GetContactList();
@@ -509,9 +519,9 @@ int World::getContacts(lua_State *L) const
 	do
 	do
 	{
 	{
 		if (!c) break;
 		if (!c) break;
-		Contact *contact = (Contact *)Memoizer::find(c);
+		Contact *contact = (Contact *)findObject(c);
 		if (!contact)
 		if (!contact)
-			contact = new Contact(c);
+			contact = new Contact(this, c);
 		else
 		else
 			contact->retain();
 			contact->retain();
 		luax_pushtype(L, contact);
 		luax_pushtype(L, contact);
@@ -538,7 +548,7 @@ int World::queryBoundingBox(lua_State *L)
 	box.lowerBound = Physics::scaleDown(b2Vec2(lx, ly));
 	box.lowerBound = Physics::scaleDown(b2Vec2(lx, ly));
 	box.upperBound = Physics::scaleDown(b2Vec2(ux, uy));
 	box.upperBound = Physics::scaleDown(b2Vec2(ux, uy));
 	luaL_checktype(L, 5, LUA_TFUNCTION);
 	luaL_checktype(L, 5, LUA_TFUNCTION);
-	QueryCallback query(L, 5);
+	QueryCallback query(this, L, 5);
 	world->QueryAABB(&query, box);
 	world->QueryAABB(&query, box);
 	return 0;
 	return 0;
 }
 }
@@ -552,7 +562,7 @@ int World::rayCast(lua_State *L)
 	b2Vec2 v1 = Physics::scaleDown(b2Vec2(x1, y1));
 	b2Vec2 v1 = Physics::scaleDown(b2Vec2(x1, y1));
 	b2Vec2 v2 = Physics::scaleDown(b2Vec2(x2, y2));
 	b2Vec2 v2 = Physics::scaleDown(b2Vec2(x2, y2));
 	luaL_checktype(L, 5, LUA_TFUNCTION);
 	luaL_checktype(L, 5, LUA_TFUNCTION);
-	RayCastCallback raycast(L, 5);
+	RayCastCallback raycast(this, L, 5);
 	world->RayCast(&raycast, v1, v2);
 	world->RayCast(&raycast, v1, v2);
 	return 0;
 	return 0;
 }
 }
@@ -586,19 +596,38 @@ void World::destroy()
 		b = b->GetNext();
 		b = b->GetNext();
 		if (t == groundBody)
 		if (t == groundBody)
 			continue;
 			continue;
-		Body *body = (Body *)Memoizer::find(t);
+		Body *body = (Body *)findObject(t);
 		if (!body)
 		if (!body)
 			throw love::Exception("A body has escaped Memoizer!");
 			throw love::Exception("A body has escaped Memoizer!");
 		body->destroy();
 		body->destroy();
 	}
 	}
 
 
 	world->DestroyBody(groundBody);
 	world->DestroyBody(groundBody);
-	Memoizer::remove(world);
+	unregisterObject(world);
 
 
 	delete world;
 	delete world;
 	world = nullptr;
 	world = nullptr;
 }
 }
 
 
+void World::registerObject(void *b2object, love::Object *object)
+{
+	box2dObjectMap[b2object] = object;
+}
+
+void World::unregisterObject(void *b2object)
+{
+	box2dObjectMap.erase(b2object);
+}
+
+love::Object *World::findObject(void *b2object) const
+{
+	auto it = box2dObjectMap.find(b2object);
+	if (it != box2dObjectMap.end())
+		return it->second;
+	else
+		return nullptr;
+}
+
 } // box2d
 } // box2d
 } // physics
 } // physics
 } // love
 } // love

+ 16 - 5
src/modules/physics/box2d/World.h

@@ -28,6 +28,7 @@
 
 
 // STD
 // STD
 #include <vector>
 #include <vector>
+#include <unordered_map>
 
 
 // Box2D
 // Box2D
 #include <Box2D/Box2D.h>
 #include <Box2D/Box2D.h>
@@ -73,7 +74,8 @@ public:
 	public:
 	public:
 		Reference *ref;
 		Reference *ref;
 		lua_State *L;
 		lua_State *L;
-		ContactCallback();
+		World *world;
+		ContactCallback(World *world);
 		~ContactCallback();
 		~ContactCallback();
 		void process(b2Contact *contact, const b2ContactImpulse *impulse = NULL);
 		void process(b2Contact *contact, const b2ContactImpulse *impulse = NULL);
 	};
 	};
@@ -91,10 +93,11 @@ public:
 	class QueryCallback : public b2QueryCallback
 	class QueryCallback : public b2QueryCallback
 	{
 	{
 	public:
 	public:
-		QueryCallback(lua_State *L, int idx);
+		QueryCallback(World *world, lua_State *L, int idx);
 		~QueryCallback();
 		~QueryCallback();
 		virtual bool ReportFixture(b2Fixture *fixture);
 		virtual bool ReportFixture(b2Fixture *fixture);
 	private:
 	private:
+		World *world;
 		lua_State *L;
 		lua_State *L;
 		int funcidx;
 		int funcidx;
 	};
 	};
@@ -102,10 +105,11 @@ public:
 	class RayCastCallback : public b2RayCastCallback
 	class RayCastCallback : public b2RayCastCallback
 	{
 	{
 	public:
 	public:
-		RayCastCallback(lua_State *L, int idx);
+		RayCastCallback(World *world, lua_State *L, int idx);
 		~RayCastCallback();
 		~RayCastCallback();
 		virtual float32 ReportFixture(b2Fixture *fixture, const b2Vec2 &point, const b2Vec2 &normal, float32 fraction);
 		virtual float32 ReportFixture(b2Fixture *fixture, const b2Vec2 &point, const b2Vec2 &normal, float32 fraction);
 	private:
 	private:
+		World *world;
 		lua_State *L;
 		lua_State *L;
 		int funcidx;
 		int funcidx;
 	};
 	};
@@ -257,7 +261,7 @@ public:
 	 * Get an array of all the Contacts in the World.
 	 * Get an array of all the Contacts in the World.
 	 * @return An array of Contacts.
 	 * @return An array of Contacts.
 	 **/
 	 **/
-	int getContacts(lua_State *L) const;
+	int getContacts(lua_State *L);
 
 
 	/**
 	/**
 	 * Gets the ground body.
 	 * Gets the ground body.
@@ -280,6 +284,10 @@ public:
 	 **/
 	 **/
 	void destroy();
 	void destroy();
 
 
+	void registerObject(void *b2object, love::Object *object);
+	void unregisterObject(void *b2object);
+	love::Object *findObject(void *b2object) const;
+
 private:
 private:
 
 
 	// Pointer to the Box2D world.
 	// Pointer to the Box2D world.
@@ -297,7 +305,10 @@ private:
 	// Contact callbacks.
 	// Contact callbacks.
 	ContactCallback begin, end, presolve, postsolve;
 	ContactCallback begin, end, presolve, postsolve;
 	ContactFilter filter;
 	ContactFilter filter;
-};
+
+	std::unordered_map<void *, love::Object *> box2dObjectMap;
+
+}; // World
 
 
 } // box2d
 } // box2d
 } // physics
 } // physics