mirror of https://github.com/bjornbytes/lovr.git
Merge 90339ee0ec
into 1cda2d59a7
This commit is contained in:
commit
7fe9baa2be
|
@ -438,8 +438,16 @@ if(LOVR_ENABLE_FILESYSTEM)
|
|||
src/modules/filesystem/filesystem.c
|
||||
src/api/l_filesystem.c
|
||||
src/api/l_filesystem_file.c
|
||||
src/lib/dmon/dmon.c
|
||||
src/lib/miniz/miniz_tinfl.c
|
||||
)
|
||||
|
||||
# dmon
|
||||
if(APPLE)
|
||||
find_library(CORE_FOUNDATION CoreFoundation)
|
||||
find_library(CORE_SERVICES CoreServices)
|
||||
target_link_libraries(lovr "${CORE_FOUNDATION}" "${CORE_SERVICES}")
|
||||
endif()
|
||||
else()
|
||||
target_compile_definitions(lovr PRIVATE LOVR_DISABLE_FILESYSTEM)
|
||||
endif()
|
||||
|
|
|
@ -450,6 +450,7 @@ src += 'src/lib/miniz/*.c'
|
|||
src += (config.modules.audio or config.modules.data) and 'src/lib/miniaudio/*.c' or nil
|
||||
src += config.modules.data and 'src/lib/jsmn/*.c' or nil
|
||||
src += config.modules.data and 'src/lib/minimp3/*.c' or nil
|
||||
src += config.modules.filesystem and 'src/lib/dmon/*.c' or nil
|
||||
src += config.modules.math and 'src/lib/noise/*.c' or nil
|
||||
src += config.modules.thread and 'src/core/job.c' or nil
|
||||
|
||||
|
|
|
@ -282,6 +282,10 @@ function lovr.threaderror(thread, err)
|
|||
error('Thread error\n\n' .. err, 0)
|
||||
end
|
||||
|
||||
function lovr.filechanged(path, action, oldpath)
|
||||
lovr.event.restart()
|
||||
end
|
||||
|
||||
function lovr.log(message, level, tag)
|
||||
message = message:gsub('\n$', '')
|
||||
print(message)
|
||||
|
|
|
@ -3,7 +3,8 @@ function lovr.arg(arg)
|
|||
_help = { short = '-h', long = '--help', help = 'Show help and exit' },
|
||||
_version = { short = '-v', long = '--version', help = 'Show version and exit' },
|
||||
console = { long = '--console', help = 'Attach Windows console' },
|
||||
debug = { long = '--debug', help = 'Enable debugging checks and logging' }
|
||||
debug = { long = '--debug', help = 'Enable debugging checks and logging' },
|
||||
watch = { short = '-w', long = '--watch', help = 'Watch files and restart on change' }
|
||||
}
|
||||
|
||||
local shift
|
||||
|
@ -68,5 +69,9 @@ function lovr.arg(arg)
|
|||
if arg.debug then
|
||||
conf.graphics.debug = true
|
||||
end
|
||||
|
||||
if arg.watch then
|
||||
lovr.filesystem.watch()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -38,6 +38,7 @@ extern StringEntry lovrDrawMode[];
|
|||
extern StringEntry lovrDrawStyle[];
|
||||
extern StringEntry lovrEffect[];
|
||||
extern StringEntry lovrEventType[];
|
||||
extern StringEntry lovrFileAction[];
|
||||
extern StringEntry lovrFilterMode[];
|
||||
extern StringEntry lovrHeadsetDriver[];
|
||||
extern StringEntry lovrHorizontalAlign[];
|
||||
|
|
|
@ -22,6 +22,7 @@ StringEntry lovrEventType[] = {
|
|||
#ifndef LOVR_DISABLE_THREAD
|
||||
[EVENT_THREAD_ERROR] = ENTRY("threaderror"),
|
||||
#endif
|
||||
[EVENT_FILECHANGED] = ENTRY("filechanged"),
|
||||
[EVENT_PERMISSION] = ENTRY("permission"),
|
||||
{ 0 }
|
||||
};
|
||||
|
@ -209,6 +210,14 @@ static int nextEvent(lua_State* L) {
|
|||
return 3;
|
||||
#endif
|
||||
|
||||
case EVENT_FILECHANGED:
|
||||
lua_pushstring(L, event.data.file.path);
|
||||
luax_pushenum(L, FileAction, event.data.file.action);
|
||||
lua_pushstring(L, event.data.file.oldpath);
|
||||
free(event.data.file.path);
|
||||
free(event.data.file.oldpath);
|
||||
return 4;
|
||||
|
||||
case EVENT_PERMISSION:
|
||||
luax_pushenum(L, Permission, event.data.permission.permission);
|
||||
lua_pushboolean(L, event.data.permission.granted);
|
||||
|
|
|
@ -5,6 +5,14 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
StringEntry lovrFileAction[] = {
|
||||
[FILE_CREATE] = ENTRY("create"),
|
||||
[FILE_DELETE] = ENTRY("delete"),
|
||||
[FILE_MODIFY] = ENTRY("modify"),
|
||||
[FILE_RENAME] = ENTRY("rename"),
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
StringEntry lovrOpenMode[] = {
|
||||
[OPEN_READ] = ENTRY("r"),
|
||||
[OPEN_WRITE] = ENTRY("w"),
|
||||
|
@ -349,6 +357,16 @@ static int l_lovrFilesystemUnmount(lua_State* L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrFilesystemUnwatch(lua_State* L) {
|
||||
lovrFilesystemUnwatch();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_lovrFilesystemWatch(lua_State* L) {
|
||||
lovrFilesystemWatch();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_lovrFilesystemWrite(lua_State* L) {
|
||||
const char* path = luaL_checkstring(L, 1);
|
||||
size_t size;
|
||||
|
@ -411,6 +429,8 @@ static const luaL_Reg lovrFilesystem[] = {
|
|||
{ "setRequirePath", l_lovrFilesystemSetRequirePath },
|
||||
{ "setSource", l_lovrFilesystemSetSource },
|
||||
{ "unmount", l_lovrFilesystemUnmount },
|
||||
{ "unwatch", l_lovrFilesystemUnwatch },
|
||||
{ "watch", l_lovrFilesystemWatch },
|
||||
{ "write", l_lovrFilesystemWrite },
|
||||
{ "newFile", l_lovrFilesystemNewFile },
|
||||
{ NULL, NULL }
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
#define DMON_IMPL
|
||||
#include "dmon.h"
|
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,7 @@
|
|||
#include "event/event.h"
|
||||
#include "thread/thread.h"
|
||||
#include "util.h"
|
||||
#include <threads.h>
|
||||
#include <stdatomic.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -9,6 +10,7 @@ static struct {
|
|||
uint32_t ref;
|
||||
arr_t(Event) events;
|
||||
size_t head;
|
||||
mtx_t lock;
|
||||
} state;
|
||||
|
||||
void lovrVariantDestroy(Variant* variant) {
|
||||
|
@ -23,11 +25,13 @@ void lovrVariantDestroy(Variant* variant) {
|
|||
bool lovrEventInit(void) {
|
||||
if (atomic_fetch_add(&state.ref, 1)) return false;
|
||||
arr_init(&state.events, arr_alloc);
|
||||
mtx_init(&state.lock, mtx_plain);
|
||||
return true;
|
||||
}
|
||||
|
||||
void lovrEventDestroy(void) {
|
||||
if (atomic_fetch_sub(&state.ref, 1) != 1) return;
|
||||
mtx_lock(&state.lock);
|
||||
for (size_t i = state.head; i < state.events.length; i++) {
|
||||
Event* event = &state.events.data[i];
|
||||
switch (event->type) {
|
||||
|
@ -43,36 +47,60 @@ void lovrEventDestroy(void) {
|
|||
}
|
||||
}
|
||||
arr_free(&state.events);
|
||||
mtx_unlock(&state.lock);
|
||||
mtx_destroy(&state.lock);
|
||||
memset(&state, 0, sizeof(state));
|
||||
}
|
||||
|
||||
void lovrEventPush(Event event) {
|
||||
if (state.ref == 0) return;
|
||||
|
||||
#ifndef LOVR_DISABLE_THREAD
|
||||
if (event.type == EVENT_THREAD_ERROR) {
|
||||
lovrRetain(event.data.thread.thread);
|
||||
size_t length = strlen(event.data.thread.error);
|
||||
char* copy = malloc(length + 1);
|
||||
lovrAssert(copy, "Out of memory");
|
||||
memcpy(copy, event.data.thread.error, length);
|
||||
copy[length] = '\0';
|
||||
memcpy(copy, event.data.thread.error, length + 1);
|
||||
event.data.thread.error = copy;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (event.type == EVENT_FILECHANGED) {
|
||||
size_t length = strlen(event.data.file.path);
|
||||
char* copy = malloc(length + 1);
|
||||
memcpy(copy, event.data.file.path, length + 1);
|
||||
event.data.file.path = copy;
|
||||
|
||||
if (event.data.file.oldpath) {
|
||||
length = strlen(event.data.file.oldpath);
|
||||
copy = malloc(length + 1);
|
||||
memcpy(copy, event.data.file.oldpath, length + 1);
|
||||
event.data.file.oldpath = copy;
|
||||
}
|
||||
}
|
||||
|
||||
mtx_lock(&state.lock);
|
||||
arr_push(&state.events, event);
|
||||
mtx_unlock(&state.lock);
|
||||
}
|
||||
|
||||
bool lovrEventPoll(Event* event) {
|
||||
mtx_lock(&state.lock);
|
||||
if (state.head == state.events.length) {
|
||||
state.head = state.events.length = 0;
|
||||
mtx_unlock(&state.lock);
|
||||
return false;
|
||||
}
|
||||
|
||||
*event = state.events.data[state.head++];
|
||||
mtx_unlock(&state.lock);
|
||||
return true;
|
||||
}
|
||||
|
||||
void lovrEventClear(void) {
|
||||
mtx_lock(&state.lock);
|
||||
arr_clear(&state.events);
|
||||
state.head = 0;
|
||||
mtx_unlock(&state.lock);
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ typedef enum {
|
|||
#ifndef LOVR_DISABLE_THREAD
|
||||
EVENT_THREAD_ERROR,
|
||||
#endif
|
||||
EVENT_FILECHANGED,
|
||||
EVENT_PERMISSION,
|
||||
EVENT_CUSTOM
|
||||
} EventType;
|
||||
|
@ -115,16 +116,22 @@ typedef struct {
|
|||
} ThreadEvent;
|
||||
|
||||
typedef struct {
|
||||
char name[MAX_EVENT_NAME_LENGTH];
|
||||
Variant data[4];
|
||||
uint32_t count;
|
||||
} CustomEvent;
|
||||
char* path;
|
||||
char* oldpath;
|
||||
int action;
|
||||
} FileEvent;
|
||||
|
||||
typedef struct {
|
||||
uint32_t permission;
|
||||
bool granted;
|
||||
} PermissionEvent;
|
||||
|
||||
typedef struct {
|
||||
char name[MAX_EVENT_NAME_LENGTH];
|
||||
Variant data[4];
|
||||
uint32_t count;
|
||||
} CustomEvent;
|
||||
|
||||
typedef union {
|
||||
QuitEvent quit;
|
||||
BoolEvent boolean;
|
||||
|
@ -134,8 +141,9 @@ typedef union {
|
|||
MouseEvent mouse;
|
||||
MouseWheelEvent wheel;
|
||||
ThreadEvent thread;
|
||||
CustomEvent custom;
|
||||
FileEvent file;
|
||||
PermissionEvent permission;
|
||||
CustomEvent custom;
|
||||
} EventData;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
#include "filesystem/filesystem.h"
|
||||
#include "event/event.h"
|
||||
#include "core/fs.h"
|
||||
#include "core/os.h"
|
||||
#include "util.h"
|
||||
#include "lib/dmon/dmon.h"
|
||||
#include "lib/miniz/miniz_tinfl.h"
|
||||
#include <stdatomic.h>
|
||||
#include <string.h>
|
||||
|
@ -75,6 +77,7 @@ struct File {
|
|||
|
||||
static struct {
|
||||
uint32_t ref;
|
||||
bool watching;
|
||||
Archive* archives;
|
||||
size_t savePathLength;
|
||||
char savePath[1024];
|
||||
|
@ -175,6 +178,7 @@ void lovrFilesystemDestroy(void) {
|
|||
lovrRelease(archive, lovrArchiveDestroy);
|
||||
archive = next;
|
||||
}
|
||||
lovrFilesystemUnwatch();
|
||||
memset(&state, 0, sizeof(state));
|
||||
}
|
||||
|
||||
|
@ -190,6 +194,40 @@ const char* lovrFilesystemGetSource(void) {
|
|||
return state.source[0] ? state.source : NULL;
|
||||
}
|
||||
|
||||
static void onFileEvent(dmon_watch_id id, dmon_action action, const char* dir, const char* path, const char* oldpath, void* ctx) {
|
||||
static const FileAction map[] = {
|
||||
[DMON_ACTION_CREATE] = FILE_CREATE,
|
||||
[DMON_ACTION_DELETE] = FILE_DELETE,
|
||||
[DMON_ACTION_MODIFY] = FILE_MODIFY,
|
||||
[DMON_ACTION_MOVE] = FILE_RENAME
|
||||
};
|
||||
|
||||
lovrEventPush((Event) {
|
||||
.type = EVENT_FILECHANGED,
|
||||
.data.file = {
|
||||
.path = (char*) path,
|
||||
.action = map[action],
|
||||
.oldpath = (char*) oldpath
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void lovrFilesystemWatch(void) {
|
||||
FileInfo info;
|
||||
if (!state.watching && fs_stat(state.source, &info) && info.type == FILE_DIRECTORY) {
|
||||
state.watching = true;
|
||||
dmon_init();
|
||||
dmon_watch(state.source, onFileEvent, DMON_WATCHFLAGS_RECURSIVE, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void lovrFilesystemUnwatch(void) {
|
||||
if (state.watching) {
|
||||
state.watching = false;
|
||||
dmon_deinit();
|
||||
}
|
||||
}
|
||||
|
||||
bool lovrFilesystemIsFused(void) {
|
||||
char path[LOVR_PATH_MAX];
|
||||
const char* root;
|
||||
|
|
|
@ -9,11 +9,20 @@
|
|||
typedef struct Archive Archive;
|
||||
typedef struct File File;
|
||||
|
||||
typedef enum {
|
||||
FILE_CREATE,
|
||||
FILE_DELETE,
|
||||
FILE_MODIFY,
|
||||
FILE_RENAME
|
||||
} FileAction;
|
||||
|
||||
bool lovrFilesystemInit(void);
|
||||
void lovrFilesystemDestroy(void);
|
||||
void lovrFilesystemSetSource(const char* source);
|
||||
const char* lovrFilesystemGetSource(void);
|
||||
bool lovrFilesystemIsFused(void);
|
||||
void lovrFilesystemWatch(void);
|
||||
void lovrFilesystemUnwatch(void);
|
||||
bool lovrFilesystemMount(const char* path, const char* mountpoint, bool append, const char *root);
|
||||
bool lovrFilesystemUnmount(const char* path);
|
||||
const char* lovrFilesystemGetRealDirectory(const char* path);
|
||||
|
|
|
@ -68,7 +68,6 @@ static void onFocus(bool focused) {
|
|||
|
||||
static bool simulator_init(HeadsetConfig* config) {
|
||||
state.config = *config;
|
||||
state.epoch = os_get_time();
|
||||
state.clipNear = .01f;
|
||||
state.clipFar = 0.f;
|
||||
state.distance = .5f;
|
||||
|
@ -101,6 +100,9 @@ static void simulator_start(void) {
|
|||
state.depthFormat = FORMAT_D24S8; // Guaranteed to be supported if the other one isn't
|
||||
}
|
||||
}
|
||||
|
||||
state.epoch = os_get_time();
|
||||
state.time = 0.;
|
||||
}
|
||||
|
||||
static void simulator_stop(void) {
|
||||
|
|
Loading…
Reference in New Issue