From 2819d4f10d74d9e8aafb7423096c40153f510d9c Mon Sep 17 00:00:00 2001 From: halx99 Date: Mon, 3 Jan 2022 22:06:49 +0800 Subject: [PATCH] Improve vec2, vec3, vec4 lua storage a. store as fixed size array b. use metatable access via: x, y, z, w c. For vec2 - vec2[0] could be access via x or w(idth) or u - vec2[1] could be access via y or h(eight) or v --- .../manual/LuaBasicConversions.cpp | 182 +++++++++++++----- .../lua-bindings/manual/LuaBasicConversions.h | 6 +- .../manual/cocos2d/lua_cocos2dx_manual.cpp | 20 ++ .../manual/cocos2d/lua_cocos2dx_manual.hpp | 2 - .../lua-bindings/script/cocos2d/Cocos2d.lua | 83 ++++---- 5 files changed, 199 insertions(+), 94 deletions(-) diff --git a/extensions/scripting/lua-bindings/manual/LuaBasicConversions.cpp b/extensions/scripting/lua-bindings/manual/LuaBasicConversions.cpp index a17f5ee6a7..b447eca59a 100644 --- a/extensions/scripting/lua-bindings/manual/LuaBasicConversions.cpp +++ b/extensions/scripting/lua-bindings/manual/LuaBasicConversions.cpp @@ -359,15 +359,33 @@ bool luaval_to_vec2(lua_State* L, int lo, cocos2d::Vec2* outValue, const char* f ok = false; } + // assertion: since we only have vec2, you should never passing rect as vec2 to native + const auto objlen = lua_objlen(L, -1); + assert(objlen == 2); + if (ok) { lua_pushstring(L, "x"); lua_gettable(L, lo); + if (lua_isnil(L, -1)) + { + lua_pop(L, 1); + lua_pushstring(L, "width"); + lua_gettable(L, lo); + } + outValue->x = lua_isnil(L, -1) ? 0.0f : (float)lua_tonumber(L, -1); lua_pop(L, 1); lua_pushstring(L, "y"); lua_gettable(L, lo); + if (lua_isnil(L, -1)) + { + lua_pop(L, 1); + lua_pushstring(L, "height"); + lua_gettable(L, lo); + } + outValue->y = lua_isnil(L, -1) ? 0.0f : (float)lua_tonumber(L, -1); lua_pop(L, 1); } @@ -2079,54 +2097,53 @@ void vec2_array_to_luaval(lua_State* L, const cocos2d::Vec2* points, int count) } static int vec2_index(lua_State* L) -{ - // top is table - const char* name = lua_tostring(L, 2); - if (strcmp(name, "width") == 0) +{ // t k + const char signature = lua_tostring(L, 2)[0]; + int n = 0; + if (signature == 'x' || signature == 'w' || signature == 'u') { - lua_pop(L, 1); // pop the old name - lua_pushstring(L, "x"); + lua_pop(L, 1); // pop the string key + n = 1; } - else if (strcmp(name, "height") == 0) + else if (signature == 'y' || signature == 'h' || signature == 'v') { - lua_pop(L, 1); - lua_pushstring(L, "y"); + lua_pop(L, 1); // pop the string key + n = 2; } - lua_rawget(L, -2); + if (n) + lua_rawgeti(L, -1, n); + else + lua_pushnil(L); return 1; } static int vec2_newindex(lua_State* L) -{ - const char* name = lua_tostring(L, 2); - if (strcmp(name, "width") == 0) +{ // t k v + const char signature = lua_tostring(L, 2)[0]; + int n = 0; + if (signature == 'x' || signature == 'w' || signature == 'u') { - lua_remove(L, 2); - lua_pushstring(L, "x"); - lua_insert(L, 2); + lua_remove(L, 2); // remove the string key + n = 1; } - else if (strcmp(name, "height") == 0) + else if (signature == 'y' || signature == 'h' || signature == 'v') { - lua_remove(L, 2); - lua_pushstring(L, "y"); - lua_insert(L, 2); + lua_remove(L, 2); // remove the string key + n = 2; } - lua_rawset(L, -3); + if (n) + lua_rawseti(L, -2, n); return 0; } -void vec2_to_luaval(lua_State* L, const cocos2d::Vec2& vec2) +int vec2_to_luaval(lua_State* L, const cocos2d::Vec2& vec2) { - if (NULL == L) - return; - lua_newtable(L); /* L: table */ - lua_pushstring(L, "x"); /* L: table key */ + lua_createtable(L, 2, 0); /* L: table */ lua_pushnumber(L, (lua_Number)vec2.x); /* L: table key value*/ - lua_rawset(L, -3); /* table[key] = value, L: table */ - lua_pushstring(L, "y"); /* L: table key */ + lua_rawseti(L, -2, 1); /* table[key] = value, L: table */ lua_pushnumber(L, (lua_Number)vec2.y); /* L: table key value*/ - lua_rawset(L, -3); + lua_rawseti(L, -2, 2); int top = lua_gettop(L); luaL_getmetatable(L, "_vec2mt"); @@ -2140,43 +2157,102 @@ void vec2_to_luaval(lua_State* L, const cocos2d::Vec2& vec2) lua_setfield(L, -2, "__newindex"); } lua_setmetatable(L, -2); + + return 1; } -void vec3_to_luaval(lua_State* L, const cocos2d::Vec3& vec3) -{ - if (NULL == L) - return; +static int vec3_index(lua_State* L) +{ // t k + const char signature = lua_tostring(L, 2)[0]; + assert(signature >= 'x' || signature <= 'z'); + lua_pop(L, 1); // pop the string key + const int n = signature - 'x' + 1; + lua_rawgeti(L, -1, n); + return 1; +} +static int vec3_newindex(lua_State* L) +{ // t k v + const char signature = lua_tostring(L, 2)[0]; + assert(signature >= 'x' || signature <= 'z'); + lua_remove(L, 2); // remove the string key + const int n = signature - 'x' + 1; + lua_rawseti(L, -2, n); - lua_newtable(L); /* L: table */ - lua_pushstring(L, "x"); /* L: table key */ + return 0; +} + +int vec3_to_luaval(lua_State* L, const cocos2d::Vec3& vec3) +{ + lua_createtable(L, 3, 0); /* L: table */ lua_pushnumber(L, (lua_Number)vec3.x); /* L: table key value*/ - lua_rawset(L, -3); /* table[key] = value, L: table */ - lua_pushstring(L, "y"); /* L: table key */ + lua_rawseti(L, -2, 1); /* table[key] = value, L: table */ lua_pushnumber(L, (lua_Number)vec3.y); /* L: table key value*/ - lua_rawset(L, -3); - lua_pushstring(L, "z"); /* L: table key */ + lua_rawseti(L, -2, 2); lua_pushnumber(L, (lua_Number)vec3.z); /* L: table key value*/ - lua_rawset(L, -3); + lua_rawseti(L, -2, 3); + + int top = lua_gettop(L); + luaL_getmetatable(L, "_vec3mt"); + if (!lua_istable(L, -1)) + { + lua_settop(L, top); // restore stack + luaL_newmetatable(L, "_vec3mt"); + lua_pushcfunction(L, vec3_index); + lua_setfield(L, -2, "__index"); + lua_pushcfunction(L, vec3_newindex); + lua_setfield(L, -2, "__newindex"); + } + lua_setmetatable(L, -2); + + return 1; } -void vec4_to_luaval(lua_State* L, const cocos2d::Vec4& vec4) -{ - if (NULL == L) - return; +static int vec4_index(lua_State* L) +{ // t k + const char signature = lua_tostring(L, 2)[0]; + assert(signature >= 'w' || signature <= 'z'); + lua_pop(L, 1); // pop the string key + const int n = signature != 'w' ? signature - 'x' + 1 : 4; + lua_rawgeti(L, -1, n); + return 1; +} +static int vec4_newindex(lua_State* L) +{ // t k v + const char signature = lua_tostring(L, 2)[0]; + assert(signature >= 'w' || signature <= 'z'); + lua_remove(L, 2); // remove the string key + const int n = signature != 'w' ? signature - 'x' + 1 : 4; + lua_rawseti(L, -2, n); - lua_newtable(L); /* L: table */ - lua_pushstring(L, "x"); /* L: table key */ + return 0; +} + +int vec4_to_luaval(lua_State* L, const cocos2d::Vec4& vec4) +{ + lua_createtable(L, 4, 0); /* L: table */ lua_pushnumber(L, (lua_Number)vec4.x); /* L: table key value*/ - lua_rawset(L, -3); /* table[key] = value, L: table */ - lua_pushstring(L, "y"); /* L: table key */ + lua_rawseti(L, -2, 1); /* table[key] = value, L: table */ lua_pushnumber(L, (lua_Number)vec4.y); /* L: table key value*/ - lua_rawset(L, -3); - lua_pushstring(L, "z"); /* L: table key */ + lua_rawseti(L, -2, 2); lua_pushnumber(L, (lua_Number)vec4.z); /* L: table key value*/ - lua_rawset(L, -3); - lua_pushstring(L, "w"); /* L: table key */ + lua_rawseti(L, -2, 3); lua_pushnumber(L, (lua_Number)vec4.w); /* L: table key value*/ - lua_rawset(L, -3); + lua_rawseti(L, -2, 4); + + int top = lua_gettop(L); + luaL_getmetatable(L, "_vec4mt"); + if (!lua_istable(L, -1)) + { + lua_settop(L, top); // restore stack + luaL_newmetatable(L, "_vec4mt"); + lua_pushcfunction(L, vec4_index); + lua_setfield(L, -2, "__index"); + lua_pushcfunction(L, vec4_newindex); + lua_setfield(L, -2, "__newindex"); + } + lua_setmetatable(L, -2); + + return 1; } #if CC_USE_PHYSICS diff --git a/extensions/scripting/lua-bindings/manual/LuaBasicConversions.h b/extensions/scripting/lua-bindings/manual/LuaBasicConversions.h index d6665b5a70..25c9780cfa 100644 --- a/extensions/scripting/lua-bindings/manual/LuaBasicConversions.h +++ b/extensions/scripting/lua-bindings/manual/LuaBasicConversions.h @@ -897,7 +897,7 @@ extern bool luaval_to_std_map_string_string(lua_State* L, * @param L the current lua_State. * @param vec2 a cocos2d::Vec2 object. */ -extern void vec2_to_luaval(lua_State* L, const cocos2d::Vec2& vec2); +extern int vec2_to_luaval(lua_State* L, const cocos2d::Vec2& vec2); /** * Push a table converted from a cocos2d::Vec3 object into the Lua stack. @@ -906,7 +906,7 @@ extern void vec2_to_luaval(lua_State* L, const cocos2d::Vec2& vec2); * @param L the current lua_State. * @param vec3 a cocos2d::Vec3 object. */ -extern void vec3_to_luaval(lua_State* L, const cocos2d::Vec3& vec3); +extern int vec3_to_luaval(lua_State* L, const cocos2d::Vec3& vec3); /** * Push a table converted from a cocos2d::Vec4 object into the Lua stack. @@ -915,7 +915,7 @@ extern void vec3_to_luaval(lua_State* L, const cocos2d::Vec3& vec3); * @param L the current lua_State. * @param vec4 a cocos2d::Vec4 object. */ -extern void vec4_to_luaval(lua_State* L, const cocos2d::Vec4& vec4); +extern int vec4_to_luaval(lua_State* L, const cocos2d::Vec4& vec4); /** * Push a table converted from a cocos2d::Vec2 array into the Lua stack. diff --git a/extensions/scripting/lua-bindings/manual/cocos2d/lua_cocos2dx_manual.cpp b/extensions/scripting/lua-bindings/manual/cocos2d/lua_cocos2dx_manual.cpp index 1b8eb8f218..dc593d8a69 100644 --- a/extensions/scripting/lua-bindings/manual/cocos2d/lua_cocos2dx_manual.cpp +++ b/extensions/scripting/lua-bindings/manual/cocos2d/lua_cocos2dx_manual.cpp @@ -8188,6 +8188,23 @@ tolua_lerror: #endif } +static int tolua_cocos2d_Vec2_new(lua_State* L) +{ + return vec2_to_luaval(L, Vec2{static_cast(lua_tonumber(L, 1)), static_cast(lua_tonumber(L, 2))}); +} + +static int tolua_cocos2d_Vec3_new(lua_State* L) +{ + return vec3_to_luaval(L, Vec3{static_cast(lua_tonumber(L, 1)), static_cast(lua_tonumber(L, 2)), + static_cast(lua_tonumber(L, 3))}); +} + +static int tolua_cocos2d_Vec4_new(lua_State* L) +{ + return vec4_to_luaval(L, Vec4{static_cast(lua_tonumber(L, 1)), static_cast(lua_tonumber(L, 2)), + static_cast(lua_tonumber(L, 3)), static_cast(lua_tonumber(L, 4))}); +} + int register_all_cocos2dx_math_manual(lua_State* tolua_S) { if (nullptr == tolua_S) @@ -8205,6 +8222,9 @@ int register_all_cocos2dx_math_manual(lua_State* tolua_S) tolua_function(tolua_S, "mat4_createTranslation", tolua_cocos2d_Mat4_createTranslation); tolua_function(tolua_S, "mat4_createRotation", tolua_cocos2d_Mat4_createRotation); tolua_function(tolua_S, "vec3_cross", tolua_cocos2d_Vec3_cross); + tolua_function(tolua_S, "vec2_new", tolua_cocos2d_Vec2_new); + tolua_function(tolua_S, "vec3_new", tolua_cocos2d_Vec3_new); + tolua_function(tolua_S, "vec4_new", tolua_cocos2d_Vec4_new); tolua_endmodule(tolua_S); return 0; } diff --git a/extensions/scripting/lua-bindings/manual/cocos2d/lua_cocos2dx_manual.hpp b/extensions/scripting/lua-bindings/manual/cocos2d/lua_cocos2dx_manual.hpp index d8ab149f92..b001cb4f6e 100644 --- a/extensions/scripting/lua-bindings/manual/cocos2d/lua_cocos2dx_manual.hpp +++ b/extensions/scripting/lua-bindings/manual/cocos2d/lua_cocos2dx_manual.hpp @@ -58,8 +58,6 @@ USING_NS_CC; TOLUA_API int register_all_cocos2dx_manual(lua_State* tolua_S); -TOLUA_API int register_cocos2dx_event_releated(lua_State* tolua_S); - TOLUA_API int register_all_cocos2dx_module_manual(lua_State* tolua_S); TOLUA_API int register_all_cocos2dx_math_manual(lua_State* tolua_S); diff --git a/extensions/scripting/lua-bindings/script/cocos2d/Cocos2d.lua b/extensions/scripting/lua-bindings/script/cocos2d/Cocos2d.lua index 89cca9e918..08d1be92b3 100644 --- a/extensions/scripting/lua-bindings/script/cocos2d/Cocos2d.lua +++ b/extensions/scripting/lua-bindings/script/cocos2d/Cocos2d.lua @@ -1,6 +1,13 @@ cc = cc or {} +-- Native vec2_new use array[2] to store x,y w,h u,v performance is better +-- p[1] alias: x w u width +-- p[2] alias: y h v height +local nvec2 = vec2_new +local nvec3 = vec3_new +local nvec4 = vec4_new + function cc.clampf(value, min_inclusive, max_inclusive) -- body local temp = 0 @@ -19,33 +26,37 @@ function cc.clampf(value, min_inclusive, max_inclusive) end end ---Point -function cc.p(_x,_y) +--Vec2/Point +function cc.vec2(_x, _y) if nil == _y then - return { x = _x.x, y = _x.y } + return nvec2(_x.x, _x.y) else - return { x = _x, y = _y } + return nvec2(_x, _y) end + +end +function cc.p(_x, ...) + return cc.vec2(_x, ...) end function cc.pAdd(pt1,pt2) - return {x = pt1.x + pt2.x , y = pt1.y + pt2.y } + return cc.p(pt1.x + pt2.x , pt1.y + pt2.y ) end function cc.pSub(pt1,pt2) - return {x = pt1.x - pt2.x , y = pt1.y - pt2.y } + return cc.p(pt1.x - pt2.x , pt1.y - pt2.y ) end function cc.pMul(pt1,factor) - return { x = pt1.x * factor , y = pt1.y * factor } + return cc.p( pt1.x * factor , pt1.y * factor ) end function cc.pMidpoint(pt1,pt2) - return { x = (pt1.x + pt2.x) / 2.0 , y = ( pt1.y + pt2.y) / 2.0 } + return cc.p( (pt1.x + pt2.x) / 2.0 , ( pt1.y + pt2.y) / 2.0 ) end function cc.pForAngle(a) - return { x = math.cos(a), y = math.sin(a) } + return cc.p( math.cos(a), math.sin(a) ) end function cc.pGetLength(pt) @@ -55,10 +66,10 @@ end function cc.pNormalize(pt) local length = cc.pGetLength(pt) if 0 == length then - return { x = 1.0,y = 0.0 } + return cc.p( 1.0, 0.0 ) end - return { x = pt.x / length, y = pt.y / length } + return cc.p( pt.x / length, pt.y / length ) end function cc.pCross(self,other) @@ -119,23 +130,23 @@ function cc.pIsLineIntersect(A, B, C, D, s, t) end function cc.pPerp(pt) - return { x = -pt.y, y = pt.x } + return cc.p( -pt.y, pt.x ) end function cc.RPerp(pt) - return { x = pt.y, y = -pt.x } + return cc.p( pt.y, -pt.x ) end function cc.pProject(pt1, pt2) - return { x = pt2.x * (cc.pDot(pt1,pt2) / cc.pDot(pt2,pt2)) , y = pt2.y * (cc.pDot(pt1,pt2) / cc.pDot(pt2,pt2)) } + return cc.p( pt2.x * (cc.pDot(pt1,pt2) / cc.pDot(pt2,pt2)) , pt2.y * (cc.pDot(pt1,pt2) / cc.pDot(pt2,pt2)) ) end function cc.pRotate(pt1, pt2) - return { x = pt1.x * pt2.x - pt1.y * pt2.y, y = pt1.x * pt2.y + pt1.y * pt2.x } + return cc.p( pt1.x * pt2.x - pt1.y * pt2.y, pt1.x * pt2.y + pt1.y * pt2.x ) end function cc.pUnrotate(pt1, pt2) - return { x = pt1.x * pt2.x + pt1.y * pt2.y, pt1.y * pt2.x - pt1.x * pt2.y } + return cc.p( pt1.x * pt2.x + pt1.y * pt2.y, pt1.y * pt2.x - pt1.x * pt2.y ) end --Calculates the square length of pt function cc.pLengthSQ(pt) @@ -147,11 +158,11 @@ function cc.pDistanceSQ(pt1,pt2) end function cc.pGetClampPoint(pt1,pt2,pt3) - return { x = cc.clampf(pt1.x, pt2.x, pt3.x), y = cc.clampf(pt1.y, pt2.y, pt3.y) } + return cc.p( cc.clampf(pt1.x, pt2.x, pt3.x), cc.clampf(pt1.y, pt2.y, pt3.y) ) end function cc.pFromSize(sz) - return { x = sz.width, y = sz.height } + return cc.p( sz.width, sz.height ) end function cc.pLerp(pt1,pt2,alpha) @@ -192,7 +203,7 @@ function cc.pGetIntersectPoint(pt1,pt2,pt3,pt4) end --Size function cc.size( _width,_height ) - return { width = _width, height = _height } + return cc.p(_width, _height) end --Rect @@ -238,7 +249,7 @@ function cc.rectContainsPoint( rect, point ) local ret = false if (point.x >= rect.x) and (point.x <= rect.x + rect.width) and - (point.y >= rect.y) and (point.y <= rect.y + rect.height) then + (point.y >= rect.y) and (point.y <= rect.y + rect.height) then ret = true end @@ -247,9 +258,9 @@ end function cc.rectIntersectsRect( rect1, rect2 ) local intersect = not ( rect1.x > rect2.x + rect2.width or - rect1.x + rect1.width < rect2.x or - rect1.y > rect2.y + rect2.height or - rect1.y + rect1.height < rect2.y ) + rect1.x + rect1.width < rect2.x or + rect1.y > rect2.y + rect2.height or + rect1.y + rect1.height < rect2.y ) return intersect end @@ -340,17 +351,17 @@ end --Vertex2F function cc.vertex2F(_x,_y) - return { x = _x, y = _y } + return cc.vec2(_x, _y ) end --Vertex3F function cc.Vertex3F(_x,_y,_z) - return { x = _x, y = _y, z = _z } + return cc.vec3(_x, _y, _z) end --Tex2F function cc.tex2F(_u,_v) - return { u = _u, v = _v } + return cc.vec2( _u, _v ) end --PointSprite @@ -410,27 +421,27 @@ end --PhysicsMaterial function cc.PhysicsMaterial(_density, _restitution, _friction) - return { density = _density, restitution = _restitution, friction = _friction } + return { density = _density, restitution = _restitution, friction = _friction } end function cc.vec3(_x, _y, _z) - return { x = _x, y = _y, z = _z } + return nvec3( _x, _y, _z) end function cc.vec4(_x, _y, _z, _w) - return { x = _x, y = _y, z = _z, w = _w } + return nvec4( _x, _y, _z, _w ) end function cc.vec3add(vec3a, vec3b) - return {x = vec3a.x + vec3b.x, y = vec3a.y + vec3b.y, z = vec3a.z + vec3b.z} + return cc.vec3( vec3a.x + vec3b.x, vec3a.y + vec3b.y, vec3a.z + vec3b.z) end function cc.vec3sub(vec3a, vec3b) - return {x = vec3a.x - vec3b.x, y = vec3a.y - vec3b.y, z = vec3a.z - vec3b.z} + return cc.vec3( vec3a.x - vec3b.x, vec3a.y - vec3b.y, vec3a.z - vec3b.z) end function cc.vec3mul(vec3, factor) - return {x = vec3.x * factor, y = vec3.y * factor, z = vec3.z * factor} + return cc.vec3( vec3.x * factor, vec3.y * factor, vec3.z * factor) end function cc.vec3dot(vec3a, vec3b) @@ -453,7 +464,7 @@ function cc.vec3normalize(vec3) end function cc.quaternion(_x, _y ,_z,_w) - return { x = _x, y = _y, z = _z, w = _w } + return cc.vec4(_x, _y, _z, _w) end function cc.quaternion_createFromAxisAngle(axis, angle) @@ -521,9 +532,9 @@ end function cc.mat4.createIdentity() return cc.mat4.new(1.0 ,0.0, 0.0, 0.0, - 0.0, 1.0, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 1.0) + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0) end function cc.mat4.translate(self,vec3)