mirror of https://github.com/mgba-emu/mgba.git
Scripting: Allow callbacks to access weakrefs
This commit is contained in:
parent
eb26b3c387
commit
44ab21ab35
|
@ -235,12 +235,15 @@ void mScriptContextTriggerCallback(struct mScriptContext* context, const char* c
|
|||
do {
|
||||
struct mScriptFrame frame;
|
||||
struct mScriptCallbackInfo* info = TableIteratorGetValue(table, &iter);
|
||||
mScriptFrameInit(&frame);
|
||||
if (args) {
|
||||
mScriptListCopy(&frame.arguments, args);
|
||||
struct mScriptValue* fn = mScriptContextAccessWeakref(context, info->fn);
|
||||
if (fn) {
|
||||
mScriptFrameInit(&frame);
|
||||
if (args) {
|
||||
mScriptListCopy(&frame.arguments, args);
|
||||
}
|
||||
mScriptInvoke(fn, &frame);
|
||||
mScriptFrameDeinit(&frame);
|
||||
}
|
||||
mScriptInvoke(info->fn, &frame);
|
||||
mScriptFrameDeinit(&frame);
|
||||
|
||||
if (info->oneshot) {
|
||||
*UInt32ListAppend(&oneshots) = info->id;
|
||||
|
@ -255,7 +258,15 @@ void mScriptContextTriggerCallback(struct mScriptContext* context, const char* c
|
|||
}
|
||||
|
||||
static uint32_t mScriptContextAddCallbackInternal(struct mScriptContext* context, const char* callback, struct mScriptValue* fn, bool oneshot) {
|
||||
if (fn->type->base != mSCRIPT_TYPE_FUNCTION) {
|
||||
if (fn->type == mSCRIPT_TYPE_MS_WEAKREF) {
|
||||
struct mScriptValue* weakref = mScriptContextAccessWeakref(context, fn);
|
||||
if (!weakref) {
|
||||
return 0;
|
||||
}
|
||||
if (weakref->type->base != mSCRIPT_TYPE_FUNCTION) {
|
||||
return 0;
|
||||
}
|
||||
} else if (fn->type->base != mSCRIPT_TYPE_FUNCTION) {
|
||||
return 0;
|
||||
}
|
||||
struct Table* table = HashTableLookup(&context->callbacks, callback);
|
||||
|
|
|
@ -126,9 +126,53 @@ M_TEST_DEFINE(oneshot) {
|
|||
mScriptContextDeinit(&context);
|
||||
}
|
||||
|
||||
static void _tableIncrement(struct mScriptValue* table) {
|
||||
assert_non_null(table);
|
||||
struct mScriptValue* value = mScriptTableLookup(table, &mSCRIPT_MAKE_CHARP("key"));
|
||||
assert_non_null(value);
|
||||
assert_ptr_equal(value->type, mSCRIPT_TYPE_MS_S32);
|
||||
++value->value.s32;
|
||||
}
|
||||
|
||||
mSCRIPT_BIND_VOID_FUNCTION(tableIncrement, _tableIncrement, 1, WTABLE, table);
|
||||
|
||||
M_TEST_DEFINE(callbackWeakref) {
|
||||
SETUP_LUA;
|
||||
|
||||
struct mScriptValue* table = mScriptValueAlloc(mSCRIPT_TYPE_MS_TABLE);
|
||||
struct mScriptList args;
|
||||
mScriptListInit(&args, 1);
|
||||
mScriptValueWrap(table, mScriptListAppend(&args));
|
||||
struct mScriptValue* lambda = mScriptLambdaCreate0(&tableIncrement, &args);
|
||||
mScriptListDeinit(&args);
|
||||
struct mScriptValue* weakref = mScriptContextMakeWeakref(&context, lambda);
|
||||
mScriptContextAddCallback(&context, "test", weakref);
|
||||
|
||||
struct mScriptValue* key = mScriptStringCreateFromUTF8("key");
|
||||
struct mScriptValue* value = mScriptValueAlloc(mSCRIPT_TYPE_MS_S32);
|
||||
value->value.s32 = 1;
|
||||
mScriptTableInsert(table, key, value);
|
||||
|
||||
mScriptContextTriggerCallback(&context, "test", NULL);
|
||||
assert_int_equal(value->value.s32, 2);
|
||||
|
||||
mScriptContextClearWeakref(&context, weakref->value.u32);
|
||||
mScriptValueDeref(weakref);
|
||||
|
||||
mScriptContextTriggerCallback(&context, "test", NULL);
|
||||
assert_int_equal(value->value.s32, 2);
|
||||
|
||||
mScriptValueDeref(table);
|
||||
mScriptValueDeref(key);
|
||||
mScriptValueDeref(value);
|
||||
|
||||
mScriptContextDeinit(&context);
|
||||
}
|
||||
|
||||
M_TEST_SUITE_DEFINE_SETUP_TEARDOWN(mScriptStdlib,
|
||||
cmocka_unit_test(bitMask),
|
||||
cmocka_unit_test(bitUnmask),
|
||||
cmocka_unit_test(callbacks),
|
||||
cmocka_unit_test(oneshot),
|
||||
cmocka_unit_test(callbackWeakref),
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue