diff options
author | George Marques <george@gmarqu.es> | 2022-04-20 14:22:22 -0300 |
---|---|---|
committer | George Marques <george@gmarqu.es> | 2022-04-24 21:49:02 -0300 |
commit | 01d13ab2c16aa69a6f81c10dfe4845a50c3e0c63 (patch) | |
tree | a469ac2f5102117868a37b43a5ad167a3cb62e99 /modules/gdscript/gdscript_vm.cpp | |
parent | 690fefe43ee74c0ae3ed5642f3aefbeb711f9d1c (diff) | |
download | redot-engine-01d13ab2c16aa69a6f81c10dfe4845a50c3e0c63.tar.gz |
GDScript: Allow using self in lambdas
Diffstat (limited to 'modules/gdscript/gdscript_vm.cpp')
-rw-r--r-- | modules/gdscript/gdscript_vm.cpp | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/modules/gdscript/gdscript_vm.cpp b/modules/gdscript/gdscript_vm.cpp index 2afb850c32..e28dd26c28 100644 --- a/modules/gdscript/gdscript_vm.cpp +++ b/modules/gdscript/gdscript_vm.cpp @@ -306,6 +306,7 @@ void (*type_init_function_table[])(Variant *) = { &&OPCODE_AWAIT, \ &&OPCODE_AWAIT_RESUME, \ &&OPCODE_CREATE_LAMBDA, \ + &&OPCODE_CREATE_SELF_LAMBDA, \ &&OPCODE_JUMP, \ &&OPCODE_JUMP_IF, \ &&OPCODE_JUMP_IF_NOT, \ @@ -2277,6 +2278,41 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a } DISPATCH_OPCODE; + OPCODE(OPCODE_CREATE_SELF_LAMBDA) { + CHECK_SPACE(2 + instr_arg_count); + + GD_ERR_BREAK(p_instance == nullptr); + + ip += instr_arg_count; + + int captures_count = _code_ptr[ip + 1]; + GD_ERR_BREAK(captures_count < 0); + + int lambda_index = _code_ptr[ip + 2]; + GD_ERR_BREAK(lambda_index < 0 || lambda_index >= _lambdas_count); + GDScriptFunction *lambda = _lambdas_ptr[lambda_index]; + + Vector<Variant> captures; + captures.resize(captures_count); + for (int i = 0; i < captures_count; i++) { + GET_INSTRUCTION_ARG(arg, i); + captures.write[i] = *arg; + } + + GDScriptLambdaSelfCallable *callable; + if (Object::cast_to<RefCounted>(p_instance->owner)) { + callable = memnew(GDScriptLambdaSelfCallable(Ref<RefCounted>(Object::cast_to<RefCounted>(p_instance->owner)), lambda, captures)); + } else { + callable = memnew(GDScriptLambdaSelfCallable(p_instance->owner, lambda, captures)); + } + + GET_INSTRUCTION_ARG(result, captures_count); + *result = Callable(callable); + + ip += 3; + } + DISPATCH_OPCODE; + OPCODE(OPCODE_JUMP) { CHECK_SPACE(2); int to = _code_ptr[ip + 1]; |