diff options
35 files changed, 1376 insertions, 577 deletions
diff --git a/core/math/expression.cpp b/core/math/expression.cpp index 426586fc9c..48ad73bd32 100644 --- a/core/math/expression.cpp +++ b/core/math/expression.cpp @@ -564,7 +564,7 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant return; } else { - *r_return = Variant::construct(Variant::Type(type), p_inputs, 1, r_error); + Variant::construct(Variant::Type(type), *r_return, p_inputs, 1, r_error); } } break; case TYPE_OF: { @@ -2021,7 +2021,7 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression: } Callable::CallError ce; - r_ret = Variant::construct(constructor->data_type, (const Variant **)argp.ptr(), argp.size(), ce); + Variant::construct(constructor->data_type, r_ret, (const Variant **)argp.ptr(), argp.size(), ce); if (ce.error != Callable::CallError::CALL_OK) { r_error_str = vformat(RTR("Invalid arguments to construct '%s'"), Variant::get_type_name(constructor->data_type)); diff --git a/core/math/transform_2d.h b/core/math/transform_2d.h index 46e97abaa7..342623939e 100644 --- a/core/math/transform_2d.h +++ b/core/math/transform_2d.h @@ -128,6 +128,12 @@ struct Transform2D { elements[2][1] = oy; } + Transform2D(const Vector2 &p_x, const Vector2 &p_y, const Vector2 &p_origin) { + elements[0] = p_x; + elements[1] = p_y; + elements[2] = p_origin; + } + Transform2D(real_t p_rot, const Vector2 &p_pos); Transform2D() { elements[0][0] = 1.0; diff --git a/core/object/object.cpp b/core/object/object.cpp index ffec2ae867..c3f49856ca 100644 --- a/core/object/object.cpp +++ b/core/object/object.cpp @@ -1690,7 +1690,8 @@ Variant::Type Object::get_static_property_type_indexed(const Vector<StringName> } Callable::CallError ce; - Variant check = Variant::construct(t, nullptr, 0, ce); + Variant check; + Variant::construct(t, check, nullptr, 0, ce); for (int i = 1; i < p_path.size(); i++) { if (check.get_type() == Variant::OBJECT || check.get_type() == Variant::DICTIONARY || check.get_type() == Variant::ARRAY) { diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp index c56de8ef93..6bbdad11f8 100644 --- a/core/register_core_types.cpp +++ b/core/register_core_types.cpp @@ -96,12 +96,6 @@ extern Mutex _global_mutex; extern void register_global_constants(); extern void unregister_global_constants(); -extern void register_variant_methods(); -extern void unregister_variant_methods(); -extern void register_variant_operators(); -extern void unregister_variant_operators(); -extern void register_variant_setters_getters(); -extern void unregister_variant_setters_getters(); void register_core_types() { //consistency check @@ -114,9 +108,8 @@ void register_core_types() { ResourceLoader::initialize(); register_global_constants(); - register_variant_methods(); - register_variant_operators(); - register_variant_setters_getters(); + + Variant::register_types(); CoreStringNames::create(); @@ -323,9 +316,8 @@ void unregister_core_types() { ClassDB::cleanup_defaults(); ObjectDB::cleanup(); - unregister_variant_setters_getters(); - unregister_variant_operators(); - unregister_variant_methods(); + Variant::unregister_types(); + unregister_global_constants(); ClassDB::cleanup(); diff --git a/core/variant/array.cpp b/core/variant/array.cpp index 64e31189de..04ee47efff 100644 --- a/core/variant/array.cpp +++ b/core/variant/array.cpp @@ -165,7 +165,7 @@ void Array::_assign(const Array &p_array) { } else if (Variant::can_convert_strict(src_val.get_type(), _p->typed.type)) { Variant *ptr = &src_val; Callable::CallError ce; - new_array.write[i] = Variant::construct(_p->typed.type, (const Variant **)&ptr, 1, ce, true); + Variant::construct(_p->typed.type, new_array.write[i], (const Variant **)&ptr, 1, ce); if (ce.error != Callable::CallError::CALL_OK) { ERR_FAIL_MSG("Unable to convert array index " + itos(i) + " from '" + Variant::get_type_name(src_val.get_type()) + "' to '" + Variant::get_type_name(_p->typed.type) + "'."); } diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp index 126420bd02..73916bbef9 100644 --- a/core/variant/variant.cpp +++ b/core/variant/variant.cpp @@ -1266,7 +1266,7 @@ void Variant::zero() { } } -void Variant::clear() { +void Variant::_clear_internal() { switch (type) { case STRING: { reinterpret_cast<String *>(_data._mem)->~String(); @@ -1358,8 +1358,6 @@ void Variant::clear() { default: { } /* not needed */ } - - type = NIL; } Variant::operator signed int() const { @@ -3519,3 +3517,16 @@ String vformat(const String &p_text, const Variant &p1, const Variant &p2, const return fmt; } + +void Variant::register_types() { + _register_variant_operators(); + _register_variant_methods(); + _register_variant_setters_getters(); + _register_variant_constructors(); +} +void Variant::unregister_types() { + _unregister_variant_operators(); + _unregister_variant_methods(); + _unregister_variant_setters_getters(); + _unregister_variant_constructors(); +} diff --git a/core/variant/variant.h b/core/variant/variant.h index c264bbcd48..55927ff211 100644 --- a/core/variant/variant.h +++ b/core/variant/variant.h @@ -207,7 +207,66 @@ private: } _data alignas(8); void reference(const Variant &p_variant); - void clear(); + + void _clear_internal(); + + _FORCE_INLINE_ void clear() { + static const bool needs_deinit[Variant::VARIANT_MAX] = { + false, //NIL, + false, //BOOL, + false, //INT, + false, //FLOAT, + true, //STRING, + false, //VECTOR2, + false, //VECTOR2I, + false, //RECT2, + false, //RECT2I, + false, //VECTOR3, + false, //VECTOR3I, + true, //TRANSFORM2D, + false, //PLANE, + false, //QUAT, + true, //AABB, + true, //BASIS, + true, //TRANSFORM, + + // misc types + false, //COLOR, + true, //STRING_NAME, + true, //NODE_PATH, + false, //_RID, + true, //OBJECT, + true, //CALLABLE, + true, //SIGNAL, + true, //DICTIONARY, + true, //ARRAY, + + // typed arrays + true, //PACKED_BYTE_ARRAY, + true, //PACKED_INT32_ARRAY, + true, //PACKED_INT64_ARRAY, + true, //PACKED_FLOAT32_ARRAY, + true, //PACKED_FLOAT64_ARRAY, + true, //PACKED_STRING_ARRAY, + true, //PACKED_VECTOR2_ARRAY, + true, //PACKED_VECTOR3_ARRAY, + true, //PACKED_COLOR_ARRAY, + }; + + if (unlikely(needs_deinit[type])) { //make it fast for types that dont need deinit + _clear_internal(); + } + type = NIL; + } + + static void _register_variant_operators(); + static void _unregister_variant_operators(); + static void _register_variant_methods(); + static void _unregister_variant_methods(); + static void _register_variant_setters_getters(); + static void _unregister_variant_setters_getters(); + static void _register_variant_constructors(); + static void _unregister_variant_constructors(); public: _FORCE_INLINE_ Type get_type() const { @@ -467,7 +526,19 @@ public: static String get_call_error_text(Object *p_base, const StringName &p_method, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce); static String get_callable_error_text(const Callable &p_callable, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce); - static Variant construct(const Variant::Type, const Variant **p_args, int p_argcount, Callable::CallError &r_error, bool p_strict = true); + // constructor + typedef void (*ValidatedConstructor)(Variant &r_base, const Variant **p_args); + typedef void (*PTRConstructor)(void *base, const void **p_args); + + static int get_constructor_count(Variant::Type p_type); + static ValidatedConstructor get_validated_constructor(Variant::Type p_type, int p_constructor); + static PTRConstructor get_ptr_constructor(Variant::Type p_type, int p_constructor); + static int get_constructor_argument_count(Variant::Type p_type, int p_constructor); + static Variant::Type get_constructor_argument_type(Variant::Type p_type, int p_constructor, int p_argument); + static String get_constructor_argument_name(Variant::Type p_type, int p_constructor, int p_argument); + static void construct(Variant::Type, Variant &base, const Variant **p_args, int p_argcount, Callable::CallError &r_error); + + static void get_constructor_list(Type p_type, List<MethodInfo> *r_list); //convenience void get_method_list(List<MethodInfo> *p_list) const; bool has_method(const StringName &p_method) const; @@ -560,7 +631,6 @@ public: String stringify(List<const void *> &stack) const; void static_assign(const Variant &p_variant); - static void get_constructor_list(Variant::Type p_type, List<MethodInfo> *p_list); static void get_constants_for_type(Variant::Type p_type, List<StringName> *p_constants); static bool has_constant(Variant::Type p_type, const StringName &p_value); static Variant get_constant_value(Variant::Type p_type, const StringName &p_value, bool *r_valid = nullptr); @@ -573,12 +643,13 @@ public: void operator=(const Variant &p_variant); // only this is enough for all the other types + static void register_types(); + static void unregister_types(); + Variant(const Variant &p_variant); _FORCE_INLINE_ Variant() {} _FORCE_INLINE_ ~Variant() { - if (type != Variant::NIL) { - clear(); - } + clear(); } }; diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp index 37424f5ff9..5b9d9e9e8d 100644 --- a/core/variant/variant_call.cpp +++ b/core/variant/variant_call.cpp @@ -61,6 +61,27 @@ _FORCE_INLINE_ Vector<String> sarray(P... p_args) { 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 T> +struct TypeAdjust { + _FORCE_INLINE_ static void adjust(Variant *r_ret) { + VariantTypeChanger<typename GetSimpleTypeT<T>::type_t>::change(r_ret); + } +}; + +template <> //do nothing for variant +struct TypeAdjust<Variant> { + _FORCE_INLINE_ static void adjust(Variant *r_ret) { + } +}; + +template <> //do nothing for variant +struct TypeAdjust<Object *> { + _FORCE_INLINE_ static void adjust(Variant *r_ret) { + VariantInternal::clear(r_ret); + *r_ret = (Object *)nullptr; + } +}; + struct _VariantCall { template <class T, class... P> class InternalMethod : public Variant::InternalMethod { @@ -166,6 +187,7 @@ struct _VariantCall { } virtual void validated_call(Variant *base, const Variant **p_args, Variant *r_ret) { + TypeAdjust<R>::adjust(r_ret); call_with_validated_variant_args_ret(base, method, p_args, r_ret); } #ifdef PTRCALL_ENABLED @@ -231,6 +253,7 @@ struct _VariantCall { } virtual void validated_call(Variant *base, const Variant **p_args, Variant *r_ret) { + TypeAdjust<R>::adjust(r_ret); call_with_validated_variant_args_retc(base, method, p_args, r_ret); } #ifdef PTRCALL_ENABLED @@ -333,6 +356,7 @@ struct _VariantCall { } virtual void validated_call(Variant *base, const Variant **p_args, Variant *r_ret) { + TypeAdjust<R>::adjust(r_ret); call_with_validated_variant_args_static_retc(base, method, p_args, r_ret); } #ifdef PTRCALL_ENABLED @@ -670,190 +694,6 @@ struct _VariantCall { signal->emit(p_args, p_argcount); } - struct ConstructData { - int arg_count; - Vector<Variant::Type> arg_types; - Vector<String> arg_names; - VariantConstructFunc func; - }; - - struct ConstructFunc { - List<ConstructData> constructors; - }; - - static ConstructFunc *construct_funcs; - - static void Vector2_init1(Variant &r_ret, const Variant **p_args) { - r_ret = Vector2(*p_args[0], *p_args[1]); - } - - static void Vector2i_init1(Variant &r_ret, const Variant **p_args) { - r_ret = Vector2i(*p_args[0], *p_args[1]); - } - - static void Rect2_init1(Variant &r_ret, const Variant **p_args) { - r_ret = Rect2(*p_args[0], *p_args[1]); - } - - static void Rect2_init2(Variant &r_ret, const Variant **p_args) { - r_ret = Rect2(*p_args[0], *p_args[1], *p_args[2], *p_args[3]); - } - - static void Rect2i_init1(Variant &r_ret, const Variant **p_args) { - r_ret = Rect2i(*p_args[0], *p_args[1]); - } - - static void Rect2i_init2(Variant &r_ret, const Variant **p_args) { - r_ret = Rect2i(*p_args[0], *p_args[1], *p_args[2], *p_args[3]); - } - - static void Transform2D_init2(Variant &r_ret, const Variant **p_args) { - Transform2D m(*p_args[0], *p_args[1]); - r_ret = m; - } - - static void Transform2D_init3(Variant &r_ret, const Variant **p_args) { - Transform2D m; - m[0] = *p_args[0]; - m[1] = *p_args[1]; - m[2] = *p_args[2]; - r_ret = m; - } - - static void Vector3_init1(Variant &r_ret, const Variant **p_args) { - r_ret = Vector3(*p_args[0], *p_args[1], *p_args[2]); - } - - static void Vector3i_init1(Variant &r_ret, const Variant **p_args) { - r_ret = Vector3i(*p_args[0], *p_args[1], *p_args[2]); - } - - static void Plane_init1(Variant &r_ret, const Variant **p_args) { - r_ret = Plane(*p_args[0], *p_args[1], *p_args[2], *p_args[3]); - } - - static void Plane_init2(Variant &r_ret, const Variant **p_args) { - r_ret = Plane(*p_args[0], *p_args[1], *p_args[2]); - } - - static void Plane_init3(Variant &r_ret, const Variant **p_args) { - r_ret = Plane(p_args[0]->operator Vector3(), p_args[1]->operator real_t()); - } - static void Plane_init4(Variant &r_ret, const Variant **p_args) { - r_ret = Plane(p_args[0]->operator Vector3(), p_args[1]->operator Vector3()); - } - - static void Quat_init1(Variant &r_ret, const Variant **p_args) { - r_ret = Quat(*p_args[0], *p_args[1], *p_args[2], *p_args[3]); - } - - static void Quat_init2(Variant &r_ret, const Variant **p_args) { - r_ret = Quat(((Vector3)(*p_args[0])), ((real_t)(*p_args[1]))); - } - - static void Quat_init3(Variant &r_ret, const Variant **p_args) { - r_ret = Quat(((Vector3)(*p_args[0]))); - } - - static void Color_init1(Variant &r_ret, const Variant **p_args) { - r_ret = Color(*p_args[0], *p_args[1], *p_args[2], *p_args[3]); - } - - static void Color_init2(Variant &r_ret, const Variant **p_args) { - r_ret = Color(*p_args[0], *p_args[1], *p_args[2]); - } - - static void Color_init3(Variant &r_ret, const Variant **p_args) { - r_ret = Color::html(*p_args[0]); - } - - static void Color_init4(Variant &r_ret, const Variant **p_args) { - r_ret = Color::hex(*p_args[0]); - } - - static void Color_init5(Variant &r_ret, const Variant **p_args) { - r_ret = Color(((Color)(*p_args[0])), *p_args[1]); - } - - static void AABB_init1(Variant &r_ret, const Variant **p_args) { - r_ret = ::AABB(*p_args[0], *p_args[1]); - } - - static void Basis_init1(Variant &r_ret, const Variant **p_args) { - Basis m; - m.set_axis(0, *p_args[0]); - m.set_axis(1, *p_args[1]); - m.set_axis(2, *p_args[2]); - r_ret = m; - } - - static void Basis_init2(Variant &r_ret, const Variant **p_args) { - r_ret = Basis(p_args[0]->operator Vector3(), p_args[1]->operator real_t()); - } - - static void Transform_init1(Variant &r_ret, const Variant **p_args) { - Transform t; - t.basis.set_axis(0, *p_args[0]); - t.basis.set_axis(1, *p_args[1]); - t.basis.set_axis(2, *p_args[2]); - t.origin = *p_args[3]; - r_ret = t; - } - - static void Transform_init2(Variant &r_ret, const Variant **p_args) { - r_ret = Transform(p_args[0]->operator Basis(), p_args[1]->operator Vector3()); - } - - static void Callable_init2(Variant &r_ret, const Variant **p_args) { - r_ret = Callable(p_args[0]->operator ObjectID(), p_args[1]->operator String()); - } - - static void Signal_init2(Variant &r_ret, const Variant **p_args) { - r_ret = Signal(p_args[0]->operator ObjectID(), p_args[1]->operator String()); - } - - static void add_constructor(VariantConstructFunc p_func, const Variant::Type p_type, - const String &p_name1 = "", const Variant::Type p_type1 = Variant::NIL, - const String &p_name2 = "", const Variant::Type p_type2 = Variant::NIL, - const String &p_name3 = "", const Variant::Type p_type3 = Variant::NIL, - const String &p_name4 = "", const Variant::Type p_type4 = Variant::NIL) { - ConstructData cd; - cd.func = p_func; - cd.arg_count = 0; - - if (p_name1 == "") { - goto end; - } - cd.arg_count++; - cd.arg_names.push_back(p_name1); - cd.arg_types.push_back(p_type1); - - if (p_name2 == "") { - goto end; - } - cd.arg_count++; - cd.arg_names.push_back(p_name2); - cd.arg_types.push_back(p_type2); - - if (p_name3 == "") { - goto end; - } - cd.arg_count++; - cd.arg_names.push_back(p_name3); - cd.arg_types.push_back(p_type3); - - if (p_name4 == "") { - goto end; - } - cd.arg_count++; - cd.arg_names.push_back(p_name4); - cd.arg_types.push_back(p_type4); - - end: - - construct_funcs[p_type].constructors.push_back(cd); - } - struct ConstantData { Map<StringName, int> value; #ifdef DEBUG_ENABLED @@ -882,7 +722,6 @@ struct _VariantCall { } }; -_VariantCall::ConstructFunc *_VariantCall::construct_funcs = nullptr; _VariantCall::ConstantData *_VariantCall::constant_data = nullptr; _VariantCall::MethodMap *_VariantCall::type_internal_methods = nullptr; List<StringName> *_VariantCall::type_internal_method_names = nullptr; @@ -935,213 +774,6 @@ void Variant::call_ptr(const StringName &p_method, const Variant **p_args, int p #define VCALL(m_type, m_method) _VariantCall::_call_##m_type##_##m_method -Variant Variant::construct(const Variant::Type p_type, const Variant **p_args, int p_argcount, Callable::CallError &r_error, bool p_strict) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; - ERR_FAIL_INDEX_V(p_type, VARIANT_MAX, Variant()); - - r_error.error = Callable::CallError::CALL_OK; - if (p_argcount == 0) { //generic construct - - switch (p_type) { - case NIL: - return Variant(); - - // atomic types - case BOOL: - return Variant(false); - case INT: - return 0; - case FLOAT: - return 0.0f; - case STRING: - return String(); - - // math types - case VECTOR2: - return Vector2(); - case VECTOR2I: - return Vector2i(); - case RECT2: - return Rect2(); - case RECT2I: - return Rect2i(); - case VECTOR3: - return Vector3(); - case VECTOR3I: - return Vector3i(); - case TRANSFORM2D: - return Transform2D(); - case PLANE: - return Plane(); - case QUAT: - return Quat(); - case AABB: - return ::AABB(); - case BASIS: - return Basis(); - case TRANSFORM: - return Transform(); - - // misc types - case COLOR: - return Color(); - case STRING_NAME: - return StringName(); - case NODE_PATH: - return NodePath(); - case _RID: - return RID(); - case OBJECT: - return (Object *)nullptr; - case CALLABLE: - return Callable(); - case SIGNAL: - return Signal(); - case DICTIONARY: - return Dictionary(); - case ARRAY: - return Array(); - case PACKED_BYTE_ARRAY: - return PackedByteArray(); - case PACKED_INT32_ARRAY: - return PackedInt32Array(); - case PACKED_INT64_ARRAY: - return PackedInt64Array(); - case PACKED_FLOAT32_ARRAY: - return PackedFloat32Array(); - case PACKED_FLOAT64_ARRAY: - return PackedFloat64Array(); - case PACKED_STRING_ARRAY: - return PackedStringArray(); - case PACKED_VECTOR2_ARRAY: - return PackedVector2Array(); - case PACKED_VECTOR3_ARRAY: - return PackedVector3Array(); - case PACKED_COLOR_ARRAY: - return PackedColorArray(); - default: - return Variant(); - } - - } else if (p_argcount == 1 && p_args[0]->type == p_type) { - return *p_args[0]; //copy construct - } else if (p_argcount == 1 && (!p_strict || Variant::can_convert(p_args[0]->type, p_type))) { - //near match construct - - switch (p_type) { - case NIL: { - return Variant(); - } break; - case BOOL: { - return Variant(bool(*p_args[0])); - } - case INT: { - return (int64_t(*p_args[0])); - } - case FLOAT: { - return double(*p_args[0]); - } - case STRING: { - return String(*p_args[0]); - } - case VECTOR2: { - return Vector2(*p_args[0]); - } - case VECTOR2I: { - return Vector2i(*p_args[0]); - } - case RECT2: - return (Rect2(*p_args[0])); - case RECT2I: - return (Rect2i(*p_args[0])); - case VECTOR3: - return (Vector3(*p_args[0])); - case VECTOR3I: - return (Vector3i(*p_args[0])); - case TRANSFORM2D: - return (Transform2D(p_args[0]->operator Transform2D())); - case PLANE: - return (Plane(*p_args[0])); - case QUAT: - return (p_args[0]->operator Quat()); - case AABB: - return (::AABB(*p_args[0])); - case BASIS: - return (Basis(p_args[0]->operator Basis())); - case TRANSFORM: - return (Transform(p_args[0]->operator Transform())); - - // misc types - case COLOR: - return p_args[0]->type == Variant::STRING ? Color::html(*p_args[0]) : Color::hex(*p_args[0]); - case STRING_NAME: - return (StringName(p_args[0]->operator StringName())); - case NODE_PATH: - return (NodePath(p_args[0]->operator NodePath())); - case _RID: - return (RID(*p_args[0])); - case OBJECT: - return ((Object *)(p_args[0]->operator Object *())); - case CALLABLE: - return ((Callable)(p_args[0]->operator Callable())); - case SIGNAL: - return ((Signal)(p_args[0]->operator Signal())); - case DICTIONARY: - return p_args[0]->operator Dictionary(); - case ARRAY: - return p_args[0]->operator Array(); - - // arrays - case PACKED_BYTE_ARRAY: - return (PackedByteArray(*p_args[0])); - case PACKED_INT32_ARRAY: - return (PackedInt32Array(*p_args[0])); - case PACKED_INT64_ARRAY: - return (PackedInt64Array(*p_args[0])); - case PACKED_FLOAT32_ARRAY: - return (PackedFloat32Array(*p_args[0])); - case PACKED_FLOAT64_ARRAY: - return (PackedFloat64Array(*p_args[0])); - case PACKED_STRING_ARRAY: - return (PackedStringArray(*p_args[0])); - case PACKED_VECTOR2_ARRAY: - return (PackedVector2Array(*p_args[0])); - case PACKED_VECTOR3_ARRAY: - return (PackedVector3Array(*p_args[0])); - case PACKED_COLOR_ARRAY: - return (PackedColorArray(*p_args[0])); - default: - return Variant(); - } - } else if (p_argcount >= 1) { - _VariantCall::ConstructFunc &c = _VariantCall::construct_funcs[p_type]; - - for (List<_VariantCall::ConstructData>::Element *E = c.constructors.front(); E; E = E->next()) { - const _VariantCall::ConstructData &cd = E->get(); - - if (cd.arg_count != p_argcount) { - continue; - } - - //validate parameters - for (int i = 0; i < cd.arg_count; i++) { - if (!Variant::can_convert(p_args[i]->type, cd.arg_types[i])) { - r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; //no such constructor - r_error.argument = i; - r_error.expected = cd.arg_types[i]; - return Variant(); - } - } - - Variant v; - cd.func(v, p_args); - return v; - } - } - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; //no such constructor - return Variant(); -} - bool Variant::has_method(const StringName &p_method) const { if (type == OBJECT) { Object *obj = get_validated_object(); @@ -1246,43 +878,6 @@ void Variant::get_method_list(List<MethodInfo> *p_list) const { } } -void Variant::get_constructor_list(Variant::Type p_type, List<MethodInfo> *p_list) { - ERR_FAIL_INDEX(p_type, VARIANT_MAX); - - //custom constructors - for (const List<_VariantCall::ConstructData>::Element *E = _VariantCall::construct_funcs[p_type].constructors.front(); E; E = E->next()) { - const _VariantCall::ConstructData &cd = E->get(); - MethodInfo mi; - mi.name = Variant::get_type_name(p_type); - mi.return_val.type = p_type; - for (int i = 0; i < cd.arg_count; i++) { - PropertyInfo pi; - pi.name = cd.arg_names[i]; - pi.type = cd.arg_types[i]; - mi.arguments.push_back(pi); - } - p_list->push_back(mi); - } - //default constructors - for (int i = 0; i < VARIANT_MAX; i++) { - if (i == p_type) { - continue; - } - if (!Variant::can_convert(Variant::Type(i), p_type)) { - continue; - } - - MethodInfo mi; - mi.name = Variant::get_type_name(p_type); - PropertyInfo pi; - pi.name = "from"; - pi.type = Variant::Type(i); - mi.arguments.push_back(pi); - mi.return_val.type = p_type; - p_list->push_back(mi); - } -} - void Variant::get_constants_for_type(Variant::Type p_type, List<StringName> *p_constants) { ERR_FAIL_INDEX(p_type, Variant::VARIANT_MAX); @@ -1350,10 +945,9 @@ Variant::InternalMethod *Variant::get_internal_method(Type p_type, const StringN return nullptr; } -void register_variant_methods() { +void Variant::_register_variant_methods() { _VariantCall::type_internal_methods = memnew_arr(_VariantCall::MethodMap, Variant::VARIANT_MAX); _VariantCall::type_internal_method_names = memnew_arr(List<StringName>, Variant::VARIANT_MAX); - _VariantCall::construct_funcs = memnew_arr(_VariantCall::ConstructFunc, Variant::VARIANT_MAX); _VariantCall::constant_data = memnew_arr(_VariantCall::ConstantData, Variant::VARIANT_MAX); /* String */ @@ -1946,47 +1540,6 @@ void register_variant_methods() { bind_method(PackedColorArray, to_byte_array, sarray(), varray()); bind_method(PackedColorArray, sort, sarray(), varray()); - /* Register constructors */ - - _VariantCall::add_constructor(_VariantCall::Vector2_init1, Variant::VECTOR2, "x", Variant::FLOAT, "y", Variant::FLOAT); - _VariantCall::add_constructor(_VariantCall::Vector2i_init1, Variant::VECTOR2I, "x", Variant::INT, "y", Variant::INT); - - _VariantCall::add_constructor(_VariantCall::Rect2_init1, Variant::RECT2, "position", Variant::VECTOR2, "size", Variant::VECTOR2); - _VariantCall::add_constructor(_VariantCall::Rect2_init2, Variant::RECT2, "x", Variant::FLOAT, "y", Variant::FLOAT, "width", Variant::FLOAT, "height", Variant::FLOAT); - - _VariantCall::add_constructor(_VariantCall::Rect2i_init1, Variant::RECT2I, "position", Variant::VECTOR2I, "size", Variant::VECTOR2I); - _VariantCall::add_constructor(_VariantCall::Rect2i_init2, Variant::RECT2I, "x", Variant::INT, "y", Variant::INT, "width", Variant::INT, "height", Variant::INT); - - _VariantCall::add_constructor(_VariantCall::Transform2D_init2, Variant::TRANSFORM2D, "rotation", Variant::FLOAT, "position", Variant::VECTOR2); - _VariantCall::add_constructor(_VariantCall::Transform2D_init3, Variant::TRANSFORM2D, "x_axis", Variant::VECTOR2, "y_axis", Variant::VECTOR2, "origin", Variant::VECTOR2); - - _VariantCall::add_constructor(_VariantCall::Vector3_init1, Variant::VECTOR3, "x", Variant::FLOAT, "y", Variant::FLOAT, "z", Variant::FLOAT); - _VariantCall::add_constructor(_VariantCall::Vector3i_init1, Variant::VECTOR3I, "x", Variant::INT, "y", Variant::INT, "z", Variant::INT); - - _VariantCall::add_constructor(_VariantCall::Plane_init1, Variant::PLANE, "a", Variant::FLOAT, "b", Variant::FLOAT, "c", Variant::FLOAT, "d", Variant::FLOAT); - _VariantCall::add_constructor(_VariantCall::Plane_init2, Variant::PLANE, "v1", Variant::VECTOR3, "v2", Variant::VECTOR3, "v3", Variant::VECTOR3); - _VariantCall::add_constructor(_VariantCall::Plane_init3, Variant::PLANE, "normal", Variant::VECTOR3, "d", Variant::FLOAT); - - _VariantCall::add_constructor(_VariantCall::Quat_init1, Variant::QUAT, "x", Variant::FLOAT, "y", Variant::FLOAT, "z", Variant::FLOAT, "w", Variant::FLOAT); - _VariantCall::add_constructor(_VariantCall::Quat_init2, Variant::QUAT, "axis", Variant::VECTOR3, "angle", Variant::FLOAT); - _VariantCall::add_constructor(_VariantCall::Quat_init3, Variant::QUAT, "euler", Variant::VECTOR3); - - _VariantCall::add_constructor(_VariantCall::Color_init1, Variant::COLOR, "r", Variant::FLOAT, "g", Variant::FLOAT, "b", Variant::FLOAT, "a", Variant::FLOAT); - _VariantCall::add_constructor(_VariantCall::Color_init2, Variant::COLOR, "r", Variant::FLOAT, "g", Variant::FLOAT, "b", Variant::FLOAT); - // init3 and init4 are the constructors for HTML hex strings and integers respectively which don't need binding here, so we skip to init5. - _VariantCall::add_constructor(_VariantCall::Color_init5, Variant::COLOR, "c", Variant::COLOR, "a", Variant::FLOAT); - - _VariantCall::add_constructor(_VariantCall::AABB_init1, Variant::AABB, "position", Variant::VECTOR3, "size", Variant::VECTOR3); - - _VariantCall::add_constructor(_VariantCall::Basis_init1, Variant::BASIS, "x_axis", Variant::VECTOR3, "y_axis", Variant::VECTOR3, "z_axis", Variant::VECTOR3); - _VariantCall::add_constructor(_VariantCall::Basis_init2, Variant::BASIS, "axis", Variant::VECTOR3, "phi", Variant::FLOAT); - - _VariantCall::add_constructor(_VariantCall::Transform_init1, Variant::TRANSFORM, "x_axis", Variant::VECTOR3, "y_axis", Variant::VECTOR3, "z_axis", Variant::VECTOR3, "origin", Variant::VECTOR3); - _VariantCall::add_constructor(_VariantCall::Transform_init2, Variant::TRANSFORM, "basis", Variant::BASIS, "origin", Variant::VECTOR3); - - _VariantCall::add_constructor(_VariantCall::Callable_init2, Variant::CALLABLE, "object", Variant::OBJECT, "method_name", Variant::STRING_NAME); - _VariantCall::add_constructor(_VariantCall::Signal_init2, Variant::SIGNAL, "object", Variant::OBJECT, "signal_name", Variant::STRING_NAME); - /* Register constants */ int ncc = Color::get_named_color_count(); @@ -2071,7 +1624,7 @@ void register_variant_methods() { _VariantCall::add_variant_constant(Variant::QUAT, "IDENTITY", Quat(0, 0, 0, 1)); } -void unregister_variant_methods() { +void Variant::_unregister_variant_methods() { //clear methods for (int i = 0; i < Variant::VARIANT_MAX; i++) { for (List<StringName>::Element *E = _VariantCall::type_internal_method_names[i].front(); E; E = E->next()) { @@ -2084,6 +1637,5 @@ void unregister_variant_methods() { memdelete_arr(_VariantCall::type_internal_methods); memdelete_arr(_VariantCall::type_internal_method_names); - memdelete_arr(_VariantCall::construct_funcs); memdelete_arr(_VariantCall::constant_data); } diff --git a/core/variant/variant_construct.cpp b/core/variant/variant_construct.cpp new file mode 100644 index 0000000000..b847ba09b9 --- /dev/null +++ b/core/variant/variant_construct.cpp @@ -0,0 +1,781 @@ +/*************************************************************************/ +/* variant_construct.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* 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.h" + +#include "core/core_string_names.h" +#include "core/crypto/crypto_core.h" +#include "core/debugger/engine_debugger.h" +#include "core/io/compression.h" +#include "core/object/class_db.h" +#include "core/os/os.h" +#include "core/templates/local_vector.h" +#include "core/templates/oa_hash_map.h" + +_FORCE_INLINE_ void sarray_add_str(Vector<String> &arr) { +} + +_FORCE_INLINE_ void sarray_add_str(Vector<String> &arr, const String &p_str) { + arr.push_back(p_str); +} + +template <class... P> +_FORCE_INLINE_ void sarray_add_str(Vector<String> &arr, const String &p_str, P... p_args) { + arr.push_back(p_str); + sarray_add_str(arr, p_args...); +} + +template <class... P> +_FORCE_INLINE_ Vector<String> sarray(P... p_args) { + Vector<String> arr; + sarray_add_str(arr, p_args...); + return arr; +} + +template <class T, class... 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...>) { + r_error.error = Callable::CallError::CALL_OK; + +#ifdef DEBUG_METHODS_ENABLED + base = T(VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...); +#else + base = T(VariantCaster<P>::cast(*p_args[Is])...); +#endif + } + + template <size_t... Is> + static _FORCE_INLINE_ void validated_construct_helper(T &base, const Variant **p_args, IndexSequence<Is...>) { + base = T((*VariantGetInternalPtr<P>::get_ptr(p_args[Is]))...); + } + + template <size_t... Is> + static _FORCE_INLINE_ void ptr_construct_helper(void *base, const void **p_args, IndexSequence<Is...>) { + PtrToArg<T>::encode(T(PtrToArg<P>::convert(p_args[Is])...), base); + } + +public: + static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { + r_error.error = Callable::CallError::CALL_OK; + VariantTypeChanger<T>::change(&r_ret); + construct_helper(*VariantGetInternalPtr<T>::get_ptr(&r_ret), p_args, r_error, BuildIndexSequence<sizeof...(P)>{}); + } + + static void validated_construct(Variant &r_ret, const Variant **p_args) { + VariantTypeChanger<T>::change(&r_ret); + validated_construct_helper(*VariantGetInternalPtr<T>::get_ptr(&r_ret), p_args, BuildIndexSequence<sizeof...(P)>{}); + } + static void ptr_construct(void *base, const void **p_args) { + ptr_construct_helper(base, p_args, BuildIndexSequence<sizeof...(P)>{}); + } + + static int get_argument_count() { + return sizeof...(P); + } + + static Variant::Type get_argument_type(int p_arg) { + return call_get_argument_type<P...>(p_arg); + } + + static Variant::Type get_base_type() { + return GetTypeInfo<T>::VARIANT_TYPE; + } +}; + +class VariantConstructorObject { +public: + static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { + VariantInternal::clear(&r_ret); + if (p_args[0]->get_type() == Variant::NIL) { + VariantInternal::object_assign_null(&r_ret); + r_error.error = Callable::CallError::CALL_OK; + } else if (p_args[0]->get_type() == Variant::OBJECT) { + VariantInternal::object_assign(&r_ret, p_args[0]); + r_error.error = Callable::CallError::CALL_OK; + } else { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 0; + r_error.expected = Variant::OBJECT; + } + } + + static void validated_construct(Variant &r_ret, const Variant **p_args) { + VariantInternal::clear(&r_ret); + VariantInternal::object_assign(&r_ret, p_args[0]); + } + static void ptr_construct(void *base, const void **p_args) { + PtrToArg<Object *>::encode(PtrToArg<Object *>::convert(p_args[0]), base); + } + + static int get_argument_count() { + return 1; + } + + static Variant::Type get_argument_type(int p_arg) { + return Variant::OBJECT; + } + + static Variant::Type get_base_type() { + return Variant::OBJECT; + } +}; + +class VariantConstructorNilObject { +public: + static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { + if (p_args[0]->get_type() != Variant::NIL) { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 0; + r_error.expected = Variant::NIL; + } + + VariantInternal::clear(&r_ret); + VariantInternal::object_assign_null(&r_ret); + } + + static void validated_construct(Variant &r_ret, const Variant **p_args) { + VariantInternal::clear(&r_ret); + VariantInternal::object_assign_null(&r_ret); + } + static void ptr_construct(void *base, const void **p_args) { + PtrToArg<Object *>::encode(nullptr, base); + } + + static int get_argument_count() { + return 1; + } + + static Variant::Type get_argument_type(int p_arg) { + return Variant::NIL; + } + + static Variant::Type get_base_type() { + return Variant::OBJECT; + } +}; + +class VariantConstructorCallableArgs { +public: + static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { + ObjectID object_id; + StringName method; + + if (p_args[0]->get_type() == Variant::NIL) { + // leave as is + } else if (p_args[0]->get_type() == Variant::OBJECT) { + object_id = VariantInternal::get_object_id(p_args[0]); + } else { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 0; + r_error.expected = Variant::OBJECT; + return; + } + + if (p_args[1]->get_type() == Variant::STRING_NAME) { + method = *VariantGetInternalPtr<StringName>::get_ptr(p_args[1]); + } else if (p_args[1]->get_type() == Variant::STRING) { + method = *VariantGetInternalPtr<String>::get_ptr(p_args[1]); + } else { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 1; + r_error.expected = Variant::STRING_NAME; + return; + } + + VariantTypeChanger<Callable>::change(&r_ret); + *VariantGetInternalPtr<Callable>::get_ptr(&r_ret) = Callable(object_id, method); + } + + static void validated_construct(Variant &r_ret, const Variant **p_args) { + VariantTypeChanger<Callable>::change(&r_ret); + *VariantGetInternalPtr<Callable>::get_ptr(&r_ret) = Callable(VariantInternal::get_object_id(p_args[0]), *VariantGetInternalPtr<StringName>::get_ptr(p_args[1])); + } + static void ptr_construct(void *base, const void **p_args) { + PtrToArg<Callable>::encode(Callable(PtrToArg<Object *>::convert(p_args[0]), PtrToArg<StringName>::convert(p_args[1])), base); + } + + static int get_argument_count() { + return 2; + } + + static Variant::Type get_argument_type(int p_arg) { + if (p_arg == 0) { + return Variant::OBJECT; + } else { + return Variant::STRING_NAME; + } + } + + static Variant::Type get_base_type() { + return Variant::CALLABLE; + } +}; + +class VariantConstructorSignalArgs { +public: + static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { + ObjectID object_id; + StringName method; + + if (p_args[0]->get_type() == Variant::NIL) { + // leave as is + } else if (p_args[0]->get_type() == Variant::OBJECT) { + object_id = VariantInternal::get_object_id(p_args[0]); + } else { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 0; + r_error.expected = Variant::OBJECT; + return; + } + + if (p_args[1]->get_type() == Variant::STRING_NAME) { + method = *VariantGetInternalPtr<StringName>::get_ptr(p_args[1]); + } else if (p_args[1]->get_type() == Variant::STRING) { + method = *VariantGetInternalPtr<String>::get_ptr(p_args[1]); + } else { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 1; + r_error.expected = Variant::STRING_NAME; + return; + } + + VariantTypeChanger<Signal>::change(&r_ret); + *VariantGetInternalPtr<Signal>::get_ptr(&r_ret) = Signal(object_id, method); + } + + static void validated_construct(Variant &r_ret, const Variant **p_args) { + VariantTypeChanger<Signal>::change(&r_ret); + *VariantGetInternalPtr<Signal>::get_ptr(&r_ret) = Signal(VariantInternal::get_object_id(p_args[0]), *VariantGetInternalPtr<StringName>::get_ptr(p_args[1])); + } + static void ptr_construct(void *base, const void **p_args) { + PtrToArg<Signal>::encode(Signal(PtrToArg<Object *>::convert(p_args[0]), PtrToArg<StringName>::convert(p_args[1])), base); + } + + static int get_argument_count() { + return 2; + } + + static Variant::Type get_argument_type(int p_arg) { + if (p_arg == 0) { + return Variant::OBJECT; + } else { + return Variant::STRING_NAME; + } + } + + static Variant::Type get_base_type() { + return Variant::CALLABLE; + } +}; + +template <class T> +class VariantConstructorToArray { +public: + static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { + if (p_args[0]->get_type() != GetTypeInfo<T>::VARIANT_TYPE) { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 0; + r_error.expected = GetTypeInfo<T>::VARIANT_TYPE; + return; + } + + VariantTypeChanger<Array>::change(&r_ret); + Array &dst_arr = *VariantGetInternalPtr<Array>::get_ptr(&r_ret); + const T &src_arr = *VariantGetInternalPtr<T>::get_ptr(p_args[0]); + + int size = src_arr.size(); + dst_arr.resize(size); + for (int i = 0; i < size; i++) { + dst_arr[i] = src_arr[i]; + } + } + + static void validated_construct(Variant &r_ret, const Variant **p_args) { + VariantTypeChanger<Array>::change(&r_ret); + Array &dst_arr = *VariantGetInternalPtr<Array>::get_ptr(&r_ret); + const T &src_arr = *VariantGetInternalPtr<T>::get_ptr(p_args[0]); + + int size = src_arr.size(); + dst_arr.resize(size); + for (int i = 0; i < size; i++) { + dst_arr[i] = src_arr[i]; + } + } + static void ptr_construct(void *base, const void **p_args) { + Array dst_arr; + T src_arr = PtrToArg<T>::convert(p_args[0]); + + int size = src_arr.size(); + dst_arr.resize(size); + for (int i = 0; i < size; i++) { + dst_arr[i] = src_arr[i]; + } + + PtrToArg<Array>::encode(dst_arr, base); + } + + static int get_argument_count() { + return 1; + } + + static Variant::Type get_argument_type(int p_arg) { + return GetTypeInfo<T>::VARIANT_TYPE; + } + + static Variant::Type get_base_type() { + return Variant::ARRAY; + } +}; + +template <class T> +class VariantConstructorFromArray { +public: + static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { + if (p_args[0]->get_type() != Variant::ARRAY) { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 0; + r_error.expected = Variant::ARRAY; + return; + } + + VariantTypeChanger<T>::change(&r_ret); + const Array &src_arr = *VariantGetInternalPtr<Array>::get_ptr(p_args[0]); + T &dst_arr = *VariantGetInternalPtr<T>::get_ptr(&r_ret); + + int size = src_arr.size(); + dst_arr.resize(size); + for (int i = 0; i < size; i++) { + dst_arr.write[i] = src_arr[i]; + } + } + + static void validated_construct(Variant &r_ret, const Variant **p_args) { + VariantTypeChanger<T>::change(&r_ret); + const Array &src_arr = *VariantGetInternalPtr<Array>::get_ptr(p_args[0]); + T &dst_arr = *VariantGetInternalPtr<T>::get_ptr(&r_ret); + + int size = src_arr.size(); + dst_arr.resize(size); + for (int i = 0; i < size; i++) { + dst_arr.write[i] = src_arr[i]; + } + } + static void ptr_construct(void *base, const void **p_args) { + Array src_arr = PtrToArg<Array>::convert(p_args[0]); + T dst_arr; + + int size = src_arr.size(); + dst_arr.resize(size); + for (int i = 0; i < size; i++) { + dst_arr.write[i] = src_arr[i]; + } + + PtrToArg<T>::encode(dst_arr, base); + } + + static int get_argument_count() { + return 1; + } + + static Variant::Type get_argument_type(int p_arg) { + return Variant::ARRAY; + } + + static Variant::Type get_base_type() { + return GetTypeInfo<T>::VARIANT_TYPE; + } +}; + +class VariantConstructorNil { +public: + static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { + if (p_args[0]->get_type() != Variant::NIL) { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument = 0; + r_error.expected = Variant::NIL; + return; + } + + r_error.error = Callable::CallError::CALL_OK; + VariantInternal::clear(&r_ret); + } + + static void validated_construct(Variant &r_ret, const Variant **p_args) { + VariantInternal::clear(&r_ret); + } + static void ptr_construct(void *base, const void **p_args) { + PtrToArg<Variant>::encode(Variant(), base); + } + + static int get_argument_count() { + return 1; + } + + static Variant::Type get_argument_type(int p_arg) { + return Variant::NIL; + } + + static Variant::Type get_base_type() { + return Variant::NIL; + } +}; + +struct VariantConstructData { + void (*construct)(Variant &r_base, const Variant **p_args, Callable::CallError &r_error); + Variant::ValidatedConstructor validated_construct; + Variant::PTRConstructor ptr_construct; + Variant::Type (*get_argument_type)(int); + int argument_count; + Vector<String> arg_names; +}; + +static LocalVector<VariantConstructData> construct_data[Variant::VARIANT_MAX]; + +static void variant_initialize_nil(Variant *v) { + VariantInternal::clear(v); +} + +template <class T> +static void variant_initialize(Variant *v) { + VariantTypeChanger<T>::change(v); +} + +template <class T> +static void variant_initialize_zero(Variant *v) { + VariantTypeChanger<T>::change(v); + *VariantGetInternalPtr<T>::get_ptr(v) = 0; +} + +static void variant_initialize_false(Variant *v) { + VariantTypeChanger<bool>::change(v); + *VariantGetInternalPtr<bool>::get_ptr(v) = false; +} + +static void variant_initialize_obj(Variant *v) { + VariantInternal::clear(v); + VariantInternal::object_assign_null(v); +} + +typedef void (*VariantInitializeFunc)(Variant *v); + +static VariantInitializeFunc initialize_funcs[Variant::VARIANT_MAX]; + +template <class 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()) + "."); + + VariantConstructData cd; + cd.construct = T::construct; + cd.validated_construct = T::validated_construct; + cd.ptr_construct = T::ptr_construct; + cd.get_argument_type = T::get_argument_type; + cd.argument_count = T::get_argument_count(); + cd.arg_names = arg_names; + construct_data[T::get_base_type()].push_back(cd); +} + +void Variant::_register_variant_constructors() { + add_constructor<VariantConstructorNil>(sarray("from")); + + add_constructor<VariantConstructor<bool, bool>>(sarray("from")); + add_constructor<VariantConstructor<bool, int64_t>>(sarray("from")); + add_constructor<VariantConstructor<bool, double>>(sarray("from")); + + add_constructor<VariantConstructor<int64_t, int64_t>>(sarray("from")); + add_constructor<VariantConstructor<int64_t, double>>(sarray("from")); + + add_constructor<VariantConstructor<double, double>>(sarray("from")); + add_constructor<VariantConstructor<double, int64_t>>(sarray("from")); + + add_constructor<VariantConstructor<String, String>>(sarray("from")); + add_constructor<VariantConstructor<String, StringName>>(sarray("from")); + add_constructor<VariantConstructor<String, NodePath>>(sarray("from")); + + add_constructor<VariantConstructor<Vector2, Vector2>>(sarray("from")); + add_constructor<VariantConstructor<Vector2, Vector2i>>(sarray("from")); + add_constructor<VariantConstructor<Vector2, double, double>>(sarray("x", "y")); + + add_constructor<VariantConstructor<Vector2i, Vector2i>>(sarray("from")); + add_constructor<VariantConstructor<Vector2i, Vector2>>(sarray("from")); + add_constructor<VariantConstructor<Vector2i, int64_t, int64_t>>(sarray("x", "y")); + + add_constructor<VariantConstructor<Rect2, Rect2>>(sarray("from")); + add_constructor<VariantConstructor<Rect2, Rect2i>>(sarray("from")); + add_constructor<VariantConstructor<Rect2, Vector2, Vector2>>(sarray("position", "size")); + add_constructor<VariantConstructor<Rect2, double, double, double, double>>(sarray("x", "y", "width", "height")); + + add_constructor<VariantConstructor<Rect2i, Rect2i>>(sarray("from")); + add_constructor<VariantConstructor<Rect2i, Rect2>>(sarray("from")); + add_constructor<VariantConstructor<Rect2i, Vector2i, Vector2i>>(sarray("position", "size")); + add_constructor<VariantConstructor<Rect2i, int64_t, int64_t, int64_t, int64_t>>(sarray("x", "y", "width", "height")); + + add_constructor<VariantConstructor<Vector3, Vector3>>(sarray("from")); + add_constructor<VariantConstructor<Vector3, Vector3i>>(sarray("from")); + add_constructor<VariantConstructor<Vector3, double, double, double>>(sarray("x", "y", "z")); + + add_constructor<VariantConstructor<Vector3i, Vector3i>>(sarray("from")); + add_constructor<VariantConstructor<Vector3i, Vector3>>(sarray("from")); + add_constructor<VariantConstructor<Vector3i, int64_t, int64_t, int64_t>>(sarray("x", "y", "z")); + + add_constructor<VariantConstructor<Transform2D, Transform2D>>(sarray("from")); + add_constructor<VariantConstructor<Transform2D, Vector2, Vector2, Vector2>>(sarray("x", "y", "origin")); + + add_constructor<VariantConstructor<Plane, Plane>>(sarray("from")); + add_constructor<VariantConstructor<Plane, Vector3, double>>(sarray("normal", "d")); + add_constructor<VariantConstructor<Plane, Vector3, Vector3>>(sarray("point", "normal")); + add_constructor<VariantConstructor<Plane, Vector3, Vector3, Vector3>>(sarray("point1", "point2", "point3")); + + add_constructor<VariantConstructor<Quat, Quat>>(sarray("from")); + add_constructor<VariantConstructor<Quat, Basis>>(sarray("from")); + add_constructor<VariantConstructor<Quat, Vector3>>(sarray("euler")); + add_constructor<VariantConstructor<Quat, Vector3, double>>(sarray("axis", "angle")); + add_constructor<VariantConstructor<Quat, Vector3, Vector3>>(sarray("arc_from", "arc_to")); + + add_constructor<VariantConstructor<::AABB, ::AABB>>(sarray("from")); + add_constructor<VariantConstructor<::AABB, Vector3, Vector3>>(sarray("position", "size")); + + add_constructor<VariantConstructor<Basis, Basis>>(sarray("from")); + add_constructor<VariantConstructor<Basis, Quat>>(sarray("from")); + add_constructor<VariantConstructor<Basis, Vector3, Vector3, Vector3>>(sarray("x", "y", "z")); + + add_constructor<VariantConstructor<Transform, Transform>>(sarray("from")); + add_constructor<VariantConstructor<Transform, Basis, Vector3>>(sarray("basis", "origin")); + + add_constructor<VariantConstructor<Color, Color>>(sarray("from")); + + add_constructor<VariantConstructor<StringName, StringName>>(sarray("from")); + add_constructor<VariantConstructor<StringName, String>>(sarray("from")); + + add_constructor<VariantConstructor<NodePath, NodePath>>(sarray("from")); + add_constructor<VariantConstructor<NodePath, String>>(sarray("from")); + + add_constructor<VariantConstructor<RID, RID>>(sarray("from")); + + add_constructor<VariantConstructorObject>(sarray("from")); + add_constructor<VariantConstructorNilObject>(sarray("from")); + + add_constructor<VariantConstructor<Callable, Callable>>(sarray("from")); + add_constructor<VariantConstructorCallableArgs>(sarray("object", "method")); + + add_constructor<VariantConstructor<Signal, Signal>>(sarray("from")); + add_constructor<VariantConstructorSignalArgs>(sarray("object", "signal")); + + add_constructor<VariantConstructor<Dictionary, Dictionary>>(sarray("from")); + + add_constructor<VariantConstructor<Array, Array>>(sarray("from")); + add_constructor<VariantConstructorToArray<PackedByteArray>>(sarray("from")); + add_constructor<VariantConstructorToArray<PackedInt32Array>>(sarray("from")); + add_constructor<VariantConstructorToArray<PackedInt64Array>>(sarray("from")); + add_constructor<VariantConstructorToArray<PackedFloat64Array>>(sarray("from")); + add_constructor<VariantConstructorToArray<PackedFloat64Array>>(sarray("from")); + add_constructor<VariantConstructorToArray<PackedStringArray>>(sarray("from")); + add_constructor<VariantConstructorToArray<PackedVector2Array>>(sarray("from")); + add_constructor<VariantConstructorToArray<PackedVector3Array>>(sarray("from")); + add_constructor<VariantConstructorToArray<PackedColorArray>>(sarray("from")); + + add_constructor<VariantConstructor<PackedByteArray, PackedByteArray>>(sarray("from")); + add_constructor<VariantConstructorFromArray<PackedByteArray>>(sarray("from")); + + add_constructor<VariantConstructor<PackedInt32Array, PackedInt32Array>>(sarray("from")); + add_constructor<VariantConstructorFromArray<PackedInt32Array>>(sarray("from")); + + add_constructor<VariantConstructor<PackedInt64Array, PackedInt64Array>>(sarray("from")); + add_constructor<VariantConstructorFromArray<PackedInt64Array>>(sarray("from")); + + add_constructor<VariantConstructor<PackedFloat32Array, PackedFloat32Array>>(sarray("from")); + add_constructor<VariantConstructorFromArray<PackedFloat32Array>>(sarray("from")); + + add_constructor<VariantConstructor<PackedFloat64Array, PackedFloat64Array>>(sarray("from")); + add_constructor<VariantConstructorFromArray<PackedFloat64Array>>(sarray("from")); + + add_constructor<VariantConstructor<PackedStringArray, PackedStringArray>>(sarray("from")); + add_constructor<VariantConstructorFromArray<PackedStringArray>>(sarray("from")); + + add_constructor<VariantConstructor<PackedVector2Array, PackedVector2Array>>(sarray("from")); + add_constructor<VariantConstructorFromArray<PackedVector2Array>>(sarray("from")); + + add_constructor<VariantConstructor<PackedVector3Array, PackedVector3Array>>(sarray("from")); + add_constructor<VariantConstructorFromArray<PackedVector3Array>>(sarray("from")); + + add_constructor<VariantConstructor<PackedColorArray, PackedColorArray>>(sarray("from")); + add_constructor<VariantConstructorFromArray<PackedColorArray>>(sarray("from")); + + initialize_funcs[NIL] = variant_initialize_nil; + + // atomic types + initialize_funcs[BOOL] = variant_initialize_false; + initialize_funcs[INT] = variant_initialize_zero<int64_t>; + initialize_funcs[FLOAT] = variant_initialize_zero<double>; + initialize_funcs[STRING] = variant_initialize<String>; + + // math types + initialize_funcs[VECTOR2] = variant_initialize<Vector2>; + initialize_funcs[VECTOR2I] = variant_initialize<Vector2i>; + initialize_funcs[RECT2] = variant_initialize<Rect2>; + initialize_funcs[RECT2I] = variant_initialize<Rect2i>; + initialize_funcs[VECTOR3] = variant_initialize<Vector3>; + initialize_funcs[VECTOR3I] = variant_initialize<Vector3i>; + initialize_funcs[TRANSFORM2D] = variant_initialize<Transform2D>; + initialize_funcs[PLANE] = variant_initialize<Plane>; + initialize_funcs[QUAT] = variant_initialize<Quat>; + initialize_funcs[AABB] = variant_initialize<::AABB>; + initialize_funcs[BASIS] = variant_initialize<Basis>; + initialize_funcs[TRANSFORM] = variant_initialize<Transform>; + + // misc types + initialize_funcs[COLOR] = variant_initialize<Color>; + initialize_funcs[STRING_NAME] = variant_initialize<StringName>; + initialize_funcs[NODE_PATH] = variant_initialize<NodePath>; + initialize_funcs[_RID] = variant_initialize<RID>; + initialize_funcs[OBJECT] = variant_initialize_obj; + initialize_funcs[CALLABLE] = variant_initialize<Callable>; + initialize_funcs[SIGNAL] = variant_initialize<Signal>; + initialize_funcs[DICTIONARY] = variant_initialize<Dictionary>; + initialize_funcs[ARRAY] = variant_initialize<Array>; + + // typed arrays + initialize_funcs[PACKED_BYTE_ARRAY] = variant_initialize<PackedByteArray>; + initialize_funcs[PACKED_INT32_ARRAY] = variant_initialize<PackedInt32Array>; + initialize_funcs[PACKED_INT64_ARRAY] = variant_initialize<PackedInt64Array>; + initialize_funcs[PACKED_FLOAT32_ARRAY] = variant_initialize<PackedFloat32Array>; + initialize_funcs[PACKED_FLOAT64_ARRAY] = variant_initialize<PackedFloat64Array>; + initialize_funcs[PACKED_STRING_ARRAY] = variant_initialize<PackedStringArray>; + initialize_funcs[PACKED_VECTOR2_ARRAY] = variant_initialize<PackedVector2Array>; + initialize_funcs[PACKED_VECTOR3_ARRAY] = variant_initialize<PackedVector3Array>; + initialize_funcs[PACKED_COLOR_ARRAY] = variant_initialize<PackedColorArray>; +} + +void Variant::_unregister_variant_constructors() { + for (int i = 0; i < Variant::VARIANT_MAX; i++) { + construct_data[i].clear(); + } +} + +void Variant::construct(Variant::Type p_type, Variant &base, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { + if (p_argcount == 0) { + initialize_funcs[p_type](&base); + r_error.error = Callable::CallError::CALL_OK; + + } else { + uint32_t s = construct_data[p_type].size(); + for (uint32_t i = 0; i < s; i++) { + int argc = construct_data[p_type][i].argument_count; + if (argc != p_argcount) { + continue; + } + bool args_match = true; + for (int j = 0; j < argc; j++) { + if (!Variant::can_convert_strict(p_args[j]->get_type(), construct_data[p_type][i].get_argument_type(j))) { + args_match = false; + break; + } + } + + if (!args_match) { + continue; + } + + construct_data[p_type][i].construct(base, p_args, r_error); + return; + } + + r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; + } +} + +int Variant::get_constructor_count(Variant::Type p_type) { + ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, -1); + return construct_data[p_type].size(); +} + +Variant::ValidatedConstructor Variant::get_validated_constructor(Variant::Type p_type, int p_constructor) { + ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, nullptr); + ERR_FAIL_INDEX_V(p_constructor, (int)construct_data[p_type].size(), nullptr); + return construct_data[p_type][p_constructor].validated_construct; +} + +Variant::PTRConstructor Variant::get_ptr_constructor(Variant::Type p_type, int p_constructor) { + ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, nullptr); + ERR_FAIL_INDEX_V(p_constructor, (int)construct_data[p_type].size(), nullptr); + return construct_data[p_type][p_constructor].ptr_construct; +} + +int Variant::get_constructor_argument_count(Variant::Type p_type, int p_constructor) { + ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, -1); + ERR_FAIL_INDEX_V(p_constructor, (int)construct_data[p_type].size(), -1); + return construct_data[p_type][p_constructor].argument_count; +} + +Variant::Type Variant::get_constructor_argument_type(Variant::Type p_type, int p_constructor, int p_argument) { + ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, Variant::VARIANT_MAX); + ERR_FAIL_INDEX_V(p_constructor, (int)construct_data[p_type].size(), Variant::VARIANT_MAX); + return construct_data[p_type][p_constructor].get_argument_type(p_argument); +} + +String Variant::get_constructor_argument_name(Variant::Type p_type, int p_constructor, int p_argument) { + ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, String()); + ERR_FAIL_INDEX_V(p_constructor, (int)construct_data[p_type].size(), String()); + return construct_data[p_type][p_constructor].arg_names[p_argument]; +} + +void VariantInternal::object_assign(Variant *v, const Variant *o) { + if (o->_get_obj().obj && o->_get_obj().id.is_reference()) { + Reference *reference = static_cast<Reference *>(o->_get_obj().obj); + if (!reference->reference()) { + v->_get_obj().obj = nullptr; + v->_get_obj().id = ObjectID(); + return; + } + } + + v->_get_obj().obj = const_cast<Object *>(o->_get_obj().obj); + v->_get_obj().id = o->_get_obj().id; +} + +void Variant::get_constructor_list(Type p_type, List<MethodInfo> *r_list) { + ERR_FAIL_INDEX(p_type, Variant::VARIANT_MAX); + + MethodInfo mi; + mi.return_val.type = p_type; + mi.name = get_type_name(p_type); + + for (int i = 0; i < get_constructor_count(p_type); i++) { + int ac = get_constructor_argument_count(p_type, i); + mi.arguments.clear(); + for (int j = 0; j < ac; j++) { + PropertyInfo arg; + arg.name = get_constructor_argument_name(p_type, i, j); + arg.type = get_constructor_argument_type(p_type, i, j); + mi.arguments.push_back(arg); + } + r_list->push_back(mi); + } +} diff --git a/core/variant/variant_internal.h b/core/variant/variant_internal.h index 7893c6d382..7fd165aa81 100644 --- a/core/variant/variant_internal.h +++ b/core/variant/variant_internal.h @@ -116,6 +116,106 @@ public: _FORCE_INLINE_ static Object **get_object(Variant *v) { return (Object **)&v->_get_obj().obj; } _FORCE_INLINE_ static const Object **get_object(const Variant *v) { return (const Object **)&v->_get_obj().obj; } + + _FORCE_INLINE_ static const ObjectID get_object_id(const Variant *v) { return v->_get_obj().id; } + + template <class T> + _FORCE_INLINE_ static void init_generic(Variant *v) { + v->type = GetTypeInfo<T>::VARIANT_TYPE; + } + + _FORCE_INLINE_ static void init_string(Variant *v) { + memnew_placement(v->_data._mem, String); + v->type = Variant::STRING; + } + + _FORCE_INLINE_ static void init_transform2d(Variant *v) { + v->_data._transform2d = memnew(Transform2D); + v->type = Variant::TRANSFORM2D; + } + _FORCE_INLINE_ static void init_aabb(Variant *v) { + v->_data._aabb = memnew(AABB); + v->type = Variant::AABB; + } + _FORCE_INLINE_ static void init_basis(Variant *v) { + v->_data._basis = memnew(Basis); + v->type = Variant::BASIS; + } + _FORCE_INLINE_ static void init_transform(Variant *v) { + v->_data._transform = memnew(Transform); + v->type = Variant::TRANSFORM; + } + _FORCE_INLINE_ static void init_string_name(Variant *v) { + memnew_placement(v->_data._mem, StringName); + v->type = Variant::STRING_NAME; + } + _FORCE_INLINE_ static void init_node_path(Variant *v) { + memnew_placement(v->_data._mem, NodePath); + v->type = Variant::NODE_PATH; + } + _FORCE_INLINE_ static void init_callable(Variant *v) { + memnew_placement(v->_data._mem, Callable); + v->type = Variant::CALLABLE; + } + _FORCE_INLINE_ static void init_signal(Variant *v) { + memnew_placement(v->_data._mem, Signal); + v->type = Variant::SIGNAL; + } + _FORCE_INLINE_ static void init_dictionary(Variant *v) { + memnew_placement(v->_data._mem, Dictionary); + v->type = Variant::DICTIONARY; + } + _FORCE_INLINE_ static void init_array(Variant *v) { + memnew_placement(v->_data._mem, Array); + v->type = Variant::ARRAY; + } + _FORCE_INLINE_ static void init_byte_array(Variant *v) { + v->_data.packed_array = Variant::PackedArrayRef<uint8_t>::create(Vector<uint8_t>()); + v->type = Variant::PACKED_BYTE_ARRAY; + } + _FORCE_INLINE_ static void init_int32_array(Variant *v) { + v->_data.packed_array = Variant::PackedArrayRef<int32_t>::create(Vector<int32_t>()); + v->type = Variant::PACKED_INT32_ARRAY; + } + _FORCE_INLINE_ static void init_int64_array(Variant *v) { + v->_data.packed_array = Variant::PackedArrayRef<int64_t>::create(Vector<int64_t>()); + v->type = Variant::PACKED_INT64_ARRAY; + } + _FORCE_INLINE_ static void init_float32_array(Variant *v) { + v->_data.packed_array = Variant::PackedArrayRef<float>::create(Vector<float>()); + v->type = Variant::PACKED_FLOAT32_ARRAY; + } + _FORCE_INLINE_ static void init_float64_array(Variant *v) { + v->_data.packed_array = Variant::PackedArrayRef<double>::create(Vector<double>()); + v->type = Variant::PACKED_FLOAT64_ARRAY; + } + _FORCE_INLINE_ static void init_string_array(Variant *v) { + v->_data.packed_array = Variant::PackedArrayRef<String>::create(Vector<String>()); + v->type = Variant::PACKED_STRING_ARRAY; + } + _FORCE_INLINE_ static void init_vector2_array(Variant *v) { + v->_data.packed_array = Variant::PackedArrayRef<Vector2>::create(Vector<Vector2>()); + v->type = Variant::PACKED_VECTOR2_ARRAY; + } + _FORCE_INLINE_ static void init_vector3_array(Variant *v) { + v->_data.packed_array = Variant::PackedArrayRef<Vector3>::create(Vector<Vector3>()); + v->type = Variant::PACKED_VECTOR3_ARRAY; + } + _FORCE_INLINE_ static void init_color_array(Variant *v) { + v->_data.packed_array = Variant::PackedArrayRef<Color>::create(Vector<Color>()); + v->type = Variant::PACKED_COLOR_ARRAY; + } + + _FORCE_INLINE_ static void clear(Variant *v) { + v->clear(); + } + + static void object_assign(Variant *v, const Variant *o); //needs to use reference, do away + + _FORCE_INLINE_ static void object_assign_null(Variant *v) { + v->_get_obj().obj = nullptr; + v->_get_obj().id = ObjectID(); + } }; template <class T> @@ -649,4 +749,201 @@ struct VariantInternalAccessor<Vector<Variant>> { } }; +template <class T> +struct VariantInitializer { +}; + +template <> +struct VariantInitializer<bool> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<bool>(v); } +}; + +#define INITIALIZER_INT(m_type) \ + template <> \ + struct VariantInitializer<m_type> { \ + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<int64_t>(v); } \ + }; + +INITIALIZER_INT(uint8_t) +INITIALIZER_INT(int8_t) +INITIALIZER_INT(uint16_t) +INITIALIZER_INT(int16_t) +INITIALIZER_INT(uint32_t) +INITIALIZER_INT(int32_t) +INITIALIZER_INT(uint64_t) +INITIALIZER_INT(int64_t) +INITIALIZER_INT(char32_t) +INITIALIZER_INT(Error) +INITIALIZER_INT(ObjectID) + +template <> +struct VariantInitializer<double> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<double>(v); } +}; + +template <> +struct VariantInitializer<float> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<double>(v); } +}; + +template <> +struct VariantInitializer<String> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_string(v); } +}; + +template <> +struct VariantInitializer<Vector2> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<Vector2>(v); } +}; + +template <> +struct VariantInitializer<Vector2i> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<Vector2i>(v); } +}; + +template <> +struct VariantInitializer<Rect2> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<Rect2>(v); } +}; + +template <> +struct VariantInitializer<Rect2i> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<Rect2i>(v); } +}; + +template <> +struct VariantInitializer<Vector3> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<Vector3>(v); } +}; + +template <> +struct VariantInitializer<Vector3i> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<Vector3i>(v); } +}; + +template <> +struct VariantInitializer<Transform2D> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_transform2d(v); } +}; + +template <> +struct VariantInitializer<Plane> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<Plane>(v); } +}; + +template <> +struct VariantInitializer<Quat> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<Quat>(v); } +}; + +template <> +struct VariantInitializer<AABB> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_aabb(v); } +}; + +template <> +struct VariantInitializer<Basis> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_basis(v); } +}; + +template <> +struct VariantInitializer<Transform> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_transform(v); } +}; + +template <> +struct VariantInitializer<Color> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<Color>(v); } +}; + +template <> +struct VariantInitializer<StringName> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_string_name(v); } +}; + +template <> +struct VariantInitializer<NodePath> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_node_path(v); } +}; + +template <> +struct VariantInitializer<RID> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<RID>(v); } +}; + +template <> +struct VariantInitializer<Callable> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_callable(v); } +}; + +template <> +struct VariantInitializer<Signal> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_signal(v); } +}; + +template <> +struct VariantInitializer<Dictionary> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_dictionary(v); } +}; + +template <> +struct VariantInitializer<Array> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_array(v); } +}; + +template <> +struct VariantInitializer<PackedByteArray> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_byte_array(v); } +}; + +template <> +struct VariantInitializer<PackedInt32Array> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_int32_array(v); } +}; + +template <> +struct VariantInitializer<PackedInt64Array> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_int64_array(v); } +}; + +template <> +struct VariantInitializer<PackedFloat32Array> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_float32_array(v); } +}; + +template <> +struct VariantInitializer<PackedFloat64Array> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_float64_array(v); } +}; + +template <> +struct VariantInitializer<PackedStringArray> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_string_array(v); } +}; + +template <> +struct VariantInitializer<PackedVector2Array> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_vector2_array(v); } +}; + +template <> +struct VariantInitializer<PackedVector3Array> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_vector3_array(v); } +}; + +template <> +struct VariantInitializer<PackedColorArray> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_color_array(v); } +}; + +template <class 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 + VariantInternal::clear(v); + VariantInitializer<T>::init(v); + } + } +}; + #endif // VARIANT_INTERNAL_H diff --git a/core/variant/variant_op.cpp b/core/variant/variant_op.cpp index 25ba66c9de..0def758388 100644 --- a/core/variant/variant_op.cpp +++ b/core/variant/variant_op.cpp @@ -44,6 +44,7 @@ public: r_valid = true; } static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<R>::change(r_ret); *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) + *VariantGetInternalPtr<B>::get_ptr(right); } #ifdef PTRCALL_ENABLED @@ -64,6 +65,7 @@ public: r_valid = true; } static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<R>::change(r_ret); *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) - *VariantGetInternalPtr<B>::get_ptr(right); } #ifdef PTRCALL_ENABLED @@ -84,6 +86,7 @@ public: r_valid = true; } static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<R>::change(r_ret); *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) * *VariantGetInternalPtr<B>::get_ptr(right); } #ifdef PTRCALL_ENABLED @@ -104,6 +107,7 @@ public: r_valid = true; } static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<R>::change(r_ret); *VariantGetInternalPtr<R>::get_ptr(r_ret) = VariantGetInternalPtr<A>::get_ptr(left)->xform(*VariantGetInternalPtr<B>::get_ptr(right)); } #ifdef PTRCALL_ENABLED @@ -124,6 +128,7 @@ public: r_valid = true; } static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<R>::change(r_ret); *VariantGetInternalPtr<R>::get_ptr(r_ret) = VariantGetInternalPtr<B>::get_ptr(right)->xform_inv(*VariantGetInternalPtr<A>::get_ptr(left)); } #ifdef PTRCALL_ENABLED @@ -144,6 +149,7 @@ public: r_valid = true; } static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<R>::change(r_ret); *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) / *VariantGetInternalPtr<B>::get_ptr(right); } #ifdef PTRCALL_ENABLED @@ -169,6 +175,7 @@ public: r_valid = true; } static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<R>::change(r_ret); *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) / *VariantGetInternalPtr<B>::get_ptr(right); } #ifdef PTRCALL_ENABLED @@ -189,6 +196,7 @@ public: r_valid = true; } static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<R>::change(r_ret); *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) % *VariantGetInternalPtr<B>::get_ptr(right); } #ifdef PTRCALL_ENABLED @@ -214,6 +222,7 @@ public: r_valid = true; } static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<R>::change(r_ret); *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) % *VariantGetInternalPtr<B>::get_ptr(right); } #ifdef PTRCALL_ENABLED @@ -233,6 +242,7 @@ public: r_valid = true; } static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<R>::change(r_ret); *VariantGetInternalPtr<R>::get_ptr(r_ret) = -*VariantGetInternalPtr<A>::get_ptr(left); } #ifdef PTRCALL_ENABLED @@ -252,6 +262,7 @@ public: r_valid = true; } static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<R>::change(r_ret); *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left); } #ifdef PTRCALL_ENABLED @@ -272,6 +283,7 @@ public: r_valid = true; } static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<R>::change(r_ret); *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) << *VariantGetInternalPtr<B>::get_ptr(right); } #ifdef PTRCALL_ENABLED @@ -292,6 +304,7 @@ public: r_valid = true; } static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<R>::change(r_ret); *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) >> *VariantGetInternalPtr<B>::get_ptr(right); } #ifdef PTRCALL_ENABLED @@ -312,6 +325,7 @@ public: r_valid = true; } static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<R>::change(r_ret); *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) | *VariantGetInternalPtr<B>::get_ptr(right); } #ifdef PTRCALL_ENABLED @@ -352,6 +366,7 @@ public: r_valid = true; } static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<R>::change(r_ret); *VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) ^ *VariantGetInternalPtr<B>::get_ptr(right); } #ifdef PTRCALL_ENABLED @@ -371,6 +386,7 @@ public: r_valid = true; } static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<R>::change(r_ret); *VariantGetInternalPtr<R>::get_ptr(r_ret) = ~*VariantGetInternalPtr<A>::get_ptr(left); } #ifdef PTRCALL_ENABLED @@ -391,6 +407,7 @@ public: r_valid = true; } static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<bool>::change(r_ret); *VariantGetInternalPtr<bool>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) == *VariantGetInternalPtr<B>::get_ptr(right); } #ifdef PTRCALL_ENABLED @@ -412,6 +429,7 @@ public: static 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(); + VariantTypeChanger<bool>::change(r_ret); *VariantGetInternalPtr<bool>::get_ptr(r_ret) = a == b; } #ifdef PTRCALL_ENABLED @@ -431,6 +449,7 @@ public: } static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { const Object *a = left->get_validated_object(); + VariantTypeChanger<bool>::change(r_ret); *VariantGetInternalPtr<bool>::get_ptr(r_ret) = a == nullptr; } #ifdef PTRCALL_ENABLED @@ -450,6 +469,7 @@ public: } static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { const Object *b = right->get_validated_object(); + VariantTypeChanger<bool>::change(r_ret); *VariantGetInternalPtr<bool>::get_ptr(r_ret) = nullptr == b; } #ifdef PTRCALL_ENABLED @@ -470,6 +490,7 @@ public: r_valid = true; } static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<bool>::change(r_ret); *VariantGetInternalPtr<bool>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) != *VariantGetInternalPtr<B>::get_ptr(right); } #ifdef PTRCALL_ENABLED @@ -491,6 +512,7 @@ public: static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { Object *a = left->get_validated_object(); Object *b = right->get_validated_object(); + VariantTypeChanger<bool>::change(r_ret); *VariantGetInternalPtr<bool>::get_ptr(r_ret) = a != b; } #ifdef PTRCALL_ENABLED @@ -510,6 +532,7 @@ public: } static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { Object *a = left->get_validated_object(); + VariantTypeChanger<bool>::change(r_ret); *VariantGetInternalPtr<bool>::get_ptr(r_ret) = a != nullptr; } #ifdef PTRCALL_ENABLED @@ -529,6 +552,7 @@ public: } static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { Object *b = right->get_validated_object(); + VariantTypeChanger<bool>::change(r_ret); *VariantGetInternalPtr<bool>::get_ptr(r_ret) = nullptr != b; } #ifdef PTRCALL_ENABLED @@ -549,6 +573,7 @@ public: r_valid = true; } static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<bool>::change(r_ret); *VariantGetInternalPtr<bool>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) < *VariantGetInternalPtr<B>::get_ptr(right); } #ifdef PTRCALL_ENABLED @@ -569,6 +594,7 @@ public: r_valid = true; } static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<bool>::change(r_ret); *VariantGetInternalPtr<bool>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) <= *VariantGetInternalPtr<B>::get_ptr(right); } #ifdef PTRCALL_ENABLED @@ -589,6 +615,7 @@ public: r_valid = true; } static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<bool>::change(r_ret); *VariantGetInternalPtr<bool>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) > *VariantGetInternalPtr<B>::get_ptr(right); } #ifdef PTRCALL_ENABLED @@ -609,6 +636,7 @@ public: r_valid = true; } static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<bool>::change(r_ret); *VariantGetInternalPtr<bool>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) >= *VariantGetInternalPtr<B>::get_ptr(right); } #ifdef PTRCALL_ENABLED @@ -629,6 +657,7 @@ public: r_valid = true; } static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<bool>::change(r_ret); *VariantGetInternalPtr<bool>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) && *VariantGetInternalPtr<B>::get_ptr(right); } #ifdef PTRCALL_ENABLED @@ -650,6 +679,7 @@ public: r_valid = true; } static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<bool>::change(r_ret); *VariantGetInternalPtr<bool>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) || *VariantGetInternalPtr<B>::get_ptr(right); } #ifdef PTRCALL_ENABLED @@ -675,6 +705,7 @@ public: r_valid = true; } static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<bool>::change(r_ret); *VariantGetInternalPtr<bool>::get_ptr(r_ret) = xor_op(*VariantGetInternalPtr<A>::get_ptr(left), *VariantGetInternalPtr<B>::get_ptr(right)); } #ifdef PTRCALL_ENABLED @@ -695,6 +726,7 @@ public: r_valid = true; } static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<bool>::change(r_ret); *VariantGetInternalPtr<bool>::get_ptr(r_ret) = !*VariantGetInternalPtr<A>::get_ptr(left); } #ifdef PTRCALL_ENABLED @@ -729,6 +761,7 @@ public: r_valid = true; } static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<Array>::change(r_ret); _add_arrays(*VariantGetInternalPtr<Array>::get_ptr(r_ret), *VariantGetInternalPtr<Array>::get_ptr(left), *VariantGetInternalPtr<Array>::get_ptr(right)); } #ifdef PTRCALL_ENABLED @@ -754,6 +787,7 @@ public: r_valid = true; } static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<Vector<T>>::change(r_ret); *VariantGetInternalPtr<Vector<T>>::get_ptr(r_ret) = *VariantGetInternalPtr<Vector<T>>::get_ptr(left); VariantGetInternalPtr<Vector<T>>::get_ptr(r_ret)->append_array(*VariantGetInternalPtr<Vector<T>>::get_ptr(right)); } @@ -787,6 +821,7 @@ public: } static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<String>::change(r_ret); *VariantGetInternalPtr<String>::get_ptr(r_ret) = do_mod(*VariantGetInternalPtr<String>::get_ptr(left), nullptr); } #ifdef PTRCALL_ENABLED @@ -813,6 +848,7 @@ public: } static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<String>::change(r_ret); *VariantGetInternalPtr<String>::get_ptr(r_ret) = do_mod(*VariantGetInternalPtr<String>::get_ptr(left), *VariantGetInternalPtr<Array>::get_ptr(right), nullptr); } #ifdef PTRCALL_ENABLED @@ -842,6 +878,7 @@ public: } static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<String>::change(r_ret); *VariantGetInternalPtr<String>::get_ptr(r_ret) = do_mod(*VariantGetInternalPtr<String>::get_ptr(left), right->get_validated_object(), nullptr); } #ifdef PTRCALL_ENABLED @@ -871,6 +908,7 @@ public: } static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<String>::change(r_ret); *VariantGetInternalPtr<String>::get_ptr(r_ret) = do_mod(*VariantGetInternalPtr<String>::get_ptr(left), *VariantGetInternalPtr<T>::get_ptr(right), nullptr); } #ifdef PTRCALL_ENABLED @@ -890,6 +928,7 @@ public: } static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<bool>::change(r_ret); *VariantGetInternalPtr<bool>::get_ptr(r_ret) = true; } #ifdef PTRCALL_ENABLED @@ -909,6 +948,7 @@ public: } static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<bool>::change(r_ret); *VariantGetInternalPtr<bool>::get_ptr(r_ret) = false; } #ifdef PTRCALL_ENABLED @@ -962,6 +1002,7 @@ _FORCE_INLINE_ static bool _operate_get_object(const Variant *p_ptr) { } \ \ static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { \ + VariantTypeChanger<bool>::change(r_ret); \ *VariantGetInternalPtr<bool>::get_ptr(r_ret) = m_op(_operate_get_##m_left(left), _operate_get_##m_right(right)); \ } \ \ @@ -1002,6 +1043,7 @@ _FORCE_INLINE_ static bool _operate_get_ptr_object(const void *p_ptr) { } \ \ static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { \ + VariantTypeChanger<bool>::change(r_ret); \ *VariantGetInternalPtr<bool>::get_ptr(r_ret) = m_op(_operate_get_##m_left(left), _operate_get_##m_right(right)); \ } \ \ @@ -1168,6 +1210,7 @@ public: } static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<bool>::change(r_ret); *VariantGetInternalPtr<bool>::get_ptr(r_ret) = !*VariantGetInternalPtr<bool>::get_ptr(left); } #ifdef PTRCALL_ENABLED @@ -1187,6 +1230,7 @@ public: } static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<bool>::change(r_ret); *VariantGetInternalPtr<bool>::get_ptr(r_ret) = !*VariantGetInternalPtr<int64_t>::get_ptr(left); } #ifdef PTRCALL_ENABLED @@ -1206,6 +1250,7 @@ public: } static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<bool>::change(r_ret); *VariantGetInternalPtr<bool>::get_ptr(r_ret) = !*VariantGetInternalPtr<double>::get_ptr(left); } #ifdef PTRCALL_ENABLED @@ -1225,6 +1270,7 @@ public: } static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<bool>::change(r_ret); *VariantGetInternalPtr<bool>::get_ptr(r_ret) = left->get_validated_object() == nullptr; } #ifdef PTRCALL_ENABLED @@ -1251,6 +1297,7 @@ public: static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { const String &str_a = *VariantGetInternalPtr<String>::get_ptr(left); const String &str_b = *VariantGetInternalPtr<String>::get_ptr(right); + VariantTypeChanger<bool>::change(r_ret); *VariantGetInternalPtr<bool>::get_ptr(r_ret) = str_b.find(str_a) != -1; } #ifdef PTRCALL_ENABLED @@ -1275,6 +1322,7 @@ public: static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { const A &a = *VariantGetInternalPtr<A>::get_ptr(left); const B &b = *VariantGetInternalPtr<B>::get_ptr(right); + VariantTypeChanger<bool>::change(r_ret); *VariantGetInternalPtr<bool>::get_ptr(r_ret) = b.find(a) != -1; } #ifdef PTRCALL_ENABLED @@ -1295,6 +1343,7 @@ public: static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { const Array &b = *VariantGetInternalPtr<Array>::get_ptr(right); + VariantTypeChanger<bool>::change(r_ret); *VariantGetInternalPtr<bool>::get_ptr(r_ret) = b.find(Variant()) != -1; } #ifdef PTRCALL_ENABLED @@ -1315,6 +1364,7 @@ public: static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { const Array &b = *VariantGetInternalPtr<Array>::get_ptr(right); + VariantTypeChanger<bool>::change(r_ret); *VariantGetInternalPtr<bool>::get_ptr(r_ret) = b.find(*left) != -1; } #ifdef PTRCALL_ENABLED @@ -1339,6 +1389,7 @@ public: static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { const Dictionary &b = *VariantGetInternalPtr<Dictionary>::get_ptr(right); const A &a = *VariantGetInternalPtr<A>::get_ptr(left); + VariantTypeChanger<bool>::change(r_ret); *VariantGetInternalPtr<bool>::get_ptr(r_ret) = b.has(a); } #ifdef PTRCALL_ENABLED @@ -1360,6 +1411,7 @@ public: static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { const Dictionary &b = *VariantGetInternalPtr<Dictionary>::get_ptr(right); + VariantTypeChanger<bool>::change(r_ret); *VariantGetInternalPtr<bool>::get_ptr(r_ret) = b.has(Variant()); } #ifdef PTRCALL_ENABLED @@ -1381,6 +1433,7 @@ public: static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { const Dictionary &b = *VariantGetInternalPtr<Dictionary>::get_ptr(right); + VariantTypeChanger<bool>::change(r_ret); *VariantGetInternalPtr<bool>::get_ptr(r_ret) = b.has(*left); } #ifdef PTRCALL_ENABLED @@ -1414,6 +1467,7 @@ public: bool valid; l->get(a, &valid); + VariantTypeChanger<bool>::change(r_ret); *VariantGetInternalPtr<bool>::get_ptr(r_ret) = valid; } #ifdef PTRCALL_ENABLED @@ -1449,6 +1503,7 @@ public: bool valid; l->get(a, &valid); + VariantTypeChanger<bool>::change(r_ret); *VariantGetInternalPtr<bool>::get_ptr(r_ret) = valid; } #ifdef PTRCALL_ENABLED @@ -1480,7 +1535,7 @@ void register_op(Variant::Operator p_op, Variant::Type p_type_a, Variant::Type p #endif } -void register_variant_operators() { +void Variant::_register_variant_operators() { zeromem(operator_return_type_table, sizeof(operator_return_type_table)); zeromem(operator_evaluator_table, sizeof(operator_evaluator_table)); zeromem(validated_operator_evaluator_table, sizeof(validated_operator_evaluator_table)); @@ -1568,8 +1623,8 @@ void register_variant_operators() { register_op<OperatorEvaluatorMul<Transform, Transform, Transform>>(Variant::OP_MULTIPLY, Variant::TRANSFORM, Variant::TRANSFORM); register_op<OperatorEvaluatorXForm<Vector3, Transform, Vector3>>(Variant::OP_MULTIPLY, Variant::TRANSFORM, Variant::VECTOR3); register_op<OperatorEvaluatorXFormInv<Vector3, Vector3, Transform>>(Variant::OP_MULTIPLY, Variant::VECTOR3, Variant::TRANSFORM); - register_op<OperatorEvaluatorXForm<AABB, Transform, AABB>>(Variant::OP_MULTIPLY, Variant::TRANSFORM, Variant::AABB); - register_op<OperatorEvaluatorXFormInv<AABB, AABB, Transform>>(Variant::OP_MULTIPLY, Variant::AABB, Variant::TRANSFORM); + register_op<OperatorEvaluatorXForm<::AABB, Transform, ::AABB>>(Variant::OP_MULTIPLY, Variant::TRANSFORM, Variant::AABB); + register_op<OperatorEvaluatorXFormInv<::AABB, ::AABB, Transform>>(Variant::OP_MULTIPLY, Variant::AABB, Variant::TRANSFORM); register_op<OperatorEvaluatorXForm<Vector<Vector3>, Transform, Vector<Vector3>>>(Variant::OP_MULTIPLY, Variant::TRANSFORM, Variant::PACKED_VECTOR3_ARRAY); register_op<OperatorEvaluatorXFormInv<Vector<Vector3>, Vector<Vector3>, Transform>>(Variant::OP_MULTIPLY, Variant::PACKED_VECTOR3_ARRAY, Variant::TRANSFORM); @@ -1645,7 +1700,7 @@ void register_variant_operators() { register_op<OperatorEvaluatorStringModT<Transform2D>>(Variant::OP_MODULE, Variant::STRING, Variant::TRANSFORM2D); register_op<OperatorEvaluatorStringModT<Plane>>(Variant::OP_MODULE, Variant::STRING, Variant::PLANE); register_op<OperatorEvaluatorStringModT<Quat>>(Variant::OP_MODULE, Variant::STRING, Variant::QUAT); - register_op<OperatorEvaluatorStringModT<AABB>>(Variant::OP_MODULE, Variant::STRING, Variant::AABB); + register_op<OperatorEvaluatorStringModT<::AABB>>(Variant::OP_MODULE, Variant::STRING, Variant::AABB); register_op<OperatorEvaluatorStringModT<Basis>>(Variant::OP_MODULE, Variant::STRING, Variant::BASIS); register_op<OperatorEvaluatorStringModT<Transform>>(Variant::OP_MODULE, Variant::STRING, Variant::TRANSFORM); @@ -1713,7 +1768,7 @@ void register_variant_operators() { register_op<OperatorEvaluatorEqual<Transform2D, Transform2D>>(Variant::OP_EQUAL, Variant::TRANSFORM2D, Variant::TRANSFORM2D); register_op<OperatorEvaluatorEqual<Plane, Plane>>(Variant::OP_EQUAL, Variant::PLANE, Variant::PLANE); register_op<OperatorEvaluatorEqual<Quat, Quat>>(Variant::OP_EQUAL, Variant::QUAT, Variant::QUAT); - register_op<OperatorEvaluatorEqual<AABB, AABB>>(Variant::OP_EQUAL, Variant::AABB, Variant::AABB); + register_op<OperatorEvaluatorEqual<::AABB, ::AABB>>(Variant::OP_EQUAL, Variant::AABB, Variant::AABB); register_op<OperatorEvaluatorEqual<Basis, Basis>>(Variant::OP_EQUAL, Variant::BASIS, Variant::BASIS); register_op<OperatorEvaluatorEqual<Transform, Transform>>(Variant::OP_EQUAL, Variant::TRANSFORM, Variant::TRANSFORM); register_op<OperatorEvaluatorEqual<Color, Color>>(Variant::OP_EQUAL, Variant::COLOR, Variant::COLOR); @@ -1759,7 +1814,7 @@ void register_variant_operators() { register_op<OperatorEvaluatorNotEqual<Transform2D, Transform2D>>(Variant::OP_NOT_EQUAL, Variant::TRANSFORM2D, Variant::TRANSFORM2D); register_op<OperatorEvaluatorNotEqual<Plane, Plane>>(Variant::OP_NOT_EQUAL, Variant::PLANE, Variant::PLANE); register_op<OperatorEvaluatorNotEqual<Quat, Quat>>(Variant::OP_NOT_EQUAL, Variant::QUAT, Variant::QUAT); - register_op<OperatorEvaluatorNotEqual<AABB, AABB>>(Variant::OP_NOT_EQUAL, Variant::AABB, Variant::AABB); + register_op<OperatorEvaluatorNotEqual<::AABB, ::AABB>>(Variant::OP_NOT_EQUAL, Variant::AABB, Variant::AABB); register_op<OperatorEvaluatorNotEqual<Basis, Basis>>(Variant::OP_NOT_EQUAL, Variant::BASIS, Variant::BASIS); register_op<OperatorEvaluatorNotEqual<Transform, Transform>>(Variant::OP_NOT_EQUAL, Variant::TRANSFORM, Variant::TRANSFORM); register_op<OperatorEvaluatorNotEqual<Color, Color>>(Variant::OP_NOT_EQUAL, Variant::COLOR, Variant::COLOR); @@ -1948,7 +2003,7 @@ void register_variant_operators() { register_op<OperatorEvaluatorInDictionaryHas<Transform2D>>(Variant::OP_IN, Variant::TRANSFORM2D, Variant::DICTIONARY); register_op<OperatorEvaluatorInDictionaryHas<Plane>>(Variant::OP_IN, Variant::PLANE, Variant::DICTIONARY); register_op<OperatorEvaluatorInDictionaryHas<Quat>>(Variant::OP_IN, Variant::QUAT, Variant::DICTIONARY); - register_op<OperatorEvaluatorInDictionaryHas<AABB>>(Variant::OP_IN, Variant::AABB, Variant::DICTIONARY); + register_op<OperatorEvaluatorInDictionaryHas<::AABB>>(Variant::OP_IN, Variant::AABB, Variant::DICTIONARY); register_op<OperatorEvaluatorInDictionaryHas<Basis>>(Variant::OP_IN, Variant::BASIS, Variant::DICTIONARY); register_op<OperatorEvaluatorInDictionaryHas<Transform>>(Variant::OP_IN, Variant::TRANSFORM, Variant::DICTIONARY); @@ -1985,7 +2040,7 @@ void register_variant_operators() { register_op<OperatorEvaluatorInArrayFind<Transform2D, Array>>(Variant::OP_IN, Variant::TRANSFORM2D, Variant::ARRAY); register_op<OperatorEvaluatorInArrayFind<Plane, Array>>(Variant::OP_IN, Variant::PLANE, Variant::ARRAY); register_op<OperatorEvaluatorInArrayFind<Quat, Array>>(Variant::OP_IN, Variant::QUAT, Variant::ARRAY); - register_op<OperatorEvaluatorInArrayFind<AABB, Array>>(Variant::OP_IN, Variant::AABB, Variant::ARRAY); + register_op<OperatorEvaluatorInArrayFind<::AABB, Array>>(Variant::OP_IN, Variant::AABB, Variant::ARRAY); register_op<OperatorEvaluatorInArrayFind<Basis, Array>>(Variant::OP_IN, Variant::BASIS, Variant::ARRAY); register_op<OperatorEvaluatorInArrayFind<Transform, Array>>(Variant::OP_IN, Variant::TRANSFORM, Variant::ARRAY); @@ -2034,7 +2089,7 @@ void register_variant_operators() { register_op<OperatorEvaluatorObjectHasPropertyStringName>(Variant::OP_IN, Variant::STRING_NAME, Variant::OBJECT); } -void unregister_variant_operators() { +void Variant::_unregister_variant_operators() { } void Variant::evaluate(const Operator &p_op, const Variant &p_a, diff --git a/core/variant/variant_setget.cpp b/core/variant/variant_setget.cpp index 6d9599a27e..cae64376d5 100644 --- a/core/variant/variant_setget.cpp +++ b/core/variant/variant_setget.cpp @@ -2576,12 +2576,12 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant & } } -void register_variant_setters_getters() { +void Variant::_register_variant_setters_getters() { register_named_setters_getters(); register_indexed_setters_getters(); register_keyed_setters_getters(); } -void unregister_variant_setters_getters() { +void Variant::_unregister_variant_setters_getters() { unregister_named_setters_getters(); unregister_indexed_setters_getters(); } diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index 5471a9907b..6f30d5a492 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -228,9 +228,9 @@ public: if (Variant::can_convert(args[idx].get_type(), t)) { Variant old = args[idx]; Variant *ptrs[1] = { &old }; - args.write[idx] = Variant::construct(t, (const Variant **)ptrs, 1, err); + Variant::construct(t, args.write[idx], (const Variant **)ptrs, 1, err); } else { - args.write[idx] = Variant::construct(t, nullptr, 0, err); + Variant::construct(t, args.write[idx], nullptr, 0, err); } change_notify_deserved = true; d_new["args"] = args; @@ -846,9 +846,9 @@ public: if (Variant::can_convert(args[idx].get_type(), t)) { Variant old = args[idx]; Variant *ptrs[1] = { &old }; - args.write[idx] = Variant::construct(t, (const Variant **)ptrs, 1, err); + Variant::construct(t, args.write[idx], (const Variant **)ptrs, 1, err); } else { - args.write[idx] = Variant::construct(t, nullptr, 0, err); + Variant::construct(t, args.write[idx], nullptr, 0, err); } change_notify_deserved = true; d_new["args"] = args; @@ -4587,7 +4587,8 @@ void AnimationTrackEditor::_add_method_key(const String &p_method) { params.push_back(arg); } else { Callable::CallError ce; - Variant arg = Variant::construct(E->get().arguments[i].type, nullptr, 0, ce); + Variant arg; + Variant::construct(E->get().arguments[i].type, arg, nullptr, 0, ce); params.push_back(arg); } } diff --git a/editor/array_property_edit.cpp b/editor/array_property_edit.cpp index 20f947e707..0b6b1ef6a7 100644 --- a/editor/array_property_edit.cpp +++ b/editor/array_property_edit.cpp @@ -43,7 +43,7 @@ Variant ArrayPropertyEdit::get_array() const { Variant arr = o->get(property); if (!arr.is_array()) { Callable::CallError ce; - arr = Variant::construct(default_type, nullptr, 0, ce); + Variant::construct(default_type, arr, nullptr, 0, ce); } return arr; } @@ -107,7 +107,7 @@ bool ArrayPropertyEdit::_set(const StringName &p_name, const Variant &p_value) { new_type = arr.get(size - 1).get_type(); } if (new_type != Variant::NIL) { - init = Variant::construct(new_type, nullptr, 0, ce); + Variant::construct(new_type, init, nullptr, 0, ce); for (int i = size; i < newsize; i++) { ur->add_do_method(this, "_set_value", i, init); } @@ -136,7 +136,8 @@ bool ArrayPropertyEdit::_set(const StringName &p_name, const Variant &p_value) { Variant value = arr.get(idx); if (value.get_type() != type && type >= 0 && type < Variant::VARIANT_MAX) { Callable::CallError ce; - Variant new_value = Variant::construct(Variant::Type(type), nullptr, 0, ce); + Variant new_value; + Variant::construct(Variant::Type(type), new_value, nullptr, 0, ce); UndoRedo *ur = EditorNode::get_undo_redo(); ur->create_action(TTR("Change Array Value Type")); diff --git a/editor/doc_data.cpp b/editor/doc_data.cpp index 1888cc1e41..5cede65fa6 100644 --- a/editor/doc_data.cpp +++ b/editor/doc_data.cpp @@ -561,7 +561,8 @@ void DocData::generate(bool p_basic_types) { c.name = cname; Callable::CallError cerror; - Variant v = Variant::construct(Variant::Type(i), nullptr, 0, cerror); + Variant v; + Variant::construct(Variant::Type(i), v, nullptr, 0, cerror); List<MethodInfo> method_list; v.get_method_list(&method_list); diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index 1837b23a0b..371100652f 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -2278,7 +2278,7 @@ void EditorInspector::_property_checked(const String &p_path, bool p_checked) { for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { if (E->get().name == p_path) { Callable::CallError ce; - to_create = Variant::construct(E->get().type, nullptr, 0, ce); + Variant::construct(E->get().type, to_create, nullptr, 0, ce); break; } } diff --git a/editor/editor_properties_array_dict.cpp b/editor/editor_properties_array_dict.cpp index 51fac6acec..aa723af292 100644 --- a/editor/editor_properties_array_dict.cpp +++ b/editor/editor_properties_array_dict.cpp @@ -186,7 +186,7 @@ void EditorPropertyArray::_change_type_menu(int p_index) { Variant value; Callable::CallError ce; - value = Variant::construct(Variant::Type(p_index), nullptr, 0, ce); + Variant::construct(Variant::Type(p_index), value, nullptr, 0, ce); Variant array = object->get_array(); array.set(changing_type_idx, value); @@ -445,7 +445,7 @@ void EditorPropertyArray::drop_data_fw(const Point2 &p_point, const Variant &p_d // Handle the case where array is not initialised yet if (!array.is_array()) { Callable::CallError ce; - array = Variant::construct(array_type, nullptr, 0, ce); + Variant::construct(array_type, array, nullptr, 0, ce); } // Loop the file array and add to existing array @@ -491,7 +491,7 @@ void EditorPropertyArray::_edit_pressed() { Variant array = get_edited_object()->get(get_edited_property()); if (!array.is_array()) { Callable::CallError ce; - array = Variant::construct(array_type, nullptr, 0, ce); + Variant::construct(array_type, array, nullptr, 0, ce); get_edited_object()->set(get_edited_property(), array); } @@ -524,7 +524,9 @@ void EditorPropertyArray::_length_changed(double p_page) { for (int i = previous_size; i < size; i++) { if (array.get(i).get_type() == Variant::NIL) { Callable::CallError ce; - array.set(i, Variant::construct(subtype, nullptr, 0, ce)); + Variant r; + Variant::construct(subtype, r, nullptr, 0, ce); + array.set(i, r); } } } @@ -534,7 +536,9 @@ void EditorPropertyArray::_length_changed(double p_page) { // Pool*Array don't initialize their elements, have to do it manually for (int i = previous_size; i < size; i++) { Callable::CallError ce; - array.set(i, Variant::construct(array.get(i).get_type(), nullptr, 0, ce)); + Variant r; + Variant::construct(array.get(i).get_type(), r, nullptr, 0, ce); + array.set(i, r); } } @@ -657,7 +661,7 @@ void EditorPropertyDictionary::_change_type_menu(int p_index) { if (changing_type_idx < 0) { Variant value; Callable::CallError ce; - value = Variant::construct(Variant::Type(p_index), nullptr, 0, ce); + Variant::construct(Variant::Type(p_index), value, nullptr, 0, ce); if (changing_type_idx == -1) { object->set_new_item_key(value); } else { @@ -672,7 +676,7 @@ void EditorPropertyDictionary::_change_type_menu(int p_index) { if (p_index < Variant::VARIANT_MAX) { Variant value; Callable::CallError ce; - value = Variant::construct(Variant::Type(p_index), nullptr, 0, ce); + Variant::construct(Variant::Type(p_index), value, nullptr, 0, ce); Variant key = dict.get_key_at_index(changing_type_idx); dict[key] = value; } else { @@ -1044,7 +1048,7 @@ void EditorPropertyDictionary::_edit_pressed() { Variant prop_val = get_edited_object()->get(get_edited_property()); if (prop_val.get_type() == Variant::NIL) { Callable::CallError ce; - prop_val = Variant::construct(Variant::DICTIONARY, nullptr, 0, ce); + Variant::construct(Variant::DICTIONARY, prop_val, nullptr, 0, ce); get_edited_object()->set(get_edited_property(), prop_val); } diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp index d231e3f353..55d80021c8 100644 --- a/editor/project_settings_editor.cpp +++ b/editor/project_settings_editor.cpp @@ -98,7 +98,8 @@ void ProjectSettingsEditor::_add_setting() { // Initialize the property with the default value for the given type. // The type list starts at 1 (as we exclude Nil), so add 1 to the selected value. Callable::CallError ce; - const Variant value = Variant::construct(Variant::Type(type->get_selected() + 1), nullptr, 0, ce); + Variant value; + Variant::construct(Variant::Type(type->get_selected() + 1), value, nullptr, 0, ce); undo_redo->create_action(TTR("Add Project Setting")); undo_redo->add_do_property(ps, setting, value); diff --git a/editor/property_selector.cpp b/editor/property_selector.cpp index 27b11e4fb5..75420a1ef4 100644 --- a/editor/property_selector.cpp +++ b/editor/property_selector.cpp @@ -95,7 +95,7 @@ void PropertySelector::_update_search() { } else if (type != Variant::NIL) { Variant v; Callable::CallError ce; - v = Variant::construct(type, nullptr, 0, ce); + Variant::construct(type, v, nullptr, 0, ce); v.get_property_list(&props); } else { @@ -200,7 +200,7 @@ void PropertySelector::_update_search() { if (type != Variant::NIL) { Variant v; Callable::CallError ce; - v = Variant::construct(type, nullptr, 0, ce); + Variant::construct(type, v, nullptr, 0, ce); v.get_method_list(&methods); } else { Object *obj = ObjectDB::get_instance(script); diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index a73268a79d..53602f7a9b 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -1092,7 +1092,8 @@ bool GDScriptInstance::set(const StringName &p_name, const Variant &p_value) { // Try conversion Callable::CallError ce; const Variant *value = &p_value; - Variant converted = Variant::construct(member->data_type.builtin_type, &value, 1, ce); + Variant converted; + Variant::construct(member->data_type.builtin_type, converted, &value, 1, ce); if (ce.error == Callable::CallError::CALL_OK) { members.write[member->index] = converted; return true; diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index a1de17b5a1..7d50b63924 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -1711,7 +1711,8 @@ void GDScriptAnalyzer::reduce_call(GDScriptParser::CallNode *p_call, bool is_awa } Callable::CallError err; - Variant value = Variant::construct(builtin_type, (const Variant **)args.ptr(), args.size(), err); + Variant value; + Variant::construct(builtin_type, value, (const Variant **)args.ptr(), args.size(), err); switch (err.error) { case Callable::CallError::CALL_ERROR_INVALID_ARGUMENT: @@ -2075,7 +2076,8 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod } default: { Callable::CallError temp; - Variant dummy = Variant::construct(base.builtin_type, nullptr, 0, temp); + Variant dummy; + Variant::construct(base.builtin_type, dummy, nullptr, 0, temp); List<PropertyInfo> properties; dummy.get_property_list(&properties); for (const List<PropertyInfo>::Element *E = properties.front(); E != nullptr; E = E->next()) { @@ -2869,7 +2871,8 @@ bool GDScriptAnalyzer::get_function_signature(GDScriptParser::Node *p_source, GD if (p_base_type.kind == GDScriptParser::DataType::BUILTIN) { // Construct a base type to get methods. Callable::CallError err; - Variant dummy = Variant::construct(p_base_type.builtin_type, nullptr, 0, err); + Variant dummy; + Variant::construct(p_base_type.builtin_type, dummy, nullptr, 0, err); if (err.error != Callable::CallError::CALL_OK) { ERR_FAIL_V_MSG(false, "Could not construct base Variant type."); } @@ -3095,7 +3098,7 @@ GDScriptParser::DataType GDScriptAnalyzer::get_operation_type(Variant::Operator a = a_ref; } else { Callable::CallError err; - a = Variant::construct(a_type, nullptr, 0, err); + Variant::construct(a_type, a, nullptr, 0, err); if (err.error != Callable::CallError::CALL_OK) { r_valid = false; ERR_FAIL_V_MSG(result, vformat("Could not construct value of type %s", Variant::get_type_name(a_type))); @@ -3108,7 +3111,7 @@ GDScriptParser::DataType GDScriptAnalyzer::get_operation_type(Variant::Operator b = b_ref; } else { Callable::CallError err; - b = Variant::construct(b_type, nullptr, 0, err); + Variant::construct(b_type, b, nullptr, 0, err); if (err.error != Callable::CallError::CALL_OK) { r_valid = false; ERR_FAIL_V_MSG(result, vformat("Could not construct value of type %s", Variant::get_type_name(b_type))); diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index 605883f6df..d0acc14a04 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -973,7 +973,8 @@ static void _find_identifiers_in_base(const GDScriptCompletionIdentifier &p_base } break; case GDScriptParser::DataType::BUILTIN: { Callable::CallError err; - Variant tmp = Variant::construct(base_type.builtin_type, nullptr, 0, err); + Variant tmp; + Variant::construct(base_type.builtin_type, tmp, nullptr, 0, err); if (err.error != Callable::CallError::CALL_OK) { return; } @@ -1523,7 +1524,8 @@ static bool _guess_expression_type(GDScriptParser::CompletionContext &p_context, found = _guess_identifier_type_from_base(c, base, id, r_type); } else if (!found && index.type.kind == GDScriptParser::DataType::BUILTIN) { Callable::CallError err; - Variant base_val = Variant::construct(base.type.builtin_type, nullptr, 0, err); + Variant base_val; + Variant::construct(base.type.builtin_type, base_val, nullptr, 0, err); bool valid = false; Variant res = base_val.get(index.value, &valid); if (valid) { @@ -1560,9 +1562,14 @@ static bool _guess_expression_type(GDScriptParser::CompletionContext &p_context, Callable::CallError ce; bool v1_use_value = p1.value.get_type() != Variant::NIL && p1.value.get_type() != Variant::OBJECT; - Variant v1 = (v1_use_value) ? p1.value : Variant::construct(p1.type.builtin_type, nullptr, 0, ce); + Variant d1; + Variant::construct(p1.type.builtin_type, d1, nullptr, 0, ce); + Variant d2; + Variant::construct(p2.type.builtin_type, d2, nullptr, 0, ce); + + Variant v1 = (v1_use_value) ? p1.value : d1; bool v2_use_value = p2.value.get_type() != Variant::NIL && p2.value.get_type() != Variant::OBJECT; - Variant v2 = (v2_use_value) ? p2.value : Variant::construct(p2.type.builtin_type, nullptr, 0, ce); + Variant v2 = (v2_use_value) ? p2.value : d2; // avoid potential invalid ops if ((op->variant_op == Variant::OP_DIVIDE || op->variant_op == Variant::OP_MODULE) && v2.get_type() == Variant::INT) { v2 = 1; @@ -1952,7 +1959,8 @@ static bool _guess_identifier_type_from_base(GDScriptParser::CompletionContext & } break; case GDScriptParser::DataType::BUILTIN: { Callable::CallError err; - Variant tmp = Variant::construct(base_type.builtin_type, nullptr, 0, err); + Variant tmp; + Variant::construct(base_type.builtin_type, tmp, nullptr, 0, err); if (err.error != Callable::CallError::CALL_OK) { return false; @@ -2102,7 +2110,8 @@ static bool _guess_method_return_type_from_base(GDScriptParser::CompletionContex } break; case GDScriptParser::DataType::BUILTIN: { Callable::CallError err; - Variant tmp = Variant::construct(base_type.builtin_type, nullptr, 0, err); + Variant tmp; + Variant::construct(base_type.builtin_type, tmp, nullptr, 0, err); if (err.error != Callable::CallError::CALL_OK) { return false; } @@ -2257,7 +2266,7 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c case GDScriptParser::DataType::BUILTIN: { if (base.get_type() == Variant::NIL) { Callable::CallError err; - base = Variant::construct(base_type.builtin_type, nullptr, 0, err); + Variant::construct(base_type.builtin_type, base, nullptr, 0, err); if (err.error != Callable::CallError::CALL_OK) { return; } @@ -2883,7 +2892,7 @@ static Error _lookup_symbol_from_base(const GDScriptParser::DataType &p_base, co v = v_ref; } else { Callable::CallError err; - v = Variant::construct(base_type.builtin_type, NULL, 0, err); + Variant::construct(base_type.builtin_type, v, NULL, 0, err); if (err.error != Callable::CallError::CALL_OK) { break; } diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp index 3a7b38dac5..59f3deb736 100644 --- a/modules/gdscript/gdscript_function.cpp +++ b/modules/gdscript/gdscript_function.cpp @@ -331,7 +331,8 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a return Variant(); } if (argument_types[i].kind == GDScriptDataType::BUILTIN) { - Variant arg = Variant::construct(argument_types[i].builtin_type, &p_args[i], 1, r_err); + Variant arg; + Variant::construct(argument_types[i].builtin_type, arg, &p_args[i], 1, r_err); memnew_placement(&stack[i], Variant(arg)); } else { memnew_placement(&stack[i], Variant(*p_args[i])); @@ -755,7 +756,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a if (Variant::can_convert_strict(src->get_type(), var_type)) { #endif // DEBUG_ENABLED Callable::CallError ce; - *dst = Variant::construct(var_type, const_cast<const Variant **>(&src), 1, ce); + Variant::construct(var_type, *dst, const_cast<const Variant **>(&src), 1, ce); } else { #ifdef DEBUG_ENABLED err_text = "Trying to assign value of type '" + Variant::get_type_name(src->get_type()) + @@ -857,7 +858,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a GD_ERR_BREAK(to_type < 0 || to_type >= Variant::VARIANT_MAX); Callable::CallError err; - *dst = Variant::construct(to_type, (const Variant **)&src, 1, err); + Variant::construct(to_type, *dst, (const Variant **)&src, 1, err); #ifdef DEBUG_ENABLED if (err.error != Callable::CallError::CALL_OK) { @@ -955,7 +956,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a GET_VARIANT_PTR(dst, 3 + argc); Callable::CallError err; - *dst = Variant::construct(t, (const Variant **)argptrs, argc, err); + Variant::construct(t, *dst, (const Variant **)argptrs, argc, err); #ifdef DEBUG_ENABLED if (err.error != Callable::CallError::CALL_OK) { diff --git a/modules/gdscript/gdscript_functions.cpp b/modules/gdscript/gdscript_functions.cpp index 3c82545190..0942552ba8 100644 --- a/modules/gdscript/gdscript_functions.cpp +++ b/modules/gdscript/gdscript_functions.cpp @@ -599,7 +599,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ return; } else { - r_ret = Variant::construct(Variant::Type(type), p_args, 1, r_error); + Variant::construct(Variant::Type(type), r_ret, p_args, 1, r_error); } } break; case TYPE_OF: { diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index 6bf8a3a908..10cc6febbc 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -2802,7 +2802,9 @@ bool GDScriptParser::validate_annotation_arguments(AnnotationNode *p_annotation) Callable::CallError error; Vector<Variant> args = varray(string->name); const Variant *name = args.ptr(); - p_annotation->resolved_arguments.push_back(Variant::construct(parameter.type, &(name), 1, error)); + Variant r; + Variant::construct(parameter.type, r, &(name), 1, error); + p_annotation->resolved_arguments.push_back(r); if (error.error != Callable::CallError::CALL_OK) { push_error(vformat(R"(Expected %s as argument %d of annotation "%s").)", Variant::get_type_name(parameter.type), i + 1, p_annotation->name)); p_annotation->resolved_arguments.remove(p_annotation->resolved_arguments.size() - 1); @@ -2824,7 +2826,9 @@ bool GDScriptParser::validate_annotation_arguments(AnnotationNode *p_annotation) } Callable::CallError error; const Variant *args = &value; - p_annotation->resolved_arguments.push_back(Variant::construct(parameter.type, &(args), 1, error)); + Variant r; + Variant::construct(parameter.type, r, &(args), 1, error); + p_annotation->resolved_arguments.push_back(r); if (error.error != Callable::CallError::CALL_OK) { push_error(vformat(R"(Expected %s as argument %d of annotation "%s").)", Variant::get_type_name(parameter.type), i + 1, p_annotation->name)); p_annotation->resolved_arguments.remove(p_annotation->resolved_arguments.size() - 1); diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp index f6a7389eec..1c7d5472cb 100644 --- a/modules/visual_script/visual_script.cpp +++ b/modules/visual_script/visual_script.cpp @@ -84,10 +84,10 @@ void VisualScriptNode::validate_input_default_values() { Callable::CallError ce; Variant existing = default_input_values[i]; const Variant *existingp = &existing; - default_input_values[i] = Variant::construct(expected, &existingp, 1, ce, false); + Variant::construct(expected, default_input_values[i], &existingp, 1, ce); if (ce.error != Callable::CallError::CALL_OK) { //could not convert? force.. - default_input_values[i] = Variant::construct(expected, nullptr, 0, ce, false); + Variant::construct(expected, default_input_values[i], nullptr, 0, ce); } } } diff --git a/modules/visual_script/visual_script_builtin_funcs.cpp b/modules/visual_script/visual_script_builtin_funcs.cpp index 9301189eaa..a27307aec2 100644 --- a/modules/visual_script/visual_script_builtin_funcs.cpp +++ b/modules/visual_script/visual_script_builtin_funcs.cpp @@ -1027,7 +1027,7 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in return; } else { - *r_return = Variant::construct(Variant::Type(type), p_inputs, 1, r_error); + Variant::construct(Variant::Type(type), *r_return, p_inputs, 1, r_error); } } break; case VisualScriptBuiltinFunc::TYPE_OF: { diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp index 082df25dbe..5fa3c2a873 100644 --- a/modules/visual_script/visual_script_editor.cpp +++ b/modules/visual_script/visual_script_editor.cpp @@ -885,7 +885,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) { //not the same, reconvert Callable::CallError ce; const Variant *existingp = &value; - value = Variant::construct(left_type, &existingp, 1, ce, false); + Variant::construct(left_type, value, &existingp, 1, ce); } if (left_type == Variant::COLOR) { @@ -1173,7 +1173,9 @@ String VisualScriptEditor::_sanitized_variant_text(const StringName &property_na if (script->get_variable_info(property_name).type != Variant::NIL) { Callable::CallError ce; const Variant *converted = &var; - var = Variant::construct(script->get_variable_info(property_name).type, &converted, 1, ce, false); + Variant n; + Variant::construct(script->get_variable_info(property_name).type, n, &converted, 1, ce); + var = n; } return String(var); @@ -3959,8 +3961,9 @@ void VisualScriptEditor::_default_value_edited(Node *p_button, int p_id, int p_i Variant existing = vsn->get_default_input_value(p_input_port); if (pinfo.type != Variant::NIL && existing.get_type() != pinfo.type) { Callable::CallError ce; - const Variant *existingp = &existing; - existing = Variant::construct(pinfo.type, &existingp, 1, ce, false); + Variant e = existing; + const Variant *existingp = &e; + Variant::construct(pinfo.type, existing, &existingp, 1, ce); } default_value_edit->set_position(Object::cast_to<Control>(p_button)->get_global_position() + Vector2(0, Object::cast_to<Control>(p_button)->get_size().y)); diff --git a/modules/visual_script/visual_script_expression.cpp b/modules/visual_script/visual_script_expression.cpp index 3785e81b9f..bb015b118d 100644 --- a/modules/visual_script/visual_script_expression.cpp +++ b/modules/visual_script/visual_script_expression.cpp @@ -1405,7 +1405,7 @@ public: argp.write[i] = &arr[i]; } - r_ret = Variant::construct(constructor->data_type, (const Variant **)argp.ptr(), argp.size(), ce); + Variant::construct(constructor->data_type, r_ret, (const Variant **)argp.ptr(), argp.size(), ce); if (ce.error != Callable::CallError::CALL_OK) { r_error_str = "Invalid arguments to construct '" + Variant::get_type_name(constructor->data_type) + "'."; diff --git a/modules/visual_script/visual_script_func_nodes.cpp b/modules/visual_script/visual_script_func_nodes.cpp index e159b039af..3b46af3cbd 100644 --- a/modules/visual_script/visual_script_func_nodes.cpp +++ b/modules/visual_script/visual_script_func_nodes.cpp @@ -976,7 +976,7 @@ void VisualScriptPropertySet::_adjust_input_index(PropertyInfo &pinfo) const { if (index != StringName()) { Variant v; Callable::CallError ce; - v = Variant::construct(pinfo.type, nullptr, 0, ce); + Variant::construct(pinfo.type, v, nullptr, 0, ce); Variant i = v.get(index); pinfo.type = i.get_type(); } @@ -1117,7 +1117,7 @@ void VisualScriptPropertySet::_update_cache() { Variant v; Callable::CallError ce; - v = Variant::construct(basic_type, nullptr, 0, ce); + Variant::construct(basic_type, v, nullptr, 0, ce); List<PropertyInfo> pinfo; v.get_property_list(&pinfo); @@ -1336,7 +1336,8 @@ void VisualScriptPropertySet::_validate_property(PropertyInfo &property) const { if (property.name == "index") { Callable::CallError ce; - Variant v = Variant::construct(type_cache.type, nullptr, 0, ce); + Variant v; + Variant::construct(type_cache.type, v, nullptr, 0, ce); List<PropertyInfo> plist; v.get_property_list(&plist); String options = ""; @@ -1786,7 +1787,7 @@ void VisualScriptPropertyGet::_update_cache() { Variant v; Callable::CallError ce; - v = Variant::construct(basic_type, nullptr, 0, ce); + Variant::construct(basic_type, v, nullptr, 0, ce); List<PropertyInfo> pinfo; v.get_property_list(&pinfo); @@ -2012,7 +2013,8 @@ void VisualScriptPropertyGet::_validate_property(PropertyInfo &property) const { if (property.name == "index") { Callable::CallError ce; - Variant v = Variant::construct(type_cache, nullptr, 0, ce); + Variant v; + Variant::construct(type_cache, v, nullptr, 0, ce); List<PropertyInfo> plist; v.get_property_list(&plist); String options = ""; @@ -2368,7 +2370,8 @@ void register_visual_script_func_nodes() { Variant::Type t = Variant::Type(i); String type_name = Variant::get_type_name(t); Callable::CallError ce; - Variant vt = Variant::construct(t, nullptr, 0, ce); + Variant vt; + Variant::construct(t, vt, nullptr, 0, ce); List<MethodInfo> ml; vt.get_method_list(&ml); diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp index 436f000498..edec270adc 100644 --- a/modules/visual_script/visual_script_nodes.cpp +++ b/modules/visual_script/visual_script_nodes.cpp @@ -1431,7 +1431,7 @@ void VisualScriptConstant::set_constant_type(Variant::Type p_type) { type = p_type; Callable::CallError ce; - value = Variant::construct(type, nullptr, 0, ce); + Variant::construct(type, value, nullptr, 0, ce); ports_changed_notify(); _change_notify(); } @@ -3255,7 +3255,7 @@ public: virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) { Callable::CallError ce; - *p_outputs[0] = Variant::construct(type, p_inputs, argcount, ce); + Variant::construct(type, *p_outputs[0], p_inputs, argcount, ce); if (ce.error != Callable::CallError::CALL_OK) { r_error_str = "Invalid arguments for constructor"; } @@ -3727,7 +3727,7 @@ void VisualScriptDeconstruct::_update_elements() { elements.clear(); Variant v; Callable::CallError ce; - v = Variant::construct(type, nullptr, 0, ce); + Variant::construct(type, v, nullptr, 0, ce); List<PropertyInfo> pinfo; v.get_property_list(&pinfo); diff --git a/modules/visual_script/visual_script_property_selector.cpp b/modules/visual_script/visual_script_property_selector.cpp index 3c44faab90..875270e74f 100644 --- a/modules/visual_script/visual_script_property_selector.cpp +++ b/modules/visual_script/visual_script_property_selector.cpp @@ -196,7 +196,7 @@ void VisualScriptPropertySelector::_update_search() { if (type != Variant::NIL) { Variant v; Callable::CallError ce; - v = Variant::construct(type, nullptr, 0, ce); + Variant::construct(type, v, nullptr, 0, ce); v.get_method_list(&methods); } else { Object *obj = ObjectDB::get_instance(script); diff --git a/scene/main/shader_globals_override.cpp b/scene/main/shader_globals_override.cpp index 86c08ca6e9..432fb5b4fb 100644 --- a/scene/main/shader_globals_override.cpp +++ b/scene/main/shader_globals_override.cpp @@ -202,7 +202,7 @@ void ShaderGlobalsOverride::_get_property_list(List<PropertyInfo> *p_list) const Override o; o.in_use = false; Callable::CallError ce; - o.override = Variant::construct(pinfo.type, nullptr, 0, ce); + Variant::construct(pinfo.type, o.override, nullptr, 0, ce); overrides[variables[i]] = o; } diff --git a/thirdparty/README.md b/thirdparty/README.md index ac1ce6d5fc..f590acaa0b 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -378,7 +378,7 @@ Collection of single-file libraries used in Godot components. * License: Apache 2.0 - `open-simplex-noise.{c,h}` * Upstream: https://github.com/smcameron/open-simplex-noise-in-c - * Version: git (0d555e7f40527d0870906fe9469a3b1bb4020b7f, 2015) + custom changes + * Version: git (0fef0dbedd76f767da7e3c894822729d0f07e54d, 2020) + custom changes * License: Unlicense - `pcg.{cpp,h}` * Upstream: http://www.pcg-random.org diff --git a/thirdparty/misc/open-simplex-noise.c b/thirdparty/misc/open-simplex-noise.c index 42f2fbb5be..88fbd3e51d 100644 --- a/thirdparty/misc/open-simplex-noise.c +++ b/thirdparty/misc/open-simplex-noise.c @@ -189,14 +189,15 @@ int open_simplex_noise(int64_t seed, struct osn_context *ctx) permGradIndex3D = ctx->permGradIndex3D; // -- GODOT end -- + uint64_t seedU = seed; for (i = 0; i < 256; i++) source[i] = (int16_t) i; - seed = seed * 6364136223846793005LL + 1442695040888963407LL; - seed = seed * 6364136223846793005LL + 1442695040888963407LL; - seed = seed * 6364136223846793005LL + 1442695040888963407LL; + seedU = seedU * 6364136223846793005ULL + 1442695040888963407ULL; + seedU = seedU * 6364136223846793005ULL + 1442695040888963407ULL; + seedU = seedU * 6364136223846793005ULL + 1442695040888963407ULL; for (i = 255; i >= 0; i--) { - seed = seed * 6364136223846793005LL + 1442695040888963407LL; - r = (int)((seed + 31) % (i + 1)); + seedU = seedU * 6364136223846793005ULL + 1442695040888963407ULL; + r = (int)((seedU + 31) % (i + 1)); if (r < 0) r += (i + 1); perm[i] = source[r]; |