summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorRémi Verschelde <rverschelde@gmail.com>2024-09-20 16:06:13 +0200
committerRémi Verschelde <rverschelde@gmail.com>2024-09-20 16:06:13 +0200
commit6bf8a3e3f8dadf485f733b8fd5a502a7d21a2ff1 (patch)
tree9cc17e4db8ecd7c16a9a40d627c1f7021a1a7a92 /core
parentda9764ad438a0dab31f74791d1cf84612ed52c69 (diff)
parent89491f4403041ec81e8506a45f00f54033e45202 (diff)
downloadredot-engine-6bf8a3e3f8dadf485f733b8fd5a502a7d21a2ff1.tar.gz
Merge pull request #95449 from SlashScreen/array_functions
Add callable support for `find` and `rfind` `Array` methods
Diffstat (limited to 'core')
-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 869499e668..3e62d3dffa 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 12824ee3f6..6c3bae6ccb 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 2da94de875..178c0bc4ec 100644
--- a/core/variant/variant_call.cpp
+++ b/core/variant/variant_call.cpp
@@ -2305,7 +2305,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());