summaryrefslogtreecommitdiffstats
path: root/core/variant
diff options
context:
space:
mode:
Diffstat (limited to 'core/variant')
-rw-r--r--core/variant/callable.cpp25
-rw-r--r--core/variant/callable.h6
-rw-r--r--core/variant/callable_bind.cpp67
-rw-r--r--core/variant/callable_bind.h6
-rw-r--r--core/variant/variant.cpp16
-rw-r--r--core/variant/variant_call.cpp1
6 files changed, 64 insertions, 57 deletions
diff --git a/core/variant/callable.cpp b/core/variant/callable.cpp
index 5ce90cd8ff..ddeea27118 100644
--- a/core/variant/callable.cpp
+++ b/core/variant/callable.cpp
@@ -206,19 +206,17 @@ int Callable::get_bound_arguments_count() const {
}
}
-void Callable::get_bound_arguments_ref(Vector<Variant> &r_arguments, int &r_argcount) const {
+void Callable::get_bound_arguments_ref(Vector<Variant> &r_arguments) const {
if (!is_null() && is_custom()) {
- custom->get_bound_arguments(r_arguments, r_argcount);
+ custom->get_bound_arguments(r_arguments);
} else {
r_arguments.clear();
- r_argcount = 0;
}
}
Array Callable::get_bound_arguments() const {
Vector<Variant> arr;
- int ac;
- get_bound_arguments_ref(arr, ac);
+ get_bound_arguments_ref(arr);
Array ret;
ret.resize(arr.size());
for (int i = 0; i < arr.size(); i++) {
@@ -227,6 +225,14 @@ Array Callable::get_bound_arguments() const {
return ret;
}
+int Callable::get_unbound_arguments_count() const {
+ if (!is_null() && is_custom()) {
+ return custom->get_unbound_arguments_count();
+ } else {
+ return 0;
+ }
+}
+
CallableCustom *Callable::get_custom() const {
ERR_FAIL_COND_V_MSG(!is_custom(), nullptr,
vformat("Can't get custom on non-CallableCustom \"%s\".", operator String()));
@@ -464,9 +470,12 @@ int CallableCustom::get_bound_arguments_count() const {
return 0;
}
-void CallableCustom::get_bound_arguments(Vector<Variant> &r_arguments, int &r_argcount) const {
- r_arguments = Vector<Variant>();
- r_argcount = 0;
+void CallableCustom::get_bound_arguments(Vector<Variant> &r_arguments) const {
+ r_arguments.clear();
+}
+
+int CallableCustom::get_unbound_arguments_count() const {
+ return 0;
}
CallableCustom::CallableCustom() {
diff --git a/core/variant/callable.h b/core/variant/callable.h
index e3c940a0e5..e76b888ac2 100644
--- a/core/variant/callable.h
+++ b/core/variant/callable.h
@@ -111,8 +111,9 @@ public:
CallableCustom *get_custom() const;
int get_argument_count(bool *r_is_valid = nullptr) const;
int get_bound_arguments_count() const;
- void get_bound_arguments_ref(Vector<Variant> &r_arguments, int &r_argcount) const; // Internal engine use, the exposed one is below.
+ void get_bound_arguments_ref(Vector<Variant> &r_arguments) const; // Internal engine use, the exposed one is below.
Array get_bound_arguments() const;
+ int get_unbound_arguments_count() const;
uint32_t hash() const;
@@ -158,7 +159,8 @@ public:
virtual const Callable *get_base_comparator() const;
virtual int get_argument_count(bool &r_is_valid) const;
virtual int get_bound_arguments_count() const;
- virtual void get_bound_arguments(Vector<Variant> &r_arguments, int &r_argcount) const;
+ virtual void get_bound_arguments(Vector<Variant> &r_arguments) const;
+ virtual int get_unbound_arguments_count() const;
CallableCustom();
virtual ~CallableCustom() {}
diff --git a/core/variant/callable_bind.cpp b/core/variant/callable_bind.cpp
index afb889551e..43cac263c1 100644
--- a/core/variant/callable_bind.cpp
+++ b/core/variant/callable_bind.cpp
@@ -100,44 +100,42 @@ int CallableCustomBind::get_argument_count(bool &r_is_valid) const {
}
int CallableCustomBind::get_bound_arguments_count() const {
- return callable.get_bound_arguments_count() + binds.size();
+ return callable.get_bound_arguments_count() + MAX(0, binds.size() - callable.get_unbound_arguments_count());
}
-void CallableCustomBind::get_bound_arguments(Vector<Variant> &r_arguments, int &r_argcount) const {
- Vector<Variant> sub_args;
- int sub_count;
- callable.get_bound_arguments_ref(sub_args, sub_count);
+void CallableCustomBind::get_bound_arguments(Vector<Variant> &r_arguments) const {
+ Vector<Variant> sub_bound_args;
+ callable.get_bound_arguments_ref(sub_bound_args);
+ int sub_bound_count = sub_bound_args.size();
- if (sub_count == 0) {
+ int sub_unbound_count = callable.get_unbound_arguments_count();
+
+ if (sub_bound_count == 0 && sub_unbound_count == 0) {
r_arguments = binds;
- r_argcount = binds.size();
return;
}
- int new_count = sub_count + binds.size();
- r_argcount = new_count;
+ int added_count = MAX(0, binds.size() - sub_unbound_count);
+ int new_count = sub_bound_count + added_count;
- if (new_count <= 0) {
- // Removed more arguments than it adds.
- r_arguments = Vector<Variant>();
+ if (added_count <= 0) {
+ // All added arguments are consumed by `sub_unbound_count`.
+ r_arguments = sub_bound_args;
return;
}
r_arguments.resize(new_count);
-
- if (sub_count > 0) {
- for (int i = 0; i < sub_count; i++) {
- r_arguments.write[i] = sub_args[i];
- }
- for (int i = 0; i < binds.size(); i++) {
- r_arguments.write[i + sub_count] = binds[i];
- }
- r_argcount = new_count;
- } else {
- for (int i = 0; i < binds.size() + sub_count; i++) {
- r_arguments.write[i] = binds[i - sub_count];
- }
+ Variant *args = r_arguments.ptrw();
+ for (int i = 0; i < added_count; i++) {
+ args[i] = binds[i];
}
+ for (int i = 0; i < sub_bound_count; i++) {
+ args[i + added_count] = sub_bound_args[i];
+ }
+}
+
+int CallableCustomBind::get_unbound_arguments_count() const {
+ return MAX(0, callable.get_unbound_arguments_count() - binds.size());
}
void CallableCustomBind::call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const {
@@ -242,22 +240,15 @@ int CallableCustomUnbind::get_argument_count(bool &r_is_valid) const {
}
int CallableCustomUnbind::get_bound_arguments_count() const {
- return callable.get_bound_arguments_count() - argcount;
+ return callable.get_bound_arguments_count();
}
-void CallableCustomUnbind::get_bound_arguments(Vector<Variant> &r_arguments, int &r_argcount) const {
- Vector<Variant> sub_args;
- int sub_count;
- callable.get_bound_arguments_ref(sub_args, sub_count);
-
- r_argcount = sub_args.size() - argcount;
+void CallableCustomUnbind::get_bound_arguments(Vector<Variant> &r_arguments) const {
+ callable.get_bound_arguments_ref(r_arguments);
+}
- if (argcount >= sub_args.size()) {
- r_arguments = Vector<Variant>();
- } else {
- sub_args.resize(sub_args.size() - argcount);
- r_arguments = sub_args;
- }
+int CallableCustomUnbind::get_unbound_arguments_count() const {
+ return callable.get_unbound_arguments_count() + argcount;
}
void CallableCustomUnbind::call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const {
diff --git a/core/variant/callable_bind.h b/core/variant/callable_bind.h
index 43cebb45f0..1346277197 100644
--- a/core/variant/callable_bind.h
+++ b/core/variant/callable_bind.h
@@ -55,7 +55,8 @@ public:
virtual const Callable *get_base_comparator() const override;
virtual int get_argument_count(bool &r_is_valid) const override;
virtual int get_bound_arguments_count() const override;
- virtual void get_bound_arguments(Vector<Variant> &r_arguments, int &r_argcount) const override;
+ virtual void get_bound_arguments(Vector<Variant> &r_arguments) const override;
+ virtual int get_unbound_arguments_count() const override;
Callable get_callable() { return callable; }
Vector<Variant> get_binds() { return binds; }
@@ -84,7 +85,8 @@ public:
virtual const Callable *get_base_comparator() const override;
virtual int get_argument_count(bool &r_is_valid) const override;
virtual int get_bound_arguments_count() const override;
- virtual void get_bound_arguments(Vector<Variant> &r_arguments, int &r_argcount) const override;
+ virtual void get_bound_arguments(Vector<Variant> &r_arguments) const override;
+ virtual int get_unbound_arguments_count() const override;
Callable get_callable() { return callable; }
int get_unbinds() { return argcount; }
diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp
index 54936eb8a2..3e74dc4e67 100644
--- a/core/variant/variant.cpp
+++ b/core/variant/variant.cpp
@@ -3664,18 +3664,20 @@ String Variant::get_call_error_text(Object *p_base, const StringName &p_method,
String Variant::get_callable_error_text(const Callable &p_callable, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce) {
Vector<Variant> binds;
- int args_bound;
- p_callable.get_bound_arguments_ref(binds, args_bound);
- if (args_bound <= 0) {
- return get_call_error_text(p_callable.get_object(), p_callable.get_method(), p_argptrs, MAX(0, p_argcount + args_bound), ce);
+ p_callable.get_bound_arguments_ref(binds);
+
+ int args_unbound = p_callable.get_unbound_arguments_count();
+
+ if (p_argcount - args_unbound < 0) {
+ return "Callable unbinds " + itos(args_unbound) + " arguments, but called with " + itos(p_argcount);
} else {
Vector<const Variant *> argptrs;
- argptrs.resize(p_argcount + binds.size());
- for (int i = 0; i < p_argcount; i++) {
+ argptrs.resize(p_argcount - args_unbound + binds.size());
+ for (int i = 0; i < p_argcount - args_unbound; i++) {
argptrs.write[i] = p_argptrs[i];
}
for (int i = 0; i < binds.size(); i++) {
- argptrs.write[i + p_argcount] = &binds[i];
+ argptrs.write[i + p_argcount - args_unbound] = &binds[i];
}
return get_call_error_text(p_callable.get_object(), p_callable.get_method(), (const Variant **)argptrs.ptr(), argptrs.size(), ce);
}
diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp
index 29e11462c9..381b848b2b 100644
--- a/core/variant/variant_call.cpp
+++ b/core/variant/variant_call.cpp
@@ -2116,6 +2116,7 @@ static void _register_variant_builtin_methods_misc() {
bind_function(Callable, get_argument_count, _VariantCall::func_Callable_get_argument_count, sarray(), varray());
bind_method(Callable, get_bound_arguments_count, sarray(), varray());
bind_method(Callable, get_bound_arguments, sarray(), varray());
+ bind_method(Callable, get_unbound_arguments_count, sarray(), varray());
bind_method(Callable, hash, sarray(), varray());
bind_method(Callable, bindv, sarray("arguments"), varray());
bind_method(Callable, unbind, sarray("argcount"), varray());