1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-14 13:41:12 +00:00

Merge pull request #95449 from SlashScreen/array_functions

Add callable support for `find` and `rfind` `Array` methods
This commit is contained in:
Rémi Verschelde
2024-09-20 16:06:13 +02:00
5 changed files with 125 additions and 1 deletions

View File

@@ -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;
}
}