lovr.filesystem.getRequirePath; setRequirePath;

This commit is contained in:
bjorn 2018-03-11 16:25:21 -07:00
parent c0ebb8f873
commit 399544cf9d
3 changed files with 54 additions and 31 deletions

View File

@ -35,39 +35,16 @@ int l_lovrFilesystemLoad(lua_State* L);
// Loader to help Lua's require understand PhysFS.
static int filesystemLoader(lua_State* L) {
const char* module = luaL_checkstring(L, -1);
char* dot;
const char* module = luaL_gsub(L, lua_tostring(L, -1), ".", "?");
lua_pop(L, 2);
char path[LOVR_PATH_MAX];
strncpy(path, module, LOVR_PATH_MAX);
while ((dot = strchr(path, '.')) != NULL) {
*dot = '/';
}
const char* requirePath[] = {
"?.lua",
"?/init.lua"
};
for (size_t i = 0; i < sizeof(requirePath) / sizeof(char*); i++) {
char filename[LOVR_PATH_MAX];
char* sub = strchr(requirePath[i], '?');
memset(filename, 0, LOVR_PATH_MAX);
if (sub) {
int index = (int) (sub - requirePath[i]);
strncat(filename, requirePath[i], index);
strncat(filename, path, strlen(path));
strncat(filename, requirePath[i] + index + 1, strlen(requirePath[i]) - index);
if (lovrFilesystemIsFile(filename)) {
lua_pop(L, 1);
lua_pushstring(L, filename);
return l_lovrFilesystemLoad(L);
}
char* path; int i;
vec_foreach(lovrFilesystemGetRequirePath(), path, i) {
const char* filename = luaL_gsub(L, path, "?", module);
if (lovrFilesystemIsFile(filename)) {
return l_lovrFilesystemLoad(L);
}
lua_pop(L, 1);
}
return 0;
@ -176,6 +153,18 @@ int l_lovrFilesystemGetRealDirectory(lua_State* L) {
return 1;
}
int l_lovrFilesystemGetRequirePath(lua_State* L) {
vec_str_t* requirePath = lovrFilesystemGetRequirePath();
char* path; int i;
vec_foreach(requirePath, path, i) {
lua_pushstring(L, path);
lua_pushstring(L, ";");
}
lua_pop(L, 1);
lua_concat(L, requirePath->length * 2 - 1);
return 1;
}
int l_lovrFilesystemGetSaveDirectory(lua_State* L) {
lua_pushstring(L, lovrFilesystemGetSaveDirectory());
return 1;
@ -288,6 +277,17 @@ int l_lovrFilesystemSetIdentity(lua_State* L) {
return 0;
}
int l_lovrFilesystemSetRequirePath(lua_State* L) {
char* requirePath = strdup(luaL_checkstring(L, 1));
char* pattern;
lovrFilesystemClearRequirePath();
while ((pattern = strsep(&requirePath, ";")) != NULL) {
lovrFilesystemAddRequirePath(pattern);
}
free(requirePath);
return 0;
}
int l_lovrFilesystemUnmount(lua_State* L) {
const char* path = luaL_checkstring(L, 1);
lua_pushboolean(L, !lovrFilesystemUnmount(path));
@ -311,6 +311,7 @@ const luaL_Reg lovrFilesystem[] = {
{ "getIdentity", l_lovrFilesystemGetIdentity },
{ "getLastModified", l_lovrFilesystemGetLastModified },
{ "getRealDirectory", l_lovrFilesystemGetRealDirectory },
{ "getRequirePath", l_lovrFilesystemGetRequirePath },
{ "getSaveDirectory", l_lovrFilesystemGetSaveDirectory },
{ "getSize", l_lovrFilesystemGetSize },
{ "getSource", l_lovrFilesystemGetSource },
@ -323,6 +324,7 @@ const luaL_Reg lovrFilesystem[] = {
{ "newBlob", l_lovrFilesystemNewBlob },
{ "read", l_lovrFilesystemRead },
{ "remove", l_lovrFilesystemRemove },
{ "setRequirePath", l_lovrFilesystemSetRequirePath },
{ "setIdentity", l_lovrFilesystemSetIdentity },
{ "write", l_lovrFilesystemWrite },
{ NULL, NULL }

View File

@ -31,6 +31,9 @@ void lovrFilesystemInit(const char* arg0, const char* arg1) {
state.source = malloc(LOVR_PATH_MAX * sizeof(char));
state.identity = NULL;
state.isFused = true;
vec_init(&state.requirePath);
vec_push(&state.requirePath, "?.lua");
vec_push(&state.requirePath, "?/init.lua");
// Try to mount either an archive fused to the executable or an archive from the command line
lovrFilesystemGetExecutablePath(state.source, LOVR_PATH_MAX);
@ -54,10 +57,19 @@ void lovrFilesystemDestroy() {
free(state.source);
free(state.savePathFull);
free(state.savePathRelative);
vec_deinit(&state.requirePath);
PHYSFS_deinit();
memset(&state, 0, sizeof(FilesystemState));
}
void lovrFilesystemAddRequirePath(const char* path) {
vec_push(&state.requirePath, path);
}
void lovrFilesystemClearRequirePath() {
vec_clear(&state.requirePath);
}
int lovrFilesystemCreateDirectory(const char* path) {
return !PHYSFS_mkdir(path);
}
@ -132,6 +144,10 @@ const char* lovrFilesystemGetRealDirectory(const char* path) {
return PHYSFS_getRealDir(path);
}
vec_str_t* lovrFilesystemGetRequirePath() {
return &state.requirePath;
}
const char* lovrFilesystemGetSaveDirectory() {
return state.savePathFull;
}

View File

@ -1,3 +1,4 @@
#include "lib/vec/vec.h"
#include <stdio.h>
#include <stdbool.h>
@ -14,10 +15,13 @@ typedef struct {
char* savePathRelative;
char* savePathFull;
bool isFused;
vec_str_t requirePath;
} FilesystemState;
void lovrFilesystemInit(const char* arg0, const char* arg1);
void lovrFilesystemDestroy();
void lovrFilesystemAddRequirePath(const char* path);
void lovrFilesystemClearRequirePath();
int lovrFilesystemCreateDirectory(const char* path);
int lovrFilesystemGetAppdataDirectory(char* dest, unsigned int size);
void lovrFilesystemGetDirectoryItems(const char* path, getDirectoryItemsCallback callback, void* userdata);
@ -25,6 +29,7 @@ int lovrFilesystemGetExecutablePath(char* dest, unsigned int size);
const char* lovrFilesystemGetIdentity();
long lovrFilesystemGetLastModified(const char* path);
const char* lovrFilesystemGetRealDirectory(const char* path);
vec_str_t* lovrFilesystemGetRequirePath();
const char* lovrFilesystemGetSaveDirectory();
size_t lovrFilesystemGetSize(const char* path);
const char* lovrFilesystemGetSource();