summaryrefslogtreecommitdiffstats
path: root/core/variant
diff options
context:
space:
mode:
authorSlashscreen <SlashScreen@users.noreply.github.com>2024-08-11 23:28:32 -0700
committerSlashscreen <SlashScreen@users.noreply.github.com>2024-09-13 00:01:53 -0700
commit89491f4403041ec81e8506a45f00f54033e45202 (patch)
tree38a94b063ee20a0f88a754f016bb11900cc5c2a7 /core/variant
parent88f3b5f9d52f740b24fabfb8bc01b8b7026ba279 (diff)
downloadredot-engine-89491f4403041ec81e8506a45f00f54033e45202.tar.gz
Add callable support for `find` and `rfind` `Array` methods
Diffstat (limited to 'core/variant')
-rw-r--r--core/variant/array.cpp65
-rw-r--r--core/variant/array.h2
-rw-r--r--core/variant/variant_call.cpp2
3 files changed, 68 insertions, 1 deletions
diff --git a/core/variant/array.cpp b/core/variant/array.cpp
index 54cd1eda2f..5d3292d0b9 100644
--- a/core/variant/array.cpp
+++ b/core/variant/array.cpp
@@ -369,6 +369,34 @@ int Array::find(const Variant &p_value, int p_from) const {
return ret;
}
+int Array::find_custom(const Callable &p_callable, int p_from) const {
+ int ret = -1;
+
+ if (p_from < 0 || size() == 0) {
+ return ret;
+ }
+
+ const Variant *argptrs[1];
+
+ for (int i = p_from; i < size(); i++) {
+ const Variant &val = _p->array[i];
+ argptrs[0] = &val;
+ Variant res;
+ Callable::CallError ce;
+ p_callable.callp(argptrs, 1, res, ce);
+ if (unlikely(ce.error != Callable::CallError::CALL_OK)) {
+ ERR_FAIL_V_MSG(ret, "Error calling method from 'find_custom': " + Variant::get_callable_error_text(p_callable, argptrs, 1, ce));
+ }
+
+ ERR_FAIL_COND_V_MSG(res.get_type() != Variant::Type::BOOL, ret, "Error on method from 'find_custom': Return type of callable must be boolean.");
+ if (res.operator bool()) {
+ return i;
+ }
+ }
+
+ return ret;
+}
+
int Array::rfind(const Variant &p_value, int p_from) const {
if (_p->array.size() == 0) {
return -1;
@@ -394,6 +422,41 @@ int Array::rfind(const Variant &p_value, int p_from) const {
return -1;
}
+int Array::rfind_custom(const Callable &p_callable, int p_from) const {
+ if (_p->array.size() == 0) {
+ return -1;
+ }
+
+ if (p_from < 0) {
+ // Relative offset from the end.
+ p_from = _p->array.size() + p_from;
+ }
+ if (p_from < 0 || p_from >= _p->array.size()) {
+ // Limit to array boundaries.
+ p_from = _p->array.size() - 1;
+ }
+
+ const Variant *argptrs[1];
+
+ for (int i = p_from; i >= 0; i--) {
+ const Variant &val = _p->array[i];
+ argptrs[0] = &val;
+ Variant res;
+ Callable::CallError ce;
+ p_callable.callp(argptrs, 1, res, ce);
+ if (unlikely(ce.error != Callable::CallError::CALL_OK)) {
+ ERR_FAIL_V_MSG(-1, "Error calling method from 'rfind_custom': " + Variant::get_callable_error_text(p_callable, argptrs, 1, ce));
+ }
+
+ ERR_FAIL_COND_V_MSG(res.get_type() != Variant::Type::BOOL, -1, "Error on method from 'rfind_custom': Return type of callable must be boolean.");
+ if (res.operator bool()) {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
int Array::count(const Variant &p_value) const {
Variant value = p_value;
ERR_FAIL_COND_V(!_p->typed.validate(value, "count"), 0);
@@ -761,7 +824,7 @@ Variant Array::max() const {
return Variant(); //not a valid comparison
}
if (bool(ret)) {
- //is less
+ //is greater
maxval = test;
}
}
diff --git a/core/variant/array.h b/core/variant/array.h
index 3aa957b312..ec6c078fb8 100644
--- a/core/variant/array.h
+++ b/core/variant/array.h
@@ -152,7 +152,9 @@ public:
void reverse();
int find(const Variant &p_value, int p_from = 0) const;
+ int find_custom(const Callable &p_callable, int p_from = 0) const;
int rfind(const Variant &p_value, int p_from = -1) const;
+ int rfind_custom(const Callable &p_callable, int p_from = -1) const;
int count(const Variant &p_value) const;
bool has(const Variant &p_value) const;
diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp
index 5e402937cf..65eea9115b 100644
--- a/core/variant/variant_call.cpp
+++ b/core/variant/variant_call.cpp
@@ -2289,7 +2289,9 @@ static void _register_variant_builtin_methods_array() {
bind_method(Array, back, sarray(), varray());
bind_method(Array, pick_random, sarray(), varray());
bind_method(Array, find, sarray("what", "from"), varray(0));
+ bind_method(Array, find_custom, sarray("method", "from"), varray(0));
bind_method(Array, rfind, sarray("what", "from"), varray(-1));
+ bind_method(Array, rfind_custom, sarray("method", "from"), varray(-1));
bind_method(Array, count, sarray("value"), varray());
bind_method(Array, has, sarray("value"), varray());
bind_method(Array, pop_back, sarray(), varray());