Replaced luax_newtype with luax_pushtype (and added luax_rawnewtype for the old functionality of luax_newtype.)

luax_pushtype keeps the object in a weak table and checks the table before creating a new userdata, so it re-uses the object's existing wrapper userdata if it can, whenever the object is pushed to Lua.

This fixes some subtle issues with love objects, where using them as keys in tables would not always work as expected (https://love2d.org/forums/viewtopic.php?f=4&t=39398&p=112388#p112415). It also decreases the amount of new Lua objects created, saving the garbage collector some work.
This commit is contained in:
Alex Szpakowski
2013-08-29 00:40:06 -03:00
parent 526ccb12ad
commit ec9dec6b80
26 changed files with 267 additions and 111 deletions
+1 -1
View File
@@ -428,7 +428,7 @@ int Body::getFixtureList(lua_State *L) const
if (!fixture)
throw love::Exception("A fixture has escaped Memoizer!");
fixture->retain();
luax_newtype(L, "Fixture", PHYSICS_FIXTURE_T, (void *)fixture);
luax_pushtype(L, "Fixture", PHYSICS_FIXTURE_T, fixture);
lua_rawseti(L, -2, i);
i++;
}
+2 -2
View File
@@ -153,7 +153,7 @@ int Physics::newPolygonShape(lua_State *L)
s->Set(vecs, vcount);
PolygonShape *p = new PolygonShape(s);
luax_newtype(L, "PolygonShape", PHYSICS_POLYGON_SHAPE_T, (void *)p);
luax_pushtype(L, "PolygonShape", PHYSICS_POLYGON_SHAPE_T, p);
return 1;
}
@@ -185,7 +185,7 @@ int Physics::newChainShape(lua_State *L)
ChainShape *c = new ChainShape(s);
delete[] vecs;
luax_newtype(L, "ChainShape", PHYSICS_CHAIN_SHAPE_T, (void *)c);
luax_pushtype(L, "ChainShape", PHYSICS_CHAIN_SHAPE_T, c);
return 1;
}
+10 -10
View File
@@ -59,7 +59,7 @@ void World::ContactCallback::process(b2Contact *contact, const b2ContactImpulse
if (a != 0)
{
a->retain();
luax_newtype(L, "Fixture", PHYSICS_FIXTURE_T, (void *)a);
luax_pushtype(L, "Fixture", PHYSICS_FIXTURE_T, a);
}
else
throw love::Exception("A fixture has escaped Memoizer!");
@@ -71,7 +71,7 @@ void World::ContactCallback::process(b2Contact *contact, const b2ContactImpulse
if (b != 0)
{
b->retain();
luax_newtype(L, "Fixture", PHYSICS_FIXTURE_T, (void *)b);
luax_pushtype(L, "Fixture", PHYSICS_FIXTURE_T, b);
}
else
throw love::Exception("A fixture has escaped Memoizer!");
@@ -83,7 +83,7 @@ void World::ContactCallback::process(b2Contact *contact, const b2ContactImpulse
else
cobj->retain();
luax_newtype(L, "Contact", (PHYSICS_CONTACT_T), (void *)cobj);
luax_pushtype(L, "Contact", (PHYSICS_CONTACT_T), cobj);
int args = 3;
if (impulse)
@@ -133,8 +133,8 @@ bool World::ContactFilter::process(Fixture *a, Fixture *b)
{
lua_State *L = ref->getL();
ref->push();
luax_newtype(L, "Fixture", PHYSICS_FIXTURE_T, (void *)a);
luax_newtype(L, "Fixture", PHYSICS_FIXTURE_T, (void *)b);
luax_pushtype(L, "Fixture", PHYSICS_FIXTURE_T, a);
luax_pushtype(L, "Fixture", PHYSICS_FIXTURE_T, b);
lua_call(L, 2, 1);
return luax_toboolean(L, -1);
}
@@ -162,7 +162,7 @@ bool World::QueryCallback::ReportFixture(b2Fixture *fixture)
if (!f)
throw love::Exception("A fixture has escaped Memoizer!");
f->retain();
luax_newtype(L, "Fixture", PHYSICS_FIXTURE_T, (void *)f);
luax_pushtype(L, "Fixture", PHYSICS_FIXTURE_T, f);
lua_call(L, 1, 1);
return luax_toboolean(L, -1);
}
@@ -190,7 +190,7 @@ float32 World::RayCastCallback::ReportFixture(b2Fixture *fixture, const b2Vec2 &
if (!f)
throw love::Exception("A fixture has escaped Memoizer!");
f->retain();
luax_newtype(L, "Fixture", PHYSICS_FIXTURE_T, (void *)f);
luax_pushtype(L, "Fixture", PHYSICS_FIXTURE_T, f);
b2Vec2 scaledPoint = Physics::scaleUp(point);
lua_pushnumber(L, scaledPoint.x);
lua_pushnumber(L, scaledPoint.y);
@@ -441,7 +441,7 @@ int World::getBodyList(lua_State *L) const
if (!body)
throw love::Exception("A body has escaped Memoizer!");
body->retain();
luax_newtype(L, "Body", PHYSICS_BODY_T, (void *)body);
luax_pushtype(L, "Body", PHYSICS_BODY_T, body);
lua_rawseti(L, -2, i);
i++;
}
@@ -460,7 +460,7 @@ int World::getJointList(lua_State *L) const
Joint *joint = (Joint *)Memoizer::find(j);
if (!joint) throw love::Exception("A joint has escaped Memoizer!");
joint->retain();
luax_newtype(L, "Joint", PHYSICS_JOINT_T, (void *)joint);
luax_pushtype(L, "Joint", PHYSICS_JOINT_T, joint);
lua_rawseti(L, -2, i);
i++;
}
@@ -481,7 +481,7 @@ int World::getContactList(lua_State *L) const
contact = new Contact(c);
else
contact->retain();
luax_newtype(L, "Contact", PHYSICS_CONTACT_T, (void *)contact);
luax_pushtype(L, "Contact", PHYSICS_CONTACT_T, contact);
lua_rawseti(L, -2, i);
i++;
}
@@ -65,7 +65,7 @@ int w_ChainShape_getChildEdge(lua_State *L)
int index = luaL_checkint(L, 2) - 1; // Convert from 1-based index
EdgeShape *e = 0;
ASSERT_GUARD(e = c->getChildEdge(index);)
luax_newtype(L, "EdgeShape", PHYSICS_EDGE_SHAPE_T, e);
luax_pushtype(L, "EdgeShape", PHYSICS_EDGE_SHAPE_T, e);
return 1;
}
+6 -6
View File
@@ -112,7 +112,7 @@ int w_Fixture_getBody(lua_State *L)
if (body == 0)
return 0;
body->retain();
luax_newtype(L, "Body", PHYSICS_BODY_T, (void *)body);
luax_pushtype(L, "Body", PHYSICS_BODY_T, body);
return 1;
}
@@ -125,19 +125,19 @@ int w_Fixture_getShape(lua_State *L)
switch (shape->getType())
{
case Shape::SHAPE_EDGE:
luax_newtype(L, "EdgeShape", PHYSICS_EDGE_SHAPE_T, (void *)shape);
luax_pushtype(L, "EdgeShape", PHYSICS_EDGE_SHAPE_T, shape);
break;
case Shape::SHAPE_CHAIN:
luax_newtype(L, "ChainShape", PHYSICS_CHAIN_SHAPE_T, (void *)shape);
luax_pushtype(L, "ChainShape", PHYSICS_CHAIN_SHAPE_T, shape);
break;
case Shape::SHAPE_CIRCLE:
luax_newtype(L, "CircleShape", PHYSICS_CIRCLE_SHAPE_T, (void *)shape);
luax_pushtype(L, "CircleShape", PHYSICS_CIRCLE_SHAPE_T, shape);
break;
case Shape::SHAPE_POLYGON:
luax_newtype(L, "PolygonShape", PHYSICS_POLYGON_SHAPE_T, (void *)shape);
luax_pushtype(L, "PolygonShape", PHYSICS_POLYGON_SHAPE_T, shape);
break;
default:
luax_newtype(L, "Shape", PHYSICS_SHAPE_T, (void *)shape);
luax_pushtype(L, "Shape", PHYSICS_SHAPE_T, shape);
break;
}
return 1;
+18 -18
View File
@@ -58,7 +58,7 @@ int w_newWorld(lua_State *L)
World *w;
ASSERT_GUARD(w = instance->newWorld(gx, gy, sleep);)
luax_newtype(L, "World", PHYSICS_WORLD_T, (void *)w);
luax_pushtype(L, "World", PHYSICS_WORLD_T, w);
return 1;
}
@@ -76,7 +76,7 @@ int w_newBody(lua_State *L)
Body *body;
ASSERT_GUARD(body = instance->newBody(world, x, y, btype);)
luax_newtype(L, "Body", PHYSICS_BODY_T, (void *)body);
luax_pushtype(L, "Body", PHYSICS_BODY_T, body);
return 1;
}
@@ -87,7 +87,7 @@ int w_newFixture(lua_State *L)
float density = (float)luaL_optnumber(L, 3, 1.0f);
Fixture *fixture;
ASSERT_GUARD(fixture = instance->newFixture(body, shape, density);)
luax_newtype(L, "Fixture", PHYSICS_FIXTURE_T, (void *)fixture);
luax_pushtype(L, "Fixture", PHYSICS_FIXTURE_T, fixture);
return 1;
}
@@ -100,7 +100,7 @@ int w_newCircleShape(lua_State *L)
float radius = (float)luaL_checknumber(L, 1);
CircleShape *shape;
ASSERT_GUARD(shape = instance->newCircleShape(radius);)
luax_newtype(L, "CircleShape", PHYSICS_CIRCLE_SHAPE_T, (void *)shape);
luax_pushtype(L, "CircleShape", PHYSICS_CIRCLE_SHAPE_T, shape);
return 1;
}
else if (top == 3)
@@ -110,7 +110,7 @@ int w_newCircleShape(lua_State *L)
float radius = (float)luaL_checknumber(L, 3);
CircleShape *shape;
ASSERT_GUARD(shape = instance->newCircleShape(x, y, radius);)
luax_newtype(L, "CircleShape", PHYSICS_CIRCLE_SHAPE_T, (void *)shape);
luax_pushtype(L, "CircleShape", PHYSICS_CIRCLE_SHAPE_T, shape);
return 1;
}
else
@@ -127,7 +127,7 @@ int w_newRectangleShape(lua_State *L)
float h = (float)luaL_checknumber(L, 2);
PolygonShape *shape;
ASSERT_GUARD(shape = instance->newRectangleShape(w, h);)
luax_newtype(L, "PolygonShape", PHYSICS_POLYGON_SHAPE_T, (void *)shape);
luax_pushtype(L, "PolygonShape", PHYSICS_POLYGON_SHAPE_T, shape);
return 1;
}
else if (top == 4 || top == 5)
@@ -139,7 +139,7 @@ int w_newRectangleShape(lua_State *L)
float angle = (float)luaL_optnumber(L, 5, 0);
PolygonShape *shape;
ASSERT_GUARD(shape = instance->newRectangleShape(x, y, w, h, angle);)
luax_newtype(L, "PolygonShape", PHYSICS_POLYGON_SHAPE_T, (void *)shape);
luax_pushtype(L, "PolygonShape", PHYSICS_POLYGON_SHAPE_T, shape);
return 1;
}
else
@@ -154,7 +154,7 @@ int w_newEdgeShape(lua_State *L)
float y2 = (float)luaL_checknumber(L, 4);
EdgeShape *shape;
ASSERT_GUARD(shape = instance->newEdgeShape(x1, y1, x2, y2);)
luax_newtype(L, "EdgeShape", PHYSICS_EDGE_SHAPE_T, (void *)shape);
luax_pushtype(L, "EdgeShape", PHYSICS_EDGE_SHAPE_T, shape);
return 1;
}
@@ -179,7 +179,7 @@ int w_newDistanceJoint(lua_State *L)
bool collideConnected = luax_optboolean(L, 7, false);
DistanceJoint *j;
ASSERT_GUARD(j = instance->newDistanceJoint(body1, body2, x1, y1, x2, y2, collideConnected);)
luax_newtype(L, "DistanceJoint", PHYSICS_DISTANCE_JOINT_T, (void *)j);
luax_pushtype(L, "DistanceJoint", PHYSICS_DISTANCE_JOINT_T, j);
return 1;
}
@@ -190,7 +190,7 @@ int w_newMouseJoint(lua_State *L)
float y = (float)luaL_checknumber(L, 3);
MouseJoint *j;
ASSERT_GUARD(j = instance->newMouseJoint(body, x, y);)
luax_newtype(L, "MouseJoint", PHYSICS_MOUSE_JOINT_T, (void *)j);
luax_pushtype(L, "MouseJoint", PHYSICS_MOUSE_JOINT_T, j);
return 1;
}
@@ -203,7 +203,7 @@ int w_newRevoluteJoint(lua_State *L)
bool collideConnected = luax_optboolean(L, 5, false);
RevoluteJoint *j;
ASSERT_GUARD(j = instance->newRevoluteJoint(body1, body2, x, y, collideConnected);)
luax_newtype(L, "RevoluteJoint", PHYSICS_REVOLUTE_JOINT_T, (void *)j);
luax_pushtype(L, "RevoluteJoint", PHYSICS_REVOLUTE_JOINT_T, j);
return 1;
}
@@ -233,7 +233,7 @@ int w_newPrismaticJoint(lua_State *L)
}
PrismaticJoint *j;
ASSERT_GUARD(j = instance->newPrismaticJoint(body1, body2, xA, yA, xB, yB, ax, ay, collideConnected);)
luax_newtype(L, "PrismaticJoint", PHYSICS_PRISMATIC_JOINT_T, (void *)j);
luax_pushtype(L, "PrismaticJoint", PHYSICS_PRISMATIC_JOINT_T, j);
return 1;
}
@@ -254,7 +254,7 @@ int w_newPulleyJoint(lua_State *L)
PulleyJoint *j;
ASSERT_GUARD(j = instance->newPulleyJoint(body1, body2, b2Vec2(gx1,gy1), b2Vec2(gx2,gy2), b2Vec2(x1,y1), b2Vec2(x2,y2), ratio, collideConnected);)
luax_newtype(L, "PulleyJoint", PHYSICS_PULLEY_JOINT_T, (void *)j);
luax_pushtype(L, "PulleyJoint", PHYSICS_PULLEY_JOINT_T, j);
return 1;
}
@@ -267,7 +267,7 @@ int w_newGearJoint(lua_State *L)
GearJoint *j;
ASSERT_GUARD(j = instance->newGearJoint(joint1, joint2, ratio, collideConnected);)
luax_newtype(L, "GearJoint", PHYSICS_GEAR_JOINT_T, (void *)j);
luax_pushtype(L, "GearJoint", PHYSICS_GEAR_JOINT_T, j);
return 1;
}
@@ -293,7 +293,7 @@ int w_newFrictionJoint(lua_State *L)
}
FrictionJoint *j;
ASSERT_GUARD(j = instance->newFrictionJoint(body1, body2, xA, yA, xB, yB, collideConnected);)
luax_newtype(L, "FrictionJoint", PHYSICS_FRICTION_JOINT_T, (void *)j);
luax_pushtype(L, "FrictionJoint", PHYSICS_FRICTION_JOINT_T, j);
return 1;
}
@@ -319,7 +319,7 @@ int w_newWeldJoint(lua_State *L)
}
WeldJoint *j;
ASSERT_GUARD(j = instance->newWeldJoint(body1, body2, xA, yA, xB, yB, collideConnected);)
luax_newtype(L, "WeldJoint", PHYSICS_WELD_JOINT_T, (void *)j);
luax_pushtype(L, "WeldJoint", PHYSICS_WELD_JOINT_T, j);
return 1;
}
@@ -350,7 +350,7 @@ int w_newWheelJoint(lua_State *L)
WheelJoint *j;
ASSERT_GUARD(j = instance->newWheelJoint(body1, body2, xA, yA, xB, yB, ax, ay, collideConnected);)
luax_newtype(L, "WheelJoint", PHYSICS_WHEEL_JOINT_T, (void *)j);
luax_pushtype(L, "WheelJoint", PHYSICS_WHEEL_JOINT_T, j);
return 1;
}
@@ -366,7 +366,7 @@ int w_newRopeJoint(lua_State *L)
bool collideConnected = luax_optboolean(L, 8, false);
RopeJoint *j;
ASSERT_GUARD(j = instance->newRopeJoint(body1, body2, x1, y1, x2, y2, maxLength, collideConnected);)
luax_newtype(L, "RopeJoint", PHYSICS_ROPE_JOINT_T, (void *)j);
luax_pushtype(L, "RopeJoint", PHYSICS_ROPE_JOINT_T, j);
return 1;
}