// // Copyright (c) 2008-2014 the Urho3D project. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // #include "Precompiled.h" #include "Object.h" #include "Ptr.h" #include "tolua++.h" #include "ToluaUtils.h" const char* tolua_tourho3dstring(lua_State* L, int narg, const char* str) { const char* s = tolua_tostring(L, narg, str); return s ? s : ""; } const char* tolua_tourho3dstring(lua_State* L, int narg, const String& str) { return tolua_tourho3dstring(L, narg, str.CString()); } // Lua state to context mapping static HashMap contextMapping; void SetContext(lua_State* L, Context* context) { if (context == 0) contextMapping.Erase(L); else contextMapping[L] = context; } Context* GetContext(lua_State* L) { HashMap::ConstIterator i = contextMapping.Find(L); if (i == contextMapping.End()) { lua_State* L1 = lua_getmainthread(L); return (L == L1) ? 0 : GetContext(L1); } return i->second_; } template<> int ToluaIsVector(lua_State* L, int lo, const char* type, int def, tolua_Error* err) { if (lua_istable(L, lo)) { int length = lua_objlen(L, lo); for (int i = 1; i <= length; ++i) { lua_pushinteger(L, i); lua_gettable(L, lo); if (!lua_isstring(L, -1)) { lua_pop(L, 1); err->index = lo; err->array = 0; err->type = type; return 0; } lua_pop(L, 1); } return 1; } err->index = lo; err->array = 0; err->type = type; return 0; } template<> void* ToluaToVector(lua_State* L, int narg, void* def) { if (!lua_istable(L, narg)) return 0; static Vector result; result.Clear(); int length = lua_objlen(L, narg); for (int i = 1; i <= length; ++i) { lua_pushinteger(L, i); lua_gettable(L, narg); if (!lua_isstring(L, -1)) { lua_pop(L, 1); return 0; } String string = tolua_tourho3dstring(L, -1, ""); result.Push(string); lua_pop(L, 1); } return &result; } template<> int ToluaPushVector(lua_State* L, void* data, const char* type) { const Vector& vectorstring = *((const Vector*)data); lua_newtable(L); for (unsigned i = 0; i < vectorstring.Size(); ++i) { tolua_pushurho3dstring(L, vectorstring[i]); lua_rawseti(L, -2, i + 1); } return 1; } template<> int ToluaPushVector(lua_State* L, void* data, const char* type) { Vector& vector = *((Vector*)data); lua_newtable(L); for (unsigned i = 0; i < vector.Size(); ++i) { tolua_pushusertype(L, &vector[i], "StringHash"); lua_rawseti(L, -2, i + 1); } return 1; } template<> int ToluaIsPODVector(lua_State* L, int lo, const char* type, int def, tolua_Error* err) { if (lua_istable(L, lo)) { int length = lua_objlen(L, lo); for (int i = 1; i <= length; ++i) { lua_pushinteger(L, i); lua_gettable(L, lo); if (!lua_isnumber(L, -1)) { lua_pop(L, 1); err->index = lo; err->array = 0; err->type = type; return 0; } lua_pop(L, 1); } return 1; } err->index = lo; err->array = 0; err->type = type; return 0; } template<> int ToluaIsPODVector(lua_State* L, int lo, const char* type, int def, tolua_Error* err) { if (lua_istable(L, lo)) { int length = lua_objlen(L, lo); for (int i = 1; i <= length; ++i) { lua_pushinteger(L, i); lua_gettable(L, lo); if (!tolua_isusertype(L, -1, "Vector2", 0, err)) { lua_pop(L, 1); return 0; } lua_pop(L, 1); } return 1; } err->index = lo; err->array = 0; err->type = type; return 0; } template<> void* ToluaToPODVector(lua_State* L, int narg, void* def) { if (!lua_istable(L, narg)) return 0; static PODVector result; result.Clear(); int length = lua_objlen(L, narg); for (int i = 1; i <= length; ++i) { lua_pushinteger(L, i); lua_gettable(L, narg); if (!lua_isnumber(L, -1)) { lua_pop(L, 1); return 0; } unsigned value = (unsigned)tolua_tonumber(L, -1, 0); result.Push(value); lua_pop(L, 1); } return &result; } template<> void* ToluaToPODVector(lua_State* L, int narg, void* def) { if (!lua_istable(L, narg)) return 0; static PODVector result; result.Clear(); tolua_Error tolua_err; int length = lua_objlen(L, narg); for (int i = 1; i <= length; ++i) { lua_pushinteger(L, i); lua_gettable(L, narg); if (!tolua_isusertype(L, -1, "Vector2", 0, &tolua_err)) { lua_pop(L, 1); return 0; } Vector2* value = (Vector2*)tolua_touserdata(L, -1, 0); result.Push(*value); lua_pop(L, 1); } return &result; } template<> int ToluaPushPODVector(lua_State* L, void* data, const char*) { const PODVector& vector = *((const PODVector*)data); lua_newtable(L); for (unsigned i = 0; i < vector.Size(); ++i) { lua_pushinteger(L, vector[i]); lua_rawseti(L, -2, i + 1); } return 1; } template<> int ToluaPushPODVector(lua_State* L, void* data, const char*) { const PODVector& vector = *((const PODVector*)data); lua_newtable(L); for (unsigned i = 0; i < vector.Size(); ++i) { lua_pushinteger(L, vector[i]); lua_rawseti(L, -2, i + 1); } return 1; } template<> int ToluaPushPODVector(lua_State* L, void* data, const char*) { const PODVector& vector = *((const PODVector*)data); lua_newtable(L); for (unsigned i = 0; i < vector.Size(); ++i) { tolua_pushusertype(L, vector[i], "SoundSource"); lua_rawseti(L, -2, i + 1); } return 1; } template<> int ToluaPushPODVector(lua_State* L, void* data, const char*) { const PODVector& vector = *((const PODVector*)data); lua_newtable(L); for (unsigned i = 0; i < vector.Size(); ++i) { tolua_pushusertype(L, vector[i], "UIElement"); lua_rawseti(L, -2, i + 1); } return 1; } #ifdef URHO3D_PHYSICS template<> int ToluaPushPODVector(lua_State* L, void* data, const char*) { const PODVector& vector = *((const PODVector*)data); lua_newtable(L); for (unsigned i = 0; i < vector.Size(); ++i) { tolua_pushusertype(L, vector[i], "RigidBody"); lua_rawseti(L, -2, i + 1); } return 1; } #endif #ifdef URHO3D_URHO2D template<> int ToluaPushPODVector(lua_State* L, void* data, const char*) { const PODVector& vector = *((const PODVector*)data); lua_newtable(L); for (unsigned i = 0; i < vector.Size(); ++i) { tolua_pushusertype(L, vector[i], "RigidBody2D"); lua_rawseti(L, -2, i + 1); } return 1; } #endif template int tolua_pushurho3dpodvectorusertype(lua_State* L, const PODVector& vector, const char* typeName) { lua_newtable(L); for (unsigned i = 0; i < vector.Size(); ++i) { void* tolua_obj = Mtolua_new((T)(vector[i])); tolua_pushusertype(L, tolua_obj, typeName); tolua_register_gc(L,lua_gettop(L)); lua_rawseti(L, -2, i + 1); } return 1; } template<> int ToluaPushPODVector(lua_State* L, void* data, const char*) { return tolua_pushurho3dpodvectorusertype(L, *((const PODVector*)data), "Vector3"); } template<> int ToluaPushPODVector(lua_State* L, void* data, const char*) { return tolua_pushurho3dpodvectorusertype(L, *((const PODVector*)data), "IntVector2"); } template<> int ToluaPushPODVector(lua_State* L, void* data, const char*) { return tolua_pushurho3dpodvectorusertype(L, *((const PODVector*)data), "OctreeQueryResult"); } #ifdef URHO3D_PHYSICS template<> int ToluaPushPODVector(lua_State* L, void* data, const char*) { return tolua_pushurho3dpodvectorusertype(L, *((const PODVector*)data), "PhysicsRaycastResult"); } #endif #ifdef URHO3D_URHO2D template<> int ToluaPushPODVector(lua_State* L, void* data, const char*) { return tolua_pushurho3dpodvectorusertype(L, *((const PODVector*)data), "PhysicsRaycastResult2D"); } #endif template<> int ToluaPushPODVector(lua_State* L, void* data, const char*) { return tolua_pushurho3dpodvectorusertype(L, *((const PODVector*)data), "RayQueryResult"); } template<> int ToluaPushPODVector(lua_State* L, void* data, const char*) { const PODVector& vector = *((const PODVector*)data); lua_newtable(L); for (unsigned i = 0; i < vector.Size(); ++i) { tolua_pushusertype(L, vector[i], "Pass"); lua_rawseti(L, -2, i + 1); } return 1; } void ToluaPushObject(lua_State*L, void* data, const char* type) { tolua_pushusertype(L, data, data ? static_cast(data)->GetTypeName().CString() : type); }