Filesystem utility functions;

This commit is contained in:
bjorn 2016-11-07 14:30:32 -08:00
parent 7362fafd8c
commit 419a03a202
5 changed files with 169 additions and 23 deletions

View File

@ -1,14 +1,20 @@
#include "filesystem.h" #include "filesystem.h"
#include "../util.h" #include "../util.h"
#include <physfs.h> #include <physfs.h>
#include <stdio.h>
#ifdef __APPLE__ #ifdef __APPLE__
#include <mach-o/dyld.h> #include <mach-o/dyld.h>
#endif #endif
static FilesystemState state;
void lovrFilesystemInit(const char* arg0) { void lovrFilesystemInit(const char* arg0) {
if (!PHYSFS_init(arg0)) { if (!PHYSFS_init(arg0)) {
error("Could not initialize filesystem: %s", PHYSFS_getLastError()); error("Could not initialize filesystem: %s", PHYSFS_getLastError());
} }
state.gameSource = NULL;
state.identity = NULL;
} }
void lovrFilesystemDestroy() { void lovrFilesystemDestroy() {
@ -19,16 +25,38 @@ int lovrFilesystemExists(const char* path) {
return PHYSFS_exists(path); return PHYSFS_exists(path);
} }
const char* lovrFilesystemGetExecutablePath() { int lovrFilesystemGetExecutablePath(char* dest, unsigned int size) {
#ifdef __APPLE__ #ifdef __APPLE__
char* path = malloc(1024); if (_NSGetExecutablePath(dest, &size) == 0) {
uint32_t size = sizeof(path); return 0;
if (_NSGetExecutablePath(path, &size) == 0) {
return path;
} }
#endif #endif
return NULL; return 1;
}
const char* lovrFilesystemGetIdentity() {
return state.identity;
}
const char* lovrFilesystemGetRealDirectory(const char* path) {
if (!PHYSFS_isInit()) {
return NULL;
}
return PHYSFS_getRealDir(path);
}
const char* lovrFilesystemGetSource() {
return state.gameSource;
}
const char* lovrFilesystemGetUserDirectory() {
if (!PHYSFS_isInit()) {
return NULL;
}
return PHYSFS_getUserDir();
} }
int lovrFilesystemIsDirectory(const char* path) { int lovrFilesystemIsDirectory(const char* path) {
@ -40,6 +68,9 @@ int lovrFilesystemIsFile(const char* path) {
} }
void* lovrFilesystemRead(const char* path, int* bytesRead) { void* lovrFilesystemRead(const char* path, int* bytesRead) {
if (!PHYSFS_isInit()) {
return NULL;
}
// Open file // Open file
PHYSFS_file* handle = PHYSFS_openRead(path); PHYSFS_file* handle = PHYSFS_openRead(path);
@ -72,6 +103,44 @@ void* lovrFilesystemRead(const char* path, int* bytesRead) {
return data; return data;
} }
int lovrFilesystemSetSource(const char* source) { int lovrFilesystemSetIdentity(const char* identity) {
return PHYSFS_mount(source, NULL, 0); state.identity = identity;
// Unmount old write directory
if (state.savePathFull && state.savePathRelative) {
PHYSFS_removeFromSearchPath(state.savePathRelative);
} else {
state.savePathRelative = malloc(LOVR_PATH_MAX);
state.savePathFull = malloc(LOVR_PATH_MAX);
}
// Set new write directory
#ifdef __APPLE__
const char* userDir = PHYSFS_getUserDir();
PHYSFS_setWriteDir(userDir);
snprintf(state.savePathRelative, LOVR_PATH_MAX, "Library/Application Support/LOVR/%s", identity);
PHYSFS_mkdir(state.savePathRelative);
snprintf(state.savePathFull, LOVR_PATH_MAX, "%s%s", userDir, state.savePathRelative);
if (PHYSFS_setWriteDir(state.savePathFull)) {
PHYSFS_mount(state.savePathFull, NULL, 0);
return 0;
}
#endif
return 1;
}
int lovrFilesystemSetSource(const char* source) {
if (state.gameSource) {
return 1;
}
if (PHYSFS_mount(source, NULL, 0)) {
state.gameSource = source;
return 0;
}
return 1;
} }

View File

@ -1,8 +1,27 @@
#ifndef LOVR_FILESYSTEM_TYPES
#define LOVR_FILESYSTEM_TYPES
#define LOVR_PATH_MAX 1024
typedef struct {
const char* gameSource;
const char* identity;
char* savePathRelative;
char* savePathFull;
} FilesystemState;
#endif
void lovrFilesystemInit(const char* arg0); void lovrFilesystemInit(const char* arg0);
void lovrFilesystemDestroy(); void lovrFilesystemDestroy();
int lovrFilesystemExists(const char* path); int lovrFilesystemExists(const char* path);
const char* lovrFilesystemGetExecutablePath(); int lovrFilesystemGetExecutablePath(char* dest, unsigned int size);
const char* lovrFilesystemGetIdentity();
const char* lovrFilesystemGetRealDirectory(const char* path);
const char* lovrFilesystemGetSource();
const char* lovrFilesystemGetUserDirectory();
int lovrFilesystemIsDirectory(const char* path); int lovrFilesystemIsDirectory(const char* path);
int lovrFilesystemIsFile(const char* path); int lovrFilesystemIsFile(const char* path);
void* lovrFilesystemRead(const char* path, int* bytesRead); void* lovrFilesystemRead(const char* path, int* bytesRead);
int lovrFilesystemSetIdentity(const char* identity);
int lovrFilesystemSetSource(const char* source); int lovrFilesystemSetSource(const char* source);

View File

@ -67,6 +67,8 @@ void lovrInit(lua_State* L, int argc, char** argv) {
" end " " end "
"end " "end "
"lovr.filesystem.setIdentity(conf.identity or 'default') "
"function lovr.run() " "function lovr.run() "
" if lovr.load then lovr.load() end " " if lovr.load then lovr.load() end "
" while true do " " while true do "

View File

@ -51,9 +51,14 @@ const luaL_Reg lovrFilesystem[] = {
{ "init", l_lovrFilesystemInitialize }, { "init", l_lovrFilesystemInitialize },
{ "exists", l_lovrFilesystemExists }, { "exists", l_lovrFilesystemExists },
{ "getExecutablePath", l_lovrFilesystemGetExecutablePath }, { "getExecutablePath", l_lovrFilesystemGetExecutablePath },
{ "getIdentity", l_lovrFilesystemGetIdentity },
{ "getRealDirectory", l_lovrFilesystemGetRealDirectory },
{ "getSource", l_lovrFilesystemGetSource },
{ "getUserDirectory", l_lovrFilesystemGetUserDirectory },
{ "isDirectory", l_lovrFilesystemIsDirectory }, { "isDirectory", l_lovrFilesystemIsDirectory },
{ "isFile", l_lovrFilesystemIsFile }, { "isFile", l_lovrFilesystemIsFile },
{ "read", l_lovrFilesystemRead }, { "read", l_lovrFilesystemRead },
{ "setIdentity", l_lovrFilesystemSetIdentity },
{ "setSource", l_lovrFilesystemSetSource }, { "setSource", l_lovrFilesystemSetSource },
{ NULL, NULL } { NULL, NULL }
}; };
@ -88,10 +93,22 @@ int l_lovrFilesystemExists(lua_State* L) {
} }
int l_lovrFilesystemGetExecutablePath(lua_State* L) { int l_lovrFilesystemGetExecutablePath(lua_State* L) {
const char* exePath = lovrFilesystemGetExecutablePath(); char buffer[1024];
if (exePath) { if (lovrFilesystemGetExecutablePath(buffer, sizeof(buffer))) {
lua_pushstring(L, exePath); lua_pushnil(L);
} else {
lua_pushstring(L, buffer);
}
return 1;
}
int l_lovrFilesystemGetIdentity(lua_State* L) {
const char* identity = lovrFilesystemGetIdentity();
if (identity) {
lua_pushstring(L, identity);
} else { } else {
lua_pushnil(L); lua_pushnil(L);
} }
@ -99,6 +116,36 @@ int l_lovrFilesystemGetExecutablePath(lua_State* L) {
return 1; return 1;
} }
int l_lovrFilesystemGetRealDirectory(lua_State* L) {
const char* path = luaL_checkstring(L, 1);
const char* realDirectory = lovrFilesystemGetRealDirectory(path);
if (realDirectory) {
lua_pushstring(L, realDirectory);
} else {
lua_pushnil(L);
}
return 1;
}
int l_lovrFilesystemGetSource(lua_State* L) {
const char* source = lovrFilesystemGetSource();
if (source) {
lua_pushstring(L, source);
} else {
lua_pushnil(L);
}
return 1;
}
int l_lovrFilesystemGetUserDirectory(lua_State* L) {
lua_pushstring(L, lovrFilesystemGetUserDirectory());
return 1;
}
int l_lovrFilesystemIsDirectory(lua_State* L) { int l_lovrFilesystemIsDirectory(lua_State* L) {
const char* path = luaL_checkstring(L, 1); const char* path = luaL_checkstring(L, 1);
lua_pushboolean(L, lovrFilesystemIsDirectory(path)); lua_pushboolean(L, lovrFilesystemIsDirectory(path));
@ -114,23 +161,27 @@ int l_lovrFilesystemIsFile(lua_State* L) {
int l_lovrFilesystemRead(lua_State* L) { int l_lovrFilesystemRead(lua_State* L) {
const char* path = luaL_checkstring(L, 1); const char* path = luaL_checkstring(L, 1);
int size; int size;
char* contents = lovrFilesystemRead(path, &size); char* content = lovrFilesystemRead(path, &size);
if (!contents) { if (!content) {
return luaL_error(L, "Could not read file '%s'", path); return luaL_error(L, "Could not read file '%s'", path);
} }
lua_pushlstring(L, contents, size); lua_pushlstring(L, content, size);
return 1; return 1;
} }
int l_lovrFilesystemSetIdentity(lua_State* L) {
const char* identity = luaL_checkstring(L, 1);
if (lovrFilesystemSetIdentity(identity)) {
return luaL_error(L, "Could not set the filesystem identity");
}
return 0;
}
int l_lovrFilesystemSetSource(lua_State* L) { int l_lovrFilesystemSetSource(lua_State* L) {
const char* source = lua_tostring(L, 1); const char* source = luaL_checkstring(L, 1);
lua_pushboolean(L, !lovrFilesystemSetSource(source));
if (source) {
lua_pushboolean(L, lovrFilesystemSetSource(source));
} else {
lua_pushboolean(L, 0);
}
return 1; return 1;
} }

View File

@ -7,7 +7,12 @@ int l_lovrFilesystemInit(lua_State* L);
int l_lovrFilesystemInitialize(lua_State* L); int l_lovrFilesystemInitialize(lua_State* L);
int l_lovrFilesystemExists(lua_State* L); int l_lovrFilesystemExists(lua_State* L);
int l_lovrFilesystemGetExecutablePath(lua_State* L); int l_lovrFilesystemGetExecutablePath(lua_State* L);
int l_lovrFilesystemGetIdentity(lua_State* L);
int l_lovrFilesystemGetRealDirectory(lua_State* L);
int l_lovrFilesystemGetSource(lua_State* L);
int l_lovrFilesystemGetUserDirectory(lua_State* L);
int l_lovrFilesystemIsDirectory(lua_State* L); int l_lovrFilesystemIsDirectory(lua_State* L);
int l_lovrFilesystemIsFile(lua_State* L); int l_lovrFilesystemIsFile(lua_State* L);
int l_lovrFilesystemRead(lua_State* L); int l_lovrFilesystemRead(lua_State* L);
int l_lovrFilesystemSetIdentity(lua_State* L);
int l_lovrFilesystemSetSource(lua_State* L); int l_lovrFilesystemSetSource(lua_State* L);