rm --root arg;

This commit is contained in:
bjorn 2020-12-25 12:18:57 -07:00
parent 30e01f94a3
commit 32fb7a7cb2
1 changed files with 43 additions and 82 deletions

View File

@ -7,8 +7,6 @@
#include <string.h>
#include <stdlib.h>
int main(int argc, char** argv);
#ifdef EMSCRIPTEN
#include <emscripten.h>
@ -19,36 +17,7 @@ typedef struct {
char** argv;
} lovrEmscriptenContext;
// Called by JS
void lovrDestroy(void* arg) {
if (arg) {
lovrEmscriptenContext* context = arg;
lua_State* L = context->L;
emscripten_cancel_main_loop();
lua_close(L);
lovrPlatformDestroy();
}
}
static void emscriptenLoop(void* arg) {
lovrEmscriptenContext* context = arg;
lua_State* T = context->T;
if (luax_resume(T, 0) != LUA_YIELD) {
bool restart = lua_type(T, -1) == LUA_TSTRING && !strcmp(lua_tostring(T, -1), "restart");
int status = lua_tonumber(T, -1);
lua_close(context->L);
emscripten_cancel_main_loop();
if (restart) {
main(context->argc, context->argv);
} else {
lovrPlatformDestroy();
exit(status);
}
}
}
static void emscriptenLoop(void*);
#endif
int main(int argc, char** argv) {
@ -72,67 +41,26 @@ int main(int argc, char** argv) {
luaL_openlibs(L);
// arg table
// Args follow the lua standard https://en.wikibooks.org/wiki/Lua_Programming/command_line_parameter
// In this standard, the contents of argv are put in a global table named "arg", but with
// indices offset such that the "script" (in lovr, the game path) is at index 0. So all
// arguments (if any) intended for the script/game are at successive indices starting with 1,
// and the exe and its arguments are in normal order but stored in negative indices.
//
// LÖVR can be run in ways normal Lua can't. It can be run with an empty argv, or with no script
// (if fused). So in the case of LÖVR:
// * The script path will always be at index 0, but it can be nil.
// * For a fused executable, whatever is given in argv as script name is still at 0, but will be ignored.
// * The exe (argv[0]) will always be the lowest-integer index. If it's present, it will always be -1 or less.
// * Any named arguments parsed by Lovr will be stored in the arg table at their named keys.
// * An exe name will always be stored in the arg table at string key "exe", even if none was supplied in argv.
lua_newtable(L);
// push dummy "lovr" in case argv is empty
lua_pushliteral(L, "lovr");
lua_pushstring(L, argc > 0 ? argv[0] : "lovr");
lua_setfield(L, -2, "exe");
luax_pushvariant(L, &cookie);
lua_setfield(L, -2, "restart");
typedef enum { // What flag is being searched for?
ARGFLAG_NONE, // Not processing a flag
ARGFLAG_ROOT
} ArgFlag;
ArgFlag currentFlag = ARGFLAG_NONE;
int lovrArgs = 0; // Arg count up to but not including the game path
// One pass to parse flags
for (int i = 0; i < argc; i++) {
if (lovrArgs > 0) {
// This argument is an argument to a -- flag
if (currentFlag == ARGFLAG_ROOT) {
lua_pushstring(L, argv[i]);
lua_setfield(L, -2, "root");
currentFlag = ARGFLAG_NONE;
// This argument is a -- flag
} else if (!strcmp(argv[i], "--root") || !strcmp(argv[i], "-r")) {
currentFlag = ARGFLAG_ROOT;
} else if (!strcmp(argv[i], "--console")) {
lovrPlatformOpenConsole();
// This is the game path
} else {
break;
}
} else { // Found exe name
lua_pushstring(L, argv[i]);
lua_setfield(L, -2, "exe");
int argOffset = 1;
for (int i = 1; i < argc; i++, argOffset++) {
if (!strcmp(argv[i], "--console")) {
lovrPlatformOpenConsole();
} else {
break; // This is the project path
}
lovrArgs++;
}
// Now that we know the negative offset to start at, copy all args in the table
for (int i = 0; i < argc; i++) {
lua_pushstring(L, argv[i]);
lua_rawseti(L, -2, -lovrArgs + i);
lua_rawseti(L, -2, -argOffset + i);
}
lua_setglobal(L, "arg");
lua_getglobal(L, "package");
@ -177,3 +105,36 @@ int main(int argc, char** argv) {
return status;
}
#ifdef EMSCRIPTEN
// Called by JS
void lovrDestroy(void* arg) {
if (arg) {
lovrEmscriptenContext* context = arg;
lua_State* L = context->L;
emscripten_cancel_main_loop();
lua_close(L);
lovrPlatformDestroy();
}
}
static void emscriptenLoop(void* arg) {
lovrEmscriptenContext* context = arg;
lua_State* T = context->T;
if (luax_resume(T, 0) != LUA_YIELD) {
bool restart = lua_type(T, -1) == LUA_TSTRING && !strcmp(lua_tostring(T, -1), "restart");
int status = lua_tonumber(T, -1);
lua_close(context->L);
emscripten_cancel_main_loop();
if (restart) {
main(context->argc, context->argv);
} else {
lovrPlatformDestroy();
exit(status);
}
}
}
#endif