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 {
|
do {
|
||||||
struct mScriptFrame frame;
|
struct mScriptFrame frame;
|
||||||
struct mScriptCallbackInfo* info = TableIteratorGetValue(table, &iter);
|
struct mScriptCallbackInfo* info = TableIteratorGetValue(table, &iter);
|
||||||
mScriptFrameInit(&frame);
|
struct mScriptValue* fn = mScriptContextAccessWeakref(context, info->fn);
|
||||||
if (args) {
|
if (fn) {
|
||||||
mScriptListCopy(&frame.arguments, args);
|
mScriptFrameInit(&frame);
|
||||||
|
if (args) {
|
||||||
|
mScriptListCopy(&frame.arguments, args);
|
||||||
|
}
|
||||||
|
mScriptInvoke(fn, &frame);
|
||||||
|
mScriptFrameDeinit(&frame);
|
||||||
}
|
}
|
||||||
mScriptInvoke(info->fn, &frame);
|
|
||||||
mScriptFrameDeinit(&frame);
|
|
||||||
|
|
||||||
if (info->oneshot) {
|
if (info->oneshot) {
|
||||||
*UInt32ListAppend(&oneshots) = info->id;
|
*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) {
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
struct Table* table = HashTableLookup(&context->callbacks, callback);
|
struct Table* table = HashTableLookup(&context->callbacks, callback);
|
||||||
|
|
|
@ -126,9 +126,53 @@ M_TEST_DEFINE(oneshot) {
|
||||||
mScriptContextDeinit(&context);
|
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,
|
M_TEST_SUITE_DEFINE_SETUP_TEARDOWN(mScriptStdlib,
|
||||||
cmocka_unit_test(bitMask),
|
cmocka_unit_test(bitMask),
|
||||||
cmocka_unit_test(bitUnmask),
|
cmocka_unit_test(bitUnmask),
|
||||||
cmocka_unit_test(callbacks),
|
cmocka_unit_test(callbacks),
|
||||||
cmocka_unit_test(oneshot),
|
cmocka_unit_test(oneshot),
|
||||||
|
cmocka_unit_test(callbackWeakref),
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue