diff options
Diffstat (limited to 'core/variant/array.cpp')
-rw-r--r-- | core/variant/array.cpp | 83 |
1 files changed, 78 insertions, 5 deletions
diff --git a/core/variant/array.cpp b/core/variant/array.cpp index 3685515db5..3e62d3dffa 100644 --- a/core/variant/array.cpp +++ b/core/variant/array.cpp @@ -235,7 +235,7 @@ void Array::assign(const Array &p_array) { for (int i = 0; i < size; i++) { const Variant &element = source[i]; if (element.get_type() != Variant::NIL && (element.get_type() != Variant::OBJECT || !typed.validate_object(element, "assign"))) { - ERR_FAIL_MSG(vformat(R"(Unable to convert array index %i from "%s" to "%s".)", i, Variant::get_type_name(element.get_type()), Variant::get_type_name(typed.type))); + ERR_FAIL_MSG(vformat(R"(Unable to convert array index %d from "%s" to "%s".)", i, Variant::get_type_name(element.get_type()), Variant::get_type_name(typed.type))); } } _p->array = p_array._p->array; @@ -258,11 +258,11 @@ void Array::assign(const Array &p_array) { continue; } if (!Variant::can_convert_strict(value->get_type(), typed.type)) { - ERR_FAIL_MSG("Unable to convert array index " + itos(i) + " from '" + Variant::get_type_name(value->get_type()) + "' to '" + Variant::get_type_name(typed.type) + "'."); + ERR_FAIL_MSG(vformat(R"(Unable to convert array index %d from "%s" to "%s".)", i, Variant::get_type_name(value->get_type()), Variant::get_type_name(typed.type))); } Callable::CallError ce; Variant::construct(typed.type, data[i], &value, 1, ce); - ERR_FAIL_COND_MSG(ce.error, vformat(R"(Unable to convert array index %i from "%s" to "%s".)", i, Variant::get_type_name(value->get_type()), Variant::get_type_name(typed.type))); + ERR_FAIL_COND_MSG(ce.error, vformat(R"(Unable to convert array index %d from "%s" to "%s".)", i, Variant::get_type_name(value->get_type()), Variant::get_type_name(typed.type))); } } else if (Variant::can_convert_strict(source_typed.type, typed.type)) { // from primitives to different convertible primitives @@ -270,7 +270,7 @@ void Array::assign(const Array &p_array) { const Variant *value = source + i; Callable::CallError ce; Variant::construct(typed.type, data[i], &value, 1, ce); - ERR_FAIL_COND_MSG(ce.error, vformat(R"(Unable to convert array index %i from "%s" to "%s".)", i, Variant::get_type_name(value->get_type()), Variant::get_type_name(typed.type))); + ERR_FAIL_COND_MSG(ce.error, vformat(R"(Unable to convert array index %d from "%s" to "%s".)", i, Variant::get_type_name(value->get_type()), Variant::get_type_name(typed.type))); } } else { ERR_FAIL_MSG(vformat(R"(Cannot assign contents of "Array[%s]" to "Array[%s]".)", Variant::get_type_name(source_typed.type), Variant::get_type_name(typed.type))); @@ -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; } } @@ -803,6 +866,10 @@ bool Array::is_same_typed(const Array &p_other) const { return _p->typed == p_other._p->typed; } +bool Array::is_same_instance(const Array &p_other) const { + return _p == p_other._p; +} + uint32_t Array::get_typed_builtin() const { return _p->typed.type; } @@ -815,6 +882,12 @@ Variant Array::get_typed_script() const { return _p->typed.script; } +Array Array::create_read_only() { + Array array; + array.make_read_only(); + return array; +} + void Array::make_read_only() { if (_p->read_only == nullptr) { _p->read_only = memnew(Variant); |