diff options
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 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()); |