void LuaInterface::newEnvironment() { newTable(); // pushes the new environment table newTable(); // pushes the new environment metatable getGlobalEnvironment(); // pushes the global environment setField("__index"); // sets metatable __index to the global environment setMetatable(); // assigns environment metatable }
void newCachedPointer(lua_State* L, void* p, const char* mtName) { void** pp = static_cast<void**>(lua_newuserdata(L, sizeof(void*))); *pp = p; setMetatable(L, mtName); lua_pushlightuserdata(L, p); lua_pushvalue(L, -2); // re-push the full userdatum lua_rawset(L, -4); lua_remove(L, -2); // remove the cache table }
int LuaInterface::newSandboxEnv() { newTable(); // pushes the new environment table newTable(); // pushes the new environment metatable getRef(getGlobalEnvironment()); // pushes the global environment setField("__index"); // sets metatable __index to the global environment setMetatable(); // assigns environment metatable return ref(); // return a reference to the environment table }
void LuaInterface::pushObject(const LuaObjectPtr& obj) { // fills a new userdata with a new LuaObjectPtr pointer new(newUserdata(sizeof(LuaObjectPtr))) LuaObjectPtr(obj); // set the userdata metatable getGlobal(Fw::mkstr(obj->getClassName(), "_mt")); assert(!isNil()); setMetatable(); }
void LuaInterface::pushObject(const LuaObjectPtr& obj) { // fills a new userdata with a new LuaObjectPtr pointer new(newUserdata(sizeof(LuaObjectPtr))) LuaObjectPtr(obj); m_totalObjRefs++; obj->luaGetMetatable(); if(isNil()) g_logger.fatal(stdext::format("metatable for class '%s' not found, did you bind the C++ class?", obj->getClassName())); setMetatable(); }
void LuaInterface::pushCppFunction(const LuaCppFunction& func) { // create a pointer to func (this pointer will hold the function existence) new(newUserdata(sizeof(LuaCppFunctionPtr))) LuaCppFunctionPtr(new LuaCppFunction(func)); // sets the userdata __gc metamethod, needed to free the function pointer when it gets collected newTable(); pushCFunction(&LuaInterface::luaCollectCppFunction); setField("__gc"); setMetatable(); // actually pushes a C function callback that will call the cpp function pushCFunction(&LuaInterface::luaCppFunctionCallback, 1); }
bool newObjectType(lua_State* L, const char* mtName, const char* baseMTName, const luaL_Reg* methods, const char* visibleName) { assert(mtName != 0); bool newMT = luaL_newmetatable(L, mtName) != 0; // always pushes a metatable if (newMT) { // this metatable didn't already exist lua_pushvalue(L, -1); lua_setfield(L, -2, "__index"); if (methods != 0) luaL_register(L, 0, methods); if (baseMTName != 0) setMetatable(L, baseMTName); if (visibleName != 0) { lua_pushstring(L, visibleName); lua_setfield(L, -2, "_visibleName"); } } lua_pop(L, 1); // remove the result of luaL_newmetatable return newMT; }
void LuaInterface::createLuaState() { // creates lua state L = luaL_newstate(); if(!L) g_logger.fatal("Unable to create lua state"); // load lua standard libraries luaL_openlibs(L); // load bit32 lib for bitwise operations luaopen_bit32(L); // creates weak table newTable(); newTable(); pushString("v"); setField("__mode"); setMetatable(); m_weakTableRef = ref(); // installs script loader getGlobal("package"); getField("loaders"); pushCFunction(&LuaInterface::luaScriptLoader); rawSeti(5); pop(2); // replace dofile pushCFunction(&LuaInterface::lua_dofile); setGlobal("dofile"); // dofiles pushCFunction(&LuaInterface::lua_dofiles); setGlobal("dofiles"); // replace loadfile pushCFunction(&LuaInterface::lua_loadfile); setGlobal("loadfile"); }
/** * Apply U's metatable for the value at the top of the stack. */ template <typename U> static inline void apply_user_type_meta_table(State* state) { setMetatable(state, UserTypeReg<StripUserType<U>>::name.c_str()); }
void LuaInterface::registerClass(const std::string& className, const std::string& baseClass) { // creates the class table (that it's also the class methods table) newTable(); pushValue(); setGlobal(className); const int klass = getTop(); // creates the class fieldmethods table newTable(); pushValue(); setGlobal(className + "_fieldmethods"); int klass_fieldmethods = getTop(); // creates the class metatable newTable(); pushValue(); setGlobal(className + "_mt"); int klass_mt = getTop(); // set metatable metamethods pushCppFunction(&LuaInterface::luaObjectGetEvent); setField("__index", klass_mt); pushCppFunction(&LuaInterface::luaObjectSetEvent); setField("__newindex", klass_mt); pushCppFunction(&LuaInterface::luaObjectEqualEvent); setField("__eq", klass_mt); pushCppFunction(&LuaInterface::luaObjectCollectEvent); setField("__gc", klass_mt); // set some fields that will be used later in metatable pushValue(klass); setField("methods", klass_mt); pushValue(klass_fieldmethods); setField("fieldmethods", klass_mt); // redirect methods and fieldmethods to the base class ones if(!className.empty() && className != "LuaObject") { // the following code is what create classes hierarchy for lua, by reproducing: // DerivedClass = { __index = BaseClass } // DerivedClass_fieldmethods = { __index = BaseClass_methods } // redirect the class methods to the base methods pushValue(klass); newTable(); getGlobal(baseClass); setField("__index"); setMetatable(); pop(); // redirect the class fieldmethods to the base fieldmethods pushValue(klass_fieldmethods); newTable(); getGlobal(baseClass + "_fieldmethods"); setField("__index"); setMetatable(); pop(); } // pops klass, klass_mt, klass_fieldmethods pop(3); }