//自定义lua的loader
void CCLuaStack::addLuaLoader(lua_CFunction func)
{
if (!func) return;
// stack content after the invoking of the function
// get loader table
lua_getglobal(m_state, "package"); /* L: package */
lua_getfield(m_state, -1, "loaders"); /* L: package, loaders */
// insert loader into index 2
lua_pushcfunction(m_state, func); /* L: package, loaders, func */
for (int i = lua_objlen(m_state, -2) + 1; i > 2; --i)
{
lua_rawgeti(m_state, -2, i - 1); /* L: package, loaders, func, function */
// we call lua_rawgeti, so the loader table now is at -3
lua_rawseti(m_state, -3, i); /* L: package, loaders, func */
}
lua_rawseti(m_state, -2, 2); /* L: package, loaders */
// set loaders into package
lua_setfield(m_state, -2, "loaders"); /* L: package */
lua_pop(m_state, 1);
}
void CCLuaStack::addLuaLoader(lua_CFunction func)
{
if (!func) return;
// stack content after the invoking of the function
// get loader table
lua_getglobal(m_state, "package"); /* L: package */
lua_getfield(m_state, -1, "loaders"); /* L: package, loaders */
// insert loader into index 2
lua_pushcfunction(m_state, func); /* L: package, loaders, func */
for (int i = lua_objlen(m_state, -2) + 1; i > 2; --i)
{
lua_rawgeti(m_state, -2, i - 1); /* L: package, loaders, func, function */
// we call lua_rawgeti, so the loader table now is at -3
lua_rawseti(m_state, -3, i); /* L: package, loaders, func */
}
lua_rawseti(m_state, -2, 2); /* L: package, loaders */
// set loaders into package
lua_setfield(m_state, -2, "loaders"); /* L: package */
lua_pop(m_state, 1);
}
int cocos2dx_lua_loader(lua_State *L)
{
static const std::string BYTECODE_FILE_EXT = ".luac";
static const std::string NOT_BYTECODE_FILE_EXT = ".lua";
std::string filename(luaL_checkstring(L, 1));
size_t pos = filename.rfind(BYTECODE_FILE_EXT);
if (pos != std::string::npos)
{
filename = filename.substr(0, pos);
}
else
{
pos = filename.rfind(NOT_BYTECODE_FILE_EXT);
if (pos == filename.length() - NOT_BYTECODE_FILE_EXT.length())
{
filename = filename.substr(0, pos);
}
}
pos = filename.find_first_of(".");
while (pos != std::string::npos)
{
filename.replace(pos, 1, "/");
pos = filename.find_first_of(".");
}
//search file in package.path
unsigned char* chunk = NULL;
unsigned long chunkSize = 0;
std::string chunkName = "";
CCFileUtils* utils = CCFileUtils::sharedFileUtils();
lua_getglobal(L, "package");
lua_getfield(L, -1, "path");
std::string searchpath(lua_tostring(L, -1));
lua_pop(L, 1);
size_t begin = 0;
size_t next = searchpath.find_first_of(";", 0);
do
{
if (next == std::string::npos)
next = searchpath.length();
std::string prefix = searchpath.substr(begin, next);
if (prefix[0] == '.' && prefix[1] == '/')
{
prefix = prefix.substr(2);
}
pos = prefix.find("?.lua");
chunkName = prefix.substr(0, pos) + filename + BYTECODE_FILE_EXT;
if (utils->isFileExist(chunkName))
{
chunk = utils->getFileData(chunkName.c_str(), "rb", &chunkSize);
break;
}
else
{
chunkName = prefix.substr(0, pos) + filename + NOT_BYTECODE_FILE_EXT;
if (utils->isFileExist(chunkName))
{
chunk = utils->getFileData(chunkName.c_str(), "rb", &chunkSize);
break;
}
}
begin = next + 1;
next = searchpath.find_first_of(";", begin);
}while ( begin < (size_t)searchpath.length());
if (NULL != chunk)
{
CCLuaStack* stack = CCLuaEngine::defaultEngine()->getLuaStack();
stack->luaLoadBuffer(L, (char*)chunk, (int)chunkSize, chunkName.c_str());
free(chunk);
}
else
{
CCLog("can not get file data of %s", filename.c_str());
}
return 1;
}