From 0b79184bf36f580e5638d871c0d76fbafa0b17ea Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 24 Apr 2023 03:41:33 -0700 Subject: [PATCH] Scripting: Add lambdas that bind an object method call --- include/mgba/script/types.h | 1 + src/script/types.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/include/mgba/script/types.h b/include/mgba/script/types.h index 8e3b0b560..d5a6d9947 100644 --- a/include/mgba/script/types.h +++ b/include/mgba/script/types.h @@ -345,6 +345,7 @@ bool mScriptObjectGetConst(const struct mScriptValue* obj, const char* member, s bool mScriptObjectSet(struct mScriptValue* obj, const char* member, struct mScriptValue*); bool mScriptObjectCast(const struct mScriptValue* input, const struct mScriptType* type, struct mScriptValue* output) ; void mScriptObjectFree(struct mScriptValue* obj); +struct mScriptValue* mScriptObjectBindLambda(struct mScriptValue* obj, const char* member, struct mScriptList* args); bool mScriptPopS32(struct mScriptList* list, int32_t* out); bool mScriptPopU32(struct mScriptList* list, uint32_t* out); diff --git a/src/script/types.c b/src/script/types.c index e80c018fb..16ef78df4 100644 --- a/src/script/types.c +++ b/src/script/types.c @@ -1682,6 +1682,40 @@ void mScriptObjectFree(struct mScriptValue* value) { } } +struct mScriptValue* mScriptObjectBindLambda(struct mScriptValue* obj, const char* member, struct mScriptList* args) { + if (obj->type->base != mSCRIPT_TYPE_OBJECT) { + return false; + } + + struct mScriptTypeClass* cls = obj->type->details.cls; + if (!cls) { + return false; + } + + mScriptClassInit(cls); + + struct mScriptList arguments; + struct mScriptValue fn; + if (!mScriptObjectGetConst(obj, member, &fn)) { + return NULL; + } + + mScriptListInit(&arguments, 0); + mScriptValueWrap(obj, mScriptListAppend(&arguments)); + if (args) { + size_t i; + for (i = 0; i < mScriptListSize(args); ++i) { + memcpy(mScriptListAppend(&arguments), mScriptListGetConstPointer(args, i), sizeof(struct mScriptValue)); + } + } + + struct mScriptValue* value = mScriptValueAlloc(fn.type); + struct mScriptValue* lambda = mScriptLambdaCreate0(value, &arguments); + mScriptValueDeref(value); + mScriptListDeinit(&arguments); + return lambda; +} + bool mScriptPopS32(struct mScriptList* list, int32_t* out) { mSCRIPT_POP(list, S32, val); *out = val;