LuaObject Lua::GetGlobalTable(const string& _strTableName, const bool _bCreate, LuaStatePtr _pState) { _pState = (NULL == _pState) ? s_pState : _pState; LuaObject lTable = _pState->GetGlobal(_strTableName.c_str()); if ((false != lTable.IsNil()) && (false != _bCreate)) { lTable = _pState->GetGlobals().CreateTable(_strTableName.c_str()); } return lTable; }
void LoggerSingleton::LoggerBinder::reg( LuaStatePtr state ) { using namespace luabind; module( state.get() ) [ def( "log", &LoggerSingleton::LoggerBinder::logWrapper ) ]; }
TEST(UserDataTest, MethodsOnly) { auto L = GL.get(); const char chunk[] = "return function(obj)\n" " return obj:value()\n" "end\n"; ASSERT_EQ(0, luaL_loadstring(L, chunk)); ASSERT_EQ(0, lua_pcall(L, 0, 1, 0)) << luaGetChecked<folly::StringPiece>(L, -1); pushUserData<TestObjectMethodsOnly>(L); ASSERT_EQ(0, lua_pcall(L, 1, 1, 0)) << luaGetChecked<folly::StringPiece>(L, -1); EXPECT_EQ(42, luaGetChecked<int>(L, -1)); lua_pop(L, 1); }
TEST(UserDataTest, Destruction) { TestObject::destructorCalled = false; TestObject::gcCalled = false; auto L = GL.get(); auto& obj = pushUserData<TestObject>(L, 42); EXPECT_EQ(42, obj.x); auto p = getUserData<TestObject>(L, -1); EXPECT_EQ(&obj, p); EXPECT_FALSE(TestObject::gcCalled); EXPECT_FALSE(TestObject::destructorCalled); lua_pop(L, 1); lua_gc(L, LUA_GCCOLLECT, 0); lua_gc(L, LUA_GCCOLLECT, 0); EXPECT_TRUE(TestObject::gcCalled); EXPECT_TRUE(TestObject::destructorCalled); }
TEST(SimpleObjectTest, Simple) { auto L = GL.get(); auto& obj = pushObject<SimpleTestObject>(L, 42); EXPECT_EQ(42, obj.x); EXPECT_EQ(&obj, getObject<SimpleTestObject>(L, -1)); EXPECT_EQ(&obj, &getObjectChecked<SimpleTestObject>(L, -1)); lua_gc(L, LUA_GCCOLLECT, 0); lua_gc(L, LUA_GCCOLLECT, 0); EXPECT_FALSE(SimpleTestObject::destructorCalled); lua_pop(L, 1); lua_gc(L, LUA_GCCOLLECT, 0); lua_gc(L, LUA_GCCOLLECT, 0); EXPECT_TRUE(SimpleTestObject::destructorCalled); }
TEST(UserDataTest, MethodsAndIndex) { auto L = GL.get(); const char chunk[] = "return function(obj)\n" " obj.y = 100\n" " return obj:value(), #obj, obj.y\n" "end\n"; ASSERT_EQ(0, luaL_loadstring(L, chunk)); ASSERT_EQ(0, lua_pcall(L, 0, 1, 0)) << luaGetChecked<folly::StringPiece>(L, -1); pushUserData<TestObject>(L, 42); ASSERT_EQ(0, lua_pcall(L, 1, 3, 0)) << luaGetChecked<folly::StringPiece>(L, -1); EXPECT_EQ(42, luaGetChecked<int>(L, -3)); EXPECT_EQ(10, luaGetChecked<int>(L, -2)); EXPECT_EQ(100, luaGetChecked<int>(L, -1)); lua_pop(L, 3); }
void Lua::OutputError(const int _sErrorCode, LuaStatePtr _pState) { const char* szMsg = lua_tostring(_pState->GetCState(), -1); if (NULL == szMsg) { szMsg = "(error with no message)"; } switch (_sErrorCode) { case LUA_ERRERR: { vsoutput("LUA_ERRERR : error while running the error handler function (%s)\n", szMsg); break; } case LUA_ERRFILE: { vsoutput("LUA_ERRFILE : file error (%s)\n", szMsg); break; } case LUA_ERRMEM: { vsoutput("LUA_ERRMEM : memory allocation error (%s)\n", szMsg); break; } case LUA_ERRRUN: { vsoutput("LUA_ERRRUN : runtime error (%s)\n", szMsg); break; } case LUA_ERRSYNTAX: { vsoutput("LUA_ERRSYNTAX : syntax error during pre-compilation (%s)\n", szMsg); break; } default: { vsoutput("%s\n", szMsg); break; } } }
void OsgAppProxy::bindToLua(LuaStatePtr & state) { // Bind this class if (state) { #ifdef VERBOSE VRJLUA_MSG_START(dbgVRJLUA_PROXY, MSG_STATUS) << "Registering vrj.OsgAppProxy with Lua" << VRJLUA_MSG_END(dbgVRJLUA_PROXY, MSG_STATUS); #endif using namespace luabind; module(state.get(), "vrjApp") [ class_<OsgAppProxy>("OsgAppProxy") .def(constructor<>()) .def("setAppDelegate", & OsgAppProxy::setAppDelegate) .def("getAppDelegate", & OsgAppProxy::getAppDelegate) .def("setActiveApplication", & OsgAppProxy::setActiveApplication) .def("getScene", & OsgAppProxy::getScene) .def("getTimeDelta", & OsgAppProxy::getTimeDelta) ]; } }
bool Lua::Loadfile(const string& _strFileName, LuaStatePtr _pState) { FilePtr pFile = FS::GetRoot()->OpenFile(_strFileName, FS::EOpenMode_READTEXT); bool bResult = (NULL != pFile); if (false != bResult) { int sSize = pFile->Size(); char* pSourceCode = new char[sSize + 1]; sSize = pFile->Read(pSourceCode, sSize); FS::GetRoot()->CloseFile(pFile); pSourceCode[sSize] = '\0'; _pState = (NULL == _pState) ? s_pState : _pState; const int sResult = _pState->DoString(pSourceCode); bResult = (0 == sResult); delete[] pSourceCode; if (false == bResult) { OutputError(sResult, _pState); } } return bResult; }
SynchronizedRunBuffer::SynchronizedRunBuffer(LuaStatePtr const& state) : _init(false) { /// @todo own this state? How? _state = state.get(); }
void LuaPath::addLuaRequirePath(LuaStatePtr state, std::string const& dirEndingInSlash) { LuaSearchPathUpdater searchpath(state.get()); searchpath.extend(SearchDirectory(dirEndingInSlash)); }
namespace fblualib { namespace test { LuaStatePtr GL; class TestObject { public: static bool gcCalled; static bool destructorCalled; explicit TestObject(int x) : x(x), y(0) { } virtual ~TestObject() { destructorCalled = true; } int luaLen(lua_State* L); int luaValue(lua_State* L); int luaIndex(lua_State* L); int luaNewIndex(lua_State* L); int luaGC(lua_State* L); virtual int luaFoo(lua_State* L); int x; int y; }; int TestObject::luaLen(lua_State* L) { luaPush(L, 10); return 1; } int TestObject::luaValue(lua_State* L) { luaPush(L, x); return 1; } int TestObject::luaIndex(lua_State* L) { auto arg = luaGet<folly::StringPiece>(L, 2); if (arg && *arg == "y") { luaPush(L, y); } else { lua_pushnil(L); } return 1; } int TestObject::luaNewIndex(lua_State* L) { auto arg = luaGet<folly::StringPiece>(L, 2); if (arg && *arg == "y") { y = luaGetChecked<int>(L, 3); } else { luaL_error(L, "Invalid field"); } return 1; } int TestObject::luaFoo(lua_State* L) { lua_pushstring(L, "base"); return 1; } int TestObject::luaGC(lua_State* /*L*/) { gcCalled = true; return 0; } bool TestObject::destructorCalled = false; bool TestObject::gcCalled = false; TEST(UserDataTest, Destruction) { TestObject::destructorCalled = false; TestObject::gcCalled = false; auto L = GL.get(); auto& obj = pushUserData<TestObject>(L, 42); EXPECT_EQ(42, obj.x); auto p = getUserData<TestObject>(L, -1); EXPECT_EQ(&obj, p); EXPECT_FALSE(TestObject::gcCalled); EXPECT_FALSE(TestObject::destructorCalled); lua_pop(L, 1); lua_gc(L, LUA_GCCOLLECT, 0); lua_gc(L, LUA_GCCOLLECT, 0); EXPECT_TRUE(TestObject::gcCalled); EXPECT_TRUE(TestObject::destructorCalled); } TEST(UserDataTest, MethodsAndIndex) { auto L = GL.get(); const char chunk[] = "return function(obj)\n" " obj.y = 100\n" " return obj:value(), #obj, obj.y\n" "end\n"; ASSERT_EQ(0, luaL_loadstring(L, chunk)); ASSERT_EQ(0, lua_pcall(L, 0, 1, 0)) << luaGetChecked<folly::StringPiece>(L, -1); pushUserData<TestObject>(L, 42); ASSERT_EQ(0, lua_pcall(L, 1, 3, 0)) << luaGetChecked<folly::StringPiece>(L, -1); EXPECT_EQ(42, luaGetChecked<int>(L, -3)); EXPECT_EQ(10, luaGetChecked<int>(L, -2)); EXPECT_EQ(100, luaGetChecked<int>(L, -1)); lua_pop(L, 3); } // The code paths are different if we have __index or not. class TestObjectMethodsOnly { public: explicit TestObjectMethodsOnly() : y(42) { } int luaValue(lua_State* L); int y; }; int TestObjectMethodsOnly::luaValue(lua_State* L) { luaPush(L, y); return 1; } TEST(UserDataTest, MethodsOnly) { auto L = GL.get(); const char chunk[] = "return function(obj)\n" " return obj:value()\n" "end\n"; ASSERT_EQ(0, luaL_loadstring(L, chunk)); ASSERT_EQ(0, lua_pcall(L, 0, 1, 0)) << luaGetChecked<folly::StringPiece>(L, -1); pushUserData<TestObjectMethodsOnly>(L); ASSERT_EQ(0, lua_pcall(L, 1, 1, 0)) << luaGetChecked<folly::StringPiece>(L, -1); EXPECT_EQ(42, luaGetChecked<int>(L, -1)); lua_pop(L, 1); } struct SimpleTestObject { static bool destructorCalled; int x; explicit SimpleTestObject(int x) : x(x) { } ~SimpleTestObject() { destructorCalled = true; } }; bool SimpleTestObject::destructorCalled = false; TEST(SimpleObjectTest, Simple) { auto L = GL.get(); auto& obj = pushObject<SimpleTestObject>(L, 42); EXPECT_EQ(42, obj.x); EXPECT_EQ(&obj, getObject<SimpleTestObject>(L, -1)); EXPECT_EQ(&obj, &getObjectChecked<SimpleTestObject>(L, -1)); lua_gc(L, LUA_GCCOLLECT, 0); lua_gc(L, LUA_GCCOLLECT, 0); EXPECT_FALSE(SimpleTestObject::destructorCalled); lua_pop(L, 1); lua_gc(L, LUA_GCCOLLECT, 0); lua_gc(L, LUA_GCCOLLECT, 0); EXPECT_TRUE(SimpleTestObject::destructorCalled); } namespace { class TestDerived1 : public TestObject { public: static bool derivedDestructorCalled; TestDerived1(int xv, int zv) : TestObject(xv), z(zv) { } ~TestDerived1() override { derivedDestructorCalled = true; } int luaFoo(lua_State* L) override; int luaBar(lua_State* L); int luaValue(lua_State* L); int z; }; int TestDerived1::luaBar(lua_State* L) { lua_pushstring(L, "bar"); return 1; } int TestDerived1::luaFoo(lua_State* L) { lua_pushstring(L, "derived"); return 1; } int TestDerived1::luaValue(lua_State* L) { lua_pushinteger(L, z); return 1; } bool TestDerived1::derivedDestructorCalled = false; } // namespace }} // namespaces