Scripting: Start hooking things together

This commit is contained in:
Vicki Pfau 2022-05-08 20:51:17 -07:00
parent cdfa6ac54b
commit 7bb051b01d
5 changed files with 88 additions and 0 deletions

View File

@ -11,6 +11,10 @@
CXX_GUARD_START
#include <mgba/core/log.h>
#ifdef ENABLE_SCRIPTING
#include <mgba/core/scripting.h>
#include <mgba/script/context.h>
#endif
struct mCoreThread;
struct mCore;
@ -39,6 +43,10 @@ struct mCoreThread {
void* userData;
void (*run)(struct mCoreThread*);
#ifdef ENABLE_SCRIPTING
struct mScriptContext* scriptContext;
#endif
struct mCoreThreadInternal* impl;
};

View File

@ -36,6 +36,8 @@ struct mScriptEngineContext {
struct mScriptContext* context;
void (*destroy)(struct mScriptEngineContext*);
bool (*isScript)(struct mScriptEngineContext*, const char* name, struct VFile* vf);
bool (*setGlobal)(struct mScriptEngineContext*, const char* name, struct mScriptValue*);
struct mScriptValue* (*getGlobal)(struct mScriptEngineContext*, const char* name);
@ -48,10 +50,15 @@ void mScriptContextInit(struct mScriptContext*);
void mScriptContextDeinit(struct mScriptContext*);
struct mScriptEngineContext* mScriptContextRegisterEngine(struct mScriptContext*, struct mScriptEngine2*);
void mScriptContextRegisterEngines(struct mScriptContext*);
void mScriptContextSetGlobal(struct mScriptContext*, const char* key, struct mScriptValue* value);
void mScriptContextRemoveGlobal(struct mScriptContext*, const char* key);
struct VFile;
bool mScriptContextLoadVF(struct mScriptContext*, const char* name, struct VFile* vf);
bool mScriptContextLoadFile(struct mScriptContext*, const char* path);
bool mScriptInvoke(const struct mScriptValue* fn, struct mScriptFrame* frame);
CXX_GUARD_END

View File

@ -219,6 +219,12 @@ static THREAD_ENTRY _mCoreThreadRun(void* context) {
mLogFilterLoad(threadContext->logger.d.filter, &core->config);
}
#ifdef ENABLE_SCRIPTING
if (threadContext->scriptContext) {
mScriptContextAttachCore(threadContext->scriptContext, core);
}
#endif
mCoreThreadRewindParamsChanged(threadContext);
if (threadContext->startCallback) {
threadContext->startCallback(threadContext);
@ -337,6 +343,11 @@ static THREAD_ENTRY _mCoreThreadRun(void* context) {
if (threadContext->cleanCallback) {
threadContext->cleanCallback(threadContext);
}
#ifdef ENABLE_SCRIPTING
if (threadContext->scriptContext) {
mScriptContextDetachCore(threadContext->scriptContext);
}
#endif
core->clearCoreCallbacks(core);
if (threadContext->logger.d.filter == &filter) {

View File

@ -4,12 +4,21 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <mgba/script/context.h>
#ifdef USE_LUA
#include <mgba/internal/script/lua.h>
#endif
struct mScriptKVPair {
const char* key;
struct mScriptValue* value;
};
struct mScriptFileInfo {
const char* name;
struct VFile* vf;
struct mScriptEngineContext* context;
};
static void _engineContextDestroy(void* ctx) {
struct mScriptEngineContext* context = ctx;
context->destroy(context);
@ -28,6 +37,18 @@ static void _contextRemoveGlobal(const char* key, void* value, void* user) {
context->setGlobal(context, user, NULL);
}
static void _contextFindForFile(const char* key, void* value, void* user) {
UNUSED(key);
struct mScriptFileInfo* info = user;
struct mScriptEngineContext* context = value;
if (info->context) {
return;
}
if (context->isScript(context, info->name, info->vf)) {
info->context = context;
}
}
void mScriptContextInit(struct mScriptContext* context) {
HashTableInit(&context->rootScope, 0, (void (*)(void*)) mScriptValueDeref);
HashTableInit(&context->engines, 0, _engineContextDestroy);
@ -46,6 +67,13 @@ struct mScriptEngineContext* mScriptContextRegisterEngine(struct mScriptContext*
return ectx;
}
void mScriptContextRegisterEngines(struct mScriptContext* context) {
UNUSED(context);
#ifdef USE_LUA
mScriptContextRegisterEngine(context, mSCRIPT_ENGINE_LUA);
#endif
}
void mScriptContextSetGlobal(struct mScriptContext* context, const char* key, struct mScriptValue* value) {
mScriptValueRef(value);
HashTableInsert(&context->rootScope, key, value);
@ -65,6 +93,29 @@ void mScriptContextRemoveGlobal(struct mScriptContext* context, const char* key)
HashTableRemove(&context->rootScope, key);
}
bool mScriptContextLoadVF(struct mScriptContext* context, const char* name, struct VFile* vf) {
struct mScriptFileInfo info = {
.name = name,
.vf = vf,
.context = NULL
};
HashTableEnumerate(&context->engines, _contextFindForFile, &info);
if (!info.context) {
return false;
}
return info.context->load(info.context, vf, NULL);
}
bool mScriptContextLoadFile(struct mScriptContext* context, const char* path) {
struct VFile* vf = VFileOpen(path, O_RDONLY);
if (!vf) {
return false;
}
bool ret = mScriptContextLoadVF(context, path, vf);
vf->close(vf);
return ret;
}
bool mScriptInvoke(const struct mScriptValue* val, struct mScriptFrame* frame) {
if (val->type->base != mSCRIPT_TYPE_FUNCTION) {
return false;

View File

@ -13,6 +13,7 @@
static struct mScriptEngineContext* _luaCreate(struct mScriptEngine2*, struct mScriptContext*);
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 bool _luaLoad(struct mScriptEngineContext*, struct VFile*, const char** error);
@ -99,6 +100,7 @@ struct mScriptEngineContext* _luaCreate(struct mScriptEngine2* engine, struct mS
luaContext->d = (struct mScriptEngineContext) {
.context = context,
.destroy = _luaDestroy,
.isScript = _luaIsScript,
.getGlobal = _luaGetGlobal,
.setGlobal = _luaSetGlobal,
.load = _luaLoad,
@ -134,6 +136,15 @@ void _luaDestroy(struct mScriptEngineContext* ctx) {
free(luaContext);
}
bool _luaIsScript(struct mScriptEngineContext* ctx, const char* name, struct VFile* vf) {
UNUSED(ctx);
UNUSED(vf);
if (!name) {
return false;
}
return endswith(name, ".lua");
}
struct mScriptValue* _luaGetGlobal(struct mScriptEngineContext* ctx, const char* name) {
struct mScriptEngineContextLua* luaContext = (struct mScriptEngineContextLua*) ctx;
lua_getglobal(luaContext->lua, name);