Scripting: Add root scope function for engines

This commit is contained in:
Vicki Pfau 2022-09-21 23:52:25 -07:00
parent 68845e080a
commit 95336463bf
3 changed files with 80 additions and 0 deletions

View File

@ -55,6 +55,7 @@ struct mScriptEngineContext {
bool (*setGlobal)(struct mScriptEngineContext*, const char* name, struct mScriptValue*); bool (*setGlobal)(struct mScriptEngineContext*, const char* name, struct mScriptValue*);
struct mScriptValue* (*getGlobal)(struct mScriptEngineContext*, const char* name); struct mScriptValue* (*getGlobal)(struct mScriptEngineContext*, const char* name);
struct mScriptValue* (*rootScope)(struct mScriptEngineContext*);
bool (*load)(struct mScriptEngineContext*, const char* filename, struct VFile*); bool (*load)(struct mScriptEngineContext*, const char* filename, struct VFile*);
bool (*run)(struct mScriptEngineContext*); bool (*run)(struct mScriptEngineContext*);

View File

@ -25,6 +25,7 @@ static void _luaDestroy(struct mScriptEngineContext*);
static bool _luaIsScript(struct mScriptEngineContext*, const char*, struct VFile*); static bool _luaIsScript(struct mScriptEngineContext*, const char*, struct VFile*);
static struct mScriptValue* _luaGetGlobal(struct mScriptEngineContext*, const char* name); static struct mScriptValue* _luaGetGlobal(struct mScriptEngineContext*, const char* name);
static bool _luaSetGlobal(struct mScriptEngineContext*, const char* name, struct mScriptValue*); 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 _luaLoad(struct mScriptEngineContext*, const char*, struct VFile*);
static bool _luaRun(struct mScriptEngineContext*); static bool _luaRun(struct mScriptEngineContext*);
static const char* _luaGetError(struct mScriptEngineContext*); static const char* _luaGetError(struct mScriptEngineContext*);
@ -214,6 +215,7 @@ static const int _mScriptSocketNumErrors = sizeof(_mScriptSocketErrors) / sizeof
#if LUA_VERSION_NUM < 502 #if LUA_VERSION_NUM < 502
#define luaL_traceback(L, M, S, level) lua_pushstring(L, S) #define luaL_traceback(L, M, S, level) lua_pushstring(L, S)
#define lua_pushglobaltable(L) lua_pushvalue(L, LUA_GLOBALSINDEX)
#endif #endif
const struct mScriptType mSTLuaFunc = { const struct mScriptType mSTLuaFunc = {
@ -294,6 +296,7 @@ struct mScriptEngineContext* _luaCreate(struct mScriptEngine2* engine, struct mS
.isScript = _luaIsScript, .isScript = _luaIsScript,
.getGlobal = _luaGetGlobal, .getGlobal = _luaGetGlobal,
.setGlobal = _luaSetGlobal, .setGlobal = _luaSetGlobal,
.rootScope = _luaRootScope,
.load = _luaLoad, .load = _luaLoad,
.run = _luaRun, .run = _luaRun,
.getError = _luaGetError .getError = _luaGetError
@ -395,6 +398,24 @@ bool _luaSetGlobal(struct mScriptEngineContext* ctx, const char* name, struct mS
return true; 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* _luaCoerceFunction(struct mScriptEngineContextLua* luaContext) {
struct mScriptValue* value = mScriptValueAlloc(&mSTLuaFunc); struct mScriptValue* value = mScriptValueAlloc(&mSTLuaFunc);
struct mScriptFunction* fn = calloc(1, sizeof(*fn)); struct mScriptFunction* fn = calloc(1, sizeof(*fn));

View File

@ -259,6 +259,63 @@ M_TEST_DEFINE(setGlobal) {
mScriptContextDeinit(&context); 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) { M_TEST_DEFINE(callLuaFunc) {
SETUP_LUA; SETUP_LUA;
@ -658,6 +715,7 @@ M_TEST_SUITE_DEFINE_SETUP_TEARDOWN(mScriptLua,
cmocka_unit_test(runNop), cmocka_unit_test(runNop),
cmocka_unit_test(getGlobal), cmocka_unit_test(getGlobal),
cmocka_unit_test(setGlobal), cmocka_unit_test(setGlobal),
cmocka_unit_test(rootScope),
cmocka_unit_test(callLuaFunc), cmocka_unit_test(callLuaFunc),
cmocka_unit_test(callCFunc), cmocka_unit_test(callCFunc),
cmocka_unit_test(globalStructFieldGet), cmocka_unit_test(globalStructFieldGet),