Browse Source

improve performance of love.graphics.draw's Lua binding code.

Sasha Szpakowski 1 year ago
parent
commit
95796caa06

+ 15 - 8
src/common/runtime.h

@@ -629,22 +629,29 @@ T *luax_optmodule(lua_State *L)
 }
 
 /**
- * Converts the value at idx to the specified type without checking that
- * this conversion is valid. If the type has been previously verified with
- * luax_istype, then this can be safely used. Otherwise, use luax_checktype.
+ * Converts the value at idx to the specified type. Returns null if the type
+ * doesn't match.
  * @param L The Lua state.
  * @param idx The index on the stack.
  * @param type The type of the object.
  **/
 template <typename T>
-T *luax_totype(lua_State *L, int idx, const love::Type& /*type*/)
+T *luax_totype(lua_State *L, int idx, const love::Type &type)
 {
-	T *o = (T *)(((Proxy *)lua_touserdata(L, idx))->object);
+	if (lua_type(L, idx) != LUA_TUSERDATA)
+		return nullptr;
 
-	if (o == nullptr)
-		luaL_error(L, "Cannot use object after it has been released.");
+	Proxy *p = (Proxy *) lua_touserdata(L, idx);
+
+	if (p->type != nullptr && p->type->isa(type))
+	{
+		if (p->object == nullptr)
+			luaL_error(L, "Cannot use object after it has been released.");
+
+		return (T *) p->object;
+	}
 
-	return o;
+	return nullptr;
 }
 
 template <typename T>

+ 5 - 6
src/modules/graphics/wrap_Graphics.cpp

@@ -3138,13 +3138,12 @@ int w_draw(lua_State *L)
 {
 	Drawable *drawable = nullptr;
 	Texture *texture = nullptr;
-	Quad *quad = nullptr;
+	Quad *quad = luax_totype<Quad>(L, 2);
 	int startidx = 2;
 
-	if (luax_istype(L, 2, Quad::type))
+	if (quad != nullptr)
 	{
 		texture = luax_checktexture(L, 1);
-		quad = luax_totype<Quad>(L, 2);
 		startidx = 3;
 	}
 	else if (lua_isnil(L, 2) && !lua_isnoneornil(L, 3))
@@ -3174,14 +3173,14 @@ int w_draw(lua_State *L)
 int w_drawLayer(lua_State *L)
 {
 	Texture *texture = luax_checktexture(L, 1);
-	Quad *quad = nullptr;
 	int layer = (int) luaL_checkinteger(L, 2) - 1;
+
 	int startidx = 3;
+	Quad *quad = luax_totype<Quad>(L, startidx);
 
-	if (luax_istype(L, startidx, Quad::type))
+	if (quad != nullptr)
 	{
 		texture = luax_checktexture(L, 1);
-		quad = luax_totype<Quad>(L, startidx);
 		startidx++;
 	}
 	else if (lua_isnil(L, startidx) && !lua_isnoneornil(L, startidx + 1))

+ 5 - 10
src/modules/graphics/wrap_SpriteBatch.cpp

@@ -35,13 +35,10 @@ SpriteBatch *luax_checkspritebatch(lua_State *L, int idx)
 
 static inline int w_SpriteBatch_add_or_set(lua_State *L, SpriteBatch *t, int startidx, int index)
 {
-	Quad *quad = nullptr;
+	Quad *quad = luax_totype<Quad>(L, startidx);
 
-	if (luax_istype(L, startidx, Quad::type))
-	{
-		quad = luax_totype<Quad>(L, startidx);
+	if (quad != nullptr)
 		startidx++;
-	}
 	else if (lua_isnil(L, startidx) && !lua_isnoneornil(L, startidx + 1))
 		return luax_typerror(L, startidx, "Quad");
 
@@ -61,15 +58,13 @@ static inline int w_SpriteBatch_add_or_set(lua_State *L, SpriteBatch *t, int sta
 
 static int w_SpriteBatch_addLayer_or_setLayer(lua_State *L, SpriteBatch *t, int startidx, int index)
 {
-	Quad *quad = nullptr;
 	int layer = (int) luaL_checkinteger(L, startidx) - 1;
 	startidx++;
 
-	if (luax_istype(L, startidx, Quad::type))
-	{
-		quad = luax_totype<Quad>(L, startidx);
+	Quad *quad = luax_totype<Quad>(L, startidx);
+
+	if (quad != nullptr)
 		startidx++;
-	}
 	else if (lua_isnil(L, startidx) && !lua_isnoneornil(L, startidx + 1))
 		return luax_typerror(L, startidx, "Quad");
 

+ 17 - 6
src/modules/graphics/wrap_SpriteBatch.h

@@ -32,22 +32,33 @@ namespace graphics
 template <typename T>
 static void luax_checkstandardtransform(lua_State *L, int idx, const T &func)
 {
-	if (luax_istype(L, idx, math::Transform::type))
+	math::Transform *tf = luax_totype<math::Transform>(L, idx);
+	if (tf != nullptr)
 	{
-		math::Transform *tf = luax_totype<math::Transform>(L, idx);
 		func(tf->getMatrix());
 	}
 	else
 	{
+		int nargs = lua_gettop(L);
 		float x  = (float) luaL_optnumber(L, idx + 0, 0.0);
 		float y  = (float) luaL_optnumber(L, idx + 1, 0.0);
 		float a  = (float) luaL_optnumber(L, idx + 2, 0.0);
 		float sx = (float) luaL_optnumber(L, idx + 3, 1.0);
 		float sy = (float) luaL_optnumber(L, idx + 4, sx);
-		float ox = (float) luaL_optnumber(L, idx + 5, 0.0);
-		float oy = (float) luaL_optnumber(L, idx + 6, 0.0);
-		float kx = (float) luaL_optnumber(L, idx + 7, 0.0);
-		float ky = (float) luaL_optnumber(L, idx + 8, 0.0);
+		float ox = 0.0f;
+		float oy = 0.0f;
+		if (nargs >= idx + 5)
+		{
+			ox = (float) luaL_optnumber(L, idx + 5, 0.0);
+			oy = (float) luaL_optnumber(L, idx + 6, 0.0);
+		}
+		float kx = 0.0f;
+		float ky = 0.0f;
+		if (nargs >= idx + 7)
+		{
+			kx = (float) luaL_optnumber(L, idx + 7, 0.0);
+			ky = (float) luaL_optnumber(L, idx + 8, 0.0);
+		}
 		func(Matrix4(x, y, a, sx, sy, ox, oy, kx, ky));
 	}
 }