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/native_ptr.h | 1 | ||||
-rw-r--r-- | core/variant/type_info.h | 37 | ||||
-rw-r--r-- | core/variant/variant.cpp | 20 | ||||
-rw-r--r-- | core/variant/variant.h | 27 | ||||
-rw-r--r-- | core/variant/variant_call.cpp | 10 | ||||
-rw-r--r-- | core/variant/variant_construct.h | 6 | ||||
-rw-r--r-- | core/variant/variant_op.cpp | 1 | ||||
-rw-r--r-- | core/variant/variant_setget.cpp | 6 | ||||
-rw-r--r-- | core/variant/variant_utility.cpp | 5 |
14 files changed, 110 insertions, 66 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/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 5ae35c92d3..bacd0d19ce 100644 --- a/core/variant/type_info.h +++ b/core/variant/type_info.h @@ -245,8 +245,9 @@ namespace godot { namespace details { inline String enum_qualified_name_to_class_info_name(const String &p_qualified_name) { Vector<String> parts = p_qualified_name.split("::", false); - if (parts.size() <= 2) + if (parts.size() <= 2) { return String(".").join(parts); + } // Contains namespace. We only want the class and enum names. return parts[parts.size() - 2] + "." + parts[parts.size() - 1]; } @@ -280,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..b3e909b489 100644 --- a/core/variant/variant.cpp +++ b/core/variant/variant.cpp @@ -1972,7 +1972,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; } @@ -3309,21 +3309,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 +3327,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) { diff --git a/core/variant/variant.h b/core/variant/variant.h index 836a67d942..ca18249f36 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; @@ -527,8 +535,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..c11925fa8c 100644 --- a/core/variant/variant_call.cpp +++ b/core/variant/variant_call.cpp @@ -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 { @@ -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()); @@ -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, to_linear, sarray(), varray()); + bind_method(Color, to_srgb, sarray(), varray()); bind_method(Color, is_equal_approx, sarray("to"), varray()); 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_setget.cpp b/core/variant/variant_setget.cpp index fa8d26a72b..e604ff9567 100644 --- a/core/variant/variant_setget.cpp +++ b/core/variant/variant_setget.cpp @@ -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; diff --git a/core/variant/variant_utility.cpp b/core/variant/variant_utility.cpp index e83c71098d..05fb577e2c 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); } @@ -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); |