From 9979abce742c2d0b696c0f0111e1e79c189125b9 Mon Sep 17 00:00:00 2001 From: reduz Date: Mon, 9 Nov 2020 15:16:39 -0300 Subject: Change how no-arg constructor is handled internally in Variant. --- core/variant/variant_construct.cpp | 234 ++++++++++++++++++++++--------------- core/variant/variant_internal.h | 182 +++++++++++++++++++++++++++++ 2 files changed, 319 insertions(+), 97 deletions(-) (limited to 'core') diff --git a/core/variant/variant_construct.cpp b/core/variant/variant_construct.cpp index 5c71f38ef1..5281265294 100644 --- a/core/variant/variant_construct.cpp +++ b/core/variant/variant_construct.cpp @@ -448,6 +448,90 @@ public: } }; +template +class VariantConstructNoArgs { +public: + static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { + VariantTypeChanger::change_and_reset(&r_ret); + r_error.error = Callable::CallError::CALL_OK; + } + + static void validated_construct(Variant &r_ret, const Variant **p_args) { + VariantTypeChanger::change_and_reset(&r_ret); + } + static void ptr_construct(void *base, const void **p_args) { + PtrToArg::encode(T(), base); + } + + static int get_argument_count() { + return 0; + } + + static Variant::Type get_argument_type(int p_arg) { + return Variant::NIL; + } + + static Variant::Type get_base_type() { + return GetTypeInfo::VARIANT_TYPE; + } +}; + +class VariantConstructNoArgsNil { +public: + static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { + VariantInternal::clear(&r_ret); + r_error.error = Callable::CallError::CALL_OK; + } + + 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) { + ERR_FAIL_MSG("can't ptrcall nil constructor"); + } + + static int get_argument_count() { + return 0; + } + + static Variant::Type get_argument_type(int p_arg) { + return Variant::NIL; + } + + static Variant::Type get_base_type() { + return Variant::NIL; + } +}; + +class VariantConstructNoArgsObject { +public: + static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { + VariantInternal::clear(&r_ret); + VariantInternal::object_assign_null(&r_ret); + r_error.error = Callable::CallError::CALL_OK; + } + + 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::encode(nullptr, base); + } + + static int get_argument_count() { + return 0; + } + + static Variant::Type get_argument_type(int p_arg) { + return Variant::NIL; + } + + static Variant::Type get_base_type() { + return Variant::OBJECT; + } +}; + struct VariantConstructData { void (*construct)(Variant &r_base, const Variant **p_args, Callable::CallError &r_error); Variant::ValidatedConstructor validated_construct; @@ -459,35 +543,6 @@ struct VariantConstructData { static LocalVector construct_data[Variant::VARIANT_MAX]; -static void variant_initialize_nil(Variant *v) { - VariantInternal::clear(v); -} - -template -static void variant_initialize(Variant *v) { - VariantTypeChanger::change(v); -} - -template -static void variant_initialize_zero(Variant *v) { - VariantTypeChanger::change(v); - *VariantGetInternalPtr::get_ptr(v) = 0; -} - -static void variant_initialize_false(Variant *v) { - VariantTypeChanger::change(v); - *VariantGetInternalPtr::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 static void add_constructor(const Vector &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()) + "."); @@ -503,93 +558,119 @@ static void add_constructor(const Vector &arg_names) { } void Variant::_register_variant_constructors() { + add_constructor(sarray()); add_constructor(sarray("from")); + add_constructor>(sarray()); add_constructor>(sarray("from")); add_constructor>(sarray("from")); add_constructor>(sarray("from")); + add_constructor>(sarray()); add_constructor>(sarray("from")); add_constructor>(sarray("from")); + add_constructor>(sarray()); add_constructor>(sarray("from")); add_constructor>(sarray("from")); + add_constructor>(sarray()); add_constructor>(sarray("from")); add_constructor>(sarray("from")); add_constructor>(sarray("from")); + add_constructor>(sarray()); add_constructor>(sarray("from")); add_constructor>(sarray("from")); add_constructor>(sarray("x", "y")); + add_constructor>(sarray()); add_constructor>(sarray("from")); add_constructor>(sarray("from")); add_constructor>(sarray("x", "y")); + add_constructor>(sarray()); add_constructor>(sarray("from")); add_constructor>(sarray("from")); add_constructor>(sarray("position", "size")); add_constructor>(sarray("x", "y", "width", "height")); + add_constructor>(sarray()); add_constructor>(sarray("from")); add_constructor>(sarray("from")); add_constructor>(sarray("position", "size")); add_constructor>(sarray("x", "y", "width", "height")); + add_constructor>(sarray()); add_constructor>(sarray("from")); add_constructor>(sarray("from")); add_constructor>(sarray("x", "y", "z")); + add_constructor>(sarray()); add_constructor>(sarray("from")); add_constructor>(sarray("from")); add_constructor>(sarray("x", "y", "z")); + add_constructor>(sarray()); add_constructor>(sarray("from")); add_constructor>(sarray("x", "y", "origin")); + add_constructor>(sarray()); add_constructor>(sarray("from")); add_constructor>(sarray("normal", "d")); add_constructor>(sarray("point", "normal")); add_constructor>(sarray("point1", "point2", "point3")); + add_constructor>(sarray()); add_constructor>(sarray("from")); add_constructor>(sarray("from")); add_constructor>(sarray("euler")); add_constructor>(sarray("axis", "angle")); add_constructor>(sarray("arc_from", "arc_to")); + add_constructor>(sarray()); add_constructor>(sarray("from")); add_constructor>(sarray("position", "size")); + add_constructor>(sarray()); add_constructor>(sarray("from")); add_constructor>(sarray("from")); add_constructor>(sarray("x", "y", "z")); + add_constructor>(sarray()); add_constructor>(sarray("from")); add_constructor>(sarray("basis", "origin")); + add_constructor>(sarray()); add_constructor>(sarray("from")); + add_constructor>(sarray()); add_constructor>(sarray("from")); add_constructor>(sarray("from")); + add_constructor>(sarray()); add_constructor>(sarray("from")); add_constructor>(sarray("from")); + add_constructor>(sarray()); add_constructor>(sarray("from")); + add_constructor(sarray()); add_constructor(sarray("from")); add_constructor(sarray("from")); + add_constructor>(sarray()); add_constructor>(sarray("from")); add_constructor(sarray("object", "method")); + add_constructor>(sarray()); add_constructor>(sarray("from")); add_constructor(sarray("object", "signal")); + add_constructor>(sarray()); add_constructor>(sarray("from")); + add_constructor>(sarray()); add_constructor>(sarray("from")); add_constructor>(sarray("from")); add_constructor>(sarray("from")); @@ -601,76 +682,41 @@ void Variant::_register_variant_constructors() { add_constructor>(sarray("from")); add_constructor>(sarray("from")); + add_constructor>(sarray()); add_constructor>(sarray("from")); add_constructor>(sarray("from")); + add_constructor>(sarray()); add_constructor>(sarray("from")); add_constructor>(sarray("from")); + add_constructor>(sarray()); add_constructor>(sarray("from")); add_constructor>(sarray("from")); + add_constructor>(sarray()); add_constructor>(sarray("from")); add_constructor>(sarray("from")); + add_constructor>(sarray()); add_constructor>(sarray("from")); add_constructor>(sarray("from")); + add_constructor>(sarray()); add_constructor>(sarray("from")); add_constructor>(sarray("from")); + add_constructor>(sarray()); add_constructor>(sarray("from")); add_constructor>(sarray("from")); + add_constructor>(sarray()); add_constructor>(sarray("from")); add_constructor>(sarray("from")); + add_constructor>(sarray()); add_constructor>(sarray("from")); add_constructor>(sarray("from")); - - initialize_funcs[NIL] = variant_initialize_nil; - - // atomic types - initialize_funcs[BOOL] = variant_initialize_false; - initialize_funcs[INT] = variant_initialize_zero; - initialize_funcs[FLOAT] = variant_initialize_zero; - initialize_funcs[STRING] = variant_initialize; - - // math types - initialize_funcs[VECTOR2] = variant_initialize; - initialize_funcs[VECTOR2I] = variant_initialize; - initialize_funcs[RECT2] = variant_initialize; - initialize_funcs[RECT2I] = variant_initialize; - initialize_funcs[VECTOR3] = variant_initialize; - initialize_funcs[VECTOR3I] = variant_initialize; - initialize_funcs[TRANSFORM2D] = variant_initialize; - initialize_funcs[PLANE] = variant_initialize; - initialize_funcs[QUAT] = variant_initialize; - initialize_funcs[AABB] = variant_initialize<::AABB>; - initialize_funcs[BASIS] = variant_initialize; - initialize_funcs[TRANSFORM] = variant_initialize; - - // misc types - initialize_funcs[COLOR] = variant_initialize; - initialize_funcs[STRING_NAME] = variant_initialize; - initialize_funcs[NODE_PATH] = variant_initialize; - initialize_funcs[RID] = variant_initialize<::RID>; - initialize_funcs[OBJECT] = variant_initialize_obj; - initialize_funcs[CALLABLE] = variant_initialize; - initialize_funcs[SIGNAL] = variant_initialize; - initialize_funcs[DICTIONARY] = variant_initialize; - initialize_funcs[ARRAY] = variant_initialize; - - // typed arrays - initialize_funcs[PACKED_BYTE_ARRAY] = variant_initialize; - initialize_funcs[PACKED_INT32_ARRAY] = variant_initialize; - initialize_funcs[PACKED_INT64_ARRAY] = variant_initialize; - initialize_funcs[PACKED_FLOAT32_ARRAY] = variant_initialize; - initialize_funcs[PACKED_FLOAT64_ARRAY] = variant_initialize; - initialize_funcs[PACKED_STRING_ARRAY] = variant_initialize; - initialize_funcs[PACKED_VECTOR2_ARRAY] = variant_initialize; - initialize_funcs[PACKED_VECTOR3_ARRAY] = variant_initialize; - initialize_funcs[PACKED_COLOR_ARRAY] = variant_initialize; } void Variant::_unregister_variant_constructors() { @@ -680,35 +726,29 @@ void Variant::_unregister_variant_constructors() { } 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; + 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; } + } - construct_data[p_type][i].construct(base, p_args, r_error); - return; + if (!args_match) { + continue; } - r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; + 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) { diff --git a/core/variant/variant_internal.h b/core/variant/variant_internal.h index eca02ad4ae..3ac7f32dec 100644 --- a/core/variant/variant_internal.h +++ b/core/variant/variant_internal.h @@ -936,6 +936,180 @@ struct VariantInitializer { static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_color_array(v); } }; +template +struct VariantZeroAssigner { +}; + +template <> +struct VariantZeroAssigner { + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_bool(v) = false; } +}; + +template <> +struct VariantZeroAssigner { + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_int(v) = 0; } +}; + +template <> +struct VariantZeroAssigner { + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_float(v) = 0.0; } +}; + +template <> +struct VariantZeroAssigner { + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_float(v) = 0.0; } +}; + +template <> +struct VariantZeroAssigner { + static _FORCE_INLINE_ void zero(Variant *v) {} +}; + +template <> +struct VariantZeroAssigner { + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_vector2(v) = Vector2(); } +}; + +template <> +struct VariantZeroAssigner { + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_vector2i(v) = Vector2i(); } +}; + +template <> +struct VariantZeroAssigner { + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_rect2(v) = Rect2(); } +}; + +template <> +struct VariantZeroAssigner { + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_rect2i(v) = Rect2i(); } +}; + +template <> +struct VariantZeroAssigner { + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_vector3(v) = Vector3(); } +}; + +template <> +struct VariantZeroAssigner { + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_vector3i(v) = Vector3i(); } +}; + +template <> +struct VariantZeroAssigner { + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_transform2d(v) = Transform2D(); } +}; + +template <> +struct VariantZeroAssigner { + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_plane(v) = Plane(); } +}; + +template <> +struct VariantZeroAssigner { + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_quat(v) = Quat(); } +}; + +template <> +struct VariantZeroAssigner { + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_aabb(v) = AABB(); } +}; + +template <> +struct VariantZeroAssigner { + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_basis(v) = Basis(); } +}; + +template <> +struct VariantZeroAssigner { + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_transform(v) = Transform(); } +}; + +template <> +struct VariantZeroAssigner { + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_color(v) = Color(); } +}; + +template <> +struct VariantZeroAssigner { + static _FORCE_INLINE_ void zero(Variant *v) {} +}; + +template <> +struct VariantZeroAssigner { + static _FORCE_INLINE_ void zero(Variant *v) {} +}; + +template <> +struct VariantZeroAssigner<::RID> { + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_rid(v) = RID(); } +}; + +template <> +struct VariantZeroAssigner { + static _FORCE_INLINE_ void zero(Variant *v) {} +}; + +template <> +struct VariantZeroAssigner { + static _FORCE_INLINE_ void zero(Variant *v) {} +}; + +template <> +struct VariantZeroAssigner { + static _FORCE_INLINE_ void zero(Variant *v) {} +}; + +template <> +struct VariantZeroAssigner { + static _FORCE_INLINE_ void zero(Variant *v) {} +}; + +template <> +struct VariantZeroAssigner { + static _FORCE_INLINE_ void zero(Variant *v) {} +}; + +template <> +struct VariantZeroAssigner { + static _FORCE_INLINE_ void zero(Variant *v) {} +}; + +template <> +struct VariantZeroAssigner { + static _FORCE_INLINE_ void zero(Variant *v) {} +}; + +template <> +struct VariantZeroAssigner { + static _FORCE_INLINE_ void zero(Variant *v) {} +}; + +template <> +struct VariantZeroAssigner { + static _FORCE_INLINE_ void zero(Variant *v) {} +}; + +template <> +struct VariantZeroAssigner { + static _FORCE_INLINE_ void zero(Variant *v) {} +}; + +template <> +struct VariantZeroAssigner { + static _FORCE_INLINE_ void zero(Variant *v) {} +}; + +template <> +struct VariantZeroAssigner { + static _FORCE_INLINE_ void zero(Variant *v) {} +}; + +template <> +struct VariantZeroAssigner { + static _FORCE_INLINE_ void zero(Variant *v) {} +}; + template struct VariantTypeChanger { static _FORCE_INLINE_ void change(Variant *v) { @@ -944,6 +1118,14 @@ struct VariantTypeChanger { VariantInitializer::init(v); } } + static _FORCE_INLINE_ void change_and_reset(Variant *v) { + if (v->get_type() != GetTypeInfo::VARIANT_TYPE || GetTypeInfo::VARIANT_TYPE >= Variant::PACKED_BYTE_ARRAY) { //second condition removed by optimizer + VariantInternal::clear(v); + VariantInitializer::init(v); + } + + VariantZeroAssigner::zero(v); + } }; #endif // VARIANT_INTERNAL_H -- cgit v1.2.3