1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-04 12:00:25 +00:00

GDScript: Allow using self in lambdas

This commit is contained in:
George Marques
2022-04-20 14:22:22 -03:00
parent 690fefe43e
commit 01d13ab2c1
16 changed files with 251 additions and 23 deletions

View File

@@ -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];