diff options
Diffstat (limited to 'core/variant')
-rw-r--r-- | core/variant/array.cpp | 27 | ||||
-rw-r--r-- | core/variant/array.h | 4 | ||||
-rw-r--r-- | core/variant/binder_common.h | 10 | ||||
-rw-r--r-- | core/variant/callable.cpp | 16 | ||||
-rw-r--r-- | core/variant/callable.h | 6 | ||||
-rw-r--r-- | core/variant/callable_bind.cpp | 16 | ||||
-rw-r--r-- | core/variant/callable_bind.h | 32 | ||||
-rw-r--r-- | core/variant/native_ptr.h | 1 | ||||
-rw-r--r-- | core/variant/type_info.h | 34 | ||||
-rw-r--r-- | core/variant/variant.cpp | 150 | ||||
-rw-r--r-- | core/variant/variant.h | 28 | ||||
-rw-r--r-- | core/variant/variant_call.cpp | 44 | ||||
-rw-r--r-- | core/variant/variant_construct.cpp | 12 | ||||
-rw-r--r-- | core/variant/variant_construct.h | 6 | ||||
-rw-r--r-- | core/variant/variant_op.cpp | 1 | ||||
-rw-r--r-- | core/variant/variant_parser.cpp | 21 | ||||
-rw-r--r-- | core/variant/variant_parser.h | 16 | ||||
-rw-r--r-- | core/variant/variant_setget.cpp | 140 | ||||
-rw-r--r-- | core/variant/variant_setget.h | 12 | ||||
-rw-r--r-- | core/variant/variant_utility.cpp | 93 |
20 files changed, 401 insertions, 268 deletions
diff --git a/core/variant/array.cpp b/core/variant/array.cpp index 1b39558dff..afc4acadf9 100644 --- a/core/variant/array.cpp +++ b/core/variant/array.cpp @@ -484,24 +484,8 @@ void Array::sort() { _p->array.sort_custom<_ArrayVariantSort>(); } -struct _ArrayVariantSortCustom { - Callable func; - - _FORCE_INLINE_ bool operator()(const Variant &p_l, const Variant &p_r) const { - const Variant *args[2] = { &p_l, &p_r }; - Callable::CallError err; - Variant res; - func.call(args, 2, res, err); - ERR_FAIL_COND_V_MSG(err.error != Callable::CallError::CALL_OK, false, - "Error calling sorting method: " + Variant::get_callable_error_text(func, args, 1, err)); - return res; - } -}; - -void Array::sort_custom(Callable p_callable) { - SortArray<Variant, _ArrayVariantSortCustom, true> avs; - avs.compare.func = p_callable; - avs.sort(_p->array.ptrw(), _p->array.size()); +void Array::sort_custom(const Callable &p_callable) { + _p->array.sort_custom<CallableComparator, true>(p_callable); } void Array::shuffle() { @@ -524,13 +508,10 @@ int Array::bsearch(const Variant &p_value, bool p_before) { return avs.bisect(_p->array.ptrw(), _p->array.size(), p_value, p_before); } -int Array::bsearch_custom(const Variant &p_value, Callable p_callable, bool p_before) { +int Array::bsearch_custom(const Variant &p_value, const Callable &p_callable, bool p_before) { ERR_FAIL_COND_V(!_p->typed.validate(p_value, "custom binary search"), -1); - SearchArray<Variant, _ArrayVariantSortCustom> avs; - avs.compare.func = p_callable; - - return avs.bisect(_p->array.ptrw(), _p->array.size(), p_value, p_before); + return _p->array.bsearch_custom<CallableComparator>(p_value, p_before, p_callable); } void Array::reverse() { diff --git a/core/variant/array.h b/core/variant/array.h index 72bed5932c..ab5f7cd50f 100644 --- a/core/variant/array.h +++ b/core/variant/array.h @@ -82,10 +82,10 @@ public: Variant back() const; void sort(); - void sort_custom(Callable p_callable); + void sort_custom(const Callable &p_callable); void shuffle(); int bsearch(const Variant &p_value, bool p_before = true); - int bsearch_custom(const Variant &p_value, Callable p_callable, bool p_before = true); + int bsearch_custom(const Variant &p_value, const Callable &p_callable, bool p_before = true); void reverse(); int find(const Variant &p_value, int p_from = 0) const; diff --git a/core/variant/binder_common.h b/core/variant/binder_common.h index b6fdb4d902..22a13b0fab 100644 --- a/core/variant/binder_common.h +++ b/core/variant/binder_common.h @@ -100,6 +100,10 @@ struct VariantCaster<const T &> { _FORCE_INLINE_ static void encode(m_enum p_val, const void *p_ptr) { \ *(int64_t *)p_ptr = (int64_t)p_val; \ } \ + }; \ + template <> \ + struct ZeroInitializer<m_enum> { \ + static void initialize(m_enum &value) { value = (m_enum)0; } \ }; // Object enum casts must go here @@ -182,7 +186,7 @@ struct VariantCasterAndValidate { static _FORCE_INLINE_ T cast(const Variant **p_args, uint32_t p_arg_idx, Callable::CallError &r_error) { Variant::Type argtype = GetTypeInfo<T>::VARIANT_TYPE; if (!Variant::can_convert_strict(p_args[p_arg_idx]->get_type(), argtype) || - !VariantObjectClassChecker<T>::check(p_args[p_arg_idx])) { + !VariantObjectClassChecker<T>::check(*p_args[p_arg_idx])) { r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = p_arg_idx; r_error.expected = argtype; @@ -197,7 +201,7 @@ struct VariantCasterAndValidate<T &> { static _FORCE_INLINE_ T cast(const Variant **p_args, uint32_t p_arg_idx, Callable::CallError &r_error) { Variant::Type argtype = GetTypeInfo<T>::VARIANT_TYPE; if (!Variant::can_convert_strict(p_args[p_arg_idx]->get_type(), argtype) || - !VariantObjectClassChecker<T>::check(p_args[p_arg_idx])) { + !VariantObjectClassChecker<T>::check(*p_args[p_arg_idx])) { r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = p_arg_idx; r_error.expected = argtype; @@ -212,7 +216,7 @@ struct VariantCasterAndValidate<const T &> { static _FORCE_INLINE_ T cast(const Variant **p_args, uint32_t p_arg_idx, Callable::CallError &r_error) { Variant::Type argtype = GetTypeInfo<T>::VARIANT_TYPE; if (!Variant::can_convert_strict(p_args[p_arg_idx]->get_type(), argtype) || - !VariantObjectClassChecker<T>::check(p_args[p_arg_idx])) { + !VariantObjectClassChecker<T>::check(*p_args[p_arg_idx])) { r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = p_arg_idx; r_error.expected = argtype; diff --git a/core/variant/callable.cpp b/core/variant/callable.cpp index 27792ce111..516b8f2d51 100644 --- a/core/variant/callable.cpp +++ b/core/variant/callable.cpp @@ -37,7 +37,7 @@ #include "core/object/script_language.h" void Callable::call_deferred(const Variant **p_arguments, int p_argcount) const { - MessageQueue::get_singleton()->push_callable(*this, p_arguments, p_argcount); + MessageQueue::get_singleton()->push_callablep(*this, p_arguments, p_argcount); } void Callable::call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, CallError &r_call_error) const { @@ -59,7 +59,7 @@ void Callable::call(const Variant **p_arguments, int p_argcount, Variant &r_retu return; } #endif - r_return_value = obj->call(method, p_arguments, p_argcount, r_call_error); + r_return_value = obj->callp(method, p_arguments, p_argcount, r_call_error); } } @@ -379,7 +379,7 @@ Error Signal::emit(const Variant **p_arguments, int p_argcount) const { return ERR_INVALID_DATA; } - return obj->emit_signal(name, p_arguments, p_argcount); + return obj->emit_signalp(name, p_arguments, p_argcount); } Error Signal::connect(const Callable &p_callable, uint32_t p_flags) { @@ -429,3 +429,13 @@ Signal::Signal(ObjectID p_object, const StringName &p_name) { object = p_object; name = p_name; } + +bool CallableComparator::operator()(const Variant &p_l, const Variant &p_r) const { + const Variant *args[2] = { &p_l, &p_r }; + Callable::CallError err; + Variant res; + func.call(args, 2, res, err); + ERR_FAIL_COND_V_MSG(err.error != Callable::CallError::CALL_OK, false, + "Error calling compare method: " + Variant::get_callable_error_text(func, args, 1, err)); + return res; +} diff --git a/core/variant/callable.h b/core/variant/callable.h index c61870f194..6a760958d6 100644 --- a/core/variant/callable.h +++ b/core/variant/callable.h @@ -170,4 +170,10 @@ public: Signal() {} }; +struct CallableComparator { + const Callable &func; + + bool operator()(const Variant &p_l, const Variant &p_r) const; +}; + #endif // CALLABLE_H diff --git a/core/variant/callable_bind.cpp b/core/variant/callable_bind.cpp index 797e8afede..1a400b4360 100644 --- a/core/variant/callable_bind.cpp +++ b/core/variant/callable_bind.cpp @@ -40,8 +40,8 @@ String CallableCustomBind::get_as_text() const { } bool CallableCustomBind::_equal_func(const CallableCustom *p_a, const CallableCustom *p_b) { - const CallableCustomBind *a = (const CallableCustomBind *)p_a; - const CallableCustomBind *b = (const CallableCustomBind *)p_b; + const CallableCustomBind *a = static_cast<const CallableCustomBind *>(p_a); + const CallableCustomBind *b = static_cast<const CallableCustomBind *>(p_b); if (!(a->callable != b->callable)) { return false; @@ -55,8 +55,8 @@ bool CallableCustomBind::_equal_func(const CallableCustom *p_a, const CallableCu } bool CallableCustomBind::_less_func(const CallableCustom *p_a, const CallableCustom *p_b) { - const CallableCustomBind *a = (const CallableCustomBind *)p_a; - const CallableCustomBind *b = (const CallableCustomBind *)p_b; + const CallableCustomBind *a = static_cast<const CallableCustomBind *>(p_a); + const CallableCustomBind *b = static_cast<const CallableCustomBind *>(p_b); if (a->callable < b->callable) { return true; @@ -117,8 +117,8 @@ String CallableCustomUnbind::get_as_text() const { } bool CallableCustomUnbind::_equal_func(const CallableCustom *p_a, const CallableCustom *p_b) { - const CallableCustomUnbind *a = (const CallableCustomUnbind *)p_a; - const CallableCustomUnbind *b = (const CallableCustomUnbind *)p_b; + const CallableCustomUnbind *a = static_cast<const CallableCustomUnbind *>(p_a); + const CallableCustomUnbind *b = static_cast<const CallableCustomUnbind *>(p_b); if (!(a->callable != b->callable)) { return false; @@ -132,8 +132,8 @@ bool CallableCustomUnbind::_equal_func(const CallableCustom *p_a, const Callable } bool CallableCustomUnbind::_less_func(const CallableCustom *p_a, const CallableCustom *p_b) { - const CallableCustomUnbind *a = (const CallableCustomUnbind *)p_a; - const CallableCustomUnbind *b = (const CallableCustomUnbind *)p_b; + const CallableCustomUnbind *a = static_cast<const CallableCustomUnbind *>(p_a); + const CallableCustomUnbind *b = static_cast<const CallableCustomUnbind *>(p_b); if (a->callable < b->callable) { return true; diff --git a/core/variant/callable_bind.h b/core/variant/callable_bind.h index 4f79a29629..a5c830e109 100644 --- a/core/variant/callable_bind.h +++ b/core/variant/callable_bind.h @@ -43,14 +43,14 @@ class CallableCustomBind : public CallableCustom { public: //for every type that inherits, these must always be the same for this type - virtual uint32_t hash() const; - virtual String get_as_text() const; - virtual CompareEqualFunc get_compare_equal_func() const; - virtual CompareLessFunc get_compare_less_func() const; - virtual StringName get_method() const; - virtual ObjectID get_object() const; //must always be able to provide an object - virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const; - virtual const Callable *get_base_comparator() const; + virtual uint32_t hash() const override; + virtual String get_as_text() const override; + virtual CompareEqualFunc get_compare_equal_func() const override; + virtual CompareLessFunc get_compare_less_func() const override; + virtual StringName get_method() const override; + virtual ObjectID get_object() const override; //must always be able to provide an object + virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const override; + virtual const Callable *get_base_comparator() const override; Callable get_callable() { return callable; } Vector<Variant> get_binds() { return binds; } @@ -68,14 +68,14 @@ class CallableCustomUnbind : public CallableCustom { public: //for every type that inherits, these must always be the same for this type - virtual uint32_t hash() const; - virtual String get_as_text() const; - virtual CompareEqualFunc get_compare_equal_func() const; - virtual CompareLessFunc get_compare_less_func() const; - virtual StringName get_method() const; - virtual ObjectID get_object() const; //must always be able to provide an object - virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const; - virtual const Callable *get_base_comparator() const; + virtual uint32_t hash() const override; + virtual String get_as_text() const override; + virtual CompareEqualFunc get_compare_equal_func() const override; + virtual CompareLessFunc get_compare_less_func() const override; + virtual StringName get_method() const override; + virtual ObjectID get_object() const override; //must always be able to provide an object + virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const override; + virtual const Callable *get_base_comparator() const override; Callable get_callable() { return callable; } int get_unbinds() { return argcount; } diff --git a/core/variant/native_ptr.h b/core/variant/native_ptr.h index 8e9fbbc0a4..ed68e0f6c9 100644 --- a/core/variant/native_ptr.h +++ b/core/variant/native_ptr.h @@ -124,6 +124,7 @@ struct PtrToArg<GDNativePtr<T>> { } }; +GDVIRTUAL_NATIVE_PTR(void) GDVIRTUAL_NATIVE_PTR(AudioFrame) GDVIRTUAL_NATIVE_PTR(bool) GDVIRTUAL_NATIVE_PTR(char) diff --git a/core/variant/type_info.h b/core/variant/type_info.h index ee050cff4f..bacd0d19ce 100644 --- a/core/variant/type_info.h +++ b/core/variant/type_info.h @@ -281,4 +281,38 @@ inline StringName __constant_get_enum_name(T param, const String &p_constant) { #define CLASS_INFO(m_type) (GetTypeInfo<m_type *>::get_class_info()) +template <typename T> +struct ZeroInitializer { + static void initialize(T &value) {} //no initialization by default +}; + +template <> +struct ZeroInitializer<bool> { + static void initialize(bool &value) { value = false; } +}; + +template <typename T> +struct ZeroInitializer<T *> { + static void initialize(T *&value) { value = nullptr; } +}; + +#define ZERO_INITIALIZER_NUMBER(m_type) \ + template <> \ + struct ZeroInitializer<m_type> { \ + static void initialize(m_type &value) { value = 0; } \ + }; + +ZERO_INITIALIZER_NUMBER(uint8_t) +ZERO_INITIALIZER_NUMBER(int8_t) +ZERO_INITIALIZER_NUMBER(uint16_t) +ZERO_INITIALIZER_NUMBER(int16_t) +ZERO_INITIALIZER_NUMBER(uint32_t) +ZERO_INITIALIZER_NUMBER(int32_t) +ZERO_INITIALIZER_NUMBER(uint64_t) +ZERO_INITIALIZER_NUMBER(int64_t) +ZERO_INITIALIZER_NUMBER(char16_t) +ZERO_INITIALIZER_NUMBER(char32_t) +ZERO_INITIALIZER_NUMBER(float) +ZERO_INITIALIZER_NUMBER(double) + #endif // TYPE_INFO_H diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp index 3d11ed6303..e69bd88413 100644 --- a/core/variant/variant.cpp +++ b/core/variant/variant.cpp @@ -184,7 +184,7 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) { if (p_type_from == p_type_to) { return true; } - if (p_type_to == NIL && p_type_from != NIL) { //nil can convert to anything + if (p_type_to == NIL) { //nil can convert to anything return true; } @@ -490,7 +490,7 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type if (p_type_from == p_type_to) { return true; } - if (p_type_to == NIL && p_type_from != NIL) { //nil can convert to anything + if (p_type_to == NIL) { //nil can convert to anything return true; } @@ -1620,6 +1620,27 @@ Variant::operator String() const { return stringify(0); } +String stringify_variant_clean(const Variant p_variant, int recursion_count) { + String s = p_variant.stringify(recursion_count); + + // Wrap strings in quotes to avoid ambiguity. + switch (p_variant.get_type()) { + case Variant::STRING: { + s = s.c_escape().quote(); + } break; + case Variant::STRING_NAME: { + s = "&" + s.c_escape().quote(); + } break; + case Variant::NODE_PATH: { + s = "^" + s.c_escape().quote(); + } break; + default: { + } break; + } + + return s; +} + template <class T> String stringify_vector(const T &vec, int recursion_count) { String str("["); @@ -1627,7 +1648,8 @@ String stringify_vector(const T &vec, int recursion_count) { if (i > 0) { str += ", "; } - str = str + Variant(vec[i]).stringify(recursion_count); + + str += stringify_variant_clean(vec[i], recursion_count); } str += "]"; return str; @@ -1691,8 +1713,8 @@ String Variant::stringify(int recursion_count) const { recursion_count++; for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { _VariantStrPair sp; - sp.key = E->get().stringify(recursion_count); - sp.value = d[E->get()].stringify(recursion_count); + sp.key = stringify_variant_clean(E->get(), recursion_count); + sp.value = stringify_variant_clean(d[E->get()], recursion_count); pairs.push_back(sp); } @@ -1741,8 +1763,7 @@ String Variant::stringify(int recursion_count) const { return "[...]"; } - String str = stringify_vector(arr, recursion_count); - return str; + return stringify_vector(arr, recursion_count); } break; case OBJECT: { @@ -1908,12 +1929,12 @@ Variant::operator Transform3D() const { } else if (type == TRANSFORM2D) { const Transform2D &t = *_data._transform2d; Transform3D m; - m.basis.elements[0][0] = t.elements[0][0]; - m.basis.elements[1][0] = t.elements[0][1]; - m.basis.elements[0][1] = t.elements[1][0]; - m.basis.elements[1][1] = t.elements[1][1]; - m.origin[0] = t.elements[2][0]; - m.origin[1] = t.elements[2][1]; + m.basis.rows[0][0] = t.columns[0][0]; + m.basis.rows[1][0] = t.columns[0][1]; + m.basis.rows[0][1] = t.columns[1][0]; + m.basis.rows[1][1] = t.columns[1][1]; + m.origin[0] = t.columns[2][0]; + m.origin[1] = t.columns[2][1]; return m; } else { return Transform3D(); @@ -1926,12 +1947,12 @@ Variant::operator Transform2D() const { } else if (type == TRANSFORM3D) { const Transform3D &t = *_data._transform3d; Transform2D m; - m.elements[0][0] = t.basis.elements[0][0]; - m.elements[0][1] = t.basis.elements[1][0]; - m.elements[1][0] = t.basis.elements[0][1]; - m.elements[1][1] = t.basis.elements[1][1]; - m.elements[2][0] = t.origin[0]; - m.elements[2][1] = t.origin[1]; + m.columns[0][0] = t.basis.rows[0][0]; + m.columns[0][1] = t.basis.rows[1][0]; + m.columns[1][0] = t.basis.rows[0][1]; + m.columns[1][1] = t.basis.rows[1][1]; + m.columns[2][0] = t.origin[0]; + m.columns[2][1] = t.origin[1]; return m; } else { return Transform2D(); @@ -1972,7 +1993,7 @@ Variant::operator ::RID() const { } #endif Callable::CallError ce; - Variant ret = _get_obj().obj->call(CoreStringNames::get_singleton()->get_rid, nullptr, 0, ce); + Variant ret = _get_obj().obj->callp(CoreStringNames::get_singleton()->get_rid, nullptr, 0, ce); if (ce.error == Callable::CallError::CALL_OK && ret.get_type() == Variant::RID) { return ret; } @@ -2790,7 +2811,7 @@ uint32_t Variant::recursive_hash(int recursion_count) const { uint32_t hash = 5831; for (int i = 0; i < 3; i++) { for (int j = 0; j < 2; j++) { - hash = hash_djb2_one_float(_data._transform2d->elements[i][j], hash); + hash = hash_djb2_one_float(_data._transform2d->columns[i][j], hash); } } @@ -2834,7 +2855,7 @@ uint32_t Variant::recursive_hash(int recursion_count) const { uint32_t hash = 5831; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { - hash = hash_djb2_one_float(_data._basis->elements[i][j], hash); + hash = hash_djb2_one_float(_data._basis->rows[i][j], hash); } } @@ -2845,7 +2866,7 @@ uint32_t Variant::recursive_hash(int recursion_count) const { uint32_t hash = 5831; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { - hash = hash_djb2_one_float(_data._transform3d->basis.elements[i][j], hash); + hash = hash_djb2_one_float(_data._transform3d->basis.rows[i][j], hash); } hash = hash_djb2_one_float(_data._transform3d->origin[i], hash); } @@ -3112,7 +3133,7 @@ bool Variant::hash_compare(const Variant &p_variant, int recursion_count) const Transform2D *r = p_variant._data._transform2d; for (int i = 0; i < 3; i++) { - if (!(hash_compare_vector2(l->elements[i], r->elements[i]))) { + if (!(hash_compare_vector2(l->columns[i], r->columns[i]))) { return false; } } @@ -3162,7 +3183,7 @@ bool Variant::hash_compare(const Variant &p_variant, int recursion_count) const const Basis *r = p_variant._data._basis; for (int i = 0; i < 3; i++) { - if (!(hash_compare_vector3(l->elements[i], r->elements[i]))) { + if (!(hash_compare_vector3(l->rows[i], r->rows[i]))) { return false; } } @@ -3175,7 +3196,7 @@ bool Variant::hash_compare(const Variant &p_variant, int recursion_count) const const Transform3D *r = p_variant._data._transform3d; for (int i = 0; i < 3; i++) { - if (!(hash_compare_vector3(l->basis.elements[i], r->basis.elements[i]))) { + if (!(hash_compare_vector3(l->basis.rows[i], r->basis.rows[i]))) { return false; } } @@ -3309,21 +3330,7 @@ bool Variant::is_shared() const { return false; } -Variant Variant::call(const StringName &p_method, VARIANT_ARG_DECLARE) { - VARIANT_ARGPTRS; - int argc = 0; - for (int i = 0; i < VARIANT_ARG_MAX; i++) { - if (argptr[i]->get_type() == Variant::NIL) { - break; - } - argc++; - } - - Callable::CallError error; - - Variant ret; - call(p_method, argptr, argc, ret, error); - +void Variant::_variant_call_error(const String &p_method, Callable::CallError &error) { switch (error.error) { case Callable::CallError::CALL_ERROR_INVALID_ARGUMENT: { String err = "Invalid type for argument #" + itos(error.argument) + ", expected '" + Variant::get_type_name(Variant::Type(error.expected)) + "'."; @@ -3341,8 +3348,6 @@ Variant Variant::call(const StringName &p_method, VARIANT_ARG_DECLARE) { default: { } } - - return ret; } void Variant::construct_from_string(const String &p_string, Variant &r_value, ObjectConstruct p_obj_construct, void *p_construct_ud) { @@ -3357,27 +3362,7 @@ String Variant::get_construct_string() const { } String Variant::get_call_error_text(const StringName &p_method, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce) { - String err_text; - - if (ce.error == Callable::CallError::CALL_ERROR_INVALID_ARGUMENT) { - int errorarg = ce.argument; - if (p_argptrs) { - err_text = "Cannot convert argument " + itos(errorarg + 1) + " from " + Variant::get_type_name(p_argptrs[errorarg]->get_type()) + " to " + Variant::get_type_name(Variant::Type(ce.expected)) + "."; - } else { - err_text = "Cannot convert argument " + itos(errorarg + 1) + " from [missing argptr, type unknown] to " + Variant::get_type_name(Variant::Type(ce.expected)) + "."; - } - } else if (ce.error == Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS) { - err_text = "Method expected " + itos(ce.argument) + " arguments, but called with " + itos(p_argcount) + "."; - } else if (ce.error == Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS) { - err_text = "Method expected " + itos(ce.argument) + " arguments, but called with " + itos(p_argcount) + "."; - } else if (ce.error == Callable::CallError::CALL_ERROR_INVALID_METHOD) { - err_text = "Method not found."; - } else if (ce.error == Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL) { - err_text = "Instance is null"; - } else if (ce.error == Callable::CallError::CALL_OK) { - return "Call OK"; - } - return "'" + String(p_method) + "': " + err_text; + return get_call_error_text(nullptr, p_method, p_argptrs, p_argcount, ce); } String Variant::get_call_error_text(Object *p_base, const StringName &p_method, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce) { @@ -3402,37 +3387,20 @@ String Variant::get_call_error_text(Object *p_base, const StringName &p_method, return "Call OK"; } - String class_name = p_base->get_class(); - Ref<Resource> script = p_base->get_script(); - if (script.is_valid() && script->get_path().is_resource_file()) { - class_name += "(" + script->get_path().get_file() + ")"; + String base_text; + if (p_base) { + base_text = p_base->get_class(); + Ref<Resource> script = p_base->get_script(); + if (script.is_valid() && script->get_path().is_resource_file()) { + base_text += "(" + script->get_path().get_file() + ")"; + } + base_text += "::"; } - return "'" + class_name + "::" + String(p_method) + "': " + err_text; + return "'" + base_text + String(p_method) + "': " + err_text; } String Variant::get_callable_error_text(const Callable &p_callable, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce) { - String err_text; - - if (ce.error == Callable::CallError::CALL_ERROR_INVALID_ARGUMENT) { - int errorarg = ce.argument; - if (p_argptrs) { - err_text = "Cannot convert argument " + itos(errorarg + 1) + " from " + Variant::get_type_name(p_argptrs[errorarg]->get_type()) + " to " + Variant::get_type_name(Variant::Type(ce.expected)) + "."; - } else { - err_text = "Cannot convert argument " + itos(errorarg + 1) + " from [missing argptr, type unknown] to " + Variant::get_type_name(Variant::Type(ce.expected)) + "."; - } - } else if (ce.error == Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS) { - err_text = "Method expected " + itos(ce.argument) + " arguments, but called with " + itos(p_argcount) + "."; - } else if (ce.error == Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS) { - err_text = "Method expected " + itos(ce.argument) + " arguments, but called with " + itos(p_argcount) + "."; - } else if (ce.error == Callable::CallError::CALL_ERROR_INVALID_METHOD) { - err_text = "Method not found."; - } else if (ce.error == Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL) { - err_text = "Instance is null"; - } else if (ce.error == Callable::CallError::CALL_OK) { - return "Call OK"; - } - - return String(p_callable) + " : " + err_text; + return get_call_error_text(p_callable.get_object(), p_callable.get_method(), p_argptrs, p_argcount, ce); } String vformat(const String &p_text, const Variant &p1, const Variant &p2, const Variant &p3, const Variant &p4, const Variant &p5) { diff --git a/core/variant/variant.h b/core/variant/variant.h index 836a67d942..475bf7158d 100644 --- a/core/variant/variant.h +++ b/core/variant/variant.h @@ -282,6 +282,14 @@ private: static void _register_variant_utility_functions(); static void _unregister_variant_utility_functions(); + void _variant_call_error(const String &p_method, Callable::CallError &error); + + // Avoid accidental conversion. If you reached this point, it's because you most likely forgot to dereference + // a Variant pointer (so add * like this: *variant_pointer). + + Variant(const Variant *) {} + Variant(const Variant **) {} + public: _FORCE_INLINE_ Type get_type() const { return type; @@ -503,6 +511,7 @@ public: Variant recursive_duplicate(bool p_deep, int recursion_count) const; static void blend(const Variant &a, const Variant &b, float c, Variant &r_dst); static void interpolate(const Variant &a, const Variant &b, float c, Variant &r_dst); + static void sub(const Variant &a, const Variant &b, Variant &r_dst); /* Built-In Methods */ @@ -527,8 +536,23 @@ public: static int get_builtin_method_count(Variant::Type p_type); static uint32_t get_builtin_method_hash(Variant::Type p_type, const StringName &p_method); - void call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error); - Variant call(const StringName &p_method, const Variant &p_arg1 = Variant(), const Variant &p_arg2 = Variant(), const Variant &p_arg3 = Variant(), const Variant &p_arg4 = Variant(), const Variant &p_arg5 = Variant(), const Variant &p_arg6 = Variant(), const Variant &p_arg7 = Variant(), const Variant &p_arg8 = Variant()); + void callp(const StringName &p_method, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error); + + template <typename... VarArgs> + Variant call(const StringName &p_method, VarArgs... p_args) { + Variant args[sizeof...(p_args) + 1] = { p_args..., Variant() }; // +1 makes sure zero sized arrays are also supported. + const Variant *argptrs[sizeof...(p_args) + 1]; + for (uint32_t i = 0; i < sizeof...(p_args); i++) { + argptrs[i] = &args[i]; + } + Callable::CallError cerr; + Variant ret; + callp(p_method, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args), ret, cerr); + if (cerr.error != Callable::CallError::CALL_OK) { + _variant_call_error(p_method, cerr); + } + return ret; + } static void call_static(Variant::Type p_type, const StringName &p_method, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error); diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp index a5e89eec80..f4b2af5a94 100644 --- a/core/variant/variant_call.cpp +++ b/core/variant/variant_call.cpp @@ -949,20 +949,20 @@ struct _VariantCall { _VariantCall::ConstantData *_VariantCall::constant_data = nullptr; struct VariantBuiltInMethodInfo { - void (*call)(Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error); - Variant::ValidatedBuiltInMethod validated_call; - Variant::PTRBuiltInMethod ptrcall; + void (*call)(Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) = nullptr; + Variant::ValidatedBuiltInMethod validated_call = nullptr; + Variant::PTRBuiltInMethod ptrcall = nullptr; Vector<Variant> default_arguments; Vector<String> argument_names; - bool is_const; - bool is_static; - bool has_return_type; - bool is_vararg; + bool is_const = false; + bool is_static = false; + bool has_return_type = false; + bool is_vararg = false; Variant::Type return_type; - int argument_count; - Variant::Type (*get_argument_type)(int p_arg); + int argument_count = 0; + Variant::Type (*get_argument_type)(int p_arg) = nullptr; }; typedef OAHashMap<StringName, VariantBuiltInMethodInfo> BuiltinMethodMap; @@ -1003,7 +1003,7 @@ static void register_builtin_method(const Vector<String> &p_argnames, const Vect builtin_method_names[T::get_base_type()].push_back(name); } -void Variant::call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) { +void Variant::callp(const StringName &p_method, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) { if (type == Variant::OBJECT) { //call object Object *obj = _get_obj().obj; @@ -1018,7 +1018,7 @@ void Variant::call(const StringName &p_method, const Variant **p_args, int p_arg } #endif - r_ret = _get_obj().obj->call(p_method, p_args, p_argcount, r_error); + r_ret = _get_obj().obj->callp(p_method, p_args, p_argcount, r_error); //else if (type==Variant::METHOD) { } else { @@ -1239,10 +1239,10 @@ void Variant::get_method_list(List<MethodInfo> *p_list) const { void Variant::get_constants_for_type(Variant::Type p_type, List<StringName> *p_constants) { ERR_FAIL_INDEX(p_type, Variant::VARIANT_MAX); - _VariantCall::ConstantData &cd = _VariantCall::constant_data[p_type]; + const _VariantCall::ConstantData &cd = _VariantCall::constant_data[p_type]; #ifdef DEBUG_ENABLED - for (List<StringName>::Element *E = cd.value_ordered.front(); E; E = E->next()) { + for (const List<StringName>::Element *E = cd.value_ordered.front(); E; E = E->next()) { p_constants->push_back(E->get()); #else for (const KeyValue<StringName, int> &E : cd.value) { @@ -1251,7 +1251,7 @@ void Variant::get_constants_for_type(Variant::Type p_type, List<StringName> *p_c } #ifdef DEBUG_ENABLED - for (List<StringName>::Element *E = cd.variant_value_ordered.front(); E; E = E->next()) { + for (const List<StringName>::Element *E = cd.variant_value_ordered.front(); E; E = E->next()) { p_constants->push_back(E->get()); #else for (const KeyValue<StringName, Variant> &E : cd.variant_value) { @@ -1467,6 +1467,8 @@ static void _register_variant_builtin_methods() { bind_static_method(String, num_scientific, sarray("number"), varray()); bind_static_method(String, num, sarray("number", "decimals"), varray(-1)); + bind_static_method(String, num_int64, sarray("number", "base", "capitalize_hex"), varray(10, false)); + bind_static_method(String, num_uint64, sarray("number", "base", "capitalize_hex"), varray(10, false)); bind_static_method(String, chr, sarray("char"), varray()); bind_static_method(String, humanize_size, sarray("size"), varray()); @@ -1493,7 +1495,7 @@ static void _register_variant_builtin_methods() { bind_method(Vector2, max_axis_index, sarray(), varray()); bind_method(Vector2, min_axis_index, sarray(), varray()); bind_method(Vector2, move_toward, sarray("to", "delta"), varray()); - bind_method(Vector2, rotated, sarray("phi"), varray()); + bind_method(Vector2, rotated, sarray("angle"), varray()); bind_method(Vector2, orthogonal, sarray(), varray()); bind_method(Vector2, floor, sarray(), varray()); bind_method(Vector2, ceil, sarray(), varray()); @@ -1573,7 +1575,7 @@ static void _register_variant_builtin_methods() { bind_method(Vector3, inverse, sarray(), varray()); bind_method(Vector3, clamp, sarray("min", "max"), varray()); bind_method(Vector3, snapped, sarray("step"), varray()); - bind_method(Vector3, rotated, sarray("by_axis", "phi"), varray()); + bind_method(Vector3, rotated, sarray("axis", "angle"), varray()); bind_method(Vector3, lerp, sarray("to", "weight"), varray()); bind_method(Vector3, slerp, sarray("to", "weight"), varray()); bind_method(Vector3, cubic_interpolate, sarray("b", "pre_a", "post_b", "weight"), varray()); @@ -1626,6 +1628,8 @@ static void _register_variant_builtin_methods() { bind_method(Quaternion, is_normalized, sarray(), varray()); bind_method(Quaternion, is_equal_approx, sarray("to"), varray()); bind_method(Quaternion, inverse, sarray(), varray()); + bind_method(Quaternion, log, sarray(), varray()); + bind_method(Quaternion, exp, sarray(), varray()); bind_method(Quaternion, angle_to, sarray("to"), varray()); bind_method(Quaternion, dot, sarray("with"), varray()); bind_method(Quaternion, slerp, sarray("to", "weight"), varray()); @@ -1652,6 +1656,8 @@ static void _register_variant_builtin_methods() { bind_method(Color, darkened, sarray("amount"), varray()); bind_method(Color, blend, sarray("over"), varray()); bind_method(Color, get_luminance, sarray(), varray()); + bind_method(Color, srgb_to_linear, sarray(), varray()); + bind_method(Color, linear_to_srgb, sarray(), varray()); bind_method(Color, is_equal_approx, sarray("to"), varray()); @@ -1724,7 +1730,7 @@ static void _register_variant_builtin_methods() { bind_method(Transform2D, get_scale, sarray(), varray()); bind_method(Transform2D, get_skew, sarray(), varray()); bind_method(Transform2D, orthonormalized, sarray(), varray()); - bind_method(Transform2D, rotated, sarray("phi"), varray()); + bind_method(Transform2D, rotated, sarray("angle"), varray()); bind_method(Transform2D, scaled, sarray("scale"), varray()); bind_method(Transform2D, translated, sarray("offset"), varray()); bind_method(Transform2D, basis_xform, sarray("v"), varray()); @@ -1742,7 +1748,7 @@ static void _register_variant_builtin_methods() { bind_method(Basis, transposed, sarray(), varray()); bind_method(Basis, orthonormalized, sarray(), varray()); bind_method(Basis, determinant, sarray(), varray()); - bind_methodv(Basis, rotated, static_cast<Basis (Basis::*)(const Vector3 &, real_t) const>(&Basis::rotated), sarray("axis", "phi"), varray()); + bind_methodv(Basis, rotated, static_cast<Basis (Basis::*)(const Vector3 &, real_t) const>(&Basis::rotated), sarray("axis", "angle"), varray()); bind_method(Basis, scaled, sarray("scale"), varray()); bind_method(Basis, get_scale, sarray(), varray()); bind_method(Basis, get_euler, sarray("order"), varray(Basis::EULER_ORDER_YXZ)); @@ -1789,7 +1795,7 @@ static void _register_variant_builtin_methods() { bind_method(Transform3D, inverse, sarray(), varray()); bind_method(Transform3D, affine_inverse, sarray(), varray()); bind_method(Transform3D, orthonormalized, sarray(), varray()); - bind_method(Transform3D, rotated, sarray("axis", "phi"), varray()); + bind_method(Transform3D, rotated, sarray("axis", "angle"), varray()); bind_method(Transform3D, scaled, sarray("scale"), varray()); bind_method(Transform3D, translated, sarray("offset"), varray()); bind_method(Transform3D, looking_at, sarray("target", "up"), varray(Vector3(0, 1, 0))); diff --git a/core/variant/variant_construct.cpp b/core/variant/variant_construct.cpp index 351f4ae253..78d5433d8c 100644 --- a/core/variant/variant_construct.cpp +++ b/core/variant/variant_construct.cpp @@ -31,11 +31,11 @@ #include "variant_construct.h" struct VariantConstructData { - void (*construct)(Variant &r_base, const Variant **p_args, Callable::CallError &r_error); - Variant::ValidatedConstructor validated_construct; - Variant::PTRConstructor ptr_construct; - Variant::Type (*get_argument_type)(int); - int argument_count; + void (*construct)(Variant &r_base, const Variant **p_args, Callable::CallError &r_error) = nullptr; + Variant::ValidatedConstructor validated_construct = nullptr; + Variant::PTRConstructor ptr_construct = nullptr; + Variant::Type (*get_argument_type)(int) = nullptr; + int argument_count = 0; Vector<String> arg_names; }; @@ -140,7 +140,7 @@ void Variant::_register_variant_constructors() { add_constructor<VariantConstructNoArgs<Basis>>(sarray()); add_constructor<VariantConstructor<Basis, Basis>>(sarray("from")); add_constructor<VariantConstructor<Basis, Quaternion>>(sarray("from")); - add_constructor<VariantConstructor<Basis, Vector3, double>>(sarray("axis", "phi")); + add_constructor<VariantConstructor<Basis, Vector3, double>>(sarray("axis", "angle")); add_constructor<VariantConstructor<Basis, Vector3, Vector3, Vector3>>(sarray("x_axis", "y_axis", "z_axis")); add_constructor<VariantConstructNoArgs<Transform3D>>(sarray()); diff --git a/core/variant/variant_construct.h b/core/variant/variant_construct.h index 6027cb027e..ce2e9af04f 100644 --- a/core/variant/variant_construct.h +++ b/core/variant/variant_construct.h @@ -543,14 +543,12 @@ public: class VariantConstructNoArgsObject { public: static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { - VariantInternal::clear(&r_ret); - VariantInternal::object_assign_null(&r_ret); + r_ret = (Object *)nullptr; // Must construct a TYPE_OBJECT containing nullptr. r_error.error = Callable::CallError::CALL_OK; } static inline void validated_construct(Variant *r_ret, const Variant **p_args) { - VariantInternal::clear(r_ret); - VariantInternal::object_assign_null(r_ret); + *r_ret = (Object *)nullptr; // Must construct a TYPE_OBJECT containing nullptr. } static void ptr_construct(void *base, const void **p_args) { PtrConstruct<Object *>::construct(nullptr, base); diff --git a/core/variant/variant_op.cpp b/core/variant/variant_op.cpp index cd1ae9f41f..35e0319aa3 100644 --- a/core/variant/variant_op.cpp +++ b/core/variant/variant_op.cpp @@ -177,6 +177,7 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorAdd<double, double, double>>(Variant::OP_ADD, Variant::FLOAT, Variant::FLOAT); register_op<OperatorEvaluatorAdd<String, String, String>>(Variant::OP_ADD, Variant::STRING, Variant::STRING); register_op<OperatorEvaluatorAdd<String, char32_t, String>>(Variant::OP_ADD, Variant::INT, Variant::STRING); + register_op<OperatorEvaluatorAdd<String, String, char32_t>>(Variant::OP_ADD, Variant::STRING, Variant::INT); register_op<OperatorEvaluatorAdd<Vector2, Vector2, Vector2>>(Variant::OP_ADD, Variant::VECTOR2, Variant::VECTOR2); register_op<OperatorEvaluatorAdd<Vector2i, Vector2i, Vector2i>>(Variant::OP_ADD, Variant::VECTOR2I, Variant::VECTOR2I); register_op<OperatorEvaluatorAdd<Vector3, Vector3, Vector3>>(Variant::OP_ADD, Variant::VECTOR3, Variant::VECTOR3); diff --git a/core/variant/variant_parser.cpp b/core/variant/variant_parser.cpp index e889a1bb40..259ca8a60d 100644 --- a/core/variant/variant_parser.cpp +++ b/core/variant/variant_parser.cpp @@ -162,6 +162,7 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri return OK; } if (ch == '\n') { + line++; break; } } @@ -344,7 +345,6 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri if (string_name) { r_token.type = TK_STRING_NAME; r_token.value = StringName(str); - string_name = false; //reset } else { r_token.type = TK_STRING; r_token.value = str; @@ -807,7 +807,7 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, return ERR_PARSE_ERROR; } - REF ref = REF(Object::cast_to<RefCounted>(obj)); + Ref<RefCounted> ref = Ref<RefCounted>(Object::cast_to<RefCounted>(obj)); get_token(p_stream, token, line, r_err_str); if (token.type != TK_COMMA) { @@ -888,7 +888,7 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, } if (p_res_parser && id == "Resource" && p_res_parser->func) { - RES res; + Ref<Resource> res; Error err = p_res_parser->func(p_res_parser->userdata, p_stream, res, line, r_err_str); if (err) { return err; @@ -896,7 +896,7 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, value = res; } else if (p_res_parser && id == "ExtResource" && p_res_parser->ext_func) { - RES res; + Ref<Resource> res; Error err = p_res_parser->ext_func(p_res_parser->userdata, p_stream, res, line, r_err_str); if (err) { return err; @@ -904,7 +904,7 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, value = res; } else if (p_res_parser && id == "SubResource" && p_res_parser->sub_func) { - RES res; + Ref<Resource> res; Error err = p_res_parser->sub_func(p_res_parser->userdata, p_stream, res, line, r_err_str); if (err) { return err; @@ -915,7 +915,7 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, get_token(p_stream, token, line, r_err_str); if (token.type == TK_STRING) { String path = token.value; - RES res = ResourceLoader::load(path); + Ref<Resource> res = ResourceLoader::load(path); if (res.is_null()) { r_err_str = "Can't load resource at path: '" + path + "'."; return ERR_PARSE_ERROR; @@ -1402,6 +1402,7 @@ Error VariantParser::parse_tag_assign_eof(Stream *p_stream, int &line, String &r return ERR_FILE_EOF; } if (ch == '\n') { + line++; break; } } @@ -1556,7 +1557,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str if (i != 0 || j != 0) { s += ", "; } - s += rtos_fix(m3.elements[i][j]); + s += rtos_fix(m3.columns[i][j]); } } @@ -1571,7 +1572,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str if (i != 0 || j != 0) { s += ", "; } - s += rtos_fix(m3.elements[i][j]); + s += rtos_fix(m3.rows[i][j]); } } @@ -1587,7 +1588,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str if (i != 0 || j != 0) { s += ", "; } - s += rtos_fix(m3.elements[i][j]); + s += rtos_fix(m3.rows[i][j]); } } @@ -1625,7 +1626,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str break; // don't save it } - RES res = p_variant; + Ref<Resource> res = p_variant; if (res.is_valid()) { //is resource String res_text; diff --git a/core/variant/variant_parser.h b/core/variant/variant_parser.h index e5585076c2..70ca8d8cb5 100644 --- a/core/variant/variant_parser.h +++ b/core/variant/variant_parser.h @@ -49,11 +49,11 @@ public: }; struct StreamFile : public Stream { - FileAccess *f = nullptr; + Ref<FileAccess> f; - virtual char32_t get_char(); - virtual bool is_utf8() const; - virtual bool is_eof() const; + virtual char32_t get_char() override; + virtual bool is_utf8() const override; + virtual bool is_eof() const override; StreamFile() {} }; @@ -62,9 +62,9 @@ public: String s; int pos = 0; - virtual char32_t get_char(); - virtual bool is_utf8() const; - virtual bool is_eof() const; + virtual char32_t get_char() override; + virtual bool is_utf8() const override; + virtual bool is_eof() const override; StreamString() {} }; @@ -138,7 +138,7 @@ public: class VariantWriter { public: typedef Error (*StoreStringFunc)(void *ud, const String &p_string); - typedef String (*EncodeResourceFunc)(void *ud, const RES &p_resource); + typedef String (*EncodeResourceFunc)(void *ud, const Ref<Resource> &p_resource); static Error write(const Variant &p_variant, StoreStringFunc p_store_string_func, void *p_store_string_ud, EncodeResourceFunc p_encode_res_func, void *p_encode_res_ud, int recursion_count = 0); static Error write_to_string(const Variant &p_variant, String &r_string, EncodeResourceFunc p_encode_res_func = nullptr, void *p_encode_res_ud = nullptr); diff --git a/core/variant/variant_setget.cpp b/core/variant/variant_setget.cpp index fa8d26a72b..6023e4d129 100644 --- a/core/variant/variant_setget.cpp +++ b/core/variant/variant_setget.cpp @@ -789,8 +789,8 @@ INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Vector3i, int64_t, int32_t, 3) INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Quaternion, double, real_t, 4) INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Color, double, float, 4) -INDEXED_SETGET_STRUCT_BULTIN_ACCESSOR(Transform2D, Vector2, .elements, 3) -INDEXED_SETGET_STRUCT_BULTIN_FUNC(Basis, Vector3, set_axis, get_axis, 3) +INDEXED_SETGET_STRUCT_BULTIN_ACCESSOR(Transform2D, Vector2, .columns, 3) +INDEXED_SETGET_STRUCT_BULTIN_FUNC(Basis, Vector3, set_column, get_column, 3) INDEXED_SETGET_STRUCT_TYPED_NUMERIC(PackedByteArray, int64_t, uint8_t) INDEXED_SETGET_STRUCT_TYPED_NUMERIC(PackedInt32Array, int64_t, int32_t) @@ -805,16 +805,16 @@ INDEXED_SETGET_STRUCT_TYPED(PackedColorArray, Color) INDEXED_SETGET_STRUCT_DICT(Dictionary) struct VariantIndexedSetterGetterInfo { - void (*setter)(Variant *base, int64_t index, const Variant *value, bool *valid, bool *oob); - void (*getter)(const Variant *base, int64_t index, Variant *value, bool *oob); + void (*setter)(Variant *base, int64_t index, const Variant *value, bool *valid, bool *oob) = nullptr; + void (*getter)(const Variant *base, int64_t index, Variant *value, bool *oob) = nullptr; - Variant::ValidatedIndexedSetter validated_setter; - Variant::ValidatedIndexedGetter validated_getter; + Variant::ValidatedIndexedSetter validated_setter = nullptr; + Variant::ValidatedIndexedGetter validated_getter = nullptr; - Variant::PTRIndexedSetter ptr_setter; - Variant::PTRIndexedGetter ptr_getter; + Variant::PTRIndexedSetter ptr_setter = nullptr; + Variant::PTRIndexedGetter ptr_getter = nullptr; - uint64_t (*get_indexed_size)(const Variant *base); + uint64_t (*get_indexed_size)(const Variant *base) = nullptr; Variant::Type index_type; @@ -1018,13 +1018,13 @@ struct VariantKeyedSetGetObject { }; struct VariantKeyedSetterGetterInfo { - Variant::ValidatedKeyedSetter validated_setter; - Variant::ValidatedKeyedGetter validated_getter; - Variant::ValidatedKeyedChecker validated_checker; + Variant::ValidatedKeyedSetter validated_setter = nullptr; + Variant::ValidatedKeyedGetter validated_getter = nullptr; + Variant::ValidatedKeyedChecker validated_checker = nullptr; - Variant::PTRKeyedSetter ptr_setter; - Variant::PTRKeyedGetter ptr_getter; - Variant::PTRKeyedChecker ptr_checker; + Variant::PTRKeyedSetter ptr_setter = nullptr; + Variant::PTRKeyedGetter ptr_getter = nullptr; + Variant::PTRKeyedChecker ptr_checker = nullptr; bool valid = false; }; @@ -1277,7 +1277,7 @@ bool Variant::iter_init(Variant &r_iter, bool &valid) const { ref.push_back(r_iter); Variant vref = ref; const Variant *refp[] = { &vref }; - Variant ret = _get_obj().obj->call(CoreStringNames::get_singleton()->_iter_init, refp, 1, ce); + Variant ret = _get_obj().obj->callp(CoreStringNames::get_singleton()->_iter_init, refp, 1, ce); if (ref.size() != 1 || ce.error != Callable::CallError::CALL_OK) { valid = false; @@ -1504,7 +1504,7 @@ bool Variant::iter_next(Variant &r_iter, bool &valid) const { ref.push_back(r_iter); Variant vref = ref; const Variant *refp[] = { &vref }; - Variant ret = _get_obj().obj->call(CoreStringNames::get_singleton()->_iter_next, refp, 1, ce); + Variant ret = _get_obj().obj->callp(CoreStringNames::get_singleton()->_iter_next, refp, 1, ce); if (ref.size() != 1 || ce.error != Callable::CallError::CALL_OK) { valid = false; @@ -1686,7 +1686,7 @@ Variant Variant::iter_get(const Variant &r_iter, bool &r_valid) const { Callable::CallError ce; ce.error = Callable::CallError::CALL_OK; const Variant *refp[] = { &r_iter }; - Variant ret = _get_obj().obj->call(CoreStringNames::get_singleton()->_iter_get, refp, 1, ce); + Variant ret = _get_obj().obj->callp(CoreStringNames::get_singleton()->_iter_get, refp, 1, ce); if (ce.error != Callable::CallError::CALL_OK) { r_valid = false; @@ -1868,6 +1868,110 @@ Variant Variant::recursive_duplicate(bool p_deep, int recursion_count) const { } } +void Variant::sub(const Variant &a, const Variant &b, Variant &r_dst) { + if (a.type != b.type) { + return; + } + + switch (a.type) { + case NIL: { + r_dst = Variant(); + } + return; + case INT: { + int64_t va = a._data._int; + int64_t vb = b._data._int; + r_dst = int(va - vb); + } + return; + case FLOAT: { + double ra = a._data._float; + double rb = b._data._float; + r_dst = ra - rb; + } + return; + case VECTOR2: { + r_dst = *reinterpret_cast<const Vector2 *>(a._data._mem) - *reinterpret_cast<const Vector2 *>(b._data._mem); + } + return; + case VECTOR2I: { + int32_t vax = reinterpret_cast<const Vector2i *>(a._data._mem)->x; + int32_t vbx = reinterpret_cast<const Vector2i *>(b._data._mem)->x; + int32_t vay = reinterpret_cast<const Vector2i *>(a._data._mem)->y; + int32_t vby = reinterpret_cast<const Vector2i *>(b._data._mem)->y; + r_dst = Vector2i(int32_t(vax - vbx), int32_t(vay - vby)); + } + return; + case RECT2: { + const Rect2 *ra = reinterpret_cast<const Rect2 *>(a._data._mem); + const Rect2 *rb = reinterpret_cast<const Rect2 *>(b._data._mem); + r_dst = Rect2(ra->position - rb->position, ra->size - rb->size); + } + return; + case RECT2I: { + const Rect2i *ra = reinterpret_cast<const Rect2i *>(a._data._mem); + const Rect2i *rb = reinterpret_cast<const Rect2i *>(b._data._mem); + + int32_t vax = ra->position.x; + int32_t vay = ra->position.y; + int32_t vbx = ra->size.x; + int32_t vby = ra->size.y; + int32_t vcx = rb->position.x; + int32_t vcy = rb->position.y; + int32_t vdx = rb->size.x; + int32_t vdy = rb->size.y; + + r_dst = Rect2i(int32_t(vax - vbx), int32_t(vay - vby), int32_t(vcx - vdx), int32_t(vcy - vdy)); + } + return; + case VECTOR3: { + r_dst = *reinterpret_cast<const Vector3 *>(a._data._mem) - *reinterpret_cast<const Vector3 *>(b._data._mem); + } + return; + case VECTOR3I: { + int32_t vax = reinterpret_cast<const Vector3i *>(a._data._mem)->x; + int32_t vbx = reinterpret_cast<const Vector3i *>(b._data._mem)->x; + int32_t vay = reinterpret_cast<const Vector3i *>(a._data._mem)->y; + int32_t vby = reinterpret_cast<const Vector3i *>(b._data._mem)->y; + int32_t vaz = reinterpret_cast<const Vector3i *>(a._data._mem)->z; + int32_t vbz = reinterpret_cast<const Vector3i *>(b._data._mem)->z; + r_dst = Vector3i(int32_t(vax - vbx), int32_t(vay - vby), int32_t(vaz - vbz)); + } + return; + case AABB: { + const ::AABB *ra = reinterpret_cast<const ::AABB *>(a._data._mem); + const ::AABB *rb = reinterpret_cast<const ::AABB *>(b._data._mem); + r_dst = ::AABB(ra->position - rb->position, ra->size - rb->size); + } + return; + case QUATERNION: { + Quaternion empty_rot; + const Quaternion *qa = reinterpret_cast<const Quaternion *>(a._data._mem); + const Quaternion *qb = reinterpret_cast<const Quaternion *>(b._data._mem); + r_dst = (*qb).inverse() * *qa; + } + return; + case COLOR: { + const Color *ca = reinterpret_cast<const Color *>(a._data._mem); + const Color *cb = reinterpret_cast<const Color *>(b._data._mem); + float new_r = ca->r - cb->r; + float new_g = ca->g - cb->g; + float new_b = ca->b - cb->b; + float new_a = ca->a - cb->a; + new_r = new_r > 1.0 ? 1.0 : new_r; + new_g = new_g > 1.0 ? 1.0 : new_g; + new_b = new_b > 1.0 ? 1.0 : new_b; + new_a = new_a > 1.0 ? 1.0 : new_a; + r_dst = Color(new_r, new_g, new_b, new_a); + } + return; + default: { + r_dst = a; + } + return; + } +} + void Variant::blend(const Variant &a, const Variant &b, float c, Variant &r_dst) { if (a.type != b.type) { if (a.is_num() && b.is_num()) { diff --git a/core/variant/variant_setget.h b/core/variant/variant_setget.h index 28277fa5d0..3b95f0531b 100644 --- a/core/variant/variant_setget.h +++ b/core/variant/variant_setget.h @@ -293,9 +293,9 @@ SETGET_STRUCT(AABB, Vector3, position) SETGET_STRUCT(AABB, Vector3, size) SETGET_STRUCT_FUNC(AABB, Vector3, end, set_end, get_end) -SETGET_STRUCT_CUSTOM(Transform2D, Vector2, x, elements[0]) -SETGET_STRUCT_CUSTOM(Transform2D, Vector2, y, elements[1]) -SETGET_STRUCT_CUSTOM(Transform2D, Vector2, origin, elements[2]) +SETGET_STRUCT_CUSTOM(Transform2D, Vector2, x, columns[0]) +SETGET_STRUCT_CUSTOM(Transform2D, Vector2, y, columns[1]) +SETGET_STRUCT_CUSTOM(Transform2D, Vector2, origin, columns[2]) SETGET_NUMBER_STRUCT_CUSTOM(Plane, double, x, normal.x) SETGET_NUMBER_STRUCT_CUSTOM(Plane, double, y, normal.y) @@ -308,9 +308,9 @@ SETGET_NUMBER_STRUCT(Quaternion, double, y) SETGET_NUMBER_STRUCT(Quaternion, double, z) SETGET_NUMBER_STRUCT(Quaternion, double, w) -SETGET_STRUCT_FUNC_INDEX(Basis, Vector3, x, set_axis, get_axis, 0) -SETGET_STRUCT_FUNC_INDEX(Basis, Vector3, y, set_axis, get_axis, 1) -SETGET_STRUCT_FUNC_INDEX(Basis, Vector3, z, set_axis, get_axis, 2) +SETGET_STRUCT_FUNC_INDEX(Basis, Vector3, x, set_column, get_column, 0) +SETGET_STRUCT_FUNC_INDEX(Basis, Vector3, y, set_column, get_column, 1) +SETGET_STRUCT_FUNC_INDEX(Basis, Vector3, z, set_column, get_column, 2) SETGET_STRUCT(Transform3D, Basis, basis) SETGET_STRUCT(Transform3D, Vector3, origin) diff --git a/core/variant/variant_utility.cpp b/core/variant/variant_utility.cpp index e83c71098d..66badce268 100644 --- a/core/variant/variant_utility.cpp +++ b/core/variant/variant_utility.cpp @@ -219,10 +219,6 @@ struct VariantUtilityFunctions { return Math::step_decimals(step); } - static inline int range_step_decimals(float step) { - return Math::range_step_decimals(step); - } - static inline double snapped(double value, double step) { return Math::snapped(value, step); } @@ -439,7 +435,7 @@ struct VariantUtilityFunctions { r_error.error = Callable::CallError::CALL_OK; if (obj.is_ref_counted()) { Ref<WeakRef> wref = memnew(WeakRef); - REF r = obj; + Ref<RefCounted> r = obj; if (r.is_valid()) { wref->set_ref(r); } @@ -474,20 +470,20 @@ struct VariantUtilityFunctions { r_error.argument = 1; return String(); } - String str; + String s; for (int i = 0; i < p_arg_count; i++) { String os = p_args[i]->operator String(); if (i == 0) { - str = os; + s = os; } else { - str += os; + s += os; } } r_error.error = Callable::CallError::CALL_OK; - return str; + return s; } static inline String error_string(Error error) { @@ -499,98 +495,98 @@ struct VariantUtilityFunctions { } static inline void print(const Variant **p_args, int p_arg_count, Callable::CallError &r_error) { - String str; + String s; for (int i = 0; i < p_arg_count; i++) { String os = p_args[i]->operator String(); if (i == 0) { - str = os; + s = os; } else { - str += os; + s += os; } } - print_line(str); + print_line(s); r_error.error = Callable::CallError::CALL_OK; } static inline void print_verbose(const Variant **p_args, int p_arg_count, Callable::CallError &r_error) { if (OS::get_singleton()->is_stdout_verbose()) { - String str; + String s; for (int i = 0; i < p_arg_count; i++) { String os = p_args[i]->operator String(); if (i == 0) { - str = os; + s = os; } else { - str += os; + s += os; } } // No need to use `print_verbose()` as this call already only happens // when verbose mode is enabled. This avoids performing string argument concatenation // when not needed. - print_line(str); + print_line(s); } r_error.error = Callable::CallError::CALL_OK; } static inline void printerr(const Variant **p_args, int p_arg_count, Callable::CallError &r_error) { - String str; + String s; for (int i = 0; i < p_arg_count; i++) { String os = p_args[i]->operator String(); if (i == 0) { - str = os; + s = os; } else { - str += os; + s += os; } } - print_error(str); + print_error(s); r_error.error = Callable::CallError::CALL_OK; } static inline void printt(const Variant **p_args, int p_arg_count, Callable::CallError &r_error) { - String str; + String s; for (int i = 0; i < p_arg_count; i++) { if (i) { - str += "\t"; + s += "\t"; } - str += p_args[i]->operator String(); + s += p_args[i]->operator String(); } - print_line(str); + print_line(s); r_error.error = Callable::CallError::CALL_OK; } static inline void prints(const Variant **p_args, int p_arg_count, Callable::CallError &r_error) { - String str; + String s; for (int i = 0; i < p_arg_count; i++) { if (i) { - str += " "; + s += " "; } - str += p_args[i]->operator String(); + s += p_args[i]->operator String(); } - print_line(str); + print_line(s); r_error.error = Callable::CallError::CALL_OK; } static inline void printraw(const Variant **p_args, int p_arg_count, Callable::CallError &r_error) { - String str; + String s; for (int i = 0; i < p_arg_count; i++) { String os = p_args[i]->operator String(); if (i == 0) { - str = os; + s = os; } else { - str += os; + s += os; } } - OS::get_singleton()->print("%s", str.utf8().get_data()); + OS::get_singleton()->print("%s", s.utf8().get_data()); r_error.error = Callable::CallError::CALL_OK; } @@ -599,18 +595,18 @@ struct VariantUtilityFunctions { r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; r_error.argument = 1; } - String str; + String s; for (int i = 0; i < p_arg_count; i++) { String os = p_args[i]->operator String(); if (i == 0) { - str = os; + s = os; } else { - str += os; + s += os; } } - ERR_PRINT(str); + ERR_PRINT(s); r_error.error = Callable::CallError::CALL_OK; } @@ -619,18 +615,18 @@ struct VariantUtilityFunctions { r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; r_error.argument = 1; } - String str; + String s; for (int i = 0; i < p_arg_count; i++) { String os = p_args[i]->operator String(); if (i == 0) { - str = os; + s = os; } else { - str += os; + s += os; } } - WARN_PRINT(str); + WARN_PRINT(s); r_error.error = Callable::CallError::CALL_OK; } @@ -1114,14 +1110,14 @@ static _FORCE_INLINE_ Variant::Type get_ret_type_helper(void (*p_func)(P...)) { register_utility_function<Func_##m_func>(#m_func, m_args) struct VariantUtilityFunctionInfo { - void (*call_utility)(Variant *r_ret, const Variant **p_args, int p_argcount, Callable::CallError &r_error); - Variant::ValidatedUtilityFunction validated_call_utility; - Variant::PTRUtilityFunction ptr_call_utility; + void (*call_utility)(Variant *r_ret, const Variant **p_args, int p_argcount, Callable::CallError &r_error) = nullptr; + Variant::ValidatedUtilityFunction validated_call_utility = nullptr; + Variant::PTRUtilityFunction ptr_call_utility = nullptr; Vector<String> argnames; - bool is_vararg; - bool returns_value; - int argcount; - Variant::Type (*get_arg_type)(int); + bool is_vararg = false; + bool returns_value = false; + int argcount = 0; + Variant::Type (*get_arg_type)(int) = nullptr; Variant::Type return_type; Variant::UtilityFunctionType type; }; @@ -1204,7 +1200,6 @@ void Variant::_register_variant_utility_functions() { FUNCBINDR(ease, sarray("x", "curve"), Variant::UTILITY_FUNC_TYPE_MATH); FUNCBINDR(step_decimals, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); - FUNCBINDR(range_step_decimals, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH); FUNCBINDR(snapped, sarray("x", "step"), Variant::UTILITY_FUNC_TYPE_MATH); FUNCBINDR(lerp, sarray("from", "to", "weight"), Variant::UTILITY_FUNC_TYPE_MATH); |