You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-07 12:30:27 +00:00
Add a const call mode to Object, Variant and Script.
For this to work safely (user not call queue_free or something in the expression), a const call mode was added to Object and Variant (and optionally Script). This mode ensures only const functions can be called, making it safe to use from the editor. Co-Authored-By: reduz <reduzio@gmail.com>
This commit is contained in:
@@ -669,6 +669,7 @@ Variant Object::callp(const StringName &p_method, const Variant **p_args, int p_
|
||||
case Callable::CallError::CALL_ERROR_INVALID_ARGUMENT:
|
||||
case Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS:
|
||||
case Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS:
|
||||
case Callable::CallError::CALL_ERROR_METHOD_NOT_CONST:
|
||||
return ret;
|
||||
case Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL: {
|
||||
}
|
||||
@@ -688,6 +689,54 @@ Variant Object::callp(const StringName &p_method, const Variant **p_args, int p_
|
||||
return ret;
|
||||
}
|
||||
|
||||
Variant Object::call_const(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
|
||||
r_error.error = Callable::CallError::CALL_OK;
|
||||
|
||||
if (p_method == CoreStringNames::get_singleton()->_free) {
|
||||
// Free is not const, so fail.
|
||||
r_error.error = Callable::CallError::CALL_ERROR_METHOD_NOT_CONST;
|
||||
return Variant();
|
||||
}
|
||||
|
||||
Variant ret;
|
||||
OBJ_DEBUG_LOCK
|
||||
|
||||
if (script_instance) {
|
||||
ret = script_instance->call_const(p_method, p_args, p_argcount, r_error);
|
||||
//force jumptable
|
||||
switch (r_error.error) {
|
||||
case Callable::CallError::CALL_OK:
|
||||
return ret;
|
||||
case Callable::CallError::CALL_ERROR_INVALID_METHOD:
|
||||
break;
|
||||
case Callable::CallError::CALL_ERROR_METHOD_NOT_CONST:
|
||||
break;
|
||||
case Callable::CallError::CALL_ERROR_INVALID_ARGUMENT:
|
||||
case Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS:
|
||||
case Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS:
|
||||
return ret;
|
||||
case Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL: {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//extension does not need this, because all methods are registered in MethodBind
|
||||
|
||||
MethodBind *method = ClassDB::get_method(get_class_name(), p_method);
|
||||
|
||||
if (method) {
|
||||
if (!method->is_const()) {
|
||||
r_error.error = Callable::CallError::CALL_ERROR_METHOD_NOT_CONST;
|
||||
return ret;
|
||||
}
|
||||
ret = method->call(this, p_args, p_argcount, r_error);
|
||||
} else {
|
||||
r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Object::notification(int p_notification, bool p_reversed) {
|
||||
_notificationv(p_notification, p_reversed);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user