diff options
author | Rémi Verschelde <rverschelde@gmail.com> | 2024-09-20 16:06:13 +0200 |
---|---|---|
committer | Rémi Verschelde <rverschelde@gmail.com> | 2024-09-20 16:06:13 +0200 |
commit | 6bf8a3e3f8dadf485f733b8fd5a502a7d21a2ff1 (patch) | |
tree | 9cc17e4db8ecd7c16a9a40d627c1f7021a1a7a92 /core | |
parent | da9764ad438a0dab31f74791d1cf84612ed52c69 (diff) | |
parent | 89491f4403041ec81e8506a45f00f54033e45202 (diff) | |
download | redot-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.cpp | 65 | ||||
-rw-r--r-- | core/variant/array.h | 2 | ||||
-rw-r--r-- | core/variant/variant_call.cpp | 2 |
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()); |