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); }
int LuaInterface::safeCall(int numArgs, int numRets) { assert(hasIndex(-numArgs-1)); // saves the current stack size for calculating the number of results later int previousStackSize = stackSize(); // pushes error function int errorFuncIndex = previousStackSize - numArgs; pushCFunction(&LuaInterface::luaErrorHandler); insert(errorFuncIndex); // calls the function in protected mode (means errors will be caught) int ret = pcall(numArgs, LUA_MULTRET, errorFuncIndex); remove(errorFuncIndex); // remove error func // if there was an error throw an exception if(ret != 0) throw LuaException(popString()); int rets = (stackSize() + numArgs + 1) - previousStackSize; while(numRets != -1 && rets != numRets) { if(rets < numRets) { pushNil(); rets++; } else { pop(); rets--; } } // returns the number of results return rets; }
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"); }