summaryrefslogtreecommitdiffstats
path: root/core/variant/variant_call.cpp
diff options
context:
space:
mode:
authorK. S. Ernest (iFire) Lee <ernest.lee@chibifire.com>2022-06-27 13:10:04 -0700
committerK. S. Ernest (iFire) Lee <ernest.lee@chibifire.com>2022-06-27 13:33:06 -0700
commit9ddebc0c22866d6b7a7ff3fa64b67cc86c8664da (patch)
tree3bb41cb3143f197ca53ee93f7375598ef5886ec6 /core/variant/variant_call.cpp
parentc41e4b10c3317f837d4b3ece2fb725a8067d884b (diff)
downloadredot-engine-9ddebc0c22866d6b7a7ff3fa64b67cc86c8664da.tar.gz
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>
Diffstat (limited to 'core/variant/variant_call.cpp')
-rw-r--r--core/variant/variant_call.cpp36
1 files changed, 36 insertions, 0 deletions
diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp
index 8e420ecf04..19c0e35777 100644
--- a/core/variant/variant_call.cpp
+++ b/core/variant/variant_call.cpp
@@ -1031,6 +1031,37 @@ void Variant::callp(const StringName &p_method, const Variant **p_args, int p_ar
#endif
r_ret = _get_obj().obj->callp(p_method, p_args, p_argcount, r_error);
+ } else {
+ r_error.error = Callable::CallError::CALL_OK;
+
+ const VariantBuiltInMethodInfo *imf = builtin_method_info[type].lookup_ptr(p_method);
+
+ if (!imf) {
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
+ return;
+ }
+
+ imf->call(this, p_args, p_argcount, r_ret, imf->default_arguments, r_error);
+ }
+}
+
+void Variant::call_const(const StringName &p_method, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) {
+ if (type == Variant::OBJECT) {
+ //call object
+ Object *obj = _get_obj().obj;
+ if (!obj) {
+ r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL;
+ return;
+ }
+#ifdef DEBUG_ENABLED
+ if (EngineDebugger::is_active() && !_get_obj().id.is_ref_counted() && ObjectDB::get_instance(_get_obj().id) == nullptr) {
+ r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL;
+ return;
+ }
+
+#endif
+ r_ret = _get_obj().obj->call_const(p_method, p_args, p_argcount, r_error);
+
//else if (type==Variant::METHOD) {
} else {
r_error.error = Callable::CallError::CALL_OK;
@@ -1042,6 +1073,11 @@ void Variant::callp(const StringName &p_method, const Variant **p_args, int p_ar
return;
}
+ if (!imf->is_const) {
+ r_error.error = Callable::CallError::CALL_ERROR_METHOD_NOT_CONST;
+ return;
+ }
+
imf->call(this, p_args, p_argcount, r_ret, imf->default_arguments, r_error);
}
}