Add a require path (much like package.path) to love.filesystem, allowing to override the searched file paths for require

--HG--
branch : minor
This commit is contained in:
Bart van Strien
2014-09-03 18:01:21 +02:00
parent 6f6bf6a2bb
commit ddf6816548
+55 -37
View File
@@ -28,6 +28,11 @@
// SDL
#include <SDL_loadso.h>
// STL
#include <vector>
#include <string>
#include <sstream>
namespace love
{
namespace filesystem
@@ -505,58 +510,69 @@ int w_isSymlink(lua_State *L)
return 1;
}
static std::vector<std::string> requirePath = {"?.lua", "?/init.lua"};
int w_getRequirePath(lua_State *L)
{
std::stringstream path;
bool seperator = false;
for (auto &element : requirePath)
{
if (seperator)
path << ";";
else
seperator = true;
path << element;
}
luax_pushstring(L, path.str());
return 1;
}
int w_setRequirePath(lua_State *L)
{
std::string element = luax_checkstring(L, 1);
requirePath.clear();
std::stringstream path;
path << element;
while(std::getline(path, element, ';'))
requirePath.push_back(element);
return 0;
}
int loader(lua_State *L)
{
const char *filename = lua_tostring(L, -1);
std::string modulename = luax_tostring(L, 1);
std::string tmp(filename);
tmp += ".lua";
int size = tmp.size();
for (int i=0; i<size-4; i++)
for (char &c : modulename)
{
if (tmp[i] == '.')
{
tmp[i] = '/';
}
if (c == '.')
c = '/';
}
// Check whether file exists.
if (instance()->isFile(tmp.c_str()))
auto *inst = instance();
for (std::string element : requirePath)
{
lua_pop(L, 1);
lua_pushstring(L, tmp.c_str());
// Ok, load it.
return w_load(L);
}
size_t pos = element.find('?');
if (pos == std::string::npos)
continue;
tmp = filename;
size = tmp.size();
for (int i=0; i<size; i++)
{
if (tmp[i] == '.')
{
tmp[i] = '/';
}
}
if (instance()->isDirectory(tmp.c_str()))
{
tmp += "/init.lua";
if (instance()->isFile(tmp.c_str()))
element.replace(pos, 1, modulename);
if (inst->isFile(element.c_str()))
{
lua_pop(L, 1);
lua_pushstring(L, tmp.c_str());
// Ok, load it.
lua_pushstring(L, element.c_str());
return w_load(L);
}
}
std::string errstr = "\n\tno file '%s' in LOVE game directories.";
errstr += errstr;
std::string errstr = "\n\tno '%s' in LOVE game directories.";
lua_pushfstring(L, errstr.c_str(), (tmp + ".lua").c_str(), (tmp + "/init.lua").c_str());
lua_pushfstring(L, errstr.c_str(), modulename.c_str());
return 1;
}
@@ -667,6 +683,8 @@ static const luaL_Reg functions[] =
{ "areSymlinksEnabled", w_areSymlinksEnabled },
{ "isSymlink", w_isSymlink },
{ "newFileData", w_newFileData },
{ "getRequirePath", w_getRequirePath },
{ "setRequirePath", w_setRequirePath },
{ 0, 0 }
};