mirror of https://github.com/mgba-emu/mgba.git
Scripting: API cleanup
This commit is contained in:
parent
ca073379fb
commit
f3ba5f7692
|
@ -11,10 +11,6 @@
|
||||||
CXX_GUARD_START
|
CXX_GUARD_START
|
||||||
|
|
||||||
#include <mgba/core/log.h>
|
#include <mgba/core/log.h>
|
||||||
#ifdef ENABLE_SCRIPTING
|
|
||||||
#include <mgba/core/scripting.h>
|
|
||||||
#include <mgba/script/context.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct mCoreThread;
|
struct mCoreThread;
|
||||||
struct mCore;
|
struct mCore;
|
||||||
|
@ -27,6 +23,9 @@ struct mThreadLogger {
|
||||||
struct mCoreThread* p;
|
struct mCoreThread* p;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef ENABLE_SCRIPTING
|
||||||
|
struct mScriptContext;
|
||||||
|
#endif
|
||||||
struct mCoreThreadInternal;
|
struct mCoreThreadInternal;
|
||||||
struct mCoreThread {
|
struct mCoreThread {
|
||||||
// Input
|
// Input
|
||||||
|
|
|
@ -45,7 +45,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);
|
||||||
|
|
||||||
bool (*load)(struct mScriptEngineContext*, struct VFile*, const char** error);
|
bool (*load)(struct mScriptEngineContext*, struct VFile*);
|
||||||
bool (*run)(struct mScriptEngineContext*);
|
bool (*run)(struct mScriptEngineContext*);
|
||||||
const char* (*getError)(struct mScriptEngineContext*);
|
const char* (*getError)(struct mScriptEngineContext*);
|
||||||
};
|
};
|
||||||
|
@ -60,7 +60,9 @@ struct mScriptEngineContext* mScriptContextRegisterEngine(struct mScriptContext*
|
||||||
void mScriptContextRegisterEngines(struct mScriptContext*);
|
void mScriptContextRegisterEngines(struct mScriptContext*);
|
||||||
|
|
||||||
void mScriptContextSetGlobal(struct mScriptContext*, const char* key, struct mScriptValue* value);
|
void mScriptContextSetGlobal(struct mScriptContext*, const char* key, struct mScriptValue* value);
|
||||||
|
struct mScriptValue* mScriptContextGetGlobal(struct mScriptContext*, const char* key);
|
||||||
void mScriptContextRemoveGlobal(struct mScriptContext*, const char* key);
|
void mScriptContextRemoveGlobal(struct mScriptContext*, const char* key);
|
||||||
|
struct mScriptValue* mScriptContextEnsureGlobal(struct mScriptContext*, const char* key, const struct mScriptType* type);
|
||||||
|
|
||||||
uint32_t mScriptContextSetWeakref(struct mScriptContext*, struct mScriptValue* value);
|
uint32_t mScriptContextSetWeakref(struct mScriptContext*, struct mScriptValue* value);
|
||||||
struct mScriptValue* mScriptContextMakeWeakref(struct mScriptContext*, struct mScriptValue* value);
|
struct mScriptValue* mScriptContextMakeWeakref(struct mScriptContext*, struct mScriptValue* value);
|
||||||
|
|
|
@ -491,7 +491,6 @@ enum mScriptTypeBase {
|
||||||
mSCRIPT_TYPE_FUNCTION,
|
mSCRIPT_TYPE_FUNCTION,
|
||||||
mSCRIPT_TYPE_OPAQUE,
|
mSCRIPT_TYPE_OPAQUE,
|
||||||
mSCRIPT_TYPE_OBJECT,
|
mSCRIPT_TYPE_OBJECT,
|
||||||
mSCRIPT_TYPE_TUPLE,
|
|
||||||
mSCRIPT_TYPE_LIST,
|
mSCRIPT_TYPE_LIST,
|
||||||
mSCRIPT_TYPE_TABLE,
|
mSCRIPT_TYPE_TABLE,
|
||||||
mSCRIPT_TYPE_WRAPPER,
|
mSCRIPT_TYPE_WRAPPER,
|
||||||
|
@ -645,6 +644,8 @@ struct mScriptValue* mScriptValueUnwrap(struct mScriptValue* val);
|
||||||
const struct mScriptValue* mScriptValueUnwrapConst(const struct mScriptValue* val);
|
const struct mScriptValue* mScriptValueUnwrapConst(const struct mScriptValue* val);
|
||||||
|
|
||||||
struct mScriptValue* mScriptStringCreateFromUTF8(const char* string);
|
struct mScriptValue* mScriptStringCreateFromUTF8(const char* string);
|
||||||
|
struct mScriptValue* mScriptValueCreateFromUInt(uint32_t value);
|
||||||
|
struct mScriptValue* mScriptValueCreateFromSInt(int32_t value);
|
||||||
|
|
||||||
bool mScriptTableInsert(struct mScriptValue* table, struct mScriptValue* key, struct mScriptValue* value);
|
bool mScriptTableInsert(struct mScriptValue* table, struct mScriptValue* key, struct mScriptValue* value);
|
||||||
bool mScriptTableRemove(struct mScriptValue* table, struct mScriptValue* key);
|
bool mScriptTableRemove(struct mScriptValue* table, struct mScriptValue* key);
|
||||||
|
|
|
@ -315,7 +315,6 @@ static void _rebuildMemoryMap(struct mScriptCoreAdapter* adapter) {
|
||||||
struct mScriptValue* key = mScriptStringCreateFromUTF8(blocks[i].internalName);
|
struct mScriptValue* key = mScriptStringCreateFromUTF8(blocks[i].internalName);
|
||||||
mScriptTableInsert(&adapter->memory, key, value);
|
mScriptTableInsert(&adapter->memory, key, value);
|
||||||
mScriptValueDeref(key);
|
mScriptValueDeref(key);
|
||||||
mScriptValueDeref(value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,9 +69,7 @@ static const uint8_t _fakeGBROM[0x4000] = {
|
||||||
#define LOAD_PROGRAM(PROG) \
|
#define LOAD_PROGRAM(PROG) \
|
||||||
do { \
|
do { \
|
||||||
struct VFile* vf = VFileFromConstMemory(PROG, strlen(PROG)); \
|
struct VFile* vf = VFileFromConstMemory(PROG, strlen(PROG)); \
|
||||||
const char* error = NULL; \
|
assert_true(lua->load(lua, vf)); \
|
||||||
assert_true(lua->load(lua, vf, &error)); \
|
|
||||||
assert_null(error); \
|
|
||||||
vf->close(vf); \
|
vf->close(vf); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <mgba/core/blip_buf.h>
|
#include <mgba/core/blip_buf.h>
|
||||||
#include <mgba/core/core.h>
|
#include <mgba/core/core.h>
|
||||||
#ifdef ENABLE_SCRIPTING
|
#ifdef ENABLE_SCRIPTING
|
||||||
|
#include <mgba/script/context.h>
|
||||||
#include <mgba/core/scripting.h>
|
#include <mgba/core/scripting.h>
|
||||||
#endif
|
#endif
|
||||||
#include <mgba/core/serialize.h>
|
#include <mgba/core/serialize.h>
|
||||||
|
|
|
@ -59,7 +59,7 @@ void mScriptContextInit(struct mScriptContext* context) {
|
||||||
HashTableInit(&context->engines, 0, _engineContextDestroy);
|
HashTableInit(&context->engines, 0, _engineContextDestroy);
|
||||||
mScriptListInit(&context->refPool, 0);
|
mScriptListInit(&context->refPool, 0);
|
||||||
TableInit(&context->weakrefs, 0, (void (*)(void*)) mScriptValueDeref);
|
TableInit(&context->weakrefs, 0, (void (*)(void*)) mScriptValueDeref);
|
||||||
context->nextWeakref = 0;
|
context->nextWeakref = 1;
|
||||||
HashTableInit(&context->callbacks, 0, (void (*)(void*)) mScriptValueDeref);
|
HashTableInit(&context->callbacks, 0, (void (*)(void*)) mScriptValueDeref);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,10 +123,7 @@ void mScriptContextSetGlobal(struct mScriptContext* context, const char* key, st
|
||||||
if (oldValue) {
|
if (oldValue) {
|
||||||
mScriptContextClearWeakref(context, oldValue->value.u32);
|
mScriptContextClearWeakref(context, oldValue->value.u32);
|
||||||
}
|
}
|
||||||
uint32_t weakref = mScriptContextSetWeakref(context, value);
|
value = mScriptContextMakeWeakref(context, value);
|
||||||
mScriptValueDeref(value);
|
|
||||||
value = mScriptValueAlloc(mSCRIPT_TYPE_MS_WEAKREF);
|
|
||||||
value->value.u32 = weakref;
|
|
||||||
HashTableInsert(&context->rootScope, key, value);
|
HashTableInsert(&context->rootScope, key, value);
|
||||||
struct mScriptKVPair pair = {
|
struct mScriptKVPair pair = {
|
||||||
.key = key,
|
.key = key,
|
||||||
|
@ -135,6 +132,14 @@ void mScriptContextSetGlobal(struct mScriptContext* context, const char* key, st
|
||||||
HashTableEnumerate(&context->engines, _contextAddGlobal, &pair);
|
HashTableEnumerate(&context->engines, _contextAddGlobal, &pair);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct mScriptValue* mScriptContextGetGlobal(struct mScriptContext* context, const char* key) {
|
||||||
|
struct mScriptValue* weakref = HashTableLookup(&context->rootScope, key);
|
||||||
|
if (!weakref) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return mScriptContextAccessWeakref(context, weakref);
|
||||||
|
}
|
||||||
|
|
||||||
void mScriptContextRemoveGlobal(struct mScriptContext* context, const char* key) {
|
void mScriptContextRemoveGlobal(struct mScriptContext* context, const char* key) {
|
||||||
if (!HashTableLookup(&context->rootScope, key)) {
|
if (!HashTableLookup(&context->rootScope, key)) {
|
||||||
return;
|
return;
|
||||||
|
@ -148,6 +153,15 @@ void mScriptContextRemoveGlobal(struct mScriptContext* context, const char* key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct mScriptValue* mScriptContextEnsureGlobal(struct mScriptContext* context, const char* key, const struct mScriptType* type) {
|
||||||
|
struct mScriptValue* value = mScriptContextGetGlobal(context, key);
|
||||||
|
if (!value) {
|
||||||
|
mScriptContextSetGlobal(context, key, mScriptValueAlloc(type));
|
||||||
|
value = mScriptContextGetGlobal(context, key);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t mScriptContextSetWeakref(struct mScriptContext* context, struct mScriptValue* value) {
|
uint32_t mScriptContextSetWeakref(struct mScriptContext* context, struct mScriptValue* value) {
|
||||||
mScriptValueRef(value);
|
mScriptValueRef(value);
|
||||||
TableInsert(&context->weakrefs, context->nextWeakref, value);
|
TableInsert(&context->weakrefs, context->nextWeakref, value);
|
||||||
|
@ -219,7 +233,7 @@ bool mScriptContextLoadVF(struct mScriptContext* context, const char* name, stru
|
||||||
if (!info.context) {
|
if (!info.context) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return info.context->load(info.context, vf, NULL);
|
return info.context->load(info.context, vf);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool mScriptContextLoadFile(struct mScriptContext* context, const char* path) {
|
bool mScriptContextLoadFile(struct mScriptContext* context, const char* path) {
|
||||||
|
|
|
@ -18,7 +18,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 bool _luaLoad(struct mScriptEngineContext*, struct VFile*, const char** error);
|
static bool _luaLoad(struct mScriptEngineContext*, struct VFile*);
|
||||||
static bool _luaRun(struct mScriptEngineContext*);
|
static bool _luaRun(struct mScriptEngineContext*);
|
||||||
static const char* _luaGetError(struct mScriptEngineContext*);
|
static const char* _luaGetError(struct mScriptEngineContext*);
|
||||||
|
|
||||||
|
@ -333,28 +333,25 @@ static const char* _reader(lua_State* lua, void* context, size_t* size) {
|
||||||
return reader->block;
|
return reader->block;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _luaLoad(struct mScriptEngineContext* ctx, struct VFile* vf, const char** error) {
|
bool _luaLoad(struct mScriptEngineContext* ctx, struct VFile* vf) {
|
||||||
struct mScriptEngineContextLua* luaContext = (struct mScriptEngineContextLua*) ctx;
|
struct mScriptEngineContextLua* luaContext = (struct mScriptEngineContextLua*) ctx;
|
||||||
struct mScriptEngineLuaReader data = {
|
struct mScriptEngineLuaReader data = {
|
||||||
.vf = vf
|
.vf = vf
|
||||||
};
|
};
|
||||||
|
if (luaContext->lastError) {
|
||||||
|
free(luaContext->lastError);
|
||||||
|
luaContext->lastError = NULL;
|
||||||
|
}
|
||||||
int ret = lua_load(luaContext->lua, _reader, &data, NULL, "t");
|
int ret = lua_load(luaContext->lua, _reader, &data, NULL, "t");
|
||||||
switch (ret) {
|
switch (ret) {
|
||||||
case LUA_OK:
|
case LUA_OK:
|
||||||
if (error) {
|
|
||||||
*error = NULL;
|
|
||||||
}
|
|
||||||
luaContext->func = luaL_ref(luaContext->lua, LUA_REGISTRYINDEX);
|
luaContext->func = luaL_ref(luaContext->lua, LUA_REGISTRYINDEX);
|
||||||
return true;
|
return true;
|
||||||
case LUA_ERRSYNTAX:
|
case LUA_ERRSYNTAX:
|
||||||
if (error) {
|
luaContext->lastError = strdup(lua_tostring(luaContext->lua, -1));
|
||||||
*error = "Syntax error";
|
lua_pop(luaContext->lua, 1);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (error) {
|
|
||||||
*error = "Unknown error";
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -15,9 +15,7 @@
|
||||||
#define LOAD_PROGRAM(PROG) \
|
#define LOAD_PROGRAM(PROG) \
|
||||||
do { \
|
do { \
|
||||||
struct VFile* vf = VFileFromConstMemory(PROG, strlen(PROG)); \
|
struct VFile* vf = VFileFromConstMemory(PROG, strlen(PROG)); \
|
||||||
const char* error = NULL; \
|
assert_true(lua->load(lua, vf)); \
|
||||||
assert_true(lua->load(lua, vf, &error)); \
|
|
||||||
assert_null(error); \
|
|
||||||
vf->close(vf); \
|
vf->close(vf); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
@ -116,9 +114,7 @@ M_TEST_DEFINE(loadGood) {
|
||||||
|
|
||||||
const char* program = "-- test\n";
|
const char* program = "-- test\n";
|
||||||
struct VFile* vf = VFileFromConstMemory(program, strlen(program));
|
struct VFile* vf = VFileFromConstMemory(program, strlen(program));
|
||||||
const char* error = NULL;
|
assert_true(lua->load(lua, vf));
|
||||||
assert_true(lua->load(lua, vf, &error));
|
|
||||||
assert_null(error);
|
|
||||||
|
|
||||||
lua->destroy(lua);
|
lua->destroy(lua);
|
||||||
mScriptContextDeinit(&context);
|
mScriptContextDeinit(&context);
|
||||||
|
@ -132,9 +128,7 @@ M_TEST_DEFINE(loadBadSyntax) {
|
||||||
|
|
||||||
const char* program = "Invalid syntax! )\n";
|
const char* program = "Invalid syntax! )\n";
|
||||||
struct VFile* vf = VFileFromConstMemory(program, strlen(program));
|
struct VFile* vf = VFileFromConstMemory(program, strlen(program));
|
||||||
const char* error = NULL;
|
assert_false(lua->load(lua, vf));
|
||||||
assert_false(lua->load(lua, vf, &error));
|
|
||||||
assert_non_null(error);
|
|
||||||
|
|
||||||
lua->destroy(lua);
|
lua->destroy(lua);
|
||||||
mScriptContextDeinit(&context);
|
mScriptContextDeinit(&context);
|
||||||
|
|
|
@ -741,6 +741,17 @@ struct mScriptValue* mScriptStringCreateFromUTF8(const char* string) {
|
||||||
internal->buffer = strdup(string);
|
internal->buffer = strdup(string);
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
struct mScriptValue* mScriptValueCreateFromSInt(int32_t value) {
|
||||||
|
struct mScriptValue* val = mScriptValueAlloc(mSCRIPT_TYPE_MS_S32);
|
||||||
|
val->value.s32 = value;
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mScriptValue* mScriptValueCreateFromUInt(uint32_t value) {
|
||||||
|
struct mScriptValue* val = mScriptValueAlloc(mSCRIPT_TYPE_MS_U32);
|
||||||
|
val->value.u32 = value;
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
bool mScriptTableInsert(struct mScriptValue* table, struct mScriptValue* key, struct mScriptValue* value) {
|
bool mScriptTableInsert(struct mScriptValue* table, struct mScriptValue* key, struct mScriptValue* value) {
|
||||||
if (table->type != mSCRIPT_TYPE_MS_TABLE) {
|
if (table->type != mSCRIPT_TYPE_MS_TABLE) {
|
||||||
|
@ -768,6 +779,9 @@ bool mScriptTableRemove(struct mScriptValue* table, struct mScriptValue* key) {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct mScriptValue* mScriptTableLookup(struct mScriptValue* table, struct mScriptValue* key) {
|
struct mScriptValue* mScriptTableLookup(struct mScriptValue* table, struct mScriptValue* key) {
|
||||||
|
if (table->type == mSCRIPT_TYPE_MS_WRAPPER) {
|
||||||
|
table = mScriptValueUnwrap(table);
|
||||||
|
}
|
||||||
if (table->type != mSCRIPT_TYPE_MS_TABLE) {
|
if (table->type != mSCRIPT_TYPE_MS_TABLE) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1003,6 +1017,7 @@ static bool _accessRawMember(struct mScriptClassMember* member, void* raw, bool
|
||||||
break;
|
break;
|
||||||
case mSCRIPT_TYPE_TABLE:
|
case mSCRIPT_TYPE_TABLE:
|
||||||
val->refs = mSCRIPT_VALUE_UNREF;
|
val->refs = mSCRIPT_VALUE_UNREF;
|
||||||
|
val->flags = 0;
|
||||||
val->type = mSCRIPT_TYPE_MS_WRAPPER;
|
val->type = mSCRIPT_TYPE_MS_WRAPPER;
|
||||||
val->value.opaque = raw;
|
val->value.opaque = raw;
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue