mirror of https://github.com/mgba-emu/mgba.git
Scripting: Add root scope function for engines
This commit is contained in:
parent
68845e080a
commit
95336463bf
|
@ -55,6 +55,7 @@ struct mScriptEngineContext {
|
|||
|
||||
bool (*setGlobal)(struct mScriptEngineContext*, const char* name, struct mScriptValue*);
|
||||
struct mScriptValue* (*getGlobal)(struct mScriptEngineContext*, const char* name);
|
||||
struct mScriptValue* (*rootScope)(struct mScriptEngineContext*);
|
||||
|
||||
bool (*load)(struct mScriptEngineContext*, const char* filename, struct VFile*);
|
||||
bool (*run)(struct mScriptEngineContext*);
|
||||
|
|
|
@ -25,6 +25,7 @@ static void _luaDestroy(struct mScriptEngineContext*);
|
|||
static bool _luaIsScript(struct mScriptEngineContext*, const char*, struct VFile*);
|
||||
static struct mScriptValue* _luaGetGlobal(struct mScriptEngineContext*, const char* name);
|
||||
static bool _luaSetGlobal(struct mScriptEngineContext*, const char* name, struct mScriptValue*);
|
||||
static struct mScriptValue* _luaRootScope(struct mScriptEngineContext*);
|
||||
static bool _luaLoad(struct mScriptEngineContext*, const char*, struct VFile*);
|
||||
static bool _luaRun(struct mScriptEngineContext*);
|
||||
static const char* _luaGetError(struct mScriptEngineContext*);
|
||||
|
@ -214,6 +215,7 @@ static const int _mScriptSocketNumErrors = sizeof(_mScriptSocketErrors) / sizeof
|
|||
|
||||
#if LUA_VERSION_NUM < 502
|
||||
#define luaL_traceback(L, M, S, level) lua_pushstring(L, S)
|
||||
#define lua_pushglobaltable(L) lua_pushvalue(L, LUA_GLOBALSINDEX)
|
||||
#endif
|
||||
|
||||
const struct mScriptType mSTLuaFunc = {
|
||||
|
@ -294,6 +296,7 @@ struct mScriptEngineContext* _luaCreate(struct mScriptEngine2* engine, struct mS
|
|||
.isScript = _luaIsScript,
|
||||
.getGlobal = _luaGetGlobal,
|
||||
.setGlobal = _luaSetGlobal,
|
||||
.rootScope = _luaRootScope,
|
||||
.load = _luaLoad,
|
||||
.run = _luaRun,
|
||||
.getError = _luaGetError
|
||||
|
@ -395,6 +398,24 @@ bool _luaSetGlobal(struct mScriptEngineContext* ctx, const char* name, struct mS
|
|||
return true;
|
||||
}
|
||||
|
||||
struct mScriptValue* _luaRootScope(struct mScriptEngineContext* ctx) {
|
||||
struct mScriptEngineContextLua* luaContext = (struct mScriptEngineContextLua*) ctx;
|
||||
|
||||
struct mScriptValue* list = mScriptValueAlloc(mSCRIPT_TYPE_MS_LIST);
|
||||
lua_pushglobaltable(luaContext->lua);
|
||||
lua_pushnil(luaContext->lua);
|
||||
while (lua_next(luaContext->lua, -2) != 0) {
|
||||
struct mScriptValue* key;
|
||||
|
||||
lua_pop(luaContext->lua, 1);
|
||||
key = _luaCoerce(luaContext, false);
|
||||
mScriptValueWrap(key, mScriptListAppend(list->value.list));
|
||||
}
|
||||
lua_pop(luaContext->lua, 1);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
struct mScriptValue* _luaCoerceFunction(struct mScriptEngineContextLua* luaContext) {
|
||||
struct mScriptValue* value = mScriptValueAlloc(&mSTLuaFunc);
|
||||
struct mScriptFunction* fn = calloc(1, sizeof(*fn));
|
||||
|
|
|
@ -259,6 +259,63 @@ M_TEST_DEFINE(setGlobal) {
|
|||
mScriptContextDeinit(&context);
|
||||
}
|
||||
|
||||
M_TEST_DEFINE(rootScope) {
|
||||
SETUP_LUA;
|
||||
|
||||
struct mScriptValue* baseline = mScriptValueAlloc(mSCRIPT_TYPE_MS_TABLE);
|
||||
|
||||
struct mScriptValue* val;
|
||||
val = lua->rootScope(lua);
|
||||
assert_non_null(val);
|
||||
assert_int_equal(val->type->base, mSCRIPT_TYPE_LIST);
|
||||
|
||||
struct mScriptValue one = mSCRIPT_MAKE_S32(1);
|
||||
size_t i;
|
||||
for (i = 0; i < mScriptListSize(val->value.list); ++i) {
|
||||
struct mScriptValue* key = mScriptListGetPointer(val->value.list, i);
|
||||
if (key->type->base == mSCRIPT_TYPE_WRAPPER) {
|
||||
key = mScriptValueUnwrap(key);
|
||||
}
|
||||
mScriptTableInsert(baseline, key, &one);
|
||||
}
|
||||
mScriptValueDeref(val);
|
||||
|
||||
TEST_PROGRAM("foo = 1; bar = 2;");
|
||||
|
||||
bool fooFound = false;
|
||||
bool barFound = false;
|
||||
|
||||
val = lua->rootScope(lua);
|
||||
assert_non_null(val);
|
||||
assert_int_equal(val->type->base, mSCRIPT_TYPE_LIST);
|
||||
assert_int_equal(mScriptListSize(val->value.list), mScriptTableSize(baseline) + 2);
|
||||
|
||||
for (i = 0; i < mScriptListSize(val->value.list); ++i) {
|
||||
struct mScriptValue* key = mScriptListGetPointer(val->value.list, i);
|
||||
if (key->type->base == mSCRIPT_TYPE_WRAPPER) {
|
||||
key = mScriptValueUnwrap(key);
|
||||
}
|
||||
if (mScriptTableLookup(baseline, key)) {
|
||||
continue;
|
||||
}
|
||||
assert_int_equal(key->type->base, mSCRIPT_TYPE_STRING);
|
||||
|
||||
if (strncmp(key->value.string->buffer, "foo", key->value.string->size) == 0) {
|
||||
fooFound = true;
|
||||
}
|
||||
if (strncmp(key->value.string->buffer, "bar", key->value.string->size) == 0) {
|
||||
barFound = true;
|
||||
}
|
||||
}
|
||||
mScriptValueDeref(val);
|
||||
|
||||
assert_true(fooFound);
|
||||
assert_true(barFound);
|
||||
|
||||
mScriptValueDeref(baseline);
|
||||
mScriptContextDeinit(&context);
|
||||
}
|
||||
|
||||
M_TEST_DEFINE(callLuaFunc) {
|
||||
SETUP_LUA;
|
||||
|
||||
|
@ -658,6 +715,7 @@ M_TEST_SUITE_DEFINE_SETUP_TEARDOWN(mScriptLua,
|
|||
cmocka_unit_test(runNop),
|
||||
cmocka_unit_test(getGlobal),
|
||||
cmocka_unit_test(setGlobal),
|
||||
cmocka_unit_test(rootScope),
|
||||
cmocka_unit_test(callLuaFunc),
|
||||
cmocka_unit_test(callCFunc),
|
||||
cmocka_unit_test(globalStructFieldGet),
|
||||
|
|
Loading…
Reference in New Issue