summaryrefslogtreecommitdiffstats
path: root/core/variant
diff options
context:
space:
mode:
Diffstat (limited to 'core/variant')
-rw-r--r--core/variant/array.cpp22
-rw-r--r--core/variant/array.h64
-rw-r--r--core/variant/binder_common.h151
-rw-r--r--core/variant/callable.cpp83
-rw-r--r--core/variant/callable.h6
-rw-r--r--core/variant/callable_bind.cpp20
-rw-r--r--core/variant/callable_bind.h2
-rw-r--r--core/variant/dictionary.cpp18
-rw-r--r--core/variant/dictionary.h2
-rw-r--r--core/variant/method_ptrcall.h250
-rw-r--r--core/variant/native_ptr.h12
-rw-r--r--core/variant/type_info.h57
-rw-r--r--core/variant/typed_array.h58
-rw-r--r--core/variant/variant.cpp521
-rw-r--r--core/variant/variant.h175
-rw-r--r--core/variant/variant_call.cpp264
-rw-r--r--core/variant/variant_callable.cpp90
-rw-r--r--core/variant/variant_callable.h59
-rw-r--r--core/variant/variant_construct.cpp2
-rw-r--r--core/variant/variant_construct.h14
-rw-r--r--core/variant/variant_destruct.cpp2
-rw-r--r--core/variant/variant_destruct.h2
-rw-r--r--core/variant/variant_internal.h174
-rw-r--r--core/variant/variant_op.cpp21
-rw-r--r--core/variant/variant_op.h112
-rw-r--r--core/variant/variant_parser.cpp133
-rw-r--r--core/variant/variant_parser.h7
-rw-r--r--core/variant/variant_setget.cpp107
-rw-r--r--core/variant/variant_utility.cpp44
-rw-r--r--core/variant/variant_utility.h6
30 files changed, 1475 insertions, 1003 deletions
diff --git a/core/variant/array.cpp b/core/variant/array.cpp
index ab0315ae34..3685515db5 100644
--- a/core/variant/array.cpp
+++ b/core/variant/array.cpp
@@ -81,6 +81,22 @@ void Array::_unref() const {
_p = nullptr;
}
+Array::Iterator Array::begin() {
+ return Iterator(_p->array.ptrw(), _p->read_only);
+}
+
+Array::Iterator Array::end() {
+ return Iterator(_p->array.ptrw() + _p->array.size(), _p->read_only);
+}
+
+Array::ConstIterator Array::begin() const {
+ return ConstIterator(_p->array.ptr(), _p->read_only);
+}
+
+Array::ConstIterator Array::end() const {
+ return ConstIterator(_p->array.ptr() + _p->array.size(), _p->read_only);
+}
+
Variant &Array::operator[](int p_idx) {
if (unlikely(_p->read_only)) {
*_p->read_only = _p->array[p_idx];
@@ -316,17 +332,17 @@ void Array::erase(const Variant &p_value) {
}
Variant Array::front() const {
- ERR_FAIL_COND_V_MSG(_p->array.size() == 0, Variant(), "Can't take value from empty array.");
+ ERR_FAIL_COND_V_MSG(_p->array.is_empty(), Variant(), "Can't take value from empty array.");
return operator[](0);
}
Variant Array::back() const {
- ERR_FAIL_COND_V_MSG(_p->array.size() == 0, Variant(), "Can't take value from empty array.");
+ ERR_FAIL_COND_V_MSG(_p->array.is_empty(), Variant(), "Can't take value from empty array.");
return operator[](_p->array.size() - 1);
}
Variant Array::pick_random() const {
- ERR_FAIL_COND_V_MSG(_p->array.size() == 0, Variant(), "Can't take value from empty array.");
+ ERR_FAIL_COND_V_MSG(_p->array.is_empty(), Variant(), "Can't take value from empty array.");
return operator[](Math::rand() % _p->array.size());
}
diff --git a/core/variant/array.h b/core/variant/array.h
index 8b1f8c0678..3aa957b312 100644
--- a/core/variant/array.h
+++ b/core/variant/array.h
@@ -46,6 +46,70 @@ class Array {
void _unref() const;
public:
+ struct ConstIterator {
+ _FORCE_INLINE_ const Variant &operator*() const;
+ _FORCE_INLINE_ const Variant *operator->() const;
+
+ _FORCE_INLINE_ ConstIterator &operator++();
+ _FORCE_INLINE_ ConstIterator &operator--();
+
+ _FORCE_INLINE_ bool operator==(const ConstIterator &p_other) const { return element_ptr == p_other.element_ptr; }
+ _FORCE_INLINE_ bool operator!=(const ConstIterator &p_other) const { return element_ptr != p_other.element_ptr; }
+
+ _FORCE_INLINE_ ConstIterator(const Variant *p_element_ptr, Variant *p_read_only = nullptr) :
+ element_ptr(p_element_ptr), read_only(p_read_only) {}
+ _FORCE_INLINE_ ConstIterator() {}
+ _FORCE_INLINE_ ConstIterator(const ConstIterator &p_other) :
+ element_ptr(p_other.element_ptr), read_only(p_other.read_only) {}
+
+ _FORCE_INLINE_ ConstIterator &operator=(const ConstIterator &p_other) {
+ element_ptr = p_other.element_ptr;
+ read_only = p_other.read_only;
+ return *this;
+ }
+
+ private:
+ const Variant *element_ptr = nullptr;
+ Variant *read_only = nullptr;
+ };
+
+ struct Iterator {
+ _FORCE_INLINE_ Variant &operator*() const;
+ _FORCE_INLINE_ Variant *operator->() const;
+
+ _FORCE_INLINE_ Iterator &operator++();
+ _FORCE_INLINE_ Iterator &operator--();
+
+ _FORCE_INLINE_ bool operator==(const Iterator &p_other) const { return element_ptr == p_other.element_ptr; }
+ _FORCE_INLINE_ bool operator!=(const Iterator &p_other) const { return element_ptr != p_other.element_ptr; }
+
+ _FORCE_INLINE_ Iterator(Variant *p_element_ptr, Variant *p_read_only = nullptr) :
+ element_ptr(p_element_ptr), read_only(p_read_only) {}
+ _FORCE_INLINE_ Iterator() {}
+ _FORCE_INLINE_ Iterator(const Iterator &p_other) :
+ element_ptr(p_other.element_ptr), read_only(p_other.read_only) {}
+
+ _FORCE_INLINE_ Iterator &operator=(const Iterator &p_other) {
+ element_ptr = p_other.element_ptr;
+ read_only = p_other.read_only;
+ return *this;
+ }
+
+ operator ConstIterator() const {
+ return ConstIterator(element_ptr, read_only);
+ }
+
+ private:
+ Variant *element_ptr = nullptr;
+ Variant *read_only = nullptr;
+ };
+
+ Iterator begin();
+ Iterator end();
+
+ ConstIterator begin() const;
+ ConstIterator end() const;
+
void _ref(const Array &p_from) const;
Variant &operator[](int p_idx);
diff --git a/core/variant/binder_common.h b/core/variant/binder_common.h
index 34b54f1d00..0fe4518b0f 100644
--- a/core/variant/binder_common.h
+++ b/core/variant/binder_common.h
@@ -47,11 +47,11 @@
// Variant cannot define an implicit cast operator for every Object subclass, so the
// casting is done here, to allow binding methods with parameters more specific than Object *
-template <class T>
+template <typename T>
struct VariantCaster {
static _FORCE_INLINE_ T cast(const Variant &p_variant) {
using TStripped = std::remove_pointer_t<T>;
- if constexpr (std::is_base_of<Object, TStripped>::value) {
+ if constexpr (std::is_base_of_v<Object, TStripped>) {
return Object::cast_to<TStripped>(p_variant);
} else {
return p_variant;
@@ -59,11 +59,11 @@ struct VariantCaster {
}
};
-template <class T>
+template <typename T>
struct VariantCaster<T &> {
static _FORCE_INLINE_ T cast(const Variant &p_variant) {
using TStripped = std::remove_pointer_t<T>;
- if constexpr (std::is_base_of<Object, TStripped>::value) {
+ if constexpr (std::is_base_of_v<Object, TStripped>) {
return Object::cast_to<TStripped>(p_variant);
} else {
return p_variant;
@@ -71,11 +71,11 @@ struct VariantCaster<T &> {
}
};
-template <class T>
+template <typename T>
struct VariantCaster<const T &> {
static _FORCE_INLINE_ T cast(const Variant &p_variant) {
using TStripped = std::remove_pointer_t<T>;
- if constexpr (std::is_base_of<Object, TStripped>::value) {
+ if constexpr (std::is_base_of_v<Object, TStripped>) {
return Object::cast_to<TStripped>(p_variant);
} else {
return p_variant;
@@ -176,6 +176,7 @@ VARIANT_ENUM_CAST(Variant::Operator);
VARIANT_ENUM_CAST(Key);
VARIANT_BITFIELD_CAST(KeyModifierMask);
+VARIANT_ENUM_CAST(KeyLocation);
static inline Key &operator|=(Key &a, BitField<KeyModifierMask> b) {
a = static_cast<Key>(static_cast<int>(a) | static_cast<int>(b.operator int64_t()));
@@ -225,7 +226,7 @@ template <typename T>
struct VariantObjectClassChecker {
static _FORCE_INLINE_ bool check(const Variant &p_variant) {
using TStripped = std::remove_pointer_t<T>;
- if constexpr (std::is_base_of<Object, TStripped>::value) {
+ if constexpr (std::is_base_of_v<Object, TStripped>) {
Object *obj = p_variant;
return Object::cast_to<TStripped>(p_variant) || !obj;
} else {
@@ -248,7 +249,7 @@ struct VariantObjectClassChecker<const Ref<T> &> {
#ifdef DEBUG_METHODS_ENABLED
-template <class T>
+template <typename T>
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;
@@ -263,7 +264,7 @@ struct VariantCasterAndValidate {
}
};
-template <class T>
+template <typename T>
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;
@@ -278,7 +279,7 @@ struct VariantCasterAndValidate<T &> {
}
};
-template <class T>
+template <typename T>
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;
@@ -295,7 +296,7 @@ struct VariantCasterAndValidate<const T &> {
#endif // DEBUG_METHODS_ENABLED
-template <class T, class... P, size_t... Is>
+template <typename T, typename... P, size_t... Is>
void call_with_variant_args_helper(T *p_instance, void (T::*p_method)(P...), const Variant **p_args, Callable::CallError &r_error, IndexSequence<Is...>) {
r_error.error = Callable::CallError::CALL_OK;
@@ -307,7 +308,7 @@ void call_with_variant_args_helper(T *p_instance, void (T::*p_method)(P...), con
(void)(p_args); //avoid warning
}
-template <class T, class... P, size_t... Is>
+template <typename T, typename... P, size_t... Is>
void call_with_variant_argsc_helper(T *p_instance, void (T::*p_method)(P...) const, const Variant **p_args, Callable::CallError &r_error, IndexSequence<Is...>) {
r_error.error = Callable::CallError::CALL_OK;
@@ -319,87 +320,87 @@ void call_with_variant_argsc_helper(T *p_instance, void (T::*p_method)(P...) con
(void)(p_args); //avoid warning
}
-template <class T, class... P, size_t... Is>
+template <typename T, typename... P, size_t... Is>
void call_with_ptr_args_helper(T *p_instance, void (T::*p_method)(P...), const void **p_args, IndexSequence<Is...>) {
(p_instance->*p_method)(PtrToArg<P>::convert(p_args[Is])...);
}
-template <class T, class... P, size_t... Is>
+template <typename T, typename... P, size_t... Is>
void call_with_ptr_argsc_helper(T *p_instance, void (T::*p_method)(P...) const, const void **p_args, IndexSequence<Is...>) {
(p_instance->*p_method)(PtrToArg<P>::convert(p_args[Is])...);
}
-template <class T, class R, class... P, size_t... Is>
+template <typename T, typename R, typename... P, size_t... Is>
void call_with_ptr_args_ret_helper(T *p_instance, R (T::*p_method)(P...), const void **p_args, void *r_ret, IndexSequence<Is...>) {
PtrToArg<R>::encode((p_instance->*p_method)(PtrToArg<P>::convert(p_args[Is])...), r_ret);
}
-template <class T, class R, class... P, size_t... Is>
+template <typename T, typename R, typename... P, size_t... Is>
void call_with_ptr_args_retc_helper(T *p_instance, R (T::*p_method)(P...) const, const void **p_args, void *r_ret, IndexSequence<Is...>) {
PtrToArg<R>::encode((p_instance->*p_method)(PtrToArg<P>::convert(p_args[Is])...), r_ret);
}
-template <class T, class... P, size_t... Is>
+template <typename T, typename... P, size_t... Is>
void call_with_ptr_args_static_helper(T *p_instance, void (*p_method)(T *, P...), const void **p_args, IndexSequence<Is...>) {
p_method(p_instance, PtrToArg<P>::convert(p_args[Is])...);
}
-template <class T, class R, class... P, size_t... Is>
+template <typename T, typename R, typename... P, size_t... Is>
void call_with_ptr_args_static_retc_helper(T *p_instance, R (*p_method)(T *, P...), const void **p_args, void *r_ret, IndexSequence<Is...>) {
PtrToArg<R>::encode(p_method(p_instance, PtrToArg<P>::convert(p_args[Is])...), r_ret);
}
-template <class R, class... P, size_t... Is>
+template <typename R, typename... P, size_t... Is>
void call_with_ptr_args_static_method_ret_helper(R (*p_method)(P...), const void **p_args, void *r_ret, IndexSequence<Is...>) {
PtrToArg<R>::encode(p_method(PtrToArg<P>::convert(p_args[Is])...), r_ret);
}
-template <class... P, size_t... Is>
+template <typename... P, size_t... Is>
void call_with_ptr_args_static_method_helper(void (*p_method)(P...), const void **p_args, IndexSequence<Is...>) {
p_method(PtrToArg<P>::convert(p_args[Is])...);
}
-template <class T, class... P, size_t... Is>
+template <typename T, typename... P, size_t... Is>
void call_with_validated_variant_args_helper(T *p_instance, void (T::*p_method)(P...), const Variant **p_args, IndexSequence<Is...>) {
(p_instance->*p_method)((VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...);
}
-template <class T, class... P, size_t... Is>
+template <typename T, typename... P, size_t... Is>
void call_with_validated_variant_argsc_helper(T *p_instance, void (T::*p_method)(P...) const, const Variant **p_args, IndexSequence<Is...>) {
(p_instance->*p_method)((VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...);
}
-template <class T, class R, class... P, size_t... Is>
+template <typename T, typename R, typename... P, size_t... Is>
void call_with_validated_variant_args_ret_helper(T *p_instance, R (T::*p_method)(P...), const Variant **p_args, Variant *r_ret, IndexSequence<Is...>) {
VariantInternalAccessor<typename GetSimpleTypeT<R>::type_t>::set(r_ret, (p_instance->*p_method)((VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...));
}
-template <class T, class R, class... P, size_t... Is>
+template <typename T, typename R, typename... P, size_t... Is>
void call_with_validated_variant_args_retc_helper(T *p_instance, R (T::*p_method)(P...) const, const Variant **p_args, Variant *r_ret, IndexSequence<Is...>) {
VariantInternalAccessor<typename GetSimpleTypeT<R>::type_t>::set(r_ret, (p_instance->*p_method)((VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...));
}
-template <class T, class R, class... P, size_t... Is>
+template <typename T, typename R, typename... P, size_t... Is>
void call_with_validated_variant_args_static_retc_helper(T *p_instance, R (*p_method)(T *, P...), const Variant **p_args, Variant *r_ret, IndexSequence<Is...>) {
VariantInternalAccessor<typename GetSimpleTypeT<R>::type_t>::set(r_ret, p_method(p_instance, (VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...));
}
-template <class T, class... P, size_t... Is>
+template <typename T, typename... P, size_t... Is>
void call_with_validated_variant_args_static_helper(T *p_instance, void (*p_method)(T *, P...), const Variant **p_args, IndexSequence<Is...>) {
p_method(p_instance, (VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...);
}
-template <class R, class... P, size_t... Is>
+template <typename R, typename... P, size_t... Is>
void call_with_validated_variant_args_static_method_ret_helper(R (*p_method)(P...), const Variant **p_args, Variant *r_ret, IndexSequence<Is...>) {
VariantInternalAccessor<typename GetSimpleTypeT<R>::type_t>::set(r_ret, p_method((VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...));
}
-template <class... P, size_t... Is>
+template <typename... P, size_t... Is>
void call_with_validated_variant_args_static_method_helper(void (*p_method)(P...), const Variant **p_args, IndexSequence<Is...>) {
p_method((VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...);
}
-template <class T, class... P>
+template <typename T, typename... P>
void call_with_variant_args(T *p_instance, void (T::*p_method)(P...), const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
#ifdef DEBUG_METHODS_ENABLED
if ((size_t)p_argcount > sizeof...(P)) {
@@ -417,7 +418,7 @@ void call_with_variant_args(T *p_instance, void (T::*p_method)(P...), const Vari
call_with_variant_args_helper<T, P...>(p_instance, p_method, p_args, r_error, BuildIndexSequence<sizeof...(P)>{});
}
-template <class T, class... P>
+template <typename T, typename... P>
void call_with_variant_args_dv(T *p_instance, void (T::*p_method)(P...), const Variant **p_args, int p_argcount, Callable::CallError &r_error, const Vector<Variant> &default_values) {
#ifdef DEBUG_ENABLED
if ((size_t)p_argcount > sizeof...(P)) {
@@ -450,7 +451,7 @@ void call_with_variant_args_dv(T *p_instance, void (T::*p_method)(P...), const V
call_with_variant_args_helper(p_instance, p_method, args, r_error, BuildIndexSequence<sizeof...(P)>{});
}
-template <class T, class... P>
+template <typename T, typename... P>
void call_with_variant_argsc(T *p_instance, void (T::*p_method)(P...) const, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
#ifdef DEBUG_METHODS_ENABLED
if ((size_t)p_argcount > sizeof...(P)) {
@@ -468,7 +469,7 @@ void call_with_variant_argsc(T *p_instance, void (T::*p_method)(P...) const, con
call_with_variant_args_helper<T, P...>(p_instance, p_method, p_args, r_error, BuildIndexSequence<sizeof...(P)>{});
}
-template <class T, class... P>
+template <typename T, typename... P>
void call_with_variant_argsc_dv(T *p_instance, void (T::*p_method)(P...) const, const Variant **p_args, int p_argcount, Callable::CallError &r_error, const Vector<Variant> &default_values) {
#ifdef DEBUG_ENABLED
if ((size_t)p_argcount > sizeof...(P)) {
@@ -501,7 +502,7 @@ void call_with_variant_argsc_dv(T *p_instance, void (T::*p_method)(P...) const,
call_with_variant_argsc_helper(p_instance, p_method, args, r_error, BuildIndexSequence<sizeof...(P)>{});
}
-template <class T, class R, class... P>
+template <typename T, typename R, typename... P>
void call_with_variant_args_ret_dv(T *p_instance, R (T::*p_method)(P...), const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error, const Vector<Variant> &default_values) {
#ifdef DEBUG_ENABLED
if ((size_t)p_argcount > sizeof...(P)) {
@@ -534,7 +535,7 @@ void call_with_variant_args_ret_dv(T *p_instance, R (T::*p_method)(P...), const
call_with_variant_args_ret_helper(p_instance, p_method, args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
}
-template <class T, class R, class... P>
+template <typename T, typename R, typename... P>
void call_with_variant_args_retc_dv(T *p_instance, R (T::*p_method)(P...) const, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error, const Vector<Variant> &default_values) {
#ifdef DEBUG_ENABLED
if ((size_t)p_argcount > sizeof...(P)) {
@@ -567,111 +568,111 @@ void call_with_variant_args_retc_dv(T *p_instance, R (T::*p_method)(P...) const,
call_with_variant_args_retc_helper(p_instance, p_method, args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
}
-template <class T, class... P>
+template <typename T, typename... P>
void call_with_ptr_args(T *p_instance, void (T::*p_method)(P...), const void **p_args) {
call_with_ptr_args_helper<T, P...>(p_instance, p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
}
-template <class T, class... P>
+template <typename T, typename... P>
void call_with_ptr_argsc(T *p_instance, void (T::*p_method)(P...) const, const void **p_args) {
call_with_ptr_argsc_helper<T, P...>(p_instance, p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
}
-template <class T, class R, class... P>
+template <typename T, typename R, typename... P>
void call_with_ptr_args_ret(T *p_instance, R (T::*p_method)(P...), const void **p_args, void *r_ret) {
call_with_ptr_args_ret_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
}
-template <class T, class R, class... P>
+template <typename T, typename R, typename... P>
void call_with_ptr_args_retc(T *p_instance, R (T::*p_method)(P...) const, const void **p_args, void *r_ret) {
call_with_ptr_args_retc_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
}
-template <class T, class... P>
+template <typename T, typename... P>
void call_with_ptr_args_static(T *p_instance, void (*p_method)(T *, P...), const void **p_args) {
call_with_ptr_args_static_helper<T, P...>(p_instance, p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
}
-template <class T, class R, class... P>
+template <typename T, typename R, typename... P>
void call_with_ptr_args_static_retc(T *p_instance, R (*p_method)(T *, P...), const void **p_args, void *r_ret) {
call_with_ptr_args_static_retc_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
}
-template <class R, class... P>
+template <typename R, typename... P>
void call_with_ptr_args_static_method_ret(R (*p_method)(P...), const void **p_args, void *r_ret) {
call_with_ptr_args_static_method_ret_helper<R, P...>(p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
}
-template <class... P>
+template <typename... P>
void call_with_ptr_args_static_method(void (*p_method)(P...), const void **p_args) {
call_with_ptr_args_static_method_helper<P...>(p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
}
// Validated
-template <class T, class... P>
+template <typename T, typename... P>
void call_with_validated_variant_args(Variant *base, void (T::*p_method)(P...), const Variant **p_args) {
call_with_validated_variant_args_helper<T, P...>(VariantGetInternalPtr<T>::get_ptr(base), p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
}
-template <class T, class R, class... P>
+template <typename T, typename R, typename... P>
void call_with_validated_variant_args_ret(Variant *base, R (T::*p_method)(P...), const Variant **p_args, Variant *r_ret) {
call_with_validated_variant_args_ret_helper<T, R, P...>(VariantGetInternalPtr<T>::get_ptr(base), p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
}
-template <class T, class R, class... P>
+template <typename T, typename R, typename... P>
void call_with_validated_variant_args_retc(Variant *base, R (T::*p_method)(P...) const, const Variant **p_args, Variant *r_ret) {
call_with_validated_variant_args_retc_helper<T, R, P...>(VariantGetInternalPtr<T>::get_ptr(base), p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
}
-template <class T, class... P>
+template <typename T, typename... P>
void call_with_validated_variant_args_static(Variant *base, void (*p_method)(T *, P...), const Variant **p_args) {
call_with_validated_variant_args_static_helper<T, P...>(VariantGetInternalPtr<T>::get_ptr(base), p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
}
-template <class T, class R, class... P>
+template <typename T, typename R, typename... P>
void call_with_validated_variant_args_static_retc(Variant *base, R (*p_method)(T *, P...), const Variant **p_args, Variant *r_ret) {
call_with_validated_variant_args_static_retc_helper<T, R, P...>(VariantGetInternalPtr<T>::get_ptr(base), p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
}
-template <class... P>
+template <typename... P>
void call_with_validated_variant_args_static_method(void (*p_method)(P...), const Variant **p_args) {
call_with_validated_variant_args_static_method_helper<P...>(p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
}
-template <class R, class... P>
+template <typename R, typename... P>
void call_with_validated_variant_args_static_method_ret(R (*p_method)(P...), const Variant **p_args, Variant *r_ret) {
call_with_validated_variant_args_static_method_ret_helper<R, P...>(p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
}
// Validated Object
-template <class T, class... P>
+template <typename T, typename... P>
void call_with_validated_object_instance_args(T *base, void (T::*p_method)(P...), const Variant **p_args) {
call_with_validated_variant_args_helper<T, P...>(base, p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
}
-template <class T, class... P>
+template <typename T, typename... P>
void call_with_validated_object_instance_argsc(T *base, void (T::*p_method)(P...) const, const Variant **p_args) {
call_with_validated_variant_argsc_helper<T, P...>(base, p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
}
-template <class T, class R, class... P>
+template <typename T, typename R, typename... P>
void call_with_validated_object_instance_args_ret(T *base, R (T::*p_method)(P...), const Variant **p_args, Variant *r_ret) {
call_with_validated_variant_args_ret_helper<T, R, P...>(base, p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
}
-template <class T, class R, class... P>
+template <typename T, typename R, typename... P>
void call_with_validated_object_instance_args_retc(T *base, R (T::*p_method)(P...) const, const Variant **p_args, Variant *r_ret) {
call_with_validated_variant_args_retc_helper<T, R, P...>(base, p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
}
-template <class T, class... P>
+template <typename T, typename... P>
void call_with_validated_object_instance_args_static(T *base, void (*p_method)(T *, P...), const Variant **p_args) {
call_with_validated_variant_args_static_helper<T, P...>(base, p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
}
-template <class T, class R, class... P>
+template <typename T, typename R, typename... P>
void call_with_validated_object_instance_args_static_retc(T *base, R (*p_method)(T *, P...), const Variant **p_args, Variant *r_ret) {
call_with_validated_variant_args_static_retc_helper<T, R, P...>(base, p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
}
@@ -683,7 +684,7 @@ void call_with_validated_object_instance_args_static_retc(T *base, R (*p_method)
#pragma GCC diagnostic ignored "-Wunused-but-set-parameter"
#endif
-template <class Q>
+template <typename Q>
void call_get_argument_type_helper(int p_arg, int &index, Variant::Type &type) {
if (p_arg == index) {
type = GetTypeInfo<Q>::VARIANT_TYPE;
@@ -691,7 +692,7 @@ void call_get_argument_type_helper(int p_arg, int &index, Variant::Type &type) {
index++;
}
-template <class... P>
+template <typename... P>
Variant::Type call_get_argument_type(int p_arg) {
Variant::Type type = Variant::NIL;
int index = 0;
@@ -703,7 +704,7 @@ Variant::Type call_get_argument_type(int p_arg) {
return type;
}
-template <class Q>
+template <typename Q>
void call_get_argument_type_info_helper(int p_arg, int &index, PropertyInfo &info) {
if (p_arg == index) {
info = GetTypeInfo<Q>::get_class_info();
@@ -711,7 +712,7 @@ void call_get_argument_type_info_helper(int p_arg, int &index, PropertyInfo &inf
index++;
}
-template <class... P>
+template <typename... P>
void call_get_argument_type_info(int p_arg, PropertyInfo &info) {
int index = 0;
// I think rocket science is simpler than modern C++.
@@ -722,7 +723,7 @@ void call_get_argument_type_info(int p_arg, PropertyInfo &info) {
}
#ifdef DEBUG_METHODS_ENABLED
-template <class Q>
+template <typename Q>
void call_get_argument_metadata_helper(int p_arg, int &index, GodotTypeInfo::Metadata &md) {
if (p_arg == index) {
md = GetTypeInfo<Q>::METADATA;
@@ -730,7 +731,7 @@ void call_get_argument_metadata_helper(int p_arg, int &index, GodotTypeInfo::Met
index++;
}
-template <class... P>
+template <typename... P>
GodotTypeInfo::Metadata call_get_argument_metadata(int p_arg) {
GodotTypeInfo::Metadata md = GodotTypeInfo::METADATA_NONE;
@@ -747,7 +748,7 @@ GodotTypeInfo::Metadata call_get_argument_metadata(int p_arg) {
//////////////////////
-template <class T, class R, class... P, size_t... Is>
+template <typename T, typename R, typename... P, size_t... Is>
void call_with_variant_args_ret_helper(T *p_instance, R (T::*p_method)(P...), const Variant **p_args, Variant &r_ret, Callable::CallError &r_error, IndexSequence<Is...>) {
r_error.error = Callable::CallError::CALL_OK;
@@ -758,7 +759,7 @@ void call_with_variant_args_ret_helper(T *p_instance, R (T::*p_method)(P...), co
#endif
}
-template <class R, class... P, size_t... Is>
+template <typename R, typename... P, size_t... Is>
void call_with_variant_args_static_ret(R (*p_method)(P...), const Variant **p_args, Variant &r_ret, Callable::CallError &r_error, IndexSequence<Is...>) {
r_error.error = Callable::CallError::CALL_OK;
@@ -769,7 +770,7 @@ void call_with_variant_args_static_ret(R (*p_method)(P...), const Variant **p_ar
#endif
}
-template <class... P, size_t... Is>
+template <typename... P, size_t... Is>
void call_with_variant_args_static(void (*p_method)(P...), const Variant **p_args, Callable::CallError &r_error, IndexSequence<Is...>) {
r_error.error = Callable::CallError::CALL_OK;
@@ -780,7 +781,7 @@ void call_with_variant_args_static(void (*p_method)(P...), const Variant **p_arg
#endif
}
-template <class T, class R, class... P>
+template <typename T, typename R, typename... P>
void call_with_variant_args_ret(T *p_instance, R (T::*p_method)(P...), const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) {
#ifdef DEBUG_METHODS_ENABLED
if ((size_t)p_argcount > sizeof...(P)) {
@@ -798,7 +799,7 @@ void call_with_variant_args_ret(T *p_instance, R (T::*p_method)(P...), const Var
call_with_variant_args_ret_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
}
-template <class T, class R, class... P, size_t... Is>
+template <typename T, typename R, typename... P, size_t... Is>
void call_with_variant_args_retc_helper(T *p_instance, R (T::*p_method)(P...) const, const Variant **p_args, Variant &r_ret, Callable::CallError &r_error, IndexSequence<Is...>) {
r_error.error = Callable::CallError::CALL_OK;
@@ -810,7 +811,7 @@ void call_with_variant_args_retc_helper(T *p_instance, R (T::*p_method)(P...) co
(void)p_args;
}
-template <class R, class... P>
+template <typename R, typename... P>
void call_with_variant_args_static_ret(R (*p_method)(P...), const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) {
#ifdef DEBUG_METHODS_ENABLED
if ((size_t)p_argcount > sizeof...(P)) {
@@ -828,7 +829,7 @@ void call_with_variant_args_static_ret(R (*p_method)(P...), const Variant **p_ar
call_with_variant_args_static_ret<R, P...>(p_method, p_args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
}
-template <class... P>
+template <typename... P>
void call_with_variant_args_static_ret(void (*p_method)(P...), const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) {
#ifdef DEBUG_METHODS_ENABLED
if ((size_t)p_argcount > sizeof...(P)) {
@@ -846,7 +847,7 @@ void call_with_variant_args_static_ret(void (*p_method)(P...), const Variant **p
call_with_variant_args_static<P...>(p_method, p_args, r_error, BuildIndexSequence<sizeof...(P)>{});
}
-template <class T, class R, class... P>
+template <typename T, typename R, typename... P>
void call_with_variant_args_retc(T *p_instance, R (T::*p_method)(P...) const, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) {
#ifdef DEBUG_METHODS_ENABLED
if ((size_t)p_argcount > sizeof...(P)) {
@@ -864,7 +865,7 @@ void call_with_variant_args_retc(T *p_instance, R (T::*p_method)(P...) const, co
call_with_variant_args_retc_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
}
-template <class T, class R, class... P, size_t... Is>
+template <typename T, typename R, typename... P, size_t... Is>
void call_with_variant_args_retc_static_helper(T *p_instance, R (*p_method)(T *, P...), const Variant **p_args, Variant &r_ret, Callable::CallError &r_error, IndexSequence<Is...>) {
r_error.error = Callable::CallError::CALL_OK;
@@ -877,7 +878,7 @@ void call_with_variant_args_retc_static_helper(T *p_instance, R (*p_method)(T *,
(void)p_args;
}
-template <class T, class R, class... P>
+template <typename T, typename R, typename... P>
void call_with_variant_args_retc_static_helper_dv(T *p_instance, R (*p_method)(T *, P...), const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &default_values, Callable::CallError &r_error) {
#ifdef DEBUG_ENABLED
if ((size_t)p_argcount > sizeof...(P)) {
@@ -910,7 +911,7 @@ void call_with_variant_args_retc_static_helper_dv(T *p_instance, R (*p_method)(T
call_with_variant_args_retc_static_helper(p_instance, p_method, args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
}
-template <class T, class... P, size_t... Is>
+template <typename T, typename... P, size_t... Is>
void call_with_variant_args_static_helper(T *p_instance, void (*p_method)(T *, P...), const Variant **p_args, Callable::CallError &r_error, IndexSequence<Is...>) {
r_error.error = Callable::CallError::CALL_OK;
@@ -923,7 +924,7 @@ void call_with_variant_args_static_helper(T *p_instance, void (*p_method)(T *, P
(void)p_args;
}
-template <class T, class... P>
+template <typename T, typename... P>
void call_with_variant_args_static_helper_dv(T *p_instance, void (*p_method)(T *, P...), const Variant **p_args, int p_argcount, const Vector<Variant> &default_values, Callable::CallError &r_error) {
#ifdef DEBUG_ENABLED
if ((size_t)p_argcount > sizeof...(P)) {
@@ -956,7 +957,7 @@ void call_with_variant_args_static_helper_dv(T *p_instance, void (*p_method)(T *
call_with_variant_args_static_helper(p_instance, p_method, args, r_error, BuildIndexSequence<sizeof...(P)>{});
}
-template <class R, class... P>
+template <typename R, typename... P>
void call_with_variant_args_static_ret_dv(R (*p_method)(P...), const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error, const Vector<Variant> &default_values) {
#ifdef DEBUG_ENABLED
if ((size_t)p_argcount > sizeof...(P)) {
@@ -989,7 +990,7 @@ void call_with_variant_args_static_ret_dv(R (*p_method)(P...), const Variant **p
call_with_variant_args_static_ret(p_method, args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
}
-template <class... P>
+template <typename... P>
void call_with_variant_args_static_dv(void (*p_method)(P...), const Variant **p_args, int p_argcount, Callable::CallError &r_error, const Vector<Variant> &default_values) {
#ifdef DEBUG_ENABLED
if ((size_t)p_argcount > sizeof...(P)) {
diff --git a/core/variant/callable.cpp b/core/variant/callable.cpp
index 0b1174c873..c6fbfd93a1 100644
--- a/core/variant/callable.cpp
+++ b/core/variant/callable.cpp
@@ -30,14 +30,14 @@
#include "callable.h"
-#include "callable_bind.h"
-#include "core/object/message_queue.h"
#include "core/object/object.h"
#include "core/object/ref_counted.h"
#include "core/object/script_language.h"
+#include "core/variant/callable_bind.h"
+#include "core/variant/variant_callable.h"
void Callable::call_deferredp(const Variant **p_arguments, int p_argcount) const {
- MessageQueue::get_singleton()->push_callablep(*this, p_arguments, p_argcount);
+ MessageQueue::get_singleton()->push_callablep(*this, p_arguments, p_argcount, true);
}
void Callable::callp(const Variant **p_arguments, int p_argcount, Variant &r_return_value, CallError &r_call_error) const {
@@ -92,10 +92,31 @@ Error Callable::rpcp(int p_id, const Variant **p_arguments, int p_argcount, Call
r_call_error.expected = 0;
return ERR_UNCONFIGURED;
} else if (!is_custom()) {
- r_call_error.error = CallError::CALL_ERROR_INVALID_METHOD;
- r_call_error.argument = 0;
- r_call_error.expected = 0;
- return ERR_UNCONFIGURED;
+ Object *obj = ObjectDB::get_instance(ObjectID(object));
+#ifdef DEBUG_ENABLED
+ if (!obj || !obj->is_class("Node")) {
+ r_call_error.error = CallError::CALL_ERROR_INSTANCE_IS_NULL;
+ r_call_error.argument = 0;
+ r_call_error.expected = 0;
+ return ERR_UNCONFIGURED;
+ }
+#endif
+
+ int argcount = p_argcount + 2;
+ const Variant **argptrs = (const Variant **)alloca(sizeof(Variant *) * argcount);
+ const Variant args[2] = { p_id, method };
+
+ argptrs[0] = &args[0];
+ argptrs[1] = &args[1];
+ for (int i = 0; i < p_argcount; ++i) {
+ argptrs[i + 2] = p_arguments[i];
+ }
+
+ CallError tmp;
+ Error err = (Error)obj->callp(SNAME("rpc_id"), argptrs, argcount, tmp).operator int64_t();
+
+ r_call_error.error = Callable::CallError::CALL_OK;
+ return err;
} else {
return custom->rpc(p_id, p_arguments, p_argcount, r_call_error);
}
@@ -163,6 +184,20 @@ StringName Callable::get_method() const {
return method;
}
+int Callable::get_argument_count(bool *r_is_valid) const {
+ if (is_custom()) {
+ bool valid = false;
+ return custom->get_argument_count(r_is_valid ? *r_is_valid : valid);
+ } else if (!is_null()) {
+ return get_object()->get_method_argument_count(method, r_is_valid);
+ } else {
+ if (r_is_valid) {
+ *r_is_valid = false;
+ }
+ return 0;
+ }
+}
+
int Callable::get_bound_arguments_count() const {
if (!is_null() && is_custom()) {
return custom->get_bound_arguments_count();
@@ -328,14 +363,27 @@ Callable::operator String() const {
}
}
+Callable Callable::create(const Variant &p_variant, const StringName &p_method) {
+ ERR_FAIL_COND_V_MSG(p_method == StringName(), Callable(), "Method argument to Callable::create method must be a non-empty string.");
+
+ switch (p_variant.get_type()) {
+ case Variant::NIL:
+ return Callable(ObjectID(), p_method);
+ case Variant::OBJECT:
+ return Callable(p_variant.operator ObjectID(), p_method);
+ default:
+ return Callable(memnew(VariantCallable(p_variant, p_method)));
+ }
+}
+
Callable::Callable(const Object *p_object, const StringName &p_method) {
- if (p_method == StringName()) {
+ if (unlikely(p_method == StringName())) {
object = 0;
- ERR_FAIL_MSG("Method argument to Callable constructor must be a non-empty string");
+ ERR_FAIL_MSG("Method argument to Callable constructor must be a non-empty string.");
}
- if (p_object == nullptr) {
+ if (unlikely(p_object == nullptr)) {
object = 0;
- ERR_FAIL_MSG("Object argument to Callable constructor must be non-null");
+ ERR_FAIL_MSG("Object argument to Callable constructor must be non-null.");
}
object = p_object->get_instance_id();
@@ -343,9 +391,9 @@ Callable::Callable(const Object *p_object, const StringName &p_method) {
}
Callable::Callable(ObjectID p_object, const StringName &p_method) {
- if (p_method == StringName()) {
+ if (unlikely(p_method == StringName())) {
object = 0;
- ERR_FAIL_MSG("Method argument to Callable constructor must be a non-empty string");
+ ERR_FAIL_MSG("Method argument to Callable constructor must be a non-empty string.");
}
object = p_object;
@@ -353,9 +401,9 @@ Callable::Callable(ObjectID p_object, const StringName &p_method) {
}
Callable::Callable(CallableCustom *p_custom) {
- if (p_custom->referenced) {
+ if (unlikely(p_custom->referenced)) {
object = 0;
- ERR_FAIL_MSG("Callable custom is already referenced");
+ ERR_FAIL_MSG("Callable custom is already referenced.");
}
p_custom->referenced = true;
object = 0; //ensure object is all zero, since pointer may be 32 bits
@@ -404,6 +452,11 @@ const Callable *CallableCustom::get_base_comparator() const {
return nullptr;
}
+int CallableCustom::get_argument_count(bool &r_is_valid) const {
+ r_is_valid = false;
+ return 0;
+}
+
int CallableCustom::get_bound_arguments_count() const {
return 0;
}
diff --git a/core/variant/callable.h b/core/variant/callable.h
index 3ae424e9bf..63757d9d6e 100644
--- a/core/variant/callable.h
+++ b/core/variant/callable.h
@@ -99,7 +99,7 @@ public:
bool is_valid() const;
template <typename... VarArgs>
- Callable bind(VarArgs... p_args);
+ Callable bind(VarArgs... p_args) const;
Callable bindv(const Array &p_arguments);
Callable bindp(const Variant **p_arguments, int p_argcount) const;
@@ -109,6 +109,7 @@ public:
ObjectID get_object_id() const;
StringName get_method() const;
CallableCustom *get_custom() const;
+ int get_argument_count(bool *r_is_valid = nullptr) const;
int get_bound_arguments_count() const;
void get_bound_arguments_ref(Vector<Variant> &r_arguments, int &r_argcount) const; // Internal engine use, the exposed one is below.
Array get_bound_arguments() const;
@@ -125,6 +126,8 @@ public:
operator String() const;
+ static Callable create(const Variant &p_variant, const StringName &p_method);
+
Callable(const Object *p_object, const StringName &p_method);
Callable(ObjectID p_object, const StringName &p_method);
Callable(CallableCustom *p_custom);
@@ -153,6 +156,7 @@ public:
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const = 0;
virtual Error rpc(int p_peer_id, const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error) const;
virtual const Callable *get_base_comparator() const;
+ virtual int get_argument_count(bool &r_is_valid) const;
virtual int get_bound_arguments_count() const;
virtual void get_bound_arguments(Vector<Variant> &r_arguments, int &r_argcount) const;
diff --git a/core/variant/callable_bind.cpp b/core/variant/callable_bind.cpp
index 9a6380a55f..d82aa3583d 100644
--- a/core/variant/callable_bind.cpp
+++ b/core/variant/callable_bind.cpp
@@ -91,6 +91,14 @@ const Callable *CallableCustomBind::get_base_comparator() const {
return callable.get_base_comparator();
}
+int CallableCustomBind::get_argument_count(bool &r_is_valid) const {
+ int ret = callable.get_argument_count(&r_is_valid);
+ if (r_is_valid) {
+ return ret - binds.size();
+ }
+ return 0;
+}
+
int CallableCustomBind::get_bound_arguments_count() const {
return callable.get_bound_arguments_count() + binds.size();
}
@@ -133,7 +141,7 @@ void CallableCustomBind::get_bound_arguments(Vector<Variant> &r_arguments, int &
}
void CallableCustomBind::call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const {
- const Variant **args = (const Variant **)alloca(sizeof(const Variant **) * (binds.size() + p_argcount));
+ const Variant **args = (const Variant **)alloca(sizeof(Variant *) * (binds.size() + p_argcount));
for (int i = 0; i < p_argcount; i++) {
args[i] = (const Variant *)p_arguments[i];
}
@@ -145,7 +153,7 @@ void CallableCustomBind::call(const Variant **p_arguments, int p_argcount, Varia
}
Error CallableCustomBind::rpc(int p_peer_id, const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error) const {
- const Variant **args = (const Variant **)alloca(sizeof(const Variant **) * (binds.size() + p_argcount));
+ const Variant **args = (const Variant **)alloca(sizeof(Variant *) * (binds.size() + p_argcount));
for (int i = 0; i < p_argcount; i++) {
args[i] = (const Variant *)p_arguments[i];
}
@@ -225,6 +233,14 @@ const Callable *CallableCustomUnbind::get_base_comparator() const {
return callable.get_base_comparator();
}
+int CallableCustomUnbind::get_argument_count(bool &r_is_valid) const {
+ int ret = callable.get_argument_count(&r_is_valid);
+ if (r_is_valid) {
+ return ret + argcount;
+ }
+ return 0;
+}
+
int CallableCustomUnbind::get_bound_arguments_count() const {
return callable.get_bound_arguments_count() - argcount;
}
diff --git a/core/variant/callable_bind.h b/core/variant/callable_bind.h
index 5798797a3d..43cebb45f0 100644
--- a/core/variant/callable_bind.h
+++ b/core/variant/callable_bind.h
@@ -53,6 +53,7 @@ public:
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const override;
virtual Error rpc(int p_peer_id, const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error) const override;
virtual const Callable *get_base_comparator() const override;
+ virtual int get_argument_count(bool &r_is_valid) const override;
virtual int get_bound_arguments_count() const override;
virtual void get_bound_arguments(Vector<Variant> &r_arguments, int &r_argcount) const override;
Callable get_callable() { return callable; }
@@ -81,6 +82,7 @@ public:
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const override;
virtual Error rpc(int p_peer_id, const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error) const override;
virtual const Callable *get_base_comparator() const override;
+ virtual int get_argument_count(bool &r_is_valid) const override;
virtual int get_bound_arguments_count() const override;
virtual void get_bound_arguments(Vector<Variant> &r_arguments, int &r_argcount) const override;
diff --git a/core/variant/dictionary.cpp b/core/variant/dictionary.cpp
index 141ce25fa6..7416101d51 100644
--- a/core/variant/dictionary.cpp
+++ b/core/variant/dictionary.cpp
@@ -150,6 +150,15 @@ Variant Dictionary::get(const Variant &p_key, const Variant &p_default) const {
return *result;
}
+Variant Dictionary::get_or_add(const Variant &p_key, const Variant &p_default) {
+ const Variant *result = getptr(p_key);
+ if (!result) {
+ operator[](p_key) = p_default;
+ return p_default;
+ }
+ return *result;
+}
+
int Dictionary::size() const {
return _p->variant_map.size();
}
@@ -240,13 +249,20 @@ void Dictionary::clear() {
}
void Dictionary::merge(const Dictionary &p_dictionary, bool p_overwrite) {
+ ERR_FAIL_COND_MSG(_p->read_only, "Dictionary is in read-only state.");
for (const KeyValue<Variant, Variant> &E : p_dictionary._p->variant_map) {
if (p_overwrite || !has(E.key)) {
- this->operator[](E.key) = E.value;
+ operator[](E.key) = E.value;
}
}
}
+Dictionary Dictionary::merged(const Dictionary &p_dictionary, bool p_overwrite) const {
+ Dictionary ret = duplicate();
+ ret.merge(p_dictionary, p_overwrite);
+ return ret;
+}
+
void Dictionary::_unref() const {
ERR_FAIL_NULL(_p);
if (_p->refcount.unref()) {
diff --git a/core/variant/dictionary.h b/core/variant/dictionary.h
index 8935d35ed9..67178ee7b7 100644
--- a/core/variant/dictionary.h
+++ b/core/variant/dictionary.h
@@ -58,11 +58,13 @@ public:
Variant get_valid(const Variant &p_key) const;
Variant get(const Variant &p_key, const Variant &p_default) const;
+ Variant get_or_add(const Variant &p_key, const Variant &p_default);
int size() const;
bool is_empty() const;
void clear();
void merge(const Dictionary &p_dictionary, bool p_overwrite = false);
+ Dictionary merged(const Dictionary &p_dictionary, bool p_overwrite = false) const;
bool has(const Variant &p_key) const;
bool has_all(const Array &p_keys) const;
diff --git a/core/variant/method_ptrcall.h b/core/variant/method_ptrcall.h
index 79be85cae6..123f2067e2 100644
--- a/core/variant/method_ptrcall.h
+++ b/core/variant/method_ptrcall.h
@@ -35,7 +35,7 @@
#include "core/typedefs.h"
#include "core/variant/variant.h"
-template <class T>
+template <typename T>
struct PtrToArg {};
#define MAKE_PTRARG(m_type) \
@@ -156,7 +156,7 @@ MAKE_PTRARG_BY_REFERENCE(Variant);
// This is for Object.
-template <class T>
+template <typename T>
struct PtrToArg<T *> {
_FORCE_INLINE_ static T *convert(const void *p_ptr) {
if (p_ptr == nullptr) {
@@ -170,7 +170,7 @@ struct PtrToArg<T *> {
}
};
-template <class T>
+template <typename T>
struct PtrToArg<const T *> {
_FORCE_INLINE_ static const T *convert(const void *p_ptr) {
if (p_ptr == nullptr) {
@@ -216,7 +216,7 @@ struct PtrToArg<ObjectID> {
} \
return ret; \
} \
- _FORCE_INLINE_ static void encode(Vector<m_type> p_vec, void *p_ptr) { \
+ _FORCE_INLINE_ static void encode(const Vector<m_type> &p_vec, void *p_ptr) { \
Vector<m_type> *dv = reinterpret_cast<Vector<m_type> *>(p_ptr); \
int len = p_vec.size(); \
dv->resize(len); \
@@ -246,49 +246,49 @@ struct PtrToArg<ObjectID> {
}
// No EncodeT because direct pointer conversion not possible.
-#define MAKE_VECARG_ALT(m_type, m_type_alt) \
- template <> \
- struct PtrToArg<Vector<m_type_alt>> { \
- _FORCE_INLINE_ static Vector<m_type_alt> convert(const void *p_ptr) { \
- const Vector<m_type> *dvs = reinterpret_cast<const Vector<m_type> *>(p_ptr); \
- Vector<m_type_alt> ret; \
- int len = dvs->size(); \
- ret.resize(len); \
- { \
- const m_type *r = dvs->ptr(); \
- for (int i = 0; i < len; i++) { \
- ret.write[i] = r[i]; \
- } \
- } \
- return ret; \
- } \
- _FORCE_INLINE_ static void encode(Vector<m_type_alt> p_vec, void *p_ptr) { \
- Vector<m_type> *dv = reinterpret_cast<Vector<m_type> *>(p_ptr); \
- int len = p_vec.size(); \
- dv->resize(len); \
- { \
- m_type *w = dv->ptrw(); \
- for (int i = 0; i < len; i++) { \
- w[i] = p_vec[i]; \
- } \
- } \
- } \
- }; \
- template <> \
- struct PtrToArg<const Vector<m_type_alt> &> { \
- _FORCE_INLINE_ static Vector<m_type_alt> convert(const void *p_ptr) { \
- const Vector<m_type> *dvs = reinterpret_cast<const Vector<m_type> *>(p_ptr); \
- Vector<m_type_alt> ret; \
- int len = dvs->size(); \
- ret.resize(len); \
- { \
- const m_type *r = dvs->ptr(); \
- for (int i = 0; i < len; i++) { \
- ret.write[i] = r[i]; \
- } \
- } \
- return ret; \
- } \
+#define MAKE_VECARG_ALT(m_type, m_type_alt) \
+ template <> \
+ struct PtrToArg<Vector<m_type_alt>> { \
+ _FORCE_INLINE_ static Vector<m_type_alt> convert(const void *p_ptr) { \
+ const Vector<m_type> *dvs = reinterpret_cast<const Vector<m_type> *>(p_ptr); \
+ Vector<m_type_alt> ret; \
+ int len = dvs->size(); \
+ ret.resize(len); \
+ { \
+ const m_type *r = dvs->ptr(); \
+ for (int i = 0; i < len; i++) { \
+ ret.write[i] = r[i]; \
+ } \
+ } \
+ return ret; \
+ } \
+ _FORCE_INLINE_ static void encode(const Vector<m_type_alt> &p_vec, void *p_ptr) { \
+ Vector<m_type> *dv = reinterpret_cast<Vector<m_type> *>(p_ptr); \
+ int len = p_vec.size(); \
+ dv->resize(len); \
+ { \
+ m_type *w = dv->ptrw(); \
+ for (int i = 0; i < len; i++) { \
+ w[i] = p_vec[i]; \
+ } \
+ } \
+ } \
+ }; \
+ template <> \
+ struct PtrToArg<const Vector<m_type_alt> &> { \
+ _FORCE_INLINE_ static Vector<m_type_alt> convert(const void *p_ptr) { \
+ const Vector<m_type> *dvs = reinterpret_cast<const Vector<m_type> *>(p_ptr); \
+ Vector<m_type_alt> ret; \
+ int len = dvs->size(); \
+ ret.resize(len); \
+ { \
+ const m_type *r = dvs->ptr(); \
+ for (int i = 0; i < len; i++) { \
+ ret.write[i] = r[i]; \
+ } \
+ } \
+ return ret; \
+ } \
}
MAKE_VECARG_ALT(String, StringName);
@@ -296,40 +296,40 @@ MAKE_VECARG_ALT(String, StringName);
// For stuff that gets converted to Array vectors.
// No EncodeT because direct pointer conversion not possible.
-#define MAKE_VECARR(m_type) \
- template <> \
- struct PtrToArg<Vector<m_type>> { \
- _FORCE_INLINE_ static Vector<m_type> convert(const void *p_ptr) { \
- const Array *arr = reinterpret_cast<const Array *>(p_ptr); \
- Vector<m_type> ret; \
- int len = arr->size(); \
- ret.resize(len); \
- for (int i = 0; i < len; i++) { \
- ret.write[i] = (*arr)[i]; \
- } \
- return ret; \
- } \
- _FORCE_INLINE_ static void encode(Vector<m_type> p_vec, void *p_ptr) { \
- Array *arr = reinterpret_cast<Array *>(p_ptr); \
- int len = p_vec.size(); \
- arr->resize(len); \
- for (int i = 0; i < len; i++) { \
- (*arr)[i] = p_vec[i]; \
- } \
- } \
- }; \
- template <> \
- struct PtrToArg<const Vector<m_type> &> { \
- _FORCE_INLINE_ static Vector<m_type> convert(const void *p_ptr) { \
- const Array *arr = reinterpret_cast<const Array *>(p_ptr); \
- Vector<m_type> ret; \
- int len = arr->size(); \
- ret.resize(len); \
- for (int i = 0; i < len; i++) { \
- ret.write[i] = (*arr)[i]; \
- } \
- return ret; \
- } \
+#define MAKE_VECARR(m_type) \
+ template <> \
+ struct PtrToArg<Vector<m_type>> { \
+ _FORCE_INLINE_ static Vector<m_type> convert(const void *p_ptr) { \
+ const Array *arr = reinterpret_cast<const Array *>(p_ptr); \
+ Vector<m_type> ret; \
+ int len = arr->size(); \
+ ret.resize(len); \
+ for (int i = 0; i < len; i++) { \
+ ret.write[i] = (*arr)[i]; \
+ } \
+ return ret; \
+ } \
+ _FORCE_INLINE_ static void encode(const Vector<m_type> &p_vec, void *p_ptr) { \
+ Array *arr = reinterpret_cast<Array *>(p_ptr); \
+ int len = p_vec.size(); \
+ arr->resize(len); \
+ for (int i = 0; i < len; i++) { \
+ (*arr)[i] = p_vec[i]; \
+ } \
+ } \
+ }; \
+ template <> \
+ struct PtrToArg<const Vector<m_type> &> { \
+ _FORCE_INLINE_ static Vector<m_type> convert(const void *p_ptr) { \
+ const Array *arr = reinterpret_cast<const Array *>(p_ptr); \
+ Vector<m_type> ret; \
+ int len = arr->size(); \
+ ret.resize(len); \
+ for (int i = 0; i < len; i++) { \
+ ret.write[i] = (*arr)[i]; \
+ } \
+ return ret; \
+ } \
}
MAKE_VECARR(Variant);
@@ -337,49 +337,49 @@ MAKE_VECARR(RID);
MAKE_VECARR(Plane);
// No EncodeT because direct pointer conversion not possible.
-#define MAKE_DVECARR(m_type) \
- template <> \
- struct PtrToArg<Vector<m_type>> { \
- _FORCE_INLINE_ static Vector<m_type> convert(const void *p_ptr) { \
- const Array *arr = reinterpret_cast<const Array *>(p_ptr); \
- Vector<m_type> ret; \
- int len = arr->size(); \
- ret.resize(len); \
- { \
- m_type *w = ret.ptrw(); \
- for (int i = 0; i < len; i++) { \
- w[i] = (*arr)[i]; \
- } \
- } \
- return ret; \
- } \
- _FORCE_INLINE_ static void encode(Vector<m_type> p_vec, void *p_ptr) { \
- Array *arr = reinterpret_cast<Array *>(p_ptr); \
- int len = p_vec.size(); \
- arr->resize(len); \
- { \
- const m_type *r = p_vec.ptr(); \
- for (int i = 0; i < len; i++) { \
- (*arr)[i] = r[i]; \
- } \
- } \
- } \
- }; \
- template <> \
- struct PtrToArg<const Vector<m_type> &> { \
- _FORCE_INLINE_ static Vector<m_type> convert(const void *p_ptr) { \
- const Array *arr = reinterpret_cast<const Array *>(p_ptr); \
- Vector<m_type> ret; \
- int len = arr->size(); \
- ret.resize(len); \
- { \
- m_type *w = ret.ptrw(); \
- for (int i = 0; i < len; i++) { \
- w[i] = (*arr)[i]; \
- } \
- } \
- return ret; \
- } \
+#define MAKE_DVECARR(m_type) \
+ template <> \
+ struct PtrToArg<Vector<m_type>> { \
+ _FORCE_INLINE_ static Vector<m_type> convert(const void *p_ptr) { \
+ const Array *arr = reinterpret_cast<const Array *>(p_ptr); \
+ Vector<m_type> ret; \
+ int len = arr->size(); \
+ ret.resize(len); \
+ { \
+ m_type *w = ret.ptrw(); \
+ for (int i = 0; i < len; i++) { \
+ w[i] = (*arr)[i]; \
+ } \
+ } \
+ return ret; \
+ } \
+ _FORCE_INLINE_ static void encode(const Vector<m_type> &p_vec, void *p_ptr) { \
+ Array *arr = reinterpret_cast<Array *>(p_ptr); \
+ int len = p_vec.size(); \
+ arr->resize(len); \
+ { \
+ const m_type *r = p_vec.ptr(); \
+ for (int i = 0; i < len; i++) { \
+ (*arr)[i] = r[i]; \
+ } \
+ } \
+ } \
+ }; \
+ template <> \
+ struct PtrToArg<const Vector<m_type> &> { \
+ _FORCE_INLINE_ static Vector<m_type> convert(const void *p_ptr) { \
+ const Array *arr = reinterpret_cast<const Array *>(p_ptr); \
+ Vector<m_type> ret; \
+ int len = arr->size(); \
+ ret.resize(len); \
+ { \
+ m_type *w = ret.ptrw(); \
+ for (int i = 0; i < len; i++) { \
+ w[i] = (*arr)[i]; \
+ } \
+ } \
+ return ret; \
+ } \
}
// Special case for IPAddress.
@@ -427,7 +427,7 @@ struct PtrToArg<Vector<Face3>> {
}
return ret;
}
- _FORCE_INLINE_ static void encode(Vector<Face3> p_vec, void *p_ptr) {
+ _FORCE_INLINE_ static void encode(const Vector<Face3> &p_vec, void *p_ptr) {
Vector<Vector3> *arr = reinterpret_cast<Vector<Vector3> *>(p_ptr);
int len = p_vec.size();
arr->resize(len * 3);
diff --git a/core/variant/native_ptr.h b/core/variant/native_ptr.h
index 9199b12845..33ba038132 100644
--- a/core/variant/native_ptr.h
+++ b/core/variant/native_ptr.h
@@ -35,7 +35,7 @@
#include "core/variant/method_ptrcall.h"
#include "core/variant/type_info.h"
-template <class T>
+template <typename T>
struct GDExtensionConstPtr {
const T *data = nullptr;
GDExtensionConstPtr(const T *p_assign) { data = p_assign; }
@@ -44,7 +44,7 @@ struct GDExtensionConstPtr {
operator Variant() const { return uint64_t(data); }
};
-template <class T>
+template <typename T>
struct GDExtensionPtr {
T *data = nullptr;
GDExtensionPtr(T *p_assign) { data = p_assign; }
@@ -95,7 +95,7 @@ struct GDExtensionPtr {
static _FORCE_INLINE_ void set(Variant *v, const GDExtensionPtr<m_type> &p_value) { *VariantInternal::get_int(v) = uint64_t(p_value.data); } \
};
-template <class T>
+template <typename T>
struct GetTypeInfo<GDExtensionConstPtr<T>> {
static const Variant::Type VARIANT_TYPE = Variant::NIL;
static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE;
@@ -104,7 +104,7 @@ struct GetTypeInfo<GDExtensionConstPtr<T>> {
}
};
-template <class T>
+template <typename T>
struct GetTypeInfo<GDExtensionPtr<T>> {
static const Variant::Type VARIANT_TYPE = Variant::NIL;
static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE;
@@ -113,7 +113,7 @@ struct GetTypeInfo<GDExtensionPtr<T>> {
}
};
-template <class T>
+template <typename T>
struct PtrToArg<GDExtensionConstPtr<T>> {
_FORCE_INLINE_ static GDExtensionConstPtr<T> convert(const void *p_ptr) {
return GDExtensionConstPtr<T>(reinterpret_cast<const T *>(p_ptr));
@@ -123,7 +123,7 @@ struct PtrToArg<GDExtensionConstPtr<T>> {
*((const T **)p_ptr) = p_val.data;
}
};
-template <class T>
+template <typename T>
struct PtrToArg<GDExtensionPtr<T>> {
_FORCE_INLINE_ static GDExtensionPtr<T> convert(const void *p_ptr) {
return GDExtensionPtr<T>(reinterpret_cast<const T *>(p_ptr));
diff --git a/core/variant/type_info.h b/core/variant/type_info.h
index e89658d25b..15cb6c9c1a 100644
--- a/core/variant/type_info.h
+++ b/core/variant/type_info.h
@@ -33,35 +33,7 @@
#include "core/typedefs.h"
-template <bool C, typename T = void>
-struct EnableIf {
- typedef T type;
-};
-
-template <typename T>
-struct EnableIf<false, T> {
-};
-
-template <typename, typename>
-struct TypesAreSame {
- static bool const value = false;
-};
-
-template <typename A>
-struct TypesAreSame<A, A> {
- static bool const value = true;
-};
-
-template <typename B, typename D>
-struct TypeInherits {
- static D *get_d();
-
- static char (&test(B *))[1];
- static char (&test(...))[2];
-
- static bool const value = sizeof(test(get_d())) == sizeof(char) &&
- !TypesAreSame<B volatile const, void volatile const>::value;
-};
+#include <type_traits>
namespace GodotTypeInfo {
enum Metadata {
@@ -84,7 +56,7 @@ enum Metadata {
// If 'T' is a class that inherits 'Object', make sure it can see the actual class declaration
// instead of a forward declaration. You can always forward declare 'T' in a header file, and then
// include the actual declaration of 'T' in the source file where 'GetTypeInfo<T>' is instantiated.
-template <class T, typename = void>
+template <typename T, typename = void>
struct GetTypeInfo;
#define MAKE_TYPE_INFO(m_type, m_var_type) \
@@ -227,16 +199,7 @@ MAKE_TEMPLATE_TYPE_INFO(Vector, Face3, Variant::PACKED_VECTOR3_ARRAY)
MAKE_TEMPLATE_TYPE_INFO(Vector, StringName, Variant::PACKED_STRING_ARRAY)
template <typename T>
-struct GetTypeInfo<T *, typename EnableIf<TypeInherits<Object, T>::value>::type> {
- static const Variant::Type VARIANT_TYPE = Variant::OBJECT;
- static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE;
- static inline PropertyInfo get_class_info() {
- return PropertyInfo(StringName(T::get_class_static()));
- }
-};
-
-template <typename T>
-struct GetTypeInfo<const T *, typename EnableIf<TypeInherits<Object, T>::value>::type> {
+struct GetTypeInfo<T *, std::enable_if_t<std::is_base_of_v<Object, T>>> {
static const Variant::Type VARIANT_TYPE = Variant::OBJECT;
static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE;
static inline PropertyInfo get_class_info() {
@@ -282,21 +245,25 @@ inline StringName __constant_get_enum_name(T param, const String &p_constant) {
return GetTypeInfo<T>::get_class_info().class_name;
}
-template <class T>
+template <typename T>
class BitField {
int64_t value = 0;
public:
- _FORCE_INLINE_ void set_flag(T p_flag) { value |= (int64_t)p_flag; }
+ _FORCE_INLINE_ BitField<T> &set_flag(T p_flag) {
+ value |= (int64_t)p_flag;
+ return *this;
+ }
_FORCE_INLINE_ bool has_flag(T p_flag) const { return value & (int64_t)p_flag; }
_FORCE_INLINE_ bool is_empty() const { return value == 0; }
_FORCE_INLINE_ void clear_flag(T p_flag) { value &= ~(int64_t)p_flag; }
_FORCE_INLINE_ void clear() { value = 0; }
- _FORCE_INLINE_ BitField() = default;
- _FORCE_INLINE_ BitField(int64_t p_value) { value = p_value; }
- _FORCE_INLINE_ BitField(T p_value) { value = (int64_t)p_value; }
+ _FORCE_INLINE_ constexpr BitField() = default;
+ _FORCE_INLINE_ constexpr BitField(int64_t p_value) { value = p_value; }
+ _FORCE_INLINE_ constexpr BitField(T p_value) { value = (int64_t)p_value; }
_FORCE_INLINE_ operator int64_t() const { return value; }
_FORCE_INLINE_ operator Variant() const { return value; }
+ _FORCE_INLINE_ BitField<T> operator^(const BitField<T> &p_b) const { return BitField<T>(value ^ p_b.value); }
};
#define TEMPL_MAKE_BITFIELD_TYPE_INFO(m_enum, m_impl) \
diff --git a/core/variant/typed_array.h b/core/variant/typed_array.h
index 037c5c7c2e..0befd19864 100644
--- a/core/variant/typed_array.h
+++ b/core/variant/typed_array.h
@@ -38,7 +38,7 @@
#include "core/variant/type_info.h"
#include "core/variant/variant.h"
-template <class T>
+template <typename T>
class TypedArray : public Array {
public:
_FORCE_INLINE_ void operator=(const Array &p_array) {
@@ -56,12 +56,12 @@ public:
}
};
-template <class T>
+template <typename T>
struct VariantInternalAccessor<TypedArray<T>> {
static _FORCE_INLINE_ TypedArray<T> get(const Variant *v) { return *VariantInternal::get_array(v); }
static _FORCE_INLINE_ void set(Variant *v, const TypedArray<T> &p_array) { *VariantInternal::get_array(v) = p_array; }
};
-template <class T>
+template <typename T>
struct VariantInternalAccessor<const TypedArray<T> &> {
static _FORCE_INLINE_ TypedArray<T> get(const Variant *v) { return *VariantInternal::get_array(v); }
static _FORCE_INLINE_ void set(Variant *v, const TypedArray<T> &p_array) { *VariantInternal::get_array(v) = p_array; }
@@ -88,6 +88,8 @@ struct VariantInternalAccessor<const TypedArray<T> &> {
} \
};
+// All Variant::OBJECT types are intentionally omitted from this list because they are handled by
+// the unspecialized TypedArray definition.
MAKE_TYPED_ARRAY(bool, Variant::BOOL)
MAKE_TYPED_ARRAY(uint8_t, Variant::INT)
MAKE_TYPED_ARRAY(int8_t, Variant::INT)
@@ -107,11 +109,14 @@ MAKE_TYPED_ARRAY(Rect2i, Variant::RECT2I)
MAKE_TYPED_ARRAY(Vector3, Variant::VECTOR3)
MAKE_TYPED_ARRAY(Vector3i, Variant::VECTOR3I)
MAKE_TYPED_ARRAY(Transform2D, Variant::TRANSFORM2D)
+MAKE_TYPED_ARRAY(Vector4, Variant::VECTOR4)
+MAKE_TYPED_ARRAY(Vector4i, Variant::VECTOR4I)
MAKE_TYPED_ARRAY(Plane, Variant::PLANE)
MAKE_TYPED_ARRAY(Quaternion, Variant::QUATERNION)
MAKE_TYPED_ARRAY(AABB, Variant::AABB)
MAKE_TYPED_ARRAY(Basis, Variant::BASIS)
MAKE_TYPED_ARRAY(Transform3D, Variant::TRANSFORM3D)
+MAKE_TYPED_ARRAY(Projection, Variant::PROJECTION)
MAKE_TYPED_ARRAY(Color, Variant::COLOR)
MAKE_TYPED_ARRAY(StringName, Variant::STRING_NAME)
MAKE_TYPED_ARRAY(NodePath, Variant::NODE_PATH)
@@ -120,18 +125,18 @@ MAKE_TYPED_ARRAY(Callable, Variant::CALLABLE)
MAKE_TYPED_ARRAY(Signal, Variant::SIGNAL)
MAKE_TYPED_ARRAY(Dictionary, Variant::DICTIONARY)
MAKE_TYPED_ARRAY(Array, Variant::ARRAY)
-MAKE_TYPED_ARRAY(Vector<uint8_t>, Variant::PACKED_BYTE_ARRAY)
-MAKE_TYPED_ARRAY(Vector<int32_t>, Variant::PACKED_INT32_ARRAY)
-MAKE_TYPED_ARRAY(Vector<int64_t>, Variant::PACKED_INT64_ARRAY)
-MAKE_TYPED_ARRAY(Vector<float>, Variant::PACKED_FLOAT32_ARRAY)
-MAKE_TYPED_ARRAY(Vector<double>, Variant::PACKED_FLOAT64_ARRAY)
-MAKE_TYPED_ARRAY(Vector<String>, Variant::PACKED_STRING_ARRAY)
-MAKE_TYPED_ARRAY(Vector<Vector2>, Variant::PACKED_VECTOR2_ARRAY)
-MAKE_TYPED_ARRAY(Vector<Vector3>, Variant::PACKED_VECTOR3_ARRAY)
-MAKE_TYPED_ARRAY(Vector<Color>, Variant::PACKED_COLOR_ARRAY)
+MAKE_TYPED_ARRAY(PackedByteArray, Variant::PACKED_BYTE_ARRAY)
+MAKE_TYPED_ARRAY(PackedInt32Array, Variant::PACKED_INT32_ARRAY)
+MAKE_TYPED_ARRAY(PackedInt64Array, Variant::PACKED_INT64_ARRAY)
+MAKE_TYPED_ARRAY(PackedFloat32Array, Variant::PACKED_FLOAT32_ARRAY)
+MAKE_TYPED_ARRAY(PackedFloat64Array, Variant::PACKED_FLOAT64_ARRAY)
+MAKE_TYPED_ARRAY(PackedStringArray, Variant::PACKED_STRING_ARRAY)
+MAKE_TYPED_ARRAY(PackedVector2Array, Variant::PACKED_VECTOR2_ARRAY)
+MAKE_TYPED_ARRAY(PackedVector3Array, Variant::PACKED_VECTOR3_ARRAY)
+MAKE_TYPED_ARRAY(PackedColorArray, Variant::PACKED_COLOR_ARRAY)
MAKE_TYPED_ARRAY(IPAddress, Variant::STRING)
-template <class T>
+template <typename T>
struct PtrToArg<TypedArray<T>> {
_FORCE_INLINE_ static TypedArray<T> convert(const void *p_ptr) {
return TypedArray<T>(*reinterpret_cast<const Array *>(p_ptr));
@@ -142,7 +147,7 @@ struct PtrToArg<TypedArray<T>> {
}
};
-template <class T>
+template <typename T>
struct PtrToArg<const TypedArray<T> &> {
typedef Array EncodeT;
_FORCE_INLINE_ static TypedArray<T> convert(const void *p_ptr) {
@@ -150,7 +155,7 @@ struct PtrToArg<const TypedArray<T> &> {
}
};
-template <class T>
+template <typename T>
struct GetTypeInfo<TypedArray<T>> {
static const Variant::Type VARIANT_TYPE = Variant::ARRAY;
static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE;
@@ -159,7 +164,7 @@ struct GetTypeInfo<TypedArray<T>> {
}
};
-template <class T>
+template <typename T>
struct GetTypeInfo<const TypedArray<T> &> {
static const Variant::Type VARIANT_TYPE = Variant::ARRAY;
static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE;
@@ -205,11 +210,14 @@ MAKE_TYPED_ARRAY_INFO(Rect2i, Variant::RECT2I)
MAKE_TYPED_ARRAY_INFO(Vector3, Variant::VECTOR3)
MAKE_TYPED_ARRAY_INFO(Vector3i, Variant::VECTOR3I)
MAKE_TYPED_ARRAY_INFO(Transform2D, Variant::TRANSFORM2D)
+MAKE_TYPED_ARRAY_INFO(Vector4, Variant::VECTOR4)
+MAKE_TYPED_ARRAY_INFO(Vector4i, Variant::VECTOR4I)
MAKE_TYPED_ARRAY_INFO(Plane, Variant::PLANE)
MAKE_TYPED_ARRAY_INFO(Quaternion, Variant::QUATERNION)
MAKE_TYPED_ARRAY_INFO(AABB, Variant::AABB)
MAKE_TYPED_ARRAY_INFO(Basis, Variant::BASIS)
MAKE_TYPED_ARRAY_INFO(Transform3D, Variant::TRANSFORM3D)
+MAKE_TYPED_ARRAY_INFO(Projection, Variant::PROJECTION)
MAKE_TYPED_ARRAY_INFO(Color, Variant::COLOR)
MAKE_TYPED_ARRAY_INFO(StringName, Variant::STRING_NAME)
MAKE_TYPED_ARRAY_INFO(NodePath, Variant::NODE_PATH)
@@ -218,15 +226,15 @@ MAKE_TYPED_ARRAY_INFO(Callable, Variant::CALLABLE)
MAKE_TYPED_ARRAY_INFO(Signal, Variant::SIGNAL)
MAKE_TYPED_ARRAY_INFO(Dictionary, Variant::DICTIONARY)
MAKE_TYPED_ARRAY_INFO(Array, Variant::ARRAY)
-MAKE_TYPED_ARRAY_INFO(Vector<uint8_t>, Variant::PACKED_BYTE_ARRAY)
-MAKE_TYPED_ARRAY_INFO(Vector<int32_t>, Variant::PACKED_INT32_ARRAY)
-MAKE_TYPED_ARRAY_INFO(Vector<int64_t>, Variant::PACKED_INT64_ARRAY)
-MAKE_TYPED_ARRAY_INFO(Vector<float>, Variant::PACKED_FLOAT32_ARRAY)
-MAKE_TYPED_ARRAY_INFO(Vector<double>, Variant::PACKED_FLOAT64_ARRAY)
-MAKE_TYPED_ARRAY_INFO(Vector<String>, Variant::PACKED_STRING_ARRAY)
-MAKE_TYPED_ARRAY_INFO(Vector<Vector2>, Variant::PACKED_VECTOR2_ARRAY)
-MAKE_TYPED_ARRAY_INFO(Vector<Vector3>, Variant::PACKED_VECTOR3_ARRAY)
-MAKE_TYPED_ARRAY_INFO(Vector<Color>, Variant::PACKED_COLOR_ARRAY)
+MAKE_TYPED_ARRAY_INFO(PackedByteArray, Variant::PACKED_BYTE_ARRAY)
+MAKE_TYPED_ARRAY_INFO(PackedInt32Array, Variant::PACKED_INT32_ARRAY)
+MAKE_TYPED_ARRAY_INFO(PackedInt64Array, Variant::PACKED_INT64_ARRAY)
+MAKE_TYPED_ARRAY_INFO(PackedFloat32Array, Variant::PACKED_FLOAT32_ARRAY)
+MAKE_TYPED_ARRAY_INFO(PackedFloat64Array, Variant::PACKED_FLOAT64_ARRAY)
+MAKE_TYPED_ARRAY_INFO(PackedStringArray, Variant::PACKED_STRING_ARRAY)
+MAKE_TYPED_ARRAY_INFO(PackedVector2Array, Variant::PACKED_VECTOR2_ARRAY)
+MAKE_TYPED_ARRAY_INFO(PackedVector3Array, Variant::PACKED_VECTOR3_ARRAY)
+MAKE_TYPED_ARRAY_INFO(PackedColorArray, Variant::PACKED_COLOR_ARRAY)
MAKE_TYPED_ARRAY_INFO(IPAddress, Variant::STRING)
#undef MAKE_TYPED_ARRAY
diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp
index 09fb34e7c1..8e702ce8bb 100644
--- a/core/variant/variant.cpp
+++ b/core/variant/variant.cpp
@@ -931,7 +931,7 @@ bool Variant::is_zero() const {
return *reinterpret_cast<const ::RID *>(_data._mem) == ::RID();
}
case OBJECT: {
- return _get_obj().obj == nullptr;
+ return get_validated_object() == nullptr;
}
case CALLABLE: {
return reinterpret_cast<const Callable *>(_data._mem)->is_null();
@@ -1246,52 +1246,58 @@ void Variant::zero() {
case NIL:
break;
case BOOL:
- this->_data._bool = false;
+ _data._bool = false;
break;
case INT:
- this->_data._int = 0;
+ _data._int = 0;
break;
case FLOAT:
- this->_data._float = 0;
+ _data._float = 0;
break;
case VECTOR2:
- *reinterpret_cast<Vector2 *>(this->_data._mem) = Vector2();
+ *reinterpret_cast<Vector2 *>(_data._mem) = Vector2();
break;
case VECTOR2I:
- *reinterpret_cast<Vector2i *>(this->_data._mem) = Vector2i();
+ *reinterpret_cast<Vector2i *>(_data._mem) = Vector2i();
break;
case RECT2:
- *reinterpret_cast<Rect2 *>(this->_data._mem) = Rect2();
+ *reinterpret_cast<Rect2 *>(_data._mem) = Rect2();
break;
case RECT2I:
- *reinterpret_cast<Rect2i *>(this->_data._mem) = Rect2i();
+ *reinterpret_cast<Rect2i *>(_data._mem) = Rect2i();
break;
case VECTOR3:
- *reinterpret_cast<Vector3 *>(this->_data._mem) = Vector3();
+ *reinterpret_cast<Vector3 *>(_data._mem) = Vector3();
break;
case VECTOR3I:
- *reinterpret_cast<Vector3i *>(this->_data._mem) = Vector3i();
+ *reinterpret_cast<Vector3i *>(_data._mem) = Vector3i();
break;
case VECTOR4:
- *reinterpret_cast<Vector4 *>(this->_data._mem) = Vector4();
+ *reinterpret_cast<Vector4 *>(_data._mem) = Vector4();
break;
case VECTOR4I:
- *reinterpret_cast<Vector4i *>(this->_data._mem) = Vector4i();
+ *reinterpret_cast<Vector4i *>(_data._mem) = Vector4i();
break;
case PLANE:
- *reinterpret_cast<Plane *>(this->_data._mem) = Plane();
+ *reinterpret_cast<Plane *>(_data._mem) = Plane();
break;
case QUATERNION:
- *reinterpret_cast<Quaternion *>(this->_data._mem) = Quaternion();
+ *reinterpret_cast<Quaternion *>(_data._mem) = Quaternion();
break;
case COLOR:
- *reinterpret_cast<Color *>(this->_data._mem) = Color();
+ *reinterpret_cast<Color *>(_data._mem) = Color();
break;
default:
- this->clear();
+ Type prev_type = type;
+ clear();
+ if (type != prev_type) {
+ // clear() changes type to NIL, so it needs to be restored.
+ Callable::CallError ce;
+ Variant::construct(prev_type, *this, nullptr, 0, ce);
+ }
break;
}
}
@@ -1411,25 +1417,7 @@ void Variant::_clear_internal() {
}
}
-Variant::operator signed int() const {
- switch (type) {
- case NIL:
- return 0;
- case BOOL:
- return _data._bool ? 1 : 0;
- case INT:
- return _data._int;
- case FLOAT:
- return _data._float;
- case STRING:
- return operator String().to_int();
- default: {
- return 0;
- }
- }
-}
-
-Variant::operator unsigned int() const {
+Variant::operator int64_t() const {
switch (type) {
case NIL:
return 0;
@@ -1447,7 +1435,7 @@ Variant::operator unsigned int() const {
}
}
-Variant::operator int64_t() const {
+Variant::operator int32_t() const {
switch (type) {
case NIL:
return 0;
@@ -1465,7 +1453,7 @@ Variant::operator int64_t() const {
}
}
-Variant::operator uint64_t() const {
+Variant::operator int16_t() const {
switch (type) {
case NIL:
return 0;
@@ -1483,18 +1471,7 @@ Variant::operator uint64_t() const {
}
}
-Variant::operator ObjectID() const {
- if (type == INT) {
- return ObjectID(_data._int);
- } else if (type == OBJECT) {
- return _get_obj().id;
- } else {
- return ObjectID();
- }
-}
-
-#ifdef NEED_LONG_INT
-Variant::operator signed long() const {
+Variant::operator int8_t() const {
switch (type) {
case NIL:
return 0;
@@ -1510,11 +1487,9 @@ Variant::operator signed long() const {
return 0;
}
}
-
- return 0;
}
-Variant::operator unsigned long() const {
+Variant::operator uint64_t() const {
switch (type) {
case NIL:
return 0;
@@ -1530,12 +1505,9 @@ Variant::operator unsigned long() const {
return 0;
}
}
-
- return 0;
}
-#endif
-Variant::operator signed short() const {
+Variant::operator uint32_t() const {
switch (type) {
case NIL:
return 0;
@@ -1553,7 +1525,7 @@ Variant::operator signed short() const {
}
}
-Variant::operator unsigned short() const {
+Variant::operator uint16_t() const {
switch (type) {
case NIL:
return 0;
@@ -1571,7 +1543,7 @@ Variant::operator unsigned short() const {
}
}
-Variant::operator signed char() const {
+Variant::operator uint8_t() const {
switch (type) {
case NIL:
return 0;
@@ -1589,26 +1561,18 @@ Variant::operator signed char() const {
}
}
-Variant::operator unsigned char() const {
- switch (type) {
- case NIL:
- return 0;
- case BOOL:
- return _data._bool ? 1 : 0;
- case INT:
- return _data._int;
- case FLOAT:
- return _data._float;
- case STRING:
- return operator String().to_int();
- default: {
- return 0;
- }
+Variant::operator ObjectID() const {
+ if (type == INT) {
+ return ObjectID(_data._int);
+ } else if (type == OBJECT) {
+ return _get_obj().id;
+ } else {
+ return ObjectID();
}
}
Variant::operator char32_t() const {
- return operator unsigned int();
+ return operator uint32_t();
}
Variant::operator float() const {
@@ -1670,7 +1634,7 @@ Variant::operator String() const {
return stringify(0);
}
-String stringify_variant_clean(const Variant p_variant, int recursion_count) {
+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.
@@ -1691,7 +1655,7 @@ String stringify_variant_clean(const Variant p_variant, int recursion_count) {
return s;
}
-template <class T>
+template <typename T>
String stringify_vector(const T &vec, int recursion_count) {
String str("[");
for (int i = 0; i < vec.size(); i++) {
@@ -1787,31 +1751,31 @@ String Variant::stringify(int recursion_count) const {
}
// Packed arrays cannot contain recursive structures, the recursion_count increment is not needed.
case PACKED_VECTOR2_ARRAY: {
- return stringify_vector(operator Vector<Vector2>(), recursion_count);
+ return stringify_vector(operator PackedVector2Array(), recursion_count);
}
case PACKED_VECTOR3_ARRAY: {
- return stringify_vector(operator Vector<Vector3>(), recursion_count);
+ return stringify_vector(operator PackedVector3Array(), recursion_count);
}
case PACKED_COLOR_ARRAY: {
- return stringify_vector(operator Vector<Color>(), recursion_count);
+ return stringify_vector(operator PackedColorArray(), recursion_count);
}
case PACKED_STRING_ARRAY: {
- return stringify_vector(operator Vector<String>(), recursion_count);
+ return stringify_vector(operator PackedStringArray(), recursion_count);
}
case PACKED_BYTE_ARRAY: {
- return stringify_vector(operator Vector<uint8_t>(), recursion_count);
+ return stringify_vector(operator PackedByteArray(), recursion_count);
}
case PACKED_INT32_ARRAY: {
- return stringify_vector(operator Vector<int32_t>(), recursion_count);
+ return stringify_vector(operator PackedInt32Array(), recursion_count);
}
case PACKED_INT64_ARRAY: {
- return stringify_vector(operator Vector<int64_t>(), recursion_count);
+ return stringify_vector(operator PackedInt64Array(), recursion_count);
}
case PACKED_FLOAT32_ARRAY: {
- return stringify_vector(operator Vector<float>(), recursion_count);
+ return stringify_vector(operator PackedFloat32Array(), recursion_count);
}
case PACKED_FLOAT64_ARRAY: {
- return stringify_vector(operator Vector<double>(), recursion_count);
+ return stringify_vector(operator PackedFloat64Array(), recursion_count);
}
case ARRAY: {
ERR_FAIL_COND_V_MSG(recursion_count > MAX_RECURSION, "[...]", "Maximum array recursion reached!");
@@ -2182,7 +2146,7 @@ Variant::operator Signal() const {
}
}
-template <class DA, class SA>
+template <typename DA, typename SA>
inline DA _convert_array(const SA &p_array) {
DA da;
da.resize(p_array.size());
@@ -2194,38 +2158,38 @@ inline DA _convert_array(const SA &p_array) {
return da;
}
-template <class DA>
+template <typename DA>
inline DA _convert_array_from_variant(const Variant &p_variant) {
switch (p_variant.get_type()) {
case Variant::ARRAY: {
return _convert_array<DA, Array>(p_variant.operator Array());
}
case Variant::PACKED_BYTE_ARRAY: {
- return _convert_array<DA, Vector<uint8_t>>(p_variant.operator Vector<uint8_t>());
+ return _convert_array<DA, PackedByteArray>(p_variant.operator PackedByteArray());
}
case Variant::PACKED_INT32_ARRAY: {
- return _convert_array<DA, Vector<int32_t>>(p_variant.operator Vector<int32_t>());
+ return _convert_array<DA, PackedInt32Array>(p_variant.operator PackedInt32Array());
}
case Variant::PACKED_INT64_ARRAY: {
- return _convert_array<DA, Vector<int64_t>>(p_variant.operator Vector<int64_t>());
+ return _convert_array<DA, PackedInt64Array>(p_variant.operator PackedInt64Array());
}
case Variant::PACKED_FLOAT32_ARRAY: {
- return _convert_array<DA, Vector<float>>(p_variant.operator Vector<float>());
+ return _convert_array<DA, PackedFloat32Array>(p_variant.operator PackedFloat32Array());
}
case Variant::PACKED_FLOAT64_ARRAY: {
- return _convert_array<DA, Vector<double>>(p_variant.operator Vector<double>());
+ return _convert_array<DA, PackedFloat64Array>(p_variant.operator PackedFloat64Array());
}
case Variant::PACKED_STRING_ARRAY: {
- return _convert_array<DA, Vector<String>>(p_variant.operator Vector<String>());
+ return _convert_array<DA, PackedStringArray>(p_variant.operator PackedStringArray());
}
case Variant::PACKED_VECTOR2_ARRAY: {
- return _convert_array<DA, Vector<Vector2>>(p_variant.operator Vector<Vector2>());
+ return _convert_array<DA, PackedVector2Array>(p_variant.operator PackedVector2Array());
}
case Variant::PACKED_VECTOR3_ARRAY: {
- return _convert_array<DA, Vector<Vector3>>(p_variant.operator Vector<Vector3>());
+ return _convert_array<DA, PackedVector3Array>(p_variant.operator PackedVector3Array());
}
case Variant::PACKED_COLOR_ARRAY: {
- return _convert_array<DA, Vector<Color>>(p_variant.operator Vector<Color>());
+ return _convert_array<DA, PackedColorArray>(p_variant.operator PackedColorArray());
}
default: {
return DA();
@@ -2241,75 +2205,75 @@ Variant::operator Array() const {
}
}
-Variant::operator Vector<uint8_t>() const {
+Variant::operator PackedByteArray() const {
if (type == PACKED_BYTE_ARRAY) {
return static_cast<PackedArrayRef<uint8_t> *>(_data.packed_array)->array;
} else {
- return _convert_array_from_variant<Vector<uint8_t>>(*this);
+ return _convert_array_from_variant<PackedByteArray>(*this);
}
}
-Variant::operator Vector<int32_t>() const {
+Variant::operator PackedInt32Array() const {
if (type == PACKED_INT32_ARRAY) {
return static_cast<PackedArrayRef<int32_t> *>(_data.packed_array)->array;
} else {
- return _convert_array_from_variant<Vector<int>>(*this);
+ return _convert_array_from_variant<PackedInt32Array>(*this);
}
}
-Variant::operator Vector<int64_t>() const {
+Variant::operator PackedInt64Array() const {
if (type == PACKED_INT64_ARRAY) {
return static_cast<PackedArrayRef<int64_t> *>(_data.packed_array)->array;
} else {
- return _convert_array_from_variant<Vector<int64_t>>(*this);
+ return _convert_array_from_variant<PackedInt64Array>(*this);
}
}
-Variant::operator Vector<float>() const {
+Variant::operator PackedFloat32Array() const {
if (type == PACKED_FLOAT32_ARRAY) {
return static_cast<PackedArrayRef<float> *>(_data.packed_array)->array;
} else {
- return _convert_array_from_variant<Vector<float>>(*this);
+ return _convert_array_from_variant<PackedFloat32Array>(*this);
}
}
-Variant::operator Vector<double>() const {
+Variant::operator PackedFloat64Array() const {
if (type == PACKED_FLOAT64_ARRAY) {
return static_cast<PackedArrayRef<double> *>(_data.packed_array)->array;
} else {
- return _convert_array_from_variant<Vector<double>>(*this);
+ return _convert_array_from_variant<PackedFloat64Array>(*this);
}
}
-Variant::operator Vector<String>() const {
+Variant::operator PackedStringArray() const {
if (type == PACKED_STRING_ARRAY) {
return static_cast<PackedArrayRef<String> *>(_data.packed_array)->array;
} else {
- return _convert_array_from_variant<Vector<String>>(*this);
+ return _convert_array_from_variant<PackedStringArray>(*this);
}
}
-Variant::operator Vector<Vector3>() const {
- if (type == PACKED_VECTOR3_ARRAY) {
- return static_cast<PackedArrayRef<Vector3> *>(_data.packed_array)->array;
+Variant::operator PackedVector2Array() const {
+ if (type == PACKED_VECTOR2_ARRAY) {
+ return static_cast<PackedArrayRef<Vector2> *>(_data.packed_array)->array;
} else {
- return _convert_array_from_variant<Vector<Vector3>>(*this);
+ return _convert_array_from_variant<PackedVector2Array>(*this);
}
}
-Variant::operator Vector<Vector2>() const {
- if (type == PACKED_VECTOR2_ARRAY) {
- return static_cast<PackedArrayRef<Vector2> *>(_data.packed_array)->array;
+Variant::operator PackedVector3Array() const {
+ if (type == PACKED_VECTOR3_ARRAY) {
+ return static_cast<PackedArrayRef<Vector3> *>(_data.packed_array)->array;
} else {
- return _convert_array_from_variant<Vector<Vector2>>(*this);
+ return _convert_array_from_variant<PackedVector3Array>(*this);
}
}
-Variant::operator Vector<Color>() const {
+Variant::operator PackedColorArray() const {
if (type == PACKED_COLOR_ARRAY) {
return static_cast<PackedArrayRef<Color> *>(_data.packed_array)->array;
} else {
- return _convert_array_from_variant<Vector<Color>>(*this);
+ return _convert_array_from_variant<PackedColorArray>(*this);
}
}
@@ -2344,7 +2308,7 @@ Variant::operator Vector<Plane>() const {
}
Variant::operator Vector<Face3>() const {
- Vector<Vector3> va = operator Vector<Vector3>();
+ PackedVector3Array va = operator PackedVector3Array();
Vector<Face3> faces;
int va_size = va.size();
if (va_size == 0) {
@@ -2380,7 +2344,7 @@ Variant::operator Vector<Variant>() const {
}
Variant::operator Vector<StringName>() const {
- Vector<String> from = operator Vector<String>();
+ PackedStringArray from = operator PackedStringArray();
Vector<StringName> to;
int len = from.size();
to.resize(len);
@@ -2409,197 +2373,183 @@ Variant::operator IPAddress() const {
return IPAddress(operator String());
}
-Variant::Variant(bool p_bool) {
- type = BOOL;
+Variant::Variant(bool p_bool) :
+ type(BOOL) {
_data._bool = p_bool;
}
-Variant::Variant(signed int p_int) {
- type = INT;
- _data._int = p_int;
+Variant::Variant(int64_t p_int64) :
+ type(INT) {
+ _data._int = p_int64;
}
-Variant::Variant(unsigned int p_int) {
- type = INT;
- _data._int = p_int;
+Variant::Variant(int32_t p_int32) :
+ type(INT) {
+ _data._int = p_int32;
}
-#ifdef NEED_LONG_INT
-
-Variant::Variant(signed long p_int) {
- type = INT;
- _data._int = p_int;
+Variant::Variant(int16_t p_int16) :
+ type(INT) {
+ _data._int = p_int16;
}
-Variant::Variant(unsigned long p_int) {
- type = INT;
- _data._int = p_int;
-}
-#endif
-
-Variant::Variant(int64_t p_int) {
- type = INT;
- _data._int = p_int;
+Variant::Variant(int8_t p_int8) :
+ type(INT) {
+ _data._int = p_int8;
}
-Variant::Variant(uint64_t p_int) {
- type = INT;
- _data._int = p_int;
+Variant::Variant(uint64_t p_uint64) :
+ type(INT) {
+ _data._int = p_uint64;
}
-Variant::Variant(signed short p_short) {
- type = INT;
- _data._int = p_short;
+Variant::Variant(uint32_t p_uint32) :
+ type(INT) {
+ _data._int = p_uint32;
}
-Variant::Variant(unsigned short p_short) {
- type = INT;
- _data._int = p_short;
+Variant::Variant(uint16_t p_uint16) :
+ type(INT) {
+ _data._int = p_uint16;
}
-Variant::Variant(signed char p_char) {
- type = INT;
- _data._int = p_char;
+Variant::Variant(uint8_t p_uint8) :
+ type(INT) {
+ _data._int = p_uint8;
}
-Variant::Variant(unsigned char p_char) {
- type = INT;
- _data._int = p_char;
-}
-
-Variant::Variant(float p_float) {
- type = FLOAT;
+Variant::Variant(float p_float) :
+ type(FLOAT) {
_data._float = p_float;
}
-Variant::Variant(double p_double) {
- type = FLOAT;
+Variant::Variant(double p_double) :
+ type(FLOAT) {
_data._float = p_double;
}
-Variant::Variant(const ObjectID &p_id) {
- type = INT;
+Variant::Variant(const ObjectID &p_id) :
+ type(INT) {
_data._int = p_id;
}
-Variant::Variant(const StringName &p_string) {
- type = STRING_NAME;
+Variant::Variant(const StringName &p_string) :
+ type(STRING_NAME) {
memnew_placement(_data._mem, StringName(p_string));
}
-Variant::Variant(const String &p_string) {
- type = STRING;
+Variant::Variant(const String &p_string) :
+ type(STRING) {
memnew_placement(_data._mem, String(p_string));
}
-Variant::Variant(const char *const p_cstring) {
- type = STRING;
+Variant::Variant(const char *const p_cstring) :
+ type(STRING) {
memnew_placement(_data._mem, String((const char *)p_cstring));
}
-Variant::Variant(const char32_t *p_wstring) {
- type = STRING;
+Variant::Variant(const char32_t *p_wstring) :
+ type(STRING) {
memnew_placement(_data._mem, String(p_wstring));
}
-Variant::Variant(const Vector3 &p_vector3) {
- type = VECTOR3;
+Variant::Variant(const Vector3 &p_vector3) :
+ type(VECTOR3) {
memnew_placement(_data._mem, Vector3(p_vector3));
}
-Variant::Variant(const Vector3i &p_vector3i) {
- type = VECTOR3I;
+Variant::Variant(const Vector3i &p_vector3i) :
+ type(VECTOR3I) {
memnew_placement(_data._mem, Vector3i(p_vector3i));
}
-Variant::Variant(const Vector4 &p_vector4) {
- type = VECTOR4;
+Variant::Variant(const Vector4 &p_vector4) :
+ type(VECTOR4) {
memnew_placement(_data._mem, Vector4(p_vector4));
}
-Variant::Variant(const Vector4i &p_vector4i) {
- type = VECTOR4I;
+Variant::Variant(const Vector4i &p_vector4i) :
+ type(VECTOR4I) {
memnew_placement(_data._mem, Vector4i(p_vector4i));
}
-Variant::Variant(const Vector2 &p_vector2) {
- type = VECTOR2;
+Variant::Variant(const Vector2 &p_vector2) :
+ type(VECTOR2) {
memnew_placement(_data._mem, Vector2(p_vector2));
}
-Variant::Variant(const Vector2i &p_vector2i) {
- type = VECTOR2I;
+Variant::Variant(const Vector2i &p_vector2i) :
+ type(VECTOR2I) {
memnew_placement(_data._mem, Vector2i(p_vector2i));
}
-Variant::Variant(const Rect2 &p_rect2) {
- type = RECT2;
+Variant::Variant(const Rect2 &p_rect2) :
+ type(RECT2) {
memnew_placement(_data._mem, Rect2(p_rect2));
}
-Variant::Variant(const Rect2i &p_rect2i) {
- type = RECT2I;
+Variant::Variant(const Rect2i &p_rect2i) :
+ type(RECT2I) {
memnew_placement(_data._mem, Rect2i(p_rect2i));
}
-Variant::Variant(const Plane &p_plane) {
- type = PLANE;
+Variant::Variant(const Plane &p_plane) :
+ type(PLANE) {
memnew_placement(_data._mem, Plane(p_plane));
}
-Variant::Variant(const ::AABB &p_aabb) {
- type = AABB;
+Variant::Variant(const ::AABB &p_aabb) :
+ type(AABB) {
_data._aabb = (::AABB *)Pools::_bucket_small.alloc();
memnew_placement(_data._aabb, ::AABB(p_aabb));
}
-Variant::Variant(const Basis &p_matrix) {
- type = BASIS;
+Variant::Variant(const Basis &p_matrix) :
+ type(BASIS) {
_data._basis = (Basis *)Pools::_bucket_medium.alloc();
memnew_placement(_data._basis, Basis(p_matrix));
}
-Variant::Variant(const Quaternion &p_quaternion) {
- type = QUATERNION;
+Variant::Variant(const Quaternion &p_quaternion) :
+ type(QUATERNION) {
memnew_placement(_data._mem, Quaternion(p_quaternion));
}
-Variant::Variant(const Transform3D &p_transform) {
- type = TRANSFORM3D;
+Variant::Variant(const Transform3D &p_transform) :
+ type(TRANSFORM3D) {
_data._transform3d = (Transform3D *)Pools::_bucket_medium.alloc();
memnew_placement(_data._transform3d, Transform3D(p_transform));
}
-Variant::Variant(const Projection &pp_projection) {
- type = PROJECTION;
+Variant::Variant(const Projection &pp_projection) :
+ type(PROJECTION) {
_data._projection = (Projection *)Pools::_bucket_large.alloc();
memnew_placement(_data._projection, Projection(pp_projection));
}
-Variant::Variant(const Transform2D &p_transform) {
- type = TRANSFORM2D;
+Variant::Variant(const Transform2D &p_transform) :
+ type(TRANSFORM2D) {
_data._transform2d = (Transform2D *)Pools::_bucket_small.alloc();
memnew_placement(_data._transform2d, Transform2D(p_transform));
}
-Variant::Variant(const Color &p_color) {
- type = COLOR;
+Variant::Variant(const Color &p_color) :
+ type(COLOR) {
memnew_placement(_data._mem, Color(p_color));
}
-Variant::Variant(const NodePath &p_node_path) {
- type = NODE_PATH;
+Variant::Variant(const NodePath &p_node_path) :
+ type(NODE_PATH) {
memnew_placement(_data._mem, NodePath(p_node_path));
}
-Variant::Variant(const ::RID &p_rid) {
- type = RID;
+Variant::Variant(const ::RID &p_rid) :
+ type(RID) {
memnew_placement(_data._mem, ::RID(p_rid));
}
-Variant::Variant(const Object *p_object) {
- type = OBJECT;
-
+Variant::Variant(const Object *p_object) :
+ type(OBJECT) {
memnew_placement(_data._mem, ObjData);
if (p_object) {
@@ -2620,98 +2570,97 @@ Variant::Variant(const Object *p_object) {
}
}
-Variant::Variant(const Callable &p_callable) {
- type = CALLABLE;
+Variant::Variant(const Callable &p_callable) :
+ type(CALLABLE) {
memnew_placement(_data._mem, Callable(p_callable));
}
-Variant::Variant(const Signal &p_callable) {
- type = SIGNAL;
+Variant::Variant(const Signal &p_callable) :
+ type(SIGNAL) {
memnew_placement(_data._mem, Signal(p_callable));
}
-Variant::Variant(const Dictionary &p_dictionary) {
- type = DICTIONARY;
+Variant::Variant(const Dictionary &p_dictionary) :
+ type(DICTIONARY) {
memnew_placement(_data._mem, Dictionary(p_dictionary));
}
-Variant::Variant(const Array &p_array) {
- type = ARRAY;
+Variant::Variant(const Array &p_array) :
+ type(ARRAY) {
memnew_placement(_data._mem, Array(p_array));
}
-Variant::Variant(const Vector<Plane> &p_array) {
- type = ARRAY;
-
- Array *plane_array = memnew_placement(_data._mem, Array);
-
- plane_array->resize(p_array.size());
-
- for (int i = 0; i < p_array.size(); i++) {
- plane_array->operator[](i) = Variant(p_array[i]);
- }
-}
-
-Variant::Variant(const Vector<::RID> &p_array) {
- type = ARRAY;
-
- Array *rid_array = memnew_placement(_data._mem, Array);
-
- rid_array->resize(p_array.size());
-
- for (int i = 0; i < p_array.size(); i++) {
- rid_array->set(i, Variant(p_array[i]));
- }
-}
-
-Variant::Variant(const Vector<uint8_t> &p_byte_array) {
- type = PACKED_BYTE_ARRAY;
-
+Variant::Variant(const PackedByteArray &p_byte_array) :
+ type(PACKED_BYTE_ARRAY) {
_data.packed_array = PackedArrayRef<uint8_t>::create(p_byte_array);
}
-Variant::Variant(const Vector<int32_t> &p_int32_array) {
- type = PACKED_INT32_ARRAY;
+Variant::Variant(const PackedInt32Array &p_int32_array) :
+ type(PACKED_INT32_ARRAY) {
_data.packed_array = PackedArrayRef<int32_t>::create(p_int32_array);
}
-Variant::Variant(const Vector<int64_t> &p_int64_array) {
- type = PACKED_INT64_ARRAY;
+Variant::Variant(const PackedInt64Array &p_int64_array) :
+ type(PACKED_INT64_ARRAY) {
_data.packed_array = PackedArrayRef<int64_t>::create(p_int64_array);
}
-Variant::Variant(const Vector<float> &p_float32_array) {
- type = PACKED_FLOAT32_ARRAY;
+Variant::Variant(const PackedFloat32Array &p_float32_array) :
+ type(PACKED_FLOAT32_ARRAY) {
_data.packed_array = PackedArrayRef<float>::create(p_float32_array);
}
-Variant::Variant(const Vector<double> &p_float64_array) {
- type = PACKED_FLOAT64_ARRAY;
+Variant::Variant(const PackedFloat64Array &p_float64_array) :
+ type(PACKED_FLOAT64_ARRAY) {
_data.packed_array = PackedArrayRef<double>::create(p_float64_array);
}
-Variant::Variant(const Vector<String> &p_string_array) {
- type = PACKED_STRING_ARRAY;
+Variant::Variant(const PackedStringArray &p_string_array) :
+ type(PACKED_STRING_ARRAY) {
_data.packed_array = PackedArrayRef<String>::create(p_string_array);
}
-Variant::Variant(const Vector<Vector3> &p_vector3_array) {
- type = PACKED_VECTOR3_ARRAY;
- _data.packed_array = PackedArrayRef<Vector3>::create(p_vector3_array);
+Variant::Variant(const PackedVector2Array &p_vector2_array) :
+ type(PACKED_VECTOR2_ARRAY) {
+ _data.packed_array = PackedArrayRef<Vector2>::create(p_vector2_array);
}
-Variant::Variant(const Vector<Vector2> &p_vector2_array) {
- type = PACKED_VECTOR2_ARRAY;
- _data.packed_array = PackedArrayRef<Vector2>::create(p_vector2_array);
+Variant::Variant(const PackedVector3Array &p_vector3_array) :
+ type(PACKED_VECTOR3_ARRAY) {
+ _data.packed_array = PackedArrayRef<Vector3>::create(p_vector3_array);
}
-Variant::Variant(const Vector<Color> &p_color_array) {
- type = PACKED_COLOR_ARRAY;
+Variant::Variant(const PackedColorArray &p_color_array) :
+ type(PACKED_COLOR_ARRAY) {
_data.packed_array = PackedArrayRef<Color>::create(p_color_array);
}
-Variant::Variant(const Vector<Face3> &p_face_array) {
- Vector<Vector3> vertices;
+/* helpers */
+Variant::Variant(const Vector<::RID> &p_array) :
+ type(ARRAY) {
+ Array *rid_array = memnew_placement(_data._mem, Array);
+
+ rid_array->resize(p_array.size());
+
+ for (int i = 0; i < p_array.size(); i++) {
+ rid_array->set(i, Variant(p_array[i]));
+ }
+}
+
+Variant::Variant(const Vector<Plane> &p_array) :
+ type(ARRAY) {
+ Array *plane_array = memnew_placement(_data._mem, Array);
+
+ plane_array->resize(p_array.size());
+
+ for (int i = 0; i < p_array.size(); i++) {
+ plane_array->operator[](i) = Variant(p_array[i]);
+ }
+}
+
+Variant::Variant(const Vector<Face3> &p_face_array) :
+ type(NIL) {
+ PackedVector3Array vertices;
int face_count = p_face_array.size();
vertices.resize(face_count * 3);
@@ -2726,14 +2675,11 @@ Variant::Variant(const Vector<Face3> &p_face_array) {
}
}
- type = NIL;
-
*this = vertices;
}
-/* helpers */
-Variant::Variant(const Vector<Variant> &p_array) {
- type = NIL;
+Variant::Variant(const Vector<Variant> &p_array) :
+ type(NIL) {
Array arr;
arr.resize(p_array.size());
for (int i = 0; i < p_array.size(); i++) {
@@ -2742,9 +2688,9 @@ Variant::Variant(const Vector<Variant> &p_array) {
*this = arr;
}
-Variant::Variant(const Vector<StringName> &p_array) {
- type = NIL;
- Vector<String> v;
+Variant::Variant(const Vector<StringName> &p_array) :
+ type(NIL) {
+ PackedStringArray v;
int len = p_array.size();
v.resize(len);
for (int i = 0; i < len; i++) {
@@ -2912,12 +2858,13 @@ void Variant::operator=(const Variant &p_variant) {
}
}
-Variant::Variant(const IPAddress &p_address) {
- type = STRING;
+Variant::Variant(const IPAddress &p_address) :
+ type(STRING) {
memnew_placement(_data._mem, String(p_address));
}
-Variant::Variant(const Variant &p_variant) {
+Variant::Variant(const Variant &p_variant) :
+ type(NIL) {
reference(p_variant);
}
@@ -3094,7 +3041,7 @@ uint32_t Variant::recursive_hash(int recursion_count) const {
} break;
case PACKED_BYTE_ARRAY: {
- const Vector<uint8_t> &arr = PackedArrayRef<uint8_t>::get_array(_data.packed_array);
+ const PackedByteArray &arr = PackedArrayRef<uint8_t>::get_array(_data.packed_array);
int len = arr.size();
if (likely(len)) {
const uint8_t *r = arr.ptr();
@@ -3105,7 +3052,7 @@ uint32_t Variant::recursive_hash(int recursion_count) const {
} break;
case PACKED_INT32_ARRAY: {
- const Vector<int32_t> &arr = PackedArrayRef<int32_t>::get_array(_data.packed_array);
+ const PackedInt32Array &arr = PackedArrayRef<int32_t>::get_array(_data.packed_array);
int len = arr.size();
if (likely(len)) {
const int32_t *r = arr.ptr();
@@ -3116,7 +3063,7 @@ uint32_t Variant::recursive_hash(int recursion_count) const {
} break;
case PACKED_INT64_ARRAY: {
- const Vector<int64_t> &arr = PackedArrayRef<int64_t>::get_array(_data.packed_array);
+ const PackedInt64Array &arr = PackedArrayRef<int64_t>::get_array(_data.packed_array);
int len = arr.size();
if (likely(len)) {
const int64_t *r = arr.ptr();
@@ -3127,7 +3074,7 @@ uint32_t Variant::recursive_hash(int recursion_count) const {
} break;
case PACKED_FLOAT32_ARRAY: {
- const Vector<float> &arr = PackedArrayRef<float>::get_array(_data.packed_array);
+ const PackedFloat32Array &arr = PackedArrayRef<float>::get_array(_data.packed_array);
int len = arr.size();
if (likely(len)) {
@@ -3143,7 +3090,7 @@ uint32_t Variant::recursive_hash(int recursion_count) const {
} break;
case PACKED_FLOAT64_ARRAY: {
- const Vector<double> &arr = PackedArrayRef<double>::get_array(_data.packed_array);
+ const PackedFloat64Array &arr = PackedArrayRef<double>::get_array(_data.packed_array);
int len = arr.size();
if (likely(len)) {
@@ -3160,7 +3107,7 @@ uint32_t Variant::recursive_hash(int recursion_count) const {
} break;
case PACKED_STRING_ARRAY: {
uint32_t hash = HASH_MURMUR3_SEED;
- const Vector<String> &arr = PackedArrayRef<String>::get_array(_data.packed_array);
+ const PackedStringArray &arr = PackedArrayRef<String>::get_array(_data.packed_array);
int len = arr.size();
if (likely(len)) {
@@ -3176,7 +3123,7 @@ uint32_t Variant::recursive_hash(int recursion_count) const {
} break;
case PACKED_VECTOR2_ARRAY: {
uint32_t hash = HASH_MURMUR3_SEED;
- const Vector<Vector2> &arr = PackedArrayRef<Vector2>::get_array(_data.packed_array);
+ const PackedVector2Array &arr = PackedArrayRef<Vector2>::get_array(_data.packed_array);
int len = arr.size();
if (likely(len)) {
@@ -3193,7 +3140,7 @@ uint32_t Variant::recursive_hash(int recursion_count) const {
} break;
case PACKED_VECTOR3_ARRAY: {
uint32_t hash = HASH_MURMUR3_SEED;
- const Vector<Vector3> &arr = PackedArrayRef<Vector3>::get_array(_data.packed_array);
+ const PackedVector3Array &arr = PackedArrayRef<Vector3>::get_array(_data.packed_array);
int len = arr.size();
if (likely(len)) {
@@ -3211,7 +3158,7 @@ uint32_t Variant::recursive_hash(int recursion_count) const {
} break;
case PACKED_COLOR_ARRAY: {
uint32_t hash = HASH_MURMUR3_SEED;
- const Vector<Color> &arr = PackedArrayRef<Color>::get_array(_data.packed_array);
+ const PackedColorArray &arr = PackedArrayRef<Color>::get_array(_data.packed_array);
int len = arr.size();
if (likely(len)) {
diff --git a/core/variant/variant.h b/core/variant/variant.h
index 21342ae6ef..e40df3171f 100644
--- a/core/variant/variant.h
+++ b/core/variant/variant.h
@@ -70,6 +70,7 @@ typedef Vector<int32_t> PackedInt32Array;
typedef Vector<int64_t> PackedInt64Array;
typedef Vector<float> PackedFloat32Array;
typedef Vector<double> PackedFloat64Array;
+typedef Vector<real_t> PackedRealArray;
typedef Vector<String> PackedStringArray;
typedef Vector<Vector2> PackedVector2Array;
typedef Vector<Vector3> PackedVector3Array;
@@ -164,7 +165,7 @@ private:
// Variant takes 20 bytes when real_t is float, and 36 if double
// it only allocates extra memory for aabb/matrix.
- Type type = NIL;
+ Type type;
struct ObjData {
ObjectID id;
@@ -175,7 +176,7 @@ private:
struct PackedArrayRefBase {
SafeRefCount refcount;
_FORCE_INLINE_ PackedArrayRefBase *reference() {
- if (this->refcount.ref()) {
+ if (refcount.ref()) {
return this;
} else {
return nullptr;
@@ -203,7 +204,7 @@ private:
_FORCE_INLINE_ virtual ~PackedArrayRefBase() {} //needs virtual destructor, but make inline
};
- template <class T>
+ template <typename T>
struct PackedArrayRef : public PackedArrayRefBase {
Vector<T> array;
static _FORCE_INLINE_ PackedArrayRef<T> *create() {
@@ -338,6 +339,9 @@ public:
_FORCE_INLINE_ bool is_num() const {
return type == INT || type == FLOAT;
}
+ _FORCE_INLINE_ bool is_string() const {
+ return type == STRING || type == STRING_NAME;
+ }
_FORCE_INLINE_ bool is_array() const {
return type >= ARRAY;
}
@@ -351,19 +355,14 @@ public:
const Variant &operator[](const Variant &p_key) const = delete;
operator bool() const;
- operator signed int() const;
- operator unsigned int() const; // this is the real one
- operator signed short() const;
- operator unsigned short() const;
- operator signed char() const;
- operator unsigned char() const;
- //operator long unsigned int() const;
operator int64_t() const;
+ operator int32_t() const;
+ operator int16_t() const;
+ operator int8_t() const;
operator uint64_t() const;
-#ifdef NEED_LONG_INT
- operator signed long() const;
- operator unsigned long() const;
-#endif
+ operator uint32_t() const;
+ operator uint16_t() const;
+ operator uint8_t() const;
operator ObjectID() const;
@@ -400,21 +399,21 @@ public:
operator Dictionary() const;
operator Array() const;
- operator Vector<uint8_t>() const;
- operator Vector<int32_t>() const;
- operator Vector<int64_t>() const;
- operator Vector<float>() const;
- operator Vector<double>() const;
- operator Vector<String>() const;
- operator Vector<Vector3>() const;
- operator Vector<Color>() const;
+ operator PackedByteArray() const;
+ operator PackedInt32Array() const;
+ operator PackedInt64Array() const;
+ operator PackedFloat32Array() const;
+ operator PackedFloat64Array() const;
+ operator PackedStringArray() const;
+ operator PackedVector3Array() const;
+ operator PackedVector2Array() const;
+ operator PackedColorArray() const;
+
+ operator Vector<::RID>() const;
operator Vector<Plane>() const;
operator Vector<Face3>() const;
-
operator Vector<Variant>() const;
operator Vector<StringName>() const;
- operator Vector<::RID>() const;
- operator Vector<Vector2>() const;
// some core type enums to convert to
operator Side() const;
@@ -426,18 +425,14 @@ public:
Object *get_validated_object_with_check(bool &r_previously_freed) const;
Variant(bool p_bool);
- Variant(signed int p_int); // real one
- Variant(unsigned int p_int);
-#ifdef NEED_LONG_INT
- Variant(signed long p_long); // real one
- Variant(unsigned long p_long);
-#endif
- Variant(signed short p_short); // real one
- Variant(unsigned short p_short);
- Variant(signed char p_char); // real one
- Variant(unsigned char p_char);
- Variant(int64_t p_int); // real one
- Variant(uint64_t p_int);
+ Variant(int64_t p_int64);
+ Variant(int32_t p_int32);
+ Variant(int16_t p_int16);
+ Variant(int8_t p_int8);
+ Variant(uint64_t p_uint64);
+ Variant(uint32_t p_uint32);
+ Variant(uint16_t p_uint16);
+ Variant(uint8_t p_uint8);
Variant(float p_float);
Variant(double p_double);
Variant(const ObjectID &p_id);
@@ -469,27 +464,27 @@ public:
Variant(const Dictionary &p_dictionary);
Variant(const Array &p_array);
+ Variant(const PackedByteArray &p_byte_array);
+ Variant(const PackedInt32Array &p_int32_array);
+ Variant(const PackedInt64Array &p_int64_array);
+ Variant(const PackedFloat32Array &p_float32_array);
+ Variant(const PackedFloat64Array &p_float64_array);
+ Variant(const PackedStringArray &p_string_array);
+ Variant(const PackedVector2Array &p_vector2_array);
+ Variant(const PackedVector3Array &p_vector3_array);
+ Variant(const PackedColorArray &p_color_array);
+
+ Variant(const Vector<::RID> &p_array); // helper
Variant(const Vector<Plane> &p_array); // helper
- Variant(const Vector<uint8_t> &p_byte_array);
- Variant(const Vector<int32_t> &p_int32_array);
- Variant(const Vector<int64_t> &p_int64_array);
- Variant(const Vector<float> &p_float32_array);
- Variant(const Vector<double> &p_float64_array);
- Variant(const Vector<String> &p_string_array);
- Variant(const Vector<Vector3> &p_vector3_array);
- Variant(const Vector<Color> &p_color_array);
Variant(const Vector<Face3> &p_face_array);
-
Variant(const Vector<Variant> &p_array);
Variant(const Vector<StringName> &p_array);
- Variant(const Vector<::RID> &p_array); // helper
- Variant(const Vector<Vector2> &p_array); // helper
Variant(const IPAddress &p_address);
#define VARIANT_ENUM_CLASS_CONSTRUCTOR(m_enum) \
- Variant(m_enum p_value) { \
- type = INT; \
+ Variant(m_enum p_value) : \
+ type(INT) { \
_data._int = (int64_t)p_value; \
}
@@ -498,6 +493,7 @@ public:
VARIANT_ENUM_CLASS_CONSTRUCTOR(JoyAxis)
VARIANT_ENUM_CLASS_CONSTRUCTOR(JoyButton)
VARIANT_ENUM_CLASS_CONSTRUCTOR(Key)
+ VARIANT_ENUM_CLASS_CONSTRUCTOR(KeyLocation)
VARIANT_ENUM_CLASS_CONSTRUCTOR(MIDIMessage)
VARIANT_ENUM_CLASS_CONSTRUCTOR(MouseButton)
@@ -568,6 +564,7 @@ public:
static ValidatedBuiltInMethod get_validated_builtin_method(Variant::Type p_type, const StringName &p_method);
static PTRBuiltInMethod get_ptr_builtin_method(Variant::Type p_type, const StringName &p_method);
+ static MethodInfo get_builtin_method_info(Variant::Type p_type, const StringName &p_method);
static int get_builtin_method_argument_count(Variant::Type p_type, const StringName &p_method);
static Variant::Type get_builtin_method_argument_type(Variant::Type p_type, const StringName &p_method, int p_argument);
static String get_builtin_method_argument_name(Variant::Type p_type, const StringName &p_method, int p_argument);
@@ -703,9 +700,20 @@ public:
bool has_key(const Variant &p_key, bool &r_valid) const;
/* Generic */
-
- void set(const Variant &p_index, const Variant &p_value, bool *r_valid = nullptr);
- Variant get(const Variant &p_index, bool *r_valid = nullptr) const;
+ enum VariantSetError {
+ SET_OK,
+ SET_KEYED_ERR,
+ SET_NAMED_ERR,
+ SET_INDEXED_ERR
+ };
+ enum VariantGetError {
+ GET_OK,
+ GET_KEYED_ERR,
+ GET_NAMED_ERR,
+ GET_INDEXED_ERR
+ };
+ void set(const Variant &p_index, const Variant &p_value, bool *r_valid = nullptr, VariantSetError *err_code = nullptr);
+ Variant get(const Variant &p_index, bool *r_valid = nullptr, VariantGetError *err_code = nullptr) const;
bool in(const Variant &p_index, bool *r_valid = nullptr) const;
bool iter_init(Variant &r_iter, bool &r_valid) const;
@@ -765,8 +773,8 @@ public:
static Variant get_constant_value(Variant::Type p_type, const StringName &p_value, bool *r_valid = nullptr);
static void get_enums_for_type(Variant::Type p_type, List<StringName> *p_enums);
- static void get_enumerations_for_enum(Variant::Type p_type, StringName p_enum_name, List<StringName> *p_enumerations);
- static int get_enum_value(Variant::Type p_type, StringName p_enum_name, StringName p_enumeration, bool *r_valid = nullptr);
+ static void get_enumerations_for_enum(Variant::Type p_type, const StringName &p_enum_name, List<StringName> *p_enumerations);
+ static int get_enum_value(Variant::Type p_type, const StringName &p_enum_name, const StringName &p_enumeration, bool *r_valid = nullptr);
typedef String (*ObjectDeConstruct)(const Variant &p_object, void *ud);
typedef void (*ObjectConstruct)(const String &p_text, void *ud, Variant &r_value);
@@ -780,7 +788,8 @@ public:
static void unregister_types();
Variant(const Variant &p_variant);
- _FORCE_INLINE_ Variant() {}
+ _FORCE_INLINE_ Variant() :
+ type(NIL) {}
_FORCE_INLINE_ ~Variant() {
clear();
}
@@ -848,7 +857,7 @@ Variant Callable::call(VarArgs... p_args) const {
}
template <typename... VarArgs>
-Callable Callable::bind(VarArgs... p_args) {
+Callable Callable::bind(VarArgs... p_args) const {
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++) {
@@ -857,4 +866,56 @@ Callable Callable::bind(VarArgs... p_args) {
return bindp(sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args));
}
+Variant &Array::Iterator::operator*() const {
+ if (unlikely(read_only)) {
+ *read_only = *element_ptr;
+ return *read_only;
+ }
+ return *element_ptr;
+}
+
+Variant *Array::Iterator::operator->() const {
+ if (unlikely(read_only)) {
+ *read_only = *element_ptr;
+ return read_only;
+ }
+ return element_ptr;
+}
+
+Array::Iterator &Array::Iterator::operator++() {
+ element_ptr++;
+ return *this;
+}
+
+Array::Iterator &Array::Iterator::operator--() {
+ element_ptr--;
+ return *this;
+}
+
+const Variant &Array::ConstIterator::operator*() const {
+ if (unlikely(read_only)) {
+ *read_only = *element_ptr;
+ return *read_only;
+ }
+ return *element_ptr;
+}
+
+const Variant *Array::ConstIterator::operator->() const {
+ if (unlikely(read_only)) {
+ *read_only = *element_ptr;
+ return read_only;
+ }
+ return element_ptr;
+}
+
+Array::ConstIterator &Array::ConstIterator::operator++() {
+ element_ptr++;
+ return *this;
+}
+
+Array::ConstIterator &Array::ConstIterator::operator--() {
+ element_ptr--;
+ return *this;
+}
+
#endif // VARIANT_H
diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp
index f041d2c95e..d0d940c47d 100644
--- a/core/variant/variant_call.cpp
+++ b/core/variant/variant_call.cpp
@@ -43,329 +43,329 @@
typedef void (*VariantFunc)(Variant &r_ret, Variant &p_self, const Variant **p_args);
typedef void (*VariantConstructFunc)(Variant &r_ret, const Variant **p_args);
-template <class R, class... P>
+template <typename R, typename... P>
static _FORCE_INLINE_ void vc_static_method_call(R (*method)(P...), const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) {
call_with_variant_args_static_ret_dv(method, p_args, p_argcount, r_ret, r_error, p_defvals);
}
-template <class... P>
+template <typename... P>
static _FORCE_INLINE_ void vc_static_method_call(void (*method)(P...), const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) {
call_with_variant_args_static_dv(method, p_args, p_argcount, r_error, p_defvals);
}
-template <class R, class T, class... P>
+template <typename R, typename T, typename... P>
static _FORCE_INLINE_ void vc_method_call(R (T::*method)(P...), Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) {
call_with_variant_args_ret_dv(VariantGetInternalPtr<T>::get_ptr(base), method, p_args, p_argcount, r_ret, r_error, p_defvals);
}
-template <class R, class T, class... P>
+template <typename R, typename T, typename... P>
static _FORCE_INLINE_ void vc_method_call(R (T::*method)(P...) const, Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) {
call_with_variant_args_retc_dv(VariantGetInternalPtr<T>::get_ptr(base), method, p_args, p_argcount, r_ret, r_error, p_defvals);
}
-template <class T, class... P>
+template <typename T, typename... P>
static _FORCE_INLINE_ void vc_method_call(void (T::*method)(P...), Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) {
VariantInternal::clear(&r_ret);
call_with_variant_args_dv(VariantGetInternalPtr<T>::get_ptr(base), method, p_args, p_argcount, r_error, p_defvals);
}
-template <class T, class... P>
+template <typename T, typename... P>
static _FORCE_INLINE_ void vc_method_call(void (T::*method)(P...) const, Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) {
VariantInternal::clear(&r_ret);
call_with_variant_argsc_dv(VariantGetInternalPtr<T>::get_ptr(base), method, p_args, p_argcount, r_error, p_defvals);
}
-template <class From, class R, class T, class... P>
+template <typename From, typename R, typename T, typename... P>
static _FORCE_INLINE_ void vc_convert_method_call(R (T::*method)(P...), Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) {
T converted(static_cast<T>(*VariantGetInternalPtr<From>::get_ptr(base)));
call_with_variant_args_ret_dv(&converted, method, p_args, p_argcount, r_ret, r_error, p_defvals);
}
-template <class From, class R, class T, class... P>
+template <typename From, typename R, typename T, typename... P>
static _FORCE_INLINE_ void vc_convert_method_call(R (T::*method)(P...) const, Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) {
T converted(static_cast<T>(*VariantGetInternalPtr<From>::get_ptr(base)));
call_with_variant_args_retc_dv(&converted, method, p_args, p_argcount, r_ret, r_error, p_defvals);
}
-template <class From, class T, class... P>
+template <typename From, typename T, typename... P>
static _FORCE_INLINE_ void vc_convert_method_call(void (T::*method)(P...), Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) {
T converted(static_cast<T>(*VariantGetInternalPtr<From>::get_ptr(base)));
call_with_variant_args_dv(&converted, method, p_args, p_argcount, r_error, p_defvals);
}
-template <class From, class T, class... P>
+template <typename From, typename T, typename... P>
static _FORCE_INLINE_ void vc_convert_method_call(void (T::*method)(P...) const, Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) {
T converted(static_cast<T>(*VariantGetInternalPtr<From>::get_ptr(base)));
call_with_variant_argsc_dv(&converted, method, p_args, p_argcount, r_error, p_defvals);
}
-template <class R, class T, class... P>
+template <typename R, typename T, typename... P>
static _FORCE_INLINE_ void vc_method_call_static(R (*method)(T *, P...), Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) {
call_with_variant_args_retc_static_helper_dv(VariantGetInternalPtr<T>::get_ptr(base), method, p_args, p_argcount, r_ret, p_defvals, r_error);
}
-template <class T, class... P>
+template <typename T, typename... P>
static _FORCE_INLINE_ void vc_method_call_static(void (*method)(T *, P...), Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) {
call_with_variant_args_static_helper_dv(VariantGetInternalPtr<T>::get_ptr(base), method, p_args, p_argcount, p_defvals, r_error);
}
-template <class R, class T, class... P>
+template <typename R, typename T, typename... P>
static _FORCE_INLINE_ void vc_validated_call(R (T::*method)(P...), Variant *base, const Variant **p_args, Variant *r_ret) {
call_with_validated_variant_args_ret(base, method, p_args, r_ret);
}
-template <class R, class T, class... P>
+template <typename R, typename T, typename... P>
static _FORCE_INLINE_ void vc_validated_call(R (T::*method)(P...) const, Variant *base, const Variant **p_args, Variant *r_ret) {
call_with_validated_variant_args_retc(base, method, p_args, r_ret);
}
-template <class T, class... P>
+template <typename T, typename... P>
static _FORCE_INLINE_ void vc_validated_call(void (T::*method)(P...), Variant *base, const Variant **p_args, Variant *r_ret) {
call_with_validated_variant_args(base, method, p_args);
}
-template <class T, class... P>
+template <typename T, typename... P>
static _FORCE_INLINE_ void vc_validated_call(void (T::*method)(P...) const, Variant *base, const Variant **p_args, Variant *r_ret) {
call_with_validated_variant_argsc(base, method, p_args);
}
-template <class From, class R, class T, class... P>
+template <typename From, typename R, typename T, typename... P>
static _FORCE_INLINE_ void vc_convert_validated_call(R (T::*method)(P...), Variant *base, const Variant **p_args, Variant *r_ret) {
T converted(static_cast<T>(*VariantGetInternalPtr<From>::get_ptr(base)));
call_with_validated_variant_args_ret_helper<T, R, P...>(&converted, method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
}
-template <class From, class R, class T, class... P>
+template <typename From, typename R, typename T, typename... P>
static _FORCE_INLINE_ void vc_convert_validated_call(R (T::*method)(P...) const, Variant *base, const Variant **p_args, Variant *r_ret) {
T converted(static_cast<T>(*VariantGetInternalPtr<From>::get_ptr(base)));
call_with_validated_variant_args_retc_helper<T, R, P...>(&converted, method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
}
-template <class From, class T, class... P>
+template <typename From, typename T, typename... P>
static _FORCE_INLINE_ void vc_convert_validated_call(void (T::*method)(P...), Variant *base, const Variant **p_args, Variant *r_ret) {
T converted(static_cast<T>(*VariantGetInternalPtr<From>::get_ptr(base)));
call_with_validated_variant_args_helper<T, P...>(&converted, method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
}
-template <class From, class T, class... P>
+template <typename From, typename T, typename... P>
static _FORCE_INLINE_ void vc_convert_validated_call(void (T::*method)(P...) const, Variant *base, const Variant **p_args, Variant *r_ret) {
T converted(static_cast<T>(*VariantGetInternalPtr<From>::get_ptr(base)));
call_with_validated_variant_argsc_helper<T, P...>(&converted, method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
}
-template <class R, class T, class... P>
+template <typename R, typename T, typename... P>
static _FORCE_INLINE_ void vc_validated_call_static(R (*method)(T *, P...), Variant *base, const Variant **p_args, Variant *r_ret) {
call_with_validated_variant_args_static_retc(base, method, p_args, r_ret);
}
-template <class T, class... P>
+template <typename T, typename... P>
static _FORCE_INLINE_ void vc_validated_call_static(void (*method)(T *, P...), Variant *base, const Variant **p_args, Variant *r_ret) {
call_with_validated_variant_args_static(base, method, p_args);
}
-template <class R, class... P>
+template <typename R, typename... P>
static _FORCE_INLINE_ void vc_validated_static_call(R (*method)(P...), const Variant **p_args, Variant *r_ret) {
call_with_validated_variant_args_static_method_ret(method, p_args, r_ret);
}
-template <class... P>
+template <typename... P>
static _FORCE_INLINE_ void vc_validated_static_call(void (*method)(P...), const Variant **p_args, Variant *r_ret) {
call_with_validated_variant_args_static_method(method, p_args);
}
-template <class R, class T, class... P>
+template <typename R, typename T, typename... P>
static _FORCE_INLINE_ void vc_ptrcall(R (T::*method)(P...), void *p_base, const void **p_args, void *r_ret) {
call_with_ptr_args_ret(reinterpret_cast<T *>(p_base), method, p_args, r_ret);
}
-template <class R, class T, class... P>
+template <typename R, typename T, typename... P>
static _FORCE_INLINE_ void vc_ptrcall(R (T::*method)(P...) const, void *p_base, const void **p_args, void *r_ret) {
call_with_ptr_args_retc(reinterpret_cast<T *>(p_base), method, p_args, r_ret);
}
-template <class T, class... P>
+template <typename T, typename... P>
static _FORCE_INLINE_ void vc_ptrcall(void (T::*method)(P...), void *p_base, const void **p_args, void *r_ret) {
call_with_ptr_args(reinterpret_cast<T *>(p_base), method, p_args);
}
-template <class T, class... P>
+template <typename T, typename... P>
static _FORCE_INLINE_ void vc_ptrcall(void (T::*method)(P...) const, void *p_base, const void **p_args, void *r_ret) {
call_with_ptr_argsc(reinterpret_cast<T *>(p_base), method, p_args);
}
-template <class From, class R, class T, class... P>
+template <typename From, typename R, typename T, typename... P>
static _FORCE_INLINE_ void vc_convert_ptrcall(R (T::*method)(P...), void *p_base, const void **p_args, void *r_ret) {
T converted(*reinterpret_cast<From *>(p_base));
call_with_ptr_args_ret(&converted, method, p_args, r_ret);
}
-template <class From, class R, class T, class... P>
+template <typename From, typename R, typename T, typename... P>
static _FORCE_INLINE_ void vc_convert_ptrcall(R (T::*method)(P...) const, void *p_base, const void **p_args, void *r_ret) {
T converted(*reinterpret_cast<From *>(p_base));
call_with_ptr_args_retc(&converted, method, p_args, r_ret);
}
-template <class From, class T, class... P>
+template <typename From, typename T, typename... P>
static _FORCE_INLINE_ void vc_convert_ptrcall(void (T::*method)(P...), void *p_base, const void **p_args, void *r_ret) {
T converted(*reinterpret_cast<From *>(p_base));
call_with_ptr_args(&converted, method, p_args);
}
-template <class From, class T, class... P>
+template <typename From, typename T, typename... P>
static _FORCE_INLINE_ void vc_convert_ptrcall(void (T::*method)(P...) const, void *p_base, const void **p_args, void *r_ret) {
T converted(*reinterpret_cast<From *>(p_base));
call_with_ptr_argsc(&converted, method, p_args);
}
-template <class R, class T, class... P>
+template <typename R, typename T, typename... P>
static _FORCE_INLINE_ int vc_get_argument_count(R (T::*method)(P...)) {
return sizeof...(P);
}
-template <class R, class T, class... P>
+template <typename R, typename T, typename... P>
static _FORCE_INLINE_ int vc_get_argument_count(R (T::*method)(P...) const) {
return sizeof...(P);
}
-template <class T, class... P>
+template <typename T, typename... P>
static _FORCE_INLINE_ int vc_get_argument_count(void (T::*method)(P...)) {
return sizeof...(P);
}
-template <class T, class... P>
+template <typename T, typename... P>
static _FORCE_INLINE_ int vc_get_argument_count(void (T::*method)(P...) const) {
return sizeof...(P);
}
-template <class R, class T, class... P>
+template <typename R, typename T, typename... P>
static _FORCE_INLINE_ int vc_get_argument_count(R (*method)(T *, P...)) {
return sizeof...(P);
}
-template <class R, class... P>
+template <typename R, typename... P>
static _FORCE_INLINE_ int vc_get_argument_count_static(R (*method)(P...)) {
return sizeof...(P);
}
-template <class R, class T, class... P>
+template <typename R, typename T, typename... P>
static _FORCE_INLINE_ Variant::Type vc_get_argument_type(R (T::*method)(P...), int p_arg) {
return call_get_argument_type<P...>(p_arg);
}
-template <class R, class T, class... P>
+template <typename R, typename T, typename... P>
static _FORCE_INLINE_ Variant::Type vc_get_argument_type(R (T::*method)(P...) const, int p_arg) {
return call_get_argument_type<P...>(p_arg);
}
-template <class T, class... P>
+template <typename T, typename... P>
static _FORCE_INLINE_ Variant::Type vc_get_argument_type(void (T::*method)(P...), int p_arg) {
return call_get_argument_type<P...>(p_arg);
}
-template <class T, class... P>
+template <typename T, typename... P>
static _FORCE_INLINE_ Variant::Type vc_get_argument_type(void (T::*method)(P...) const, int p_arg) {
return call_get_argument_type<P...>(p_arg);
}
-template <class R, class T, class... P>
+template <typename R, typename T, typename... P>
static _FORCE_INLINE_ Variant::Type vc_get_argument_type(R (*method)(T *, P...), int p_arg) {
return call_get_argument_type<P...>(p_arg);
}
-template <class R, class... P>
+template <typename R, typename... P>
static _FORCE_INLINE_ Variant::Type vc_get_argument_type_static(R (*method)(P...), int p_arg) {
return call_get_argument_type<P...>(p_arg);
}
-template <class R, class T, class... P>
+template <typename R, typename T, typename... P>
static _FORCE_INLINE_ Variant::Type vc_get_return_type(R (T::*method)(P...)) {
return GetTypeInfo<R>::VARIANT_TYPE;
}
-template <class R, class T, class... P>
+template <typename R, typename T, typename... P>
static _FORCE_INLINE_ Variant::Type vc_get_return_type(R (T::*method)(P...) const) {
return GetTypeInfo<R>::VARIANT_TYPE;
}
-template <class T, class... P>
+template <typename T, typename... P>
static _FORCE_INLINE_ Variant::Type vc_get_return_type(void (T::*method)(P...)) {
return Variant::NIL;
}
-template <class T, class... P>
+template <typename T, typename... P>
static _FORCE_INLINE_ Variant::Type vc_get_return_type(void (T::*method)(P...) const) {
return Variant::NIL;
}
-template <class R, class... P>
+template <typename R, typename... P>
static _FORCE_INLINE_ Variant::Type vc_get_return_type(R (*method)(P...)) {
return GetTypeInfo<R>::VARIANT_TYPE;
}
-template <class... P>
+template <typename... P>
static _FORCE_INLINE_ Variant::Type vc_get_return_type(void (*method)(P...)) {
return Variant::NIL;
}
-template <class R, class T, class... P>
+template <typename R, typename T, typename... P>
static _FORCE_INLINE_ bool vc_has_return_type(R (T::*method)(P...)) {
return true;
}
-template <class R, class T, class... P>
+template <typename R, typename T, typename... P>
static _FORCE_INLINE_ bool vc_has_return_type(R (T::*method)(P...) const) {
return true;
}
-template <class T, class... P>
+template <typename T, typename... P>
static _FORCE_INLINE_ bool vc_has_return_type(void (T::*method)(P...)) {
return false;
}
-template <class T, class... P>
+template <typename T, typename... P>
static _FORCE_INLINE_ bool vc_has_return_type(void (T::*method)(P...) const) {
return false;
}
-template <class... P>
+template <typename... P>
static _FORCE_INLINE_ bool vc_has_return_type_static(void (*method)(P...)) {
return false;
}
-template <class R, class... P>
+template <typename R, typename... P>
static _FORCE_INLINE_ bool vc_has_return_type_static(R (*method)(P...)) {
return true;
}
-template <class R, class T, class... P>
+template <typename R, typename T, typename... P>
static _FORCE_INLINE_ bool vc_is_const(R (T::*method)(P...)) {
return false;
}
-template <class R, class T, class... P>
+template <typename R, typename T, typename... P>
static _FORCE_INLINE_ bool vc_is_const(R (T::*method)(P...) const) {
return true;
}
-template <class T, class... P>
+template <typename T, typename... P>
static _FORCE_INLINE_ bool vc_is_const(void (T::*method)(P...)) {
return false;
}
-template <class T, class... P>
+template <typename T, typename... P>
static _FORCE_INLINE_ bool vc_is_const(void (T::*method)(P...) const) {
return true;
}
-template <class R, class T, class... P>
+template <typename R, typename T, typename... P>
static _FORCE_INLINE_ Variant::Type vc_get_base_type(R (T::*method)(P...)) {
return GetTypeInfo<T>::VARIANT_TYPE;
}
-template <class R, class T, class... P>
+template <typename R, typename T, typename... P>
static _FORCE_INLINE_ Variant::Type vc_get_base_type(R (T::*method)(P...) const) {
return GetTypeInfo<T>::VARIANT_TYPE;
}
-template <class T, class... P>
+template <typename T, typename... P>
static _FORCE_INLINE_ Variant::Type vc_get_base_type(void (T::*method)(P...)) {
return GetTypeInfo<T>::VARIANT_TYPE;
}
-template <class T, class... P>
+template <typename T, typename... P>
static _FORCE_INLINE_ Variant::Type vc_get_base_type(void (T::*method)(P...) const) {
return GetTypeInfo<T>::VARIANT_TYPE;
}
@@ -450,12 +450,12 @@ static _FORCE_INLINE_ Variant::Type vc_get_base_type(void (T::*method)(P...) con
} \
};
-template <class R, class... P>
+template <typename R, typename... P>
static _FORCE_INLINE_ void vc_static_ptrcall(R (*method)(P...), const void **p_args, void *r_ret) {
call_with_ptr_args_static_method_ret<R, P...>(method, p_args, r_ret);
}
-template <class... P>
+template <typename... P>
static _FORCE_INLINE_ void vc_static_ptrcall(void (*method)(P...), const void **p_args, void *r_ret) {
call_with_ptr_args_static_method<P...>(method, p_args);
}
@@ -500,12 +500,12 @@ static _FORCE_INLINE_ void vc_static_ptrcall(void (*method)(P...), const void **
} \
};
-template <class R, class T, class... P>
+template <typename R, typename T, typename... P>
static _FORCE_INLINE_ void vc_ptrcall(R (*method)(T *, P...), void *p_base, const void **p_args, void *r_ret) {
call_with_ptr_args_static_retc<T, R, P...>(reinterpret_cast<T *>(p_base), method, p_args, r_ret);
}
-template <class T, class... P>
+template <typename T, typename... P>
static _FORCE_INLINE_ void vc_ptrcall(void (*method)(T *, P...), void *p_base, const void **p_args, void *r_ret) {
call_with_ptr_args_static<T, P...>(reinterpret_cast<T *>(p_base), method, p_args);
}
@@ -666,7 +666,7 @@ struct _VariantCall {
CharString cs;
cs.resize(p_instance->size() + 1);
memcpy(cs.ptrw(), r, p_instance->size());
- cs[p_instance->size()] = 0;
+ cs[(int)p_instance->size()] = 0;
s = cs.get_data();
}
@@ -885,7 +885,7 @@ struct _VariantCall {
ERR_FAIL_COND_V_MSG(size % sizeof(int32_t), dest, "PackedByteArray size must be a multiple of 4 (size of 32-bit integer) to convert to PackedInt32Array.");
const uint8_t *r = p_instance->ptr();
dest.resize(size / sizeof(int32_t));
- ERR_FAIL_COND_V(dest.size() == 0, dest); // Avoid UB in case resize failed.
+ ERR_FAIL_COND_V(dest.is_empty(), dest); // Avoid UB in case resize failed.
memcpy(dest.ptrw(), r, dest.size() * sizeof(int32_t));
return dest;
}
@@ -899,7 +899,7 @@ struct _VariantCall {
ERR_FAIL_COND_V_MSG(size % sizeof(int64_t), dest, "PackedByteArray size must be a multiple of 8 (size of 64-bit integer) to convert to PackedInt64Array.");
const uint8_t *r = p_instance->ptr();
dest.resize(size / sizeof(int64_t));
- ERR_FAIL_COND_V(dest.size() == 0, dest); // Avoid UB in case resize failed.
+ ERR_FAIL_COND_V(dest.is_empty(), dest); // Avoid UB in case resize failed.
memcpy(dest.ptrw(), r, dest.size() * sizeof(int64_t));
return dest;
}
@@ -913,7 +913,7 @@ struct _VariantCall {
ERR_FAIL_COND_V_MSG(size % sizeof(float), dest, "PackedByteArray size must be a multiple of 4 (size of 32-bit float) to convert to PackedFloat32Array.");
const uint8_t *r = p_instance->ptr();
dest.resize(size / sizeof(float));
- ERR_FAIL_COND_V(dest.size() == 0, dest); // Avoid UB in case resize failed.
+ ERR_FAIL_COND_V(dest.is_empty(), dest); // Avoid UB in case resize failed.
memcpy(dest.ptrw(), r, dest.size() * sizeof(float));
return dest;
}
@@ -927,7 +927,7 @@ struct _VariantCall {
ERR_FAIL_COND_V_MSG(size % sizeof(double), dest, "PackedByteArray size must be a multiple of 8 (size of 64-bit double) to convert to PackedFloat64Array.");
const uint8_t *r = p_instance->ptr();
dest.resize(size / sizeof(double));
- ERR_FAIL_COND_V(dest.size() == 0, dest); // Avoid UB in case resize failed.
+ ERR_FAIL_COND_V(dest.is_empty(), dest); // Avoid UB in case resize failed.
memcpy(dest.ptrw(), r, dest.size() * sizeof(double));
return dest;
}
@@ -1053,6 +1053,10 @@ struct _VariantCall {
r_ret = callable->bindp(p_args, p_argcount);
}
+ static int func_Callable_get_argument_count(Callable *p_callable) {
+ return p_callable->get_argument_count();
+ }
+
static void func_Signal_emit(Variant *v, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) {
Signal *signal = VariantGetInternalPtr<Signal>::get_ptr(v);
signal->emit(p_args, p_argcount);
@@ -1071,14 +1075,14 @@ struct _VariantCall {
static ConstantData *constant_data;
- static void add_constant(int p_type, StringName p_constant_name, int64_t p_constant_value) {
+ static void add_constant(int p_type, const StringName &p_constant_name, int64_t p_constant_value) {
constant_data[p_type].value[p_constant_name] = p_constant_value;
#ifdef DEBUG_ENABLED
constant_data[p_type].value_ordered.push_back(p_constant_name);
#endif
}
- static void add_variant_constant(int p_type, StringName p_constant_name, const Variant &p_constant_value) {
+ static void add_variant_constant(int p_type, const StringName &p_constant_name, const Variant &p_constant_value) {
constant_data[p_type].variant_value[p_constant_name] = p_constant_value;
#ifdef DEBUG_ENABLED
constant_data[p_type].variant_value_ordered.push_back(p_constant_name);
@@ -1091,7 +1095,7 @@ struct _VariantCall {
static EnumData *enum_data;
- static void add_enum_constant(int p_type, StringName p_enum_type_name, StringName p_enumeration_name, int p_enum_value) {
+ static void add_enum_constant(int p_type, const StringName &p_enum_type_name, const StringName &p_enumeration_name, int p_enum_value) {
enum_data[p_type].value[p_enum_type_name][p_enumeration_name] = p_enum_value;
}
};
@@ -1114,13 +1118,53 @@ struct VariantBuiltInMethodInfo {
Variant::Type return_type;
int argument_count = 0;
Variant::Type (*get_argument_type)(int p_arg) = nullptr;
+
+ MethodInfo get_method_info(const StringName &p_name) const {
+ MethodInfo mi;
+ mi.name = p_name;
+
+ if (has_return_type) {
+ mi.return_val.type = return_type;
+ if (mi.return_val.type == Variant::NIL) {
+ mi.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
+ }
+ }
+
+ if (is_const) {
+ mi.flags |= METHOD_FLAG_CONST;
+ }
+ if (is_vararg) {
+ mi.flags |= METHOD_FLAG_VARARG;
+ }
+ if (is_static) {
+ mi.flags |= METHOD_FLAG_STATIC;
+ }
+
+ for (int i = 0; i < argument_count; i++) {
+ PropertyInfo pi;
+#ifdef DEBUG_METHODS_ENABLED
+ pi.name = argument_names[i];
+#else
+ pi.name = "arg" + itos(i + 1);
+#endif
+ pi.type = (*get_argument_type)(i);
+ if (pi.type == Variant::NIL) {
+ pi.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
+ }
+ mi.arguments.push_back(pi);
+ }
+
+ mi.default_arguments = default_arguments;
+
+ return mi;
+ }
};
typedef OAHashMap<StringName, VariantBuiltInMethodInfo> BuiltinMethodMap;
static BuiltinMethodMap *builtin_method_info;
static List<StringName> *builtin_method_names;
-template <class T>
+template <typename T>
static void register_builtin_method(const Vector<String> &p_argnames, const Vector<Variant> &p_def_args) {
StringName name = T::get_name();
@@ -1268,6 +1312,13 @@ Variant::PTRBuiltInMethod Variant::get_ptr_builtin_method(Variant::Type p_type,
return method->ptrcall;
}
+MethodInfo Variant::get_builtin_method_info(Variant::Type p_type, const StringName &p_method) {
+ ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, MethodInfo());
+ const VariantBuiltInMethodInfo *method = builtin_method_info[p_type].lookup_ptr(p_method);
+ ERR_FAIL_NULL_V(method, MethodInfo());
+ return method->get_method_info(p_method);
+}
+
int Variant::get_builtin_method_argument_count(Variant::Type p_type, const StringName &p_method) {
ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, 0);
const VariantBuiltInMethodInfo *method = builtin_method_info[p_type].lookup_ptr(p_method);
@@ -1378,43 +1429,7 @@ void Variant::get_method_list(List<MethodInfo> *p_list) const {
for (const StringName &E : builtin_method_names[type]) {
const VariantBuiltInMethodInfo *method = builtin_method_info[type].lookup_ptr(E);
ERR_CONTINUE(!method);
-
- MethodInfo mi;
- mi.name = E;
-
- //return type
- if (method->has_return_type) {
- mi.return_val.type = method->return_type;
- if (mi.return_val.type == Variant::NIL) {
- mi.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
- }
- }
-
- if (method->is_const) {
- mi.flags |= METHOD_FLAG_CONST;
- }
- if (method->is_vararg) {
- mi.flags |= METHOD_FLAG_VARARG;
- }
- if (method->is_static) {
- mi.flags |= METHOD_FLAG_STATIC;
- }
- for (int i = 0; i < method->argument_count; i++) {
- PropertyInfo pi;
-#ifdef DEBUG_METHODS_ENABLED
- pi.name = method->argument_names[i];
-#else
- pi.name = "arg" + itos(i + 1);
-#endif
- pi.type = method->get_argument_type(i);
- if (pi.type == Variant::NIL) {
- pi.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
- }
- mi.arguments.push_back(pi);
- }
-
- mi.default_arguments = method->default_arguments;
- p_list->push_back(mi);
+ p_list->push_back(method->get_method_info(E));
}
}
}
@@ -1493,7 +1508,7 @@ void Variant::get_enums_for_type(Variant::Type p_type, List<StringName> *p_enums
}
}
-void Variant::get_enumerations_for_enum(Variant::Type p_type, StringName p_enum_name, List<StringName> *p_enumerations) {
+void Variant::get_enumerations_for_enum(Variant::Type p_type, const StringName &p_enum_name, List<StringName> *p_enumerations) {
ERR_FAIL_INDEX(p_type, Variant::VARIANT_MAX);
_VariantCall::EnumData &enum_data = _VariantCall::enum_data[p_type];
@@ -1505,7 +1520,7 @@ void Variant::get_enumerations_for_enum(Variant::Type p_type, StringName p_enum_
}
}
-int Variant::get_enum_value(Variant::Type p_type, StringName p_enum_name, StringName p_enumeration, bool *r_valid) {
+int Variant::get_enum_value(Variant::Type p_type, const StringName &p_enum_name, const StringName &p_enumeration, bool *r_valid) {
if (r_valid) {
*r_valid = false;
}
@@ -1629,6 +1644,8 @@ static void _register_variant_builtin_methods() {
bind_string_method(nocasecmp_to, sarray("to"), varray());
bind_string_method(naturalcasecmp_to, sarray("to"), varray());
bind_string_method(naturalnocasecmp_to, sarray("to"), varray());
+ bind_string_method(filecasecmp_to, sarray("to"), varray());
+ bind_string_method(filenocasecmp_to, sarray("to"), varray());
bind_string_method(length, sarray(), varray());
bind_string_method(substr, sarray("from", "len"), varray(-1));
bind_string_method(get_slice, sarray("delimiter", "slice"), varray());
@@ -1782,7 +1799,7 @@ static void _register_variant_builtin_methods() {
bind_method(Vector2, dot, sarray("with"), varray());
bind_method(Vector2, slide, sarray("n"), varray());
bind_method(Vector2, bounce, sarray("n"), varray());
- bind_method(Vector2, reflect, sarray("n"), varray());
+ bind_method(Vector2, reflect, sarray("line"), varray());
bind_method(Vector2, cross, sarray("with"), varray());
bind_method(Vector2, abs, sarray(), varray());
bind_method(Vector2, sign, sarray(), varray());
@@ -1796,6 +1813,8 @@ static void _register_variant_builtin_methods() {
bind_method(Vector2i, aspect, sarray(), varray());
bind_method(Vector2i, max_axis_index, sarray(), varray());
bind_method(Vector2i, min_axis_index, sarray(), varray());
+ bind_method(Vector2i, distance_to, sarray("to"), varray());
+ bind_method(Vector2i, distance_squared_to, sarray("to"), varray());
bind_method(Vector2i, length, sarray(), varray());
bind_method(Vector2i, length_squared, sarray(), varray());
bind_method(Vector2i, sign, sarray(), varray());
@@ -1877,7 +1896,7 @@ static void _register_variant_builtin_methods() {
bind_method(Vector3, project, sarray("b"), varray());
bind_method(Vector3, slide, sarray("n"), varray());
bind_method(Vector3, bounce, sarray("n"), varray());
- bind_method(Vector3, reflect, sarray("n"), varray());
+ bind_method(Vector3, reflect, sarray("direction"), varray());
bind_method(Vector3, sign, sarray(), varray());
bind_method(Vector3, octahedron_encode, sarray(), varray());
bind_static_method(Vector3, octahedron_decode, sarray("uv"), varray());
@@ -1886,6 +1905,8 @@ static void _register_variant_builtin_methods() {
bind_method(Vector3i, min_axis_index, sarray(), varray());
bind_method(Vector3i, max_axis_index, sarray(), varray());
+ bind_method(Vector3i, distance_to, sarray("to"), varray());
+ bind_method(Vector3i, distance_squared_to, sarray("to"), varray());
bind_method(Vector3i, length, sarray(), varray());
bind_method(Vector3i, length_squared, sarray(), varray());
bind_method(Vector3i, sign, sarray(), varray());
@@ -1932,6 +1953,8 @@ static void _register_variant_builtin_methods() {
bind_method(Vector4i, abs, sarray(), varray());
bind_method(Vector4i, clamp, sarray("min", "max"), varray());
bind_method(Vector4i, snapped, sarray("step"), varray());
+ bind_method(Vector4i, distance_to, sarray("to"), varray());
+ bind_method(Vector4i, distance_squared_to, sarray("to"), varray());
/* Plane */
@@ -2016,11 +2039,13 @@ static void _register_variant_builtin_methods() {
bind_method(NodePath, get_subname, sarray("idx"), varray());
bind_method(NodePath, get_concatenated_names, sarray(), varray());
bind_method(NodePath, get_concatenated_subnames, sarray(), varray());
+ bind_method(NodePath, slice, sarray("begin", "end"), varray(INT_MAX));
bind_method(NodePath, get_as_property_path, sarray(), varray());
bind_method(NodePath, is_empty, sarray(), varray());
/* Callable */
+ bind_static_method(Callable, create, sarray("variant", "method"), varray());
bind_method(Callable, callv, sarray("arguments"), varray());
bind_method(Callable, is_null, sarray(), varray());
bind_method(Callable, is_custom, sarray(), varray());
@@ -2029,6 +2054,7 @@ static void _register_variant_builtin_methods() {
bind_method(Callable, get_object, sarray(), varray());
bind_method(Callable, get_object_id, sarray(), varray());
bind_method(Callable, get_method, sarray(), varray());
+ bind_function(Callable, get_argument_count, _VariantCall::func_Callable_get_argument_count, sarray(), varray());
bind_method(Callable, get_bound_arguments_count, sarray(), varray());
bind_method(Callable, get_bound_arguments, sarray(), varray());
bind_method(Callable, hash, sarray(), varray());
@@ -2186,6 +2212,7 @@ static void _register_variant_builtin_methods() {
bind_method(Dictionary, is_empty, sarray(), varray());
bind_method(Dictionary, clear, sarray(), varray());
bind_method(Dictionary, merge, sarray("dictionary", "overwrite"), varray(false));
+ bind_method(Dictionary, merged, sarray("dictionary", "overwrite"), varray(false));
bind_method(Dictionary, has, sarray("key"), varray());
bind_method(Dictionary, has_all, sarray("keys"), varray());
bind_method(Dictionary, find_key, sarray("value"), varray());
@@ -2195,6 +2222,7 @@ static void _register_variant_builtin_methods() {
bind_method(Dictionary, values, sarray(), varray());
bind_method(Dictionary, duplicate, sarray("deep"), varray(false));
bind_method(Dictionary, get, sarray("key", "default"), varray(Variant()));
+ bind_method(Dictionary, get_or_add, sarray("key", "default"), varray(Variant()));
bind_method(Dictionary, make_read_only, sarray(), varray());
bind_method(Dictionary, is_read_only, sarray(), varray());
diff --git a/core/variant/variant_callable.cpp b/core/variant/variant_callable.cpp
new file mode 100644
index 0000000000..21f9a4f52b
--- /dev/null
+++ b/core/variant/variant_callable.cpp
@@ -0,0 +1,90 @@
+/**************************************************************************/
+/* variant_callable.cpp */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#include "variant_callable.h"
+
+#include "core/templates/hashfuncs.h"
+
+bool VariantCallable::compare_equal(const CallableCustom *p_a, const CallableCustom *p_b) {
+ return p_a->hash() == p_b->hash();
+}
+
+bool VariantCallable::compare_less(const CallableCustom *p_a, const CallableCustom *p_b) {
+ return p_a->hash() < p_b->hash();
+}
+
+uint32_t VariantCallable::hash() const {
+ return h;
+}
+
+String VariantCallable::get_as_text() const {
+ return vformat("%s::%s (Callable)", Variant::get_type_name(variant.get_type()), method);
+}
+
+CallableCustom::CompareEqualFunc VariantCallable::get_compare_equal_func() const {
+ return compare_equal;
+}
+
+CallableCustom::CompareLessFunc VariantCallable::get_compare_less_func() const {
+ return compare_less;
+}
+
+bool VariantCallable::is_valid() const {
+ return Variant::has_builtin_method(variant.get_type(), method);
+}
+
+StringName VariantCallable::get_method() const {
+ return method;
+}
+
+ObjectID VariantCallable::get_object() const {
+ return ObjectID();
+}
+
+int VariantCallable::get_argument_count(bool &r_is_valid) const {
+ if (!Variant::has_builtin_method(variant.get_type(), method)) {
+ r_is_valid = false;
+ return 0;
+ }
+ r_is_valid = true;
+ return Variant::get_builtin_method_argument_count(variant.get_type(), method);
+}
+
+void VariantCallable::call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const {
+ Variant v = variant;
+ v.callp(method, p_arguments, p_argcount, r_return_value, r_call_error);
+}
+
+VariantCallable::VariantCallable(const Variant &p_variant, const StringName &p_method) {
+ variant = p_variant;
+ method = p_method;
+ h = variant.hash();
+ h = hash_murmur3_one_64(Variant::get_builtin_method_hash(variant.get_type(), method), h);
+}
diff --git a/core/variant/variant_callable.h b/core/variant/variant_callable.h
new file mode 100644
index 0000000000..1811f3bb9a
--- /dev/null
+++ b/core/variant/variant_callable.h
@@ -0,0 +1,59 @@
+/**************************************************************************/
+/* variant_callable.h */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#ifndef VARIANT_CALLABLE_H
+#define VARIANT_CALLABLE_H
+
+#include "core/variant/callable.h"
+#include "core/variant/variant.h"
+
+class VariantCallable : public CallableCustom {
+ Variant variant;
+ StringName method;
+ uint32_t h = 0;
+
+ static bool compare_equal(const CallableCustom *p_a, const CallableCustom *p_b);
+ static bool compare_less(const CallableCustom *p_a, const CallableCustom *p_b);
+
+public:
+ uint32_t hash() const override;
+ String get_as_text() const override;
+ CompareEqualFunc get_compare_equal_func() const override;
+ CompareLessFunc get_compare_less_func() const override;
+ bool is_valid() const override;
+ StringName get_method() const override;
+ ObjectID get_object() const override;
+ int get_argument_count(bool &r_is_valid) const override;
+ void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const override;
+
+ VariantCallable(const Variant &p_variant, const StringName &p_method);
+};
+
+#endif // VARIANT_CALLABLE_H
diff --git a/core/variant/variant_construct.cpp b/core/variant/variant_construct.cpp
index 3427950224..b0ed49be5d 100644
--- a/core/variant/variant_construct.cpp
+++ b/core/variant/variant_construct.cpp
@@ -41,7 +41,7 @@ struct VariantConstructData {
static LocalVector<VariantConstructData> construct_data[Variant::VARIANT_MAX];
-template <class T>
+template <typename T>
static void add_constructor(const Vector<String> &arg_names) {
ERR_FAIL_COND_MSG(arg_names.size() != T::get_argument_count(), "Argument names size mismatch for " + Variant::get_type_name(T::get_base_type()) + ".");
diff --git a/core/variant/variant_construct.h b/core/variant/variant_construct.h
index ef7bf2dfc2..a93723a910 100644
--- a/core/variant/variant_construct.h
+++ b/core/variant/variant_construct.h
@@ -42,7 +42,7 @@
#include "core/templates/local_vector.h"
#include "core/templates/oa_hash_map.h"
-template <class T>
+template <typename T>
struct PtrConstruct {};
#define MAKE_PTRCONSTRUCT(m_type) \
@@ -99,7 +99,7 @@ MAKE_PTRCONSTRUCT(PackedVector3Array);
MAKE_PTRCONSTRUCT(PackedColorArray);
MAKE_PTRCONSTRUCT(Variant);
-template <class T, class... P>
+template <typename T, typename... P>
class VariantConstructor {
template <size_t... Is>
static _FORCE_INLINE_ void construct_helper(T &base, const Variant **p_args, Callable::CallError &r_error, IndexSequence<Is...>) {
@@ -222,7 +222,7 @@ public:
}
};
-template <class T>
+template <typename T>
class VariantConstructorFromString {
public:
static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) {
@@ -470,7 +470,7 @@ public:
}
};
-template <class T>
+template <typename T>
class VariantConstructorToArray {
public:
static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) {
@@ -529,7 +529,7 @@ public:
}
};
-template <class T>
+template <typename T>
class VariantConstructorFromArray {
public:
static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) {
@@ -622,7 +622,7 @@ public:
}
};
-template <class T>
+template <typename T>
class VariantConstructNoArgs {
public:
static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) {
@@ -661,7 +661,7 @@ public:
VariantInternal::clear(r_ret);
}
static void ptr_construct(void *base, const void **p_args) {
- ERR_FAIL_MSG("can't ptrcall nil constructor");
+ ERR_FAIL_MSG("Cannot ptrcall nil constructor");
}
static int get_argument_count() {
diff --git a/core/variant/variant_destruct.cpp b/core/variant/variant_destruct.cpp
index 5308eba97d..c7455d5117 100644
--- a/core/variant/variant_destruct.cpp
+++ b/core/variant/variant_destruct.cpp
@@ -34,7 +34,7 @@
static Variant::PTRDestructor destruct_pointers[Variant::VARIANT_MAX] = { nullptr };
-template <class T>
+template <typename T>
static void add_destructor() {
destruct_pointers[T::get_base_type()] = T::ptr_destruct;
}
diff --git a/core/variant/variant_destruct.h b/core/variant/variant_destruct.h
index c5f9c260c0..c496189c6d 100644
--- a/core/variant/variant_destruct.h
+++ b/core/variant/variant_destruct.h
@@ -35,7 +35,7 @@
#include "core/object/class_db.h"
-template <class T>
+template <typename T>
struct VariantDestruct {};
#define MAKE_PTRDESTRUCT(m_type) \
diff --git a/core/variant/variant_internal.h b/core/variant/variant_internal.h
index 116210e8de..dbd4a6a7ad 100644
--- a/core/variant/variant_internal.h
+++ b/core/variant/variant_internal.h
@@ -211,7 +211,7 @@ public:
_FORCE_INLINE_ static const ObjectID get_object_id(const Variant *v) { return v->_get_obj().id; }
- template <class T>
+ template <typename T>
_FORCE_INLINE_ static void init_generic(Variant *v) {
v->type = GetTypeInfo<T>::VARIANT_TYPE;
}
@@ -510,7 +510,7 @@ public:
}
};
-template <class T>
+template <typename T>
struct VariantGetInternalPtr {
};
@@ -797,7 +797,7 @@ struct VariantGetInternalPtr<PackedColorArray> {
static const PackedColorArray *get_ptr(const Variant *v) { return VariantInternal::get_color_array(v); }
};
-template <class T>
+template <typename T>
struct VariantInternalAccessor {
};
@@ -810,7 +810,7 @@ struct VariantInternalAccessor<bool> {
#define VARIANT_ACCESSOR_NUMBER(m_type) \
template <> \
struct VariantInternalAccessor<m_type> { \
- static _FORCE_INLINE_ m_type get(const Variant *v) { return (m_type)*VariantInternal::get_int(v); } \
+ static _FORCE_INLINE_ m_type get(const Variant *v) { return (m_type) * VariantInternal::get_int(v); } \
static _FORCE_INLINE_ void set(Variant *v, m_type p_value) { *VariantInternal::get_int(v) = p_value; } \
};
@@ -830,13 +830,13 @@ struct VariantInternalAccessor<ObjectID> {
static _FORCE_INLINE_ void set(Variant *v, ObjectID p_value) { *VariantInternal::get_int(v) = p_value; }
};
-template <class T>
+template <typename T>
struct VariantInternalAccessor<T *> {
static _FORCE_INLINE_ T *get(const Variant *v) { return const_cast<T *>(static_cast<const T *>(*VariantInternal::get_object(v))); }
static _FORCE_INLINE_ void set(Variant *v, const T *p_value) { VariantInternal::object_assign(v, p_value); }
};
-template <class T>
+template <typename T>
struct VariantInternalAccessor<const T *> {
static _FORCE_INLINE_ const T *get(const Variant *v) { return static_cast<const T *>(*VariantInternal::get_object(v)); }
static _FORCE_INLINE_ void set(Variant *v, const T *p_value) { VariantInternal::object_assign(v, p_value); }
@@ -1091,7 +1091,7 @@ struct VariantInternalAccessor<Vector<Variant>> {
}
};
-template <class T>
+template <typename T>
struct VariantInitializer {
};
@@ -1301,196 +1301,196 @@ struct VariantInitializer<Object *> {
static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_object(v); }
};
-template <class T>
-struct VariantZeroAssigner {
+template <typename T>
+struct VariantDefaultInitializer {
};
template <>
-struct VariantZeroAssigner<bool> {
- static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_bool(v) = false; }
+struct VariantDefaultInitializer<bool> {
+ static _FORCE_INLINE_ void init(Variant *v) { *VariantInternal::get_bool(v) = false; }
};
template <>
-struct VariantZeroAssigner<int64_t> {
- static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_int(v) = 0; }
+struct VariantDefaultInitializer<int64_t> {
+ static _FORCE_INLINE_ void init(Variant *v) { *VariantInternal::get_int(v) = 0; }
};
template <>
-struct VariantZeroAssigner<double> {
- static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_float(v) = 0.0; }
+struct VariantDefaultInitializer<double> {
+ static _FORCE_INLINE_ void init(Variant *v) { *VariantInternal::get_float(v) = 0.0; }
};
template <>
-struct VariantZeroAssigner<float> {
- static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_float(v) = 0.0; }
+struct VariantDefaultInitializer<float> {
+ static _FORCE_INLINE_ void init(Variant *v) { *VariantInternal::get_float(v) = 0.0; }
};
template <>
-struct VariantZeroAssigner<String> {
- static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_string(v) = String(); }
+struct VariantDefaultInitializer<String> {
+ static _FORCE_INLINE_ void init(Variant *v) { *VariantInternal::get_string(v) = String(); }
};
template <>
-struct VariantZeroAssigner<Vector2> {
- static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_vector2(v) = Vector2(); }
+struct VariantDefaultInitializer<Vector2> {
+ static _FORCE_INLINE_ void init(Variant *v) { *VariantInternal::get_vector2(v) = Vector2(); }
};
template <>
-struct VariantZeroAssigner<Vector2i> {
- static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_vector2i(v) = Vector2i(); }
+struct VariantDefaultInitializer<Vector2i> {
+ static _FORCE_INLINE_ void init(Variant *v) { *VariantInternal::get_vector2i(v) = Vector2i(); }
};
template <>
-struct VariantZeroAssigner<Rect2> {
- static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_rect2(v) = Rect2(); }
+struct VariantDefaultInitializer<Rect2> {
+ static _FORCE_INLINE_ void init(Variant *v) { *VariantInternal::get_rect2(v) = Rect2(); }
};
template <>
-struct VariantZeroAssigner<Rect2i> {
- static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_rect2i(v) = Rect2i(); }
+struct VariantDefaultInitializer<Rect2i> {
+ static _FORCE_INLINE_ void init(Variant *v) { *VariantInternal::get_rect2i(v) = Rect2i(); }
};
template <>
-struct VariantZeroAssigner<Vector3> {
- static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_vector3(v) = Vector3(); }
+struct VariantDefaultInitializer<Vector3> {
+ static _FORCE_INLINE_ void init(Variant *v) { *VariantInternal::get_vector3(v) = Vector3(); }
};
template <>
-struct VariantZeroAssigner<Vector3i> {
- static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_vector3i(v) = Vector3i(); }
+struct VariantDefaultInitializer<Vector3i> {
+ static _FORCE_INLINE_ void init(Variant *v) { *VariantInternal::get_vector3i(v) = Vector3i(); }
};
template <>
-struct VariantZeroAssigner<Vector4> {
- static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_vector4(v) = Vector4(); }
+struct VariantDefaultInitializer<Vector4> {
+ static _FORCE_INLINE_ void init(Variant *v) { *VariantInternal::get_vector4(v) = Vector4(); }
};
template <>
-struct VariantZeroAssigner<Vector4i> {
- static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_vector4i(v) = Vector4i(); }
+struct VariantDefaultInitializer<Vector4i> {
+ static _FORCE_INLINE_ void init(Variant *v) { *VariantInternal::get_vector4i(v) = Vector4i(); }
};
template <>
-struct VariantZeroAssigner<Transform2D> {
- static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_transform2d(v) = Transform2D(); }
+struct VariantDefaultInitializer<Transform2D> {
+ static _FORCE_INLINE_ void init(Variant *v) { *VariantInternal::get_transform2d(v) = Transform2D(); }
};
template <>
-struct VariantZeroAssigner<Plane> {
- static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_plane(v) = Plane(); }
+struct VariantDefaultInitializer<Plane> {
+ static _FORCE_INLINE_ void init(Variant *v) { *VariantInternal::get_plane(v) = Plane(); }
};
template <>
-struct VariantZeroAssigner<Quaternion> {
- static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_quaternion(v) = Quaternion(); }
+struct VariantDefaultInitializer<Quaternion> {
+ static _FORCE_INLINE_ void init(Variant *v) { *VariantInternal::get_quaternion(v) = Quaternion(); }
};
template <>
-struct VariantZeroAssigner<AABB> {
- static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_aabb(v) = AABB(); }
+struct VariantDefaultInitializer<AABB> {
+ static _FORCE_INLINE_ void init(Variant *v) { *VariantInternal::get_aabb(v) = AABB(); }
};
template <>
-struct VariantZeroAssigner<Basis> {
- static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_basis(v) = Basis(); }
+struct VariantDefaultInitializer<Basis> {
+ static _FORCE_INLINE_ void init(Variant *v) { *VariantInternal::get_basis(v) = Basis(); }
};
template <>
-struct VariantZeroAssigner<Transform3D> {
- static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_transform(v) = Transform3D(); }
+struct VariantDefaultInitializer<Transform3D> {
+ static _FORCE_INLINE_ void init(Variant *v) { *VariantInternal::get_transform(v) = Transform3D(); }
};
template <>
-struct VariantZeroAssigner<Projection> {
- static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_projection(v) = Projection(); }
+struct VariantDefaultInitializer<Projection> {
+ static _FORCE_INLINE_ void init(Variant *v) { *VariantInternal::get_projection(v) = Projection(); }
};
template <>
-struct VariantZeroAssigner<Color> {
- static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_color(v) = Color(); }
+struct VariantDefaultInitializer<Color> {
+ static _FORCE_INLINE_ void init(Variant *v) { *VariantInternal::get_color(v) = Color(); }
};
template <>
-struct VariantZeroAssigner<StringName> {
- static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_string_name(v) = StringName(); }
+struct VariantDefaultInitializer<StringName> {
+ static _FORCE_INLINE_ void init(Variant *v) { *VariantInternal::get_string_name(v) = StringName(); }
};
template <>
-struct VariantZeroAssigner<NodePath> {
- static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_node_path(v) = NodePath(); }
+struct VariantDefaultInitializer<NodePath> {
+ static _FORCE_INLINE_ void init(Variant *v) { *VariantInternal::get_node_path(v) = NodePath(); }
};
template <>
-struct VariantZeroAssigner<::RID> {
- static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_rid(v) = RID(); }
+struct VariantDefaultInitializer<::RID> {
+ static _FORCE_INLINE_ void init(Variant *v) { *VariantInternal::get_rid(v) = RID(); }
};
template <>
-struct VariantZeroAssigner<Callable> {
- static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_callable(v) = Callable(); }
+struct VariantDefaultInitializer<Callable> {
+ static _FORCE_INLINE_ void init(Variant *v) { *VariantInternal::get_callable(v) = Callable(); }
};
template <>
-struct VariantZeroAssigner<Signal> {
- static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_signal(v) = Signal(); }
+struct VariantDefaultInitializer<Signal> {
+ static _FORCE_INLINE_ void init(Variant *v) { *VariantInternal::get_signal(v) = Signal(); }
};
template <>
-struct VariantZeroAssigner<Dictionary> {
- static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_dictionary(v) = Dictionary(); }
+struct VariantDefaultInitializer<Dictionary> {
+ static _FORCE_INLINE_ void init(Variant *v) { *VariantInternal::get_dictionary(v) = Dictionary(); }
};
template <>
-struct VariantZeroAssigner<Array> {
- static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_array(v) = Array(); }
+struct VariantDefaultInitializer<Array> {
+ static _FORCE_INLINE_ void init(Variant *v) { *VariantInternal::get_array(v) = Array(); }
};
template <>
-struct VariantZeroAssigner<PackedByteArray> {
- static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_byte_array(v) = PackedByteArray(); }
+struct VariantDefaultInitializer<PackedByteArray> {
+ static _FORCE_INLINE_ void init(Variant *v) { *VariantInternal::get_byte_array(v) = PackedByteArray(); }
};
template <>
-struct VariantZeroAssigner<PackedInt32Array> {
- static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_int32_array(v) = PackedInt32Array(); }
+struct VariantDefaultInitializer<PackedInt32Array> {
+ static _FORCE_INLINE_ void init(Variant *v) { *VariantInternal::get_int32_array(v) = PackedInt32Array(); }
};
template <>
-struct VariantZeroAssigner<PackedInt64Array> {
- static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_int64_array(v) = PackedInt64Array(); }
+struct VariantDefaultInitializer<PackedInt64Array> {
+ static _FORCE_INLINE_ void init(Variant *v) { *VariantInternal::get_int64_array(v) = PackedInt64Array(); }
};
template <>
-struct VariantZeroAssigner<PackedFloat32Array> {
- static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_float32_array(v) = PackedFloat32Array(); }
+struct VariantDefaultInitializer<PackedFloat32Array> {
+ static _FORCE_INLINE_ void init(Variant *v) { *VariantInternal::get_float32_array(v) = PackedFloat32Array(); }
};
template <>
-struct VariantZeroAssigner<PackedFloat64Array> {
- static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_float64_array(v) = PackedFloat64Array(); }
+struct VariantDefaultInitializer<PackedFloat64Array> {
+ static _FORCE_INLINE_ void init(Variant *v) { *VariantInternal::get_float64_array(v) = PackedFloat64Array(); }
};
template <>
-struct VariantZeroAssigner<PackedStringArray> {
- static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_string_array(v) = PackedStringArray(); }
+struct VariantDefaultInitializer<PackedStringArray> {
+ static _FORCE_INLINE_ void init(Variant *v) { *VariantInternal::get_string_array(v) = PackedStringArray(); }
};
template <>
-struct VariantZeroAssigner<PackedVector2Array> {
- static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_vector2_array(v) = PackedVector2Array(); }
+struct VariantDefaultInitializer<PackedVector2Array> {
+ static _FORCE_INLINE_ void init(Variant *v) { *VariantInternal::get_vector2_array(v) = PackedVector2Array(); }
};
template <>
-struct VariantZeroAssigner<PackedVector3Array> {
- static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_vector3_array(v) = PackedVector3Array(); }
+struct VariantDefaultInitializer<PackedVector3Array> {
+ static _FORCE_INLINE_ void init(Variant *v) { *VariantInternal::get_vector3_array(v) = PackedVector3Array(); }
};
template <>
-struct VariantZeroAssigner<PackedColorArray> {
- static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_color_array(v) = PackedColorArray(); }
+struct VariantDefaultInitializer<PackedColorArray> {
+ static _FORCE_INLINE_ void init(Variant *v) { *VariantInternal::get_color_array(v) = PackedColorArray(); }
};
-template <class T>
+template <typename T>
struct VariantTypeChanger {
static _FORCE_INLINE_ void change(Variant *v) {
if (v->get_type() != GetTypeInfo<T>::VARIANT_TYPE || GetTypeInfo<T>::VARIANT_TYPE >= Variant::PACKED_BYTE_ARRAY) { //second condition removed by optimizer
@@ -1504,11 +1504,11 @@ struct VariantTypeChanger {
VariantInitializer<T>::init(v);
}
- VariantZeroAssigner<T>::zero(v);
+ VariantDefaultInitializer<T>::init(v);
}
};
-template <class T>
+template <typename T>
struct VariantTypeAdjust {
_FORCE_INLINE_ static void adjust(Variant *r_ret) {
VariantTypeChanger<typename GetSimpleTypeT<T>::type_t>::change(r_ret);
@@ -1532,7 +1532,7 @@ struct VariantTypeAdjust<Object *> {
// GDExtension helpers.
-template <class T>
+template <typename T>
struct VariantTypeConstructor {
_FORCE_INLINE_ static void variant_from_type(void *r_variant, void *p_value) {
// r_variant is provided by caller as uninitialized memory
diff --git a/core/variant/variant_op.cpp b/core/variant/variant_op.cpp
index aed83ac010..dcf4b287d1 100644
--- a/core/variant/variant_op.cpp
+++ b/core/variant/variant_op.cpp
@@ -37,7 +37,7 @@ static VariantEvaluatorFunction operator_evaluator_table[Variant::OP_MAX][Varian
static Variant::ValidatedOperatorEvaluator validated_operator_evaluator_table[Variant::OP_MAX][Variant::VARIANT_MAX][Variant::VARIANT_MAX];
static Variant::PTROperatorEvaluator ptr_operator_evaluator_table[Variant::OP_MAX][Variant::VARIANT_MAX][Variant::VARIANT_MAX];
-template <class T>
+template <typename T>
void register_op(Variant::Operator p_op, Variant::Type p_type_a, Variant::Type p_type_b) {
operator_return_type_table[p_op][p_type_a][p_type_b] = T::get_return_type();
operator_evaluator_table[p_op][p_type_a][p_type_b] = T::evaluate;
@@ -230,18 +230,20 @@ public:
};
#define register_string_op(m_op_type, m_op_code) \
- do { \
+ if constexpr (true) { \
register_op<m_op_type<String, String>>(m_op_code, Variant::STRING, Variant::STRING); \
register_op<m_op_type<String, StringName>>(m_op_code, Variant::STRING, Variant::STRING_NAME); \
register_op<m_op_type<StringName, String>>(m_op_code, Variant::STRING_NAME, Variant::STRING); \
register_op<m_op_type<StringName, StringName>>(m_op_code, Variant::STRING_NAME, Variant::STRING_NAME); \
- } while (false)
+ } else \
+ ((void)0)
#define register_string_modulo_op(m_class, m_type) \
- do { \
+ if constexpr (true) { \
register_op<OperatorEvaluatorStringFormat<String, m_class>>(Variant::OP_MODULE, Variant::STRING, m_type); \
register_op<OperatorEvaluatorStringFormat<StringName, m_class>>(Variant::OP_MODULE, Variant::STRING_NAME, m_type); \
- } while (false)
+ } else \
+ ((void)0)
void Variant::_register_variant_operators() {
memset(operator_return_type_table, 0, sizeof(operator_return_type_table));
@@ -412,6 +414,15 @@ void Variant::_register_variant_operators() {
register_op<OperatorEvaluatorDivNZ<Vector4, Vector4i, double>>(Variant::OP_DIVIDE, Variant::VECTOR4I, Variant::FLOAT);
register_op<OperatorEvaluatorDivNZ<Vector4i, Vector4i, int64_t>>(Variant::OP_DIVIDE, Variant::VECTOR4I, Variant::INT);
+ register_op<OperatorEvaluatorDiv<Transform2D, Transform2D, int64_t>>(Variant::OP_DIVIDE, Variant::TRANSFORM2D, Variant::INT);
+ register_op<OperatorEvaluatorDiv<Transform2D, Transform2D, double>>(Variant::OP_DIVIDE, Variant::TRANSFORM2D, Variant::FLOAT);
+
+ register_op<OperatorEvaluatorDiv<Transform3D, Transform3D, int64_t>>(Variant::OP_DIVIDE, Variant::TRANSFORM3D, Variant::INT);
+ register_op<OperatorEvaluatorDiv<Transform3D, Transform3D, double>>(Variant::OP_DIVIDE, Variant::TRANSFORM3D, Variant::FLOAT);
+
+ register_op<OperatorEvaluatorDiv<Basis, Basis, int64_t>>(Variant::OP_DIVIDE, Variant::BASIS, Variant::INT);
+ register_op<OperatorEvaluatorDiv<Basis, Basis, double>>(Variant::OP_DIVIDE, Variant::BASIS, Variant::FLOAT);
+
register_op<OperatorEvaluatorDiv<Quaternion, Quaternion, double>>(Variant::OP_DIVIDE, Variant::QUATERNION, Variant::FLOAT);
register_op<OperatorEvaluatorDiv<Quaternion, Quaternion, int64_t>>(Variant::OP_DIVIDE, Variant::QUATERNION, Variant::INT);
diff --git a/core/variant/variant_op.h b/core/variant/variant_op.h
index 9e6367ab6d..3142f49fc6 100644
--- a/core/variant/variant_op.h
+++ b/core/variant/variant_op.h
@@ -37,7 +37,7 @@
#include "core/debugger/engine_debugger.h"
#include "core/object/class_db.h"
-template <class R, class A, class B>
+template <typename R, typename A, typename B>
class OperatorEvaluatorAdd {
public:
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
@@ -55,7 +55,7 @@ public:
static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; }
};
-template <class R, class A, class B>
+template <typename R, typename A, typename B>
class OperatorEvaluatorSub {
public:
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
@@ -73,7 +73,7 @@ public:
static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; }
};
-template <class R, class A, class B>
+template <typename R, typename A, typename B>
class OperatorEvaluatorMul {
public:
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
@@ -91,7 +91,7 @@ public:
static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; }
};
-template <class R, class A, class B>
+template <typename R, typename A, typename B>
class OperatorEvaluatorPow {
public:
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
@@ -109,7 +109,7 @@ public:
static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; }
};
-template <class R, class A, class B>
+template <typename R, typename A, typename B>
class OperatorEvaluatorXForm {
public:
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
@@ -127,7 +127,7 @@ public:
static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; }
};
-template <class R, class A, class B>
+template <typename R, typename A, typename B>
class OperatorEvaluatorXFormInv {
public:
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
@@ -145,7 +145,7 @@ public:
static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; }
};
-template <class R, class A, class B>
+template <typename R, typename A, typename B>
class OperatorEvaluatorDiv {
public:
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
@@ -163,7 +163,7 @@ public:
static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; }
};
-template <class R, class A, class B>
+template <typename R, typename A, typename B>
class OperatorEvaluatorDivNZ {
public:
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
@@ -258,7 +258,7 @@ public:
static Variant::Type get_return_type() { return GetTypeInfo<Vector4i>::VARIANT_TYPE; }
};
-template <class R, class A, class B>
+template <typename R, typename A, typename B>
class OperatorEvaluatorMod {
public:
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
@@ -276,7 +276,7 @@ public:
static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; }
};
-template <class R, class A, class B>
+template <typename R, typename A, typename B>
class OperatorEvaluatorModNZ {
public:
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
@@ -371,7 +371,7 @@ public:
static Variant::Type get_return_type() { return GetTypeInfo<Vector4i>::VARIANT_TYPE; }
};
-template <class R, class A>
+template <typename R, typename A>
class OperatorEvaluatorNeg {
public:
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
@@ -388,7 +388,7 @@ public:
static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; }
};
-template <class R, class A>
+template <typename R, typename A>
class OperatorEvaluatorPos {
public:
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
@@ -405,7 +405,7 @@ public:
static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; }
};
-template <class R, class A, class B>
+template <typename R, typename A, typename B>
class OperatorEvaluatorShiftLeft {
public:
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
@@ -431,7 +431,7 @@ public:
static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; }
};
-template <class R, class A, class B>
+template <typename R, typename A, typename B>
class OperatorEvaluatorShiftRight {
public:
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
@@ -457,7 +457,7 @@ public:
static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; }
};
-template <class R, class A, class B>
+template <typename R, typename A, typename B>
class OperatorEvaluatorBitOr {
public:
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
@@ -475,7 +475,7 @@ public:
static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; }
};
-template <class R, class A, class B>
+template <typename R, typename A, typename B>
class OperatorEvaluatorBitAnd {
public:
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
@@ -493,7 +493,7 @@ public:
static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; }
};
-template <class R, class A, class B>
+template <typename R, typename A, typename B>
class OperatorEvaluatorBitXor {
public:
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
@@ -511,7 +511,7 @@ public:
static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; }
};
-template <class R, class A>
+template <typename R, typename A>
class OperatorEvaluatorBitNeg {
public:
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
@@ -528,7 +528,7 @@ public:
static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; }
};
-template <class A, class B>
+template <typename A, typename B>
class OperatorEvaluatorEqual {
public:
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
@@ -549,14 +549,14 @@ public:
class OperatorEvaluatorEqualObject {
public:
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
- const Object *a = p_left.get_validated_object();
- const Object *b = p_right.get_validated_object();
+ const ObjectID &a = VariantInternal::get_object_id(&p_left);
+ const ObjectID &b = VariantInternal::get_object_id(&p_right);
*r_ret = a == b;
r_valid = true;
}
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
- const Object *a = left->get_validated_object();
- const Object *b = right->get_validated_object();
+ const ObjectID &a = VariantInternal::get_object_id(left);
+ const ObjectID &b = VariantInternal::get_object_id(right);
*VariantGetInternalPtr<bool>::get_ptr(r_ret) = a == b;
}
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
@@ -568,12 +568,12 @@ public:
class OperatorEvaluatorEqualObjectNil {
public:
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
- const Object *a = p_left.get_validated_object();
+ const Object *a = p_left.operator Object *();
*r_ret = a == nullptr;
r_valid = true;
}
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
- const Object *a = left->get_validated_object();
+ const Object *a = left->operator Object *();
*VariantGetInternalPtr<bool>::get_ptr(r_ret) = a == nullptr;
}
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
@@ -585,12 +585,12 @@ public:
class OperatorEvaluatorEqualNilObject {
public:
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
- const Object *b = p_right.get_validated_object();
+ const Object *b = p_right.operator Object *();
*r_ret = nullptr == b;
r_valid = true;
}
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
- const Object *b = right->get_validated_object();
+ const Object *b = right->operator Object *();
*VariantGetInternalPtr<bool>::get_ptr(r_ret) = nullptr == b;
}
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
@@ -599,7 +599,7 @@ public:
static Variant::Type get_return_type() { return Variant::BOOL; }
};
-template <class A, class B>
+template <typename A, typename B>
class OperatorEvaluatorNotEqual {
public:
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
@@ -620,14 +620,14 @@ public:
class OperatorEvaluatorNotEqualObject {
public:
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
- Object *a = p_left.get_validated_object();
- Object *b = p_right.get_validated_object();
+ const ObjectID &a = VariantInternal::get_object_id(&p_left);
+ const ObjectID &b = VariantInternal::get_object_id(&p_right);
*r_ret = a != b;
r_valid = true;
}
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
- Object *a = left->get_validated_object();
- Object *b = right->get_validated_object();
+ const ObjectID &a = VariantInternal::get_object_id(left);
+ const ObjectID &b = VariantInternal::get_object_id(right);
*VariantGetInternalPtr<bool>::get_ptr(r_ret) = a != b;
}
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
@@ -639,12 +639,12 @@ public:
class OperatorEvaluatorNotEqualObjectNil {
public:
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
- Object *a = p_left.get_validated_object();
+ Object *a = p_left.operator Object *();
*r_ret = a != nullptr;
r_valid = true;
}
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
- Object *a = left->get_validated_object();
+ Object *a = left->operator Object *();
*VariantGetInternalPtr<bool>::get_ptr(r_ret) = a != nullptr;
}
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
@@ -656,12 +656,12 @@ public:
class OperatorEvaluatorNotEqualNilObject {
public:
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
- Object *b = p_right.get_validated_object();
+ Object *b = p_right.operator Object *();
*r_ret = nullptr != b;
r_valid = true;
}
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
- Object *b = right->get_validated_object();
+ Object *b = right->operator Object *();
*VariantGetInternalPtr<bool>::get_ptr(r_ret) = nullptr != b;
}
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
@@ -670,7 +670,7 @@ public:
static Variant::Type get_return_type() { return Variant::BOOL; }
};
-template <class A, class B>
+template <typename A, typename B>
class OperatorEvaluatorLess {
public:
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
@@ -688,7 +688,7 @@ public:
static Variant::Type get_return_type() { return Variant::BOOL; }
};
-template <class A, class B>
+template <typename A, typename B>
class OperatorEvaluatorLessEqual {
public:
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
@@ -706,7 +706,7 @@ public:
static Variant::Type get_return_type() { return Variant::BOOL; }
};
-template <class A, class B>
+template <typename A, typename B>
class OperatorEvaluatorGreater {
public:
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
@@ -724,7 +724,7 @@ public:
static Variant::Type get_return_type() { return Variant::BOOL; }
};
-template <class A, class B>
+template <typename A, typename B>
class OperatorEvaluatorGreaterEqual {
public:
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
@@ -742,7 +742,7 @@ public:
static Variant::Type get_return_type() { return Variant::BOOL; }
};
-template <class A, class B>
+template <typename A, typename B>
class OperatorEvaluatorAnd {
public:
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
@@ -760,7 +760,7 @@ public:
static Variant::Type get_return_type() { return Variant::BOOL; }
};
-template <class A, class B>
+template <typename A, typename B>
class OperatorEvaluatorOr {
public:
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
@@ -779,7 +779,7 @@ public:
};
#define XOR_OP(m_a, m_b) (((m_a) || (m_b)) && !((m_a) && (m_b)))
-template <class A, class B>
+template <typename A, typename B>
class OperatorEvaluatorXor {
public:
_FORCE_INLINE_ static bool xor_op(const A &a, const B &b) {
@@ -800,7 +800,7 @@ public:
static Variant::Type get_return_type() { return Variant::BOOL; }
};
-template <class A>
+template <typename A>
class OperatorEvaluatorNot {
public:
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
@@ -857,7 +857,7 @@ public:
static Variant::Type get_return_type() { return Variant::ARRAY; }
};
-template <class T>
+template <typename T>
class OperatorEvaluatorAppendArray {
public:
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
@@ -880,7 +880,7 @@ public:
static Variant::Type get_return_type() { return GetTypeInfo<Vector<T>>::VARIANT_TYPE; }
};
-template <class Left, class Right>
+template <typename Left, typename Right>
class OperatorEvaluatorStringConcat {
public:
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
@@ -902,10 +902,10 @@ public:
static Variant::Type get_return_type() { return Variant::STRING; }
};
-template <class S, class T>
+template <typename S, typename T>
class OperatorEvaluatorStringFormat;
-template <class S>
+template <typename S>
class OperatorEvaluatorStringFormat<S, void> {
public:
_FORCE_INLINE_ static String do_mod(const String &s, bool *r_valid) {
@@ -933,7 +933,7 @@ public:
static Variant::Type get_return_type() { return Variant::STRING; }
};
-template <class S>
+template <typename S>
class OperatorEvaluatorStringFormat<S, Array> {
public:
_FORCE_INLINE_ static String do_mod(const String &s, const Array &p_values, bool *r_valid) {
@@ -958,7 +958,7 @@ public:
static Variant::Type get_return_type() { return Variant::STRING; }
};
-template <class S>
+template <typename S>
class OperatorEvaluatorStringFormat<S, Object> {
public:
_FORCE_INLINE_ static String do_mod(const String &s, const Object *p_object, bool *r_valid) {
@@ -986,7 +986,7 @@ public:
static Variant::Type get_return_type() { return Variant::STRING; }
};
-template <class S, class T>
+template <typename S, typename T>
class OperatorEvaluatorStringFormat {
public:
_FORCE_INLINE_ static String do_mod(const String &s, const T &p_value, bool *r_valid) {
@@ -1317,10 +1317,10 @@ public:
////
-template <class Left, class Right>
+template <typename Left, typename Right>
class OperatorEvaluatorInStringFind;
-template <class Left>
+template <typename Left>
class OperatorEvaluatorInStringFind<Left, String> {
public:
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
@@ -1341,7 +1341,7 @@ public:
static Variant::Type get_return_type() { return Variant::BOOL; }
};
-template <class Left>
+template <typename Left>
class OperatorEvaluatorInStringFind<Left, StringName> {
public:
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
@@ -1362,7 +1362,7 @@ public:
static Variant::Type get_return_type() { return Variant::BOOL; }
};
-template <class A, class B>
+template <typename A, typename B>
class OperatorEvaluatorInArrayFind {
public:
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
@@ -1417,7 +1417,7 @@ public:
static Variant::Type get_return_type() { return Variant::BOOL; }
};
-template <class A>
+template <typename A>
class OperatorEvaluatorInDictionaryHas {
public:
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
diff --git a/core/variant/variant_parser.cpp b/core/variant/variant_parser.cpp
index 86e7654090..50f8007efa 100644
--- a/core/variant/variant_parser.cpp
+++ b/core/variant/variant_parser.cpp
@@ -30,6 +30,7 @@
#include "variant_parser.h"
+#include "core/crypto/crypto_core.h"
#include "core/input/input_event.h"
#include "core/io/resource_loader.h"
#include "core/object/script_language.h"
@@ -488,11 +489,11 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri
r_token.value = num.as_int();
}
return OK;
- } else if (is_ascii_char(cchar) || is_underscore(cchar)) {
+ } else if (is_ascii_alphabet_char(cchar) || is_underscore(cchar)) {
StringBuffer<> id;
bool first = true;
- while (is_ascii_char(cchar) || is_underscore(cchar) || (!first && is_digit(cchar))) {
+ while (is_ascii_alphabet_char(cchar) || is_underscore(cchar) || (!first && is_digit(cchar))) {
id += cchar;
cchar = p_stream->get_char();
first = false;
@@ -546,7 +547,7 @@ Error VariantParser::_parse_enginecfg(Stream *p_stream, Vector<String> &strings,
}
}
-template <class T>
+template <typename T>
Error VariantParser::_parse_construct(Stream *p_stream, Vector<T> &r_construct, int &line, String &r_err_str) {
Token token;
get_token(p_stream, token, line, r_err_str);
@@ -595,6 +596,82 @@ Error VariantParser::_parse_construct(Stream *p_stream, Vector<T> &r_construct,
return OK;
}
+Error VariantParser::_parse_byte_array(Stream *p_stream, Vector<uint8_t> &r_construct, int &line, String &r_err_str) {
+ Token token;
+ get_token(p_stream, token, line, r_err_str);
+ if (token.type != TK_PARENTHESIS_OPEN) {
+ r_err_str = "Expected '(' in constructor";
+ return ERR_PARSE_ERROR;
+ }
+
+ get_token(p_stream, token, line, r_err_str);
+ if (token.type == TK_STRING) {
+ // Base64 encoded array.
+ String base64_encoded_string = token.value;
+ int strlen = base64_encoded_string.length();
+ CharString cstr = base64_encoded_string.ascii();
+
+ size_t arr_len = 0;
+ r_construct.resize(strlen / 4 * 3 + 1);
+ uint8_t *w = r_construct.ptrw();
+ Error err = CryptoCore::b64_decode(&w[0], r_construct.size(), &arr_len, (unsigned char *)cstr.get_data(), strlen);
+ if (err) {
+ r_err_str = "Invalid base64-encoded string";
+ return ERR_PARSE_ERROR;
+ }
+ r_construct.resize(arr_len);
+
+ get_token(p_stream, token, line, r_err_str);
+ if (token.type != TK_PARENTHESIS_CLOSE) {
+ r_err_str = "Expected ')' in constructor";
+ return ERR_PARSE_ERROR;
+ }
+
+ } else if (token.type == TK_NUMBER || token.type == TK_IDENTIFIER) {
+ // Individual elements.
+ while (true) {
+ if (token.type != TK_NUMBER) {
+ bool valid = false;
+ if (token.type == TK_IDENTIFIER) {
+ double real = stor_fix(token.value);
+ if (real != -1) {
+ token.type = TK_NUMBER;
+ token.value = real;
+ valid = true;
+ }
+ }
+ if (!valid) {
+ r_err_str = "Expected number in constructor";
+ return ERR_PARSE_ERROR;
+ }
+ }
+
+ r_construct.push_back(token.value);
+
+ get_token(p_stream, token, line, r_err_str);
+
+ if (token.type == TK_COMMA) {
+ //do none
+ } else if (token.type == TK_PARENTHESIS_CLOSE) {
+ break;
+ } else {
+ r_err_str = "Expected ',' or ')' in constructor";
+ return ERR_PARSE_ERROR;
+ }
+
+ get_token(p_stream, token, line, r_err_str);
+ }
+ } else if (token.type == TK_PARENTHESIS_CLOSE) {
+ // Empty array.
+ return OK;
+ } else {
+ r_err_str = "Expected base64 string, or list of numbers in constructor";
+ return ERR_PARSE_ERROR;
+ }
+
+ return OK;
+}
+
Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, int &line, String &r_err_str, ResourceParser *p_res_parser) {
if (token.type == TK_CURLY_BRACKET_OPEN) {
Dictionary d;
@@ -1026,7 +1103,10 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
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;
+ // If the file is missing, the error can be ignored.
+ if (err != ERR_FILE_NOT_FOUND && err != ERR_CANT_OPEN && err != ERR_FILE_CANT_OPEN) {
+ return err;
+ }
}
value = res;
@@ -1145,7 +1225,7 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
value = array;
} else if (id == "PackedByteArray" || id == "PoolByteArray" || id == "ByteArray") {
Vector<uint8_t> args;
- Error err = _parse_construct<uint8_t>(p_stream, args, line, r_err_str);
+ Error err = _parse_byte_array(p_stream, args, line, r_err_str);
if (err) {
return err;
}
@@ -1709,7 +1789,7 @@ static String rtos_fix(double p_value) {
}
}
-Error VariantWriter::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 p_recursion_count) {
+Error VariantWriter::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 p_recursion_count, bool p_compat) {
switch (p_variant.get_type()) {
case Variant::NIL: {
p_store_string_func(p_store_string_ud, "null");
@@ -1929,7 +2009,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
}
p_store_string_func(p_store_string_ud, "\"" + E.name + "\":");
- write(obj->get(E.name), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, p_recursion_count);
+ write(obj->get(E.name), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, p_recursion_count, p_compat);
}
}
@@ -1955,9 +2035,9 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
p_store_string_func(p_store_string_ud, "{\n");
for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
- write(E->get(), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, p_recursion_count);
+ write(E->get(), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, p_recursion_count, p_compat);
p_store_string_func(p_store_string_ud, ": ");
- write(dict[E->get()], p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, p_recursion_count);
+ write(dict[E->get()], p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, p_recursion_count, p_compat);
if (E->next()) {
p_store_string_func(p_store_string_ud, ",\n");
} else {
@@ -2009,12 +2089,14 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
p_recursion_count++;
p_store_string_func(p_store_string_ud, "[");
- int len = array.size();
- for (int i = 0; i < len; i++) {
- if (i > 0) {
+ bool first = true;
+ for (const Variant &var : array) {
+ if (first) {
+ first = false;
+ } else {
p_store_string_func(p_store_string_ud, ", ");
}
- write(array[i], p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, p_recursion_count);
+ write(var, p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, p_recursion_count, p_compat);
}
p_store_string_func(p_store_string_ud, "]");
@@ -2028,17 +2110,20 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
case Variant::PACKED_BYTE_ARRAY: {
p_store_string_func(p_store_string_ud, "PackedByteArray(");
Vector<uint8_t> data = p_variant;
- int len = data.size();
- const uint8_t *ptr = data.ptr();
-
- for (int i = 0; i < len; i++) {
- if (i > 0) {
- p_store_string_func(p_store_string_ud, ", ");
+ if (p_compat) {
+ int len = data.size();
+ const uint8_t *ptr = data.ptr();
+ for (int i = 0; i < len; i++) {
+ if (i > 0) {
+ p_store_string_func(p_store_string_ud, ", ");
+ }
+ p_store_string_func(p_store_string_ud, itos(ptr[i]));
}
-
- p_store_string_func(p_store_string_ud, itos(ptr[i]));
+ } else if (data.size() > 0) {
+ p_store_string_func(p_store_string_ud, "\"");
+ p_store_string_func(p_store_string_ud, CryptoCore::b64_encode_str(data.ptr(), data.size()));
+ p_store_string_func(p_store_string_ud, "\"");
}
-
p_store_string_func(p_store_string_ud, ")");
} break;
case Variant::PACKED_INT32_ARRAY: {
@@ -2179,8 +2264,8 @@ static Error _write_to_str(void *ud, const String &p_string) {
return OK;
}
-Error VariantWriter::write_to_string(const Variant &p_variant, String &r_string, EncodeResourceFunc p_encode_res_func, void *p_encode_res_ud) {
+Error VariantWriter::write_to_string(const Variant &p_variant, String &r_string, EncodeResourceFunc p_encode_res_func, void *p_encode_res_ud, bool p_compat) {
r_string = String();
- return write(p_variant, _write_to_str, &r_string, p_encode_res_func, p_encode_res_ud);
+ return write(p_variant, _write_to_str, &r_string, p_encode_res_func, p_encode_res_ud, 0, p_compat);
}
diff --git a/core/variant/variant_parser.h b/core/variant/variant_parser.h
index 8505fff739..b0ac07170d 100644
--- a/core/variant/variant_parser.h
+++ b/core/variant/variant_parser.h
@@ -139,8 +139,9 @@ public:
private:
static const char *tk_name[TK_MAX];
- template <class T>
+ template <typename T>
static Error _parse_construct(Stream *p_stream, Vector<T> &r_construct, int &line, String &r_err_str);
+ static Error _parse_byte_array(Stream *p_stream, Vector<uint8_t> &r_construct, int &line, String &r_err_str);
static Error _parse_enginecfg(Stream *p_stream, Vector<String> &strings, int &line, String &r_err_str);
static Error _parse_dictionary(Dictionary &object, Stream *p_stream, int &line, String &r_err_str, ResourceParser *p_res_parser = nullptr);
static Error _parse_array(Array &array, Stream *p_stream, int &line, String &r_err_str, ResourceParser *p_res_parser = nullptr);
@@ -160,8 +161,8 @@ public:
typedef Error (*StoreStringFunc)(void *ud, const String &p_string);
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 p_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);
+ 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 p_recursion_count = 0, bool p_compat = true);
+ static Error write_to_string(const Variant &p_variant, String &r_string, EncodeResourceFunc p_encode_res_func = nullptr, void *p_encode_res_ud = nullptr, bool p_compat = true);
};
#endif // VARIANT_PARSER_H
diff --git a/core/variant/variant_setget.cpp b/core/variant/variant_setget.cpp
index 05f7abf32c..9d5ed22b1a 100644
--- a/core/variant/variant_setget.cpp
+++ b/core/variant/variant_setget.cpp
@@ -30,6 +30,8 @@
#include "variant_setget.h"
+#include "variant_callable.h"
+
struct VariantSetterGetterInfo {
void (*setter)(Variant *base, const Variant *value, bool &valid);
void (*getter)(const Variant *base, Variant *value);
@@ -43,7 +45,7 @@ struct VariantSetterGetterInfo {
static LocalVector<VariantSetterGetterInfo> variant_setters_getters[Variant::VARIANT_MAX];
static LocalVector<StringName> variant_setters_getters_names[Variant::VARIANT_MAX]; //one next to another to make it cache friendly
-template <class T>
+template <typename T>
static void register_member(Variant::Type p_type, const StringName &p_member) {
VariantSetterGetterInfo sgi;
sgi.setter = T::set;
@@ -264,42 +266,45 @@ void Variant::set_named(const StringName &p_member, const Variant &p_value, bool
}
Variant Variant::get_named(const StringName &p_member, bool &r_valid) const {
- Variant ret;
uint32_t s = variant_setters_getters[type].size();
if (s) {
for (uint32_t i = 0; i < s; i++) {
if (variant_setters_getters_names[type][i] == p_member) {
+ Variant ret;
variant_setters_getters[type][i].getter(this, &ret);
r_valid = true;
return ret;
}
}
+ }
- r_valid = false;
-
- } else if (type == Variant::OBJECT) {
- Object *obj = get_validated_object();
- if (!obj) {
- r_valid = false;
- return "Instance base is null.";
- } else {
- return obj->get(p_member, &r_valid);
- }
- } else if (type == Variant::DICTIONARY) {
- const Variant *v = VariantGetInternalPtr<Dictionary>::get_ptr(this)->getptr(p_member);
- if (v) {
- r_valid = true;
-
- return *v;
- } else {
- r_valid = false;
- }
-
- } else {
- r_valid = false;
+ switch (type) {
+ case Variant::OBJECT: {
+ Object *obj = get_validated_object();
+ if (!obj) {
+ r_valid = false;
+ return "Instance base is null.";
+ } else {
+ return obj->get(p_member, &r_valid);
+ }
+ } break;
+ case Variant::DICTIONARY: {
+ const Variant *v = VariantGetInternalPtr<Dictionary>::get_ptr(this)->getptr(p_member);
+ if (v) {
+ r_valid = true;
+ return *v;
+ }
+ } break;
+ default: {
+ if (Variant::has_builtin_method(type, p_member)) {
+ r_valid = true;
+ return Callable(memnew(VariantCallable(*this, p_member)));
+ }
+ } break;
}
- return ret;
+ r_valid = false;
+ return Variant();
}
/**** INDEXED SETTERS AND GETTERS ****/
@@ -428,9 +433,9 @@ Variant Variant::get_named(const StringName &p_member, bool &r_valid) const {
} \
m_assign_type num; \
if (value->get_type() == Variant::INT) { \
- num = (m_assign_type)*VariantGetInternalPtr<int64_t>::get_ptr(value); \
+ num = (m_assign_type) * VariantGetInternalPtr<int64_t>::get_ptr(value); \
} else if (value->get_type() == Variant::FLOAT) { \
- num = (m_assign_type)*VariantGetInternalPtr<double>::get_ptr(value); \
+ num = (m_assign_type) * VariantGetInternalPtr<double>::get_ptr(value); \
} else { \
*oob = false; \
*valid = false; \
@@ -490,9 +495,9 @@ Variant Variant::get_named(const StringName &p_member, bool &r_valid) const {
} \
m_assign_type num; \
if (value->get_type() == Variant::INT) { \
- num = (m_assign_type)*VariantGetInternalPtr<int64_t>::get_ptr(value); \
+ num = (m_assign_type) * VariantGetInternalPtr<int64_t>::get_ptr(value); \
} else if (value->get_type() == Variant::FLOAT) { \
- num = (m_assign_type)*VariantGetInternalPtr<double>::get_ptr(value); \
+ num = (m_assign_type) * VariantGetInternalPtr<double>::get_ptr(value); \
} else { \
*oob = false; \
*valid = false; \
@@ -868,7 +873,7 @@ struct VariantIndexedSetterGetterInfo {
static VariantIndexedSetterGetterInfo variant_indexed_setters_getters[Variant::VARIANT_MAX];
-template <class T>
+template <typename T>
static void register_indexed_member(Variant::Type p_type) {
VariantIndexedSetterGetterInfo &sgi = variant_indexed_setters_getters[p_type];
@@ -1089,7 +1094,7 @@ struct VariantKeyedSetterGetterInfo {
static VariantKeyedSetterGetterInfo variant_keyed_setters_getters[Variant::VARIANT_MAX];
-template <class T>
+template <typename T>
static void register_keyed_member(Variant::Type p_type) {
VariantKeyedSetterGetterInfo &sgi = variant_keyed_setters_getters[p_type];
@@ -1166,30 +1171,48 @@ bool Variant::has_key(const Variant &p_key, bool &r_valid) const {
}
}
-void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid) {
+void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid, VariantSetError *err_code) {
+ if (err_code) {
+ *err_code = VariantSetError::SET_OK;
+ }
if (type == DICTIONARY || type == OBJECT) {
bool valid;
set_keyed(p_index, p_value, valid);
if (r_valid) {
*r_valid = valid;
+ if (!valid && err_code) {
+ *err_code = VariantSetError::SET_KEYED_ERR;
+ }
}
} else {
bool valid = false;
if (p_index.get_type() == STRING_NAME) {
set_named(*VariantGetInternalPtr<StringName>::get_ptr(&p_index), p_value, valid);
+ if (!valid && err_code) {
+ *err_code = VariantSetError::SET_NAMED_ERR;
+ }
} else if (p_index.get_type() == INT) {
bool obb;
set_indexed(*VariantGetInternalPtr<int64_t>::get_ptr(&p_index), p_value, valid, obb);
if (obb) {
valid = false;
+ if (err_code) {
+ *err_code = VariantSetError::SET_INDEXED_ERR;
+ }
}
} else if (p_index.get_type() == STRING) { // less efficient version of named
set_named(*VariantGetInternalPtr<String>::get_ptr(&p_index), p_value, valid);
+ if (!valid && err_code) {
+ *err_code = VariantSetError::SET_NAMED_ERR;
+ }
} else if (p_index.get_type() == FLOAT) { // less efficient version of indexed
bool obb;
set_indexed(*VariantGetInternalPtr<double>::get_ptr(&p_index), p_value, valid, obb);
if (obb) {
valid = false;
+ if (err_code) {
+ *err_code = VariantSetError::SET_INDEXED_ERR;
+ }
}
}
if (r_valid) {
@@ -1198,31 +1221,49 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
}
}
-Variant Variant::get(const Variant &p_index, bool *r_valid) const {
+Variant Variant::get(const Variant &p_index, bool *r_valid, VariantGetError *err_code) const {
+ if (err_code) {
+ *err_code = VariantGetError::GET_OK;
+ }
Variant ret;
if (type == DICTIONARY || type == OBJECT) {
bool valid;
ret = get_keyed(p_index, valid);
if (r_valid) {
*r_valid = valid;
+ if (!valid && err_code) {
+ *err_code = VariantGetError::GET_KEYED_ERR;
+ }
}
} else {
bool valid = false;
if (p_index.get_type() == STRING_NAME) {
ret = get_named(*VariantGetInternalPtr<StringName>::get_ptr(&p_index), valid);
+ if (!valid && err_code) {
+ *err_code = VariantGetError::GET_NAMED_ERR;
+ }
} else if (p_index.get_type() == INT) {
bool obb;
ret = get_indexed(*VariantGetInternalPtr<int64_t>::get_ptr(&p_index), valid, obb);
if (obb) {
valid = false;
+ if (err_code) {
+ *err_code = VariantGetError::GET_INDEXED_ERR;
+ }
}
} else if (p_index.get_type() == STRING) { // less efficient version of named
ret = get_named(*VariantGetInternalPtr<String>::get_ptr(&p_index), valid);
+ if (!valid && err_code) {
+ *err_code = VariantGetError::GET_NAMED_ERR;
+ }
} else if (p_index.get_type() == FLOAT) { // less efficient version of indexed
bool obb;
ret = get_indexed(*VariantGetInternalPtr<double>::get_ptr(&p_index), valid, obb);
if (obb) {
valid = false;
+ if (err_code) {
+ *err_code = VariantGetError::GET_INDEXED_ERR;
+ }
}
}
if (r_valid) {
diff --git a/core/variant/variant_utility.cpp b/core/variant/variant_utility.cpp
index cc48394b64..916ba7aa2f 100644
--- a/core/variant/variant_utility.cpp
+++ b/core/variant/variant_utility.cpp
@@ -109,7 +109,7 @@ int64_t VariantUtilityFunctions::posmod(int64_t b, int64_t r) {
return Math::posmod(b, r);
}
-Variant VariantUtilityFunctions::floor(Variant x, Callable::CallError &r_error) {
+Variant VariantUtilityFunctions::floor(const Variant &x, Callable::CallError &r_error) {
r_error.error = Callable::CallError::CALL_OK;
switch (x.get_type()) {
case Variant::INT: {
@@ -153,7 +153,7 @@ int64_t VariantUtilityFunctions::floori(double x) {
return int64_t(Math::floor(x));
}
-Variant VariantUtilityFunctions::ceil(Variant x, Callable::CallError &r_error) {
+Variant VariantUtilityFunctions::ceil(const Variant &x, Callable::CallError &r_error) {
r_error.error = Callable::CallError::CALL_OK;
switch (x.get_type()) {
case Variant::INT: {
@@ -197,7 +197,7 @@ int64_t VariantUtilityFunctions::ceili(double x) {
return int64_t(Math::ceil(x));
}
-Variant VariantUtilityFunctions::round(Variant x, Callable::CallError &r_error) {
+Variant VariantUtilityFunctions::round(const Variant &x, Callable::CallError &r_error) {
r_error.error = Callable::CallError::CALL_OK;
switch (x.get_type()) {
case Variant::INT: {
@@ -1235,7 +1235,7 @@ bool VariantUtilityFunctions::is_same(const Variant &p_a, const Variant &p_b) {
#define VCALL p_func(VariantCaster<P>::cast(*p_args[Is])...)
#endif
-template <class R, class... P, size_t... Is>
+template <typename R, typename... P, size_t... Is>
static _FORCE_INLINE_ void call_helperpr(R (*p_func)(P...), Variant *ret, const Variant **p_args, Callable::CallError &r_error, IndexSequence<Is...>) {
r_error.error = Callable::CallError::CALL_OK;
VCALLR;
@@ -1243,51 +1243,51 @@ static _FORCE_INLINE_ void call_helperpr(R (*p_func)(P...), Variant *ret, const
(void)r_error;
}
-template <class R, class... P, size_t... Is>
+template <typename R, typename... P, size_t... Is>
static _FORCE_INLINE_ void validated_call_helperpr(R (*p_func)(P...), Variant *ret, const Variant **p_args, IndexSequence<Is...>) {
*ret = p_func(VariantCaster<P>::cast(*p_args[Is])...);
(void)p_args;
}
-template <class R, class... P, size_t... Is>
+template <typename R, typename... P, size_t... Is>
static _FORCE_INLINE_ void ptr_call_helperpr(R (*p_func)(P...), void *ret, const void **p_args, IndexSequence<Is...>) {
PtrToArg<R>::encode(p_func(PtrToArg<P>::convert(p_args[Is])...), ret);
(void)p_args;
}
-template <class R, class... P>
+template <typename R, typename... P>
static _FORCE_INLINE_ void call_helperr(R (*p_func)(P...), Variant *ret, const Variant **p_args, Callable::CallError &r_error) {
call_helperpr(p_func, ret, p_args, r_error, BuildIndexSequence<sizeof...(P)>{});
}
-template <class R, class... P>
+template <typename R, typename... P>
static _FORCE_INLINE_ void validated_call_helperr(R (*p_func)(P...), Variant *ret, const Variant **p_args) {
validated_call_helperpr(p_func, ret, p_args, BuildIndexSequence<sizeof...(P)>{});
}
-template <class R, class... P>
+template <typename R, typename... P>
static _FORCE_INLINE_ void ptr_call_helperr(R (*p_func)(P...), void *ret, const void **p_args) {
ptr_call_helperpr(p_func, ret, p_args, BuildIndexSequence<sizeof...(P)>{});
}
-template <class R, class... P>
+template <typename R, typename... P>
static _FORCE_INLINE_ int get_arg_count_helperr(R (*p_func)(P...)) {
return sizeof...(P);
}
-template <class R, class... P>
+template <typename R, typename... P>
static _FORCE_INLINE_ Variant::Type get_arg_type_helperr(R (*p_func)(P...), int p_arg) {
return call_get_argument_type<P...>(p_arg);
}
-template <class R, class... P>
+template <typename R, typename... P>
static _FORCE_INLINE_ Variant::Type get_ret_type_helperr(R (*p_func)(P...)) {
return GetTypeInfo<R>::VARIANT_TYPE;
}
// WITHOUT RET
-template <class... P, size_t... Is>
+template <typename... P, size_t... Is>
static _FORCE_INLINE_ void call_helperp(void (*p_func)(P...), const Variant **p_args, Callable::CallError &r_error, IndexSequence<Is...>) {
r_error.error = Callable::CallError::CALL_OK;
VCALL;
@@ -1295,44 +1295,44 @@ static _FORCE_INLINE_ void call_helperp(void (*p_func)(P...), const Variant **p_
(void)r_error;
}
-template <class... P, size_t... Is>
+template <typename... P, size_t... Is>
static _FORCE_INLINE_ void validated_call_helperp(void (*p_func)(P...), const Variant **p_args, IndexSequence<Is...>) {
p_func(VariantCaster<P>::cast(*p_args[Is])...);
(void)p_args;
}
-template <class... P, size_t... Is>
+template <typename... P, size_t... Is>
static _FORCE_INLINE_ void ptr_call_helperp(void (*p_func)(P...), const void **p_args, IndexSequence<Is...>) {
p_func(PtrToArg<P>::convert(p_args[Is])...);
(void)p_args;
}
-template <class... P>
+template <typename... P>
static _FORCE_INLINE_ void call_helper(void (*p_func)(P...), const Variant **p_args, Callable::CallError &r_error) {
call_helperp(p_func, p_args, r_error, BuildIndexSequence<sizeof...(P)>{});
}
-template <class... P>
+template <typename... P>
static _FORCE_INLINE_ void validated_call_helper(void (*p_func)(P...), const Variant **p_args) {
validated_call_helperp(p_func, p_args, BuildIndexSequence<sizeof...(P)>{});
}
-template <class... P>
+template <typename... P>
static _FORCE_INLINE_ void ptr_call_helper(void (*p_func)(P...), const void **p_args) {
ptr_call_helperp(p_func, p_args, BuildIndexSequence<sizeof...(P)>{});
}
-template <class... P>
+template <typename... P>
static _FORCE_INLINE_ int get_arg_count_helper(void (*p_func)(P...)) {
return sizeof...(P);
}
-template <class... P>
+template <typename... P>
static _FORCE_INLINE_ Variant::Type get_arg_type_helper(void (*p_func)(P...), int p_arg) {
return call_get_argument_type<P...>(p_arg);
}
-template <class... P>
+template <typename... P>
static _FORCE_INLINE_ Variant::Type get_ret_type_helper(void (*p_func)(P...)) {
return Variant::NIL;
}
@@ -1645,7 +1645,7 @@ struct VariantUtilityFunctionInfo {
static OAHashMap<StringName, VariantUtilityFunctionInfo> utility_function_table;
static List<StringName> utility_function_name_table;
-template <class T>
+template <typename T>
static void register_utility_function(const String &p_name, const Vector<String> &argnames) {
String name = p_name;
if (name.begins_with("_")) {
diff --git a/core/variant/variant_utility.h b/core/variant/variant_utility.h
index a56c84a8e9..75cde4942b 100644
--- a/core/variant/variant_utility.h
+++ b/core/variant/variant_utility.h
@@ -52,13 +52,13 @@ struct VariantUtilityFunctions {
static double fmod(double b, double r);
static double fposmod(double b, double r);
static int64_t posmod(int64_t b, int64_t r);
- static Variant floor(Variant x, Callable::CallError &r_error);
+ static Variant floor(const Variant &x, Callable::CallError &r_error);
static double floorf(double x);
static int64_t floori(double x);
- static Variant ceil(Variant x, Callable::CallError &r_error);
+ static Variant ceil(const Variant &x, Callable::CallError &r_error);
static double ceilf(double x);
static int64_t ceili(double x);
- static Variant round(Variant x, Callable::CallError &r_error);
+ static Variant round(const Variant &x, Callable::CallError &r_error);
static double roundf(double x);
static int64_t roundi(double x);
static Variant abs(const Variant &x, Callable::CallError &r_error);