This commit is contained in:
Bjorn 2024-03-10 05:38:20 -06:00 committed by GitHub
commit 7fe9baa2be
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 1892 additions and 9 deletions

View File

@ -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()

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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[];

View File

@ -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);

View File

@ -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 }

2
src/lib/dmon/dmon.c Normal file
View File

@ -0,0 +1,2 @@
#define DMON_IMPL
#include "dmon.h"

1748
src/lib/dmon/dmon.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -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);
}

View File

@ -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 {

View File

@ -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;

View File

@ -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);

View File

@ -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) {