Merge pull request #1379 from dsnopek/uninitialized-value-mk2

Avoid creating most objects that Godot is going to use placement new to initialize
pull/1413/head
David Snopek 2024-03-14 11:06:59 -05:00 committed by GitHub
commit a62f633ceb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 48 additions and 53 deletions

View File

@ -587,6 +587,8 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
result.append("") result.append("")
result.append("\tstatic struct _MethodBindings {") result.append("\tstatic struct _MethodBindings {")
result.append("\t\tGDExtensionTypeFromVariantConstructorFunc from_variant_constructor;")
if "constructors" in builtin_api: if "constructors" in builtin_api:
for constructor in builtin_api["constructors"]: for constructor in builtin_api["constructors"]:
result.append(f'\t\tGDExtensionPtrConstructor constructor_{constructor["index"]};') result.append(f'\t\tGDExtensionPtrConstructor constructor_{constructor["index"]};')
@ -627,6 +629,9 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
result.append("\tstatic void init_bindings();") result.append("\tstatic void init_bindings();")
result.append("\tstatic void _init_bindings_constructors_destructor();") result.append("\tstatic void _init_bindings_constructors_destructor();")
result.append("")
result.append(f"\t{class_name}(const Variant *p_variant);")
result.append("") result.append("")
result.append("public:") result.append("public:")
@ -962,6 +967,10 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl
result.append(f"void {class_name}::_init_bindings_constructors_destructor() {{") result.append(f"void {class_name}::_init_bindings_constructors_destructor() {{")
result.append(
f"\t_method_bindings.from_variant_constructor = internal::gdextension_interface_get_variant_to_type_constructor({enum_type_name});"
)
if "constructors" in builtin_api: if "constructors" in builtin_api:
for constructor in builtin_api["constructors"]: for constructor in builtin_api["constructors"]:
result.append( result.append(
@ -1043,6 +1052,11 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl
copy_constructor_index = -1 copy_constructor_index = -1
result.append(f"{class_name}::{class_name}(const Variant *p_variant) {{")
result.append("\t_method_bindings.from_variant_constructor(&opaque, p_variant->_native_ptr());")
result.append("}")
result.append("")
if "constructors" in builtin_api: if "constructors" in builtin_api:
for constructor in builtin_api["constructors"]: for constructor in builtin_api["constructors"]:
method_signature = f"{class_name}::{class_name}(" method_signature = f"{class_name}::{class_name}("

View File

@ -47,8 +47,6 @@ class ObjectID;
class Variant { class Variant {
uint8_t opaque[GODOT_CPP_VARIANT_SIZE]{ 0 }; uint8_t opaque[GODOT_CPP_VARIANT_SIZE]{ 0 };
_FORCE_INLINE_ GDExtensionVariantPtr _native_ptr() const { return const_cast<uint8_t(*)[GODOT_CPP_VARIANT_SIZE]>(&opaque); }
friend class GDExtensionBinding; friend class GDExtensionBinding;
friend class MethodBind; friend class MethodBind;
@ -145,6 +143,7 @@ private:
static GDExtensionTypeFromVariantConstructorFunc to_type_constructor[VARIANT_MAX]; static GDExtensionTypeFromVariantConstructorFunc to_type_constructor[VARIANT_MAX];
public: public:
_FORCE_INLINE_ GDExtensionVariantPtr _native_ptr() const { return const_cast<uint8_t(*)[GODOT_CPP_VARIANT_SIZE]>(&opaque); }
Variant(); Variant();
Variant(std::nullptr_t n) : Variant(std::nullptr_t n) :
Variant() {} Variant() {}

View File

@ -303,123 +303,131 @@ Variant::operator float() const {
} }
Variant::operator String() const { Variant::operator String() const {
String result; return String(this);
to_type_constructor[STRING](result._native_ptr(), _native_ptr());
return result;
} }
Variant::operator Vector2() const { Variant::operator Vector2() const {
// @todo Avoid initializing result before calling constructor (which will initialize it again)
Vector2 result; Vector2 result;
to_type_constructor[VECTOR2]((GDExtensionTypePtr)&result, _native_ptr()); to_type_constructor[VECTOR2]((GDExtensionTypePtr)&result, _native_ptr());
return result; return result;
} }
Variant::operator Vector2i() const { Variant::operator Vector2i() const {
// @todo Avoid initializing result before calling constructor (which will initialize it again)
Vector2i result; Vector2i result;
to_type_constructor[VECTOR2I]((GDExtensionTypePtr)&result, _native_ptr()); to_type_constructor[VECTOR2I]((GDExtensionTypePtr)&result, _native_ptr());
return result; return result;
} }
Variant::operator Rect2() const { Variant::operator Rect2() const {
// @todo Avoid initializing result before calling constructor (which will initialize it again)
Rect2 result; Rect2 result;
to_type_constructor[RECT2]((GDExtensionTypePtr)&result, _native_ptr()); to_type_constructor[RECT2]((GDExtensionTypePtr)&result, _native_ptr());
return result; return result;
} }
Variant::operator Rect2i() const { Variant::operator Rect2i() const {
// @todo Avoid initializing result before calling constructor (which will initialize it again)
Rect2i result; Rect2i result;
to_type_constructor[RECT2I]((GDExtensionTypePtr)&result, _native_ptr()); to_type_constructor[RECT2I]((GDExtensionTypePtr)&result, _native_ptr());
return result; return result;
} }
Variant::operator Vector3() const { Variant::operator Vector3() const {
// @todo Avoid initializing result before calling constructor (which will initialize it again)
Vector3 result; Vector3 result;
to_type_constructor[VECTOR3]((GDExtensionTypePtr)&result, _native_ptr()); to_type_constructor[VECTOR3]((GDExtensionTypePtr)&result, _native_ptr());
return result; return result;
} }
Variant::operator Vector3i() const { Variant::operator Vector3i() const {
// @todo Avoid initializing result before calling constructor (which will initialize it again)
Vector3i result; Vector3i result;
to_type_constructor[VECTOR3I]((GDExtensionTypePtr)&result, _native_ptr()); to_type_constructor[VECTOR3I]((GDExtensionTypePtr)&result, _native_ptr());
return result; return result;
} }
Variant::operator Transform2D() const { Variant::operator Transform2D() const {
// @todo Avoid initializing result before calling constructor (which will initialize it again)
Transform2D result; Transform2D result;
to_type_constructor[TRANSFORM2D]((GDExtensionTypePtr)&result, _native_ptr()); to_type_constructor[TRANSFORM2D]((GDExtensionTypePtr)&result, _native_ptr());
return result; return result;
} }
Variant::operator Vector4() const { Variant::operator Vector4() const {
// @todo Avoid initializing result before calling constructor (which will initialize it again)
Vector4 result; Vector4 result;
to_type_constructor[VECTOR4]((GDExtensionTypePtr)&result, _native_ptr()); to_type_constructor[VECTOR4]((GDExtensionTypePtr)&result, _native_ptr());
return result; return result;
} }
Variant::operator Vector4i() const { Variant::operator Vector4i() const {
// @todo Avoid initializing result before calling constructor (which will initialize it again)
Vector4i result; Vector4i result;
to_type_constructor[VECTOR4I]((GDExtensionTypePtr)&result, _native_ptr()); to_type_constructor[VECTOR4I]((GDExtensionTypePtr)&result, _native_ptr());
return result; return result;
} }
Variant::operator Plane() const { Variant::operator Plane() const {
// @todo Avoid initializing result before calling constructor (which will initialize it again)
Plane result; Plane result;
to_type_constructor[PLANE]((GDExtensionTypePtr)&result, _native_ptr()); to_type_constructor[PLANE]((GDExtensionTypePtr)&result, _native_ptr());
return result; return result;
} }
Variant::operator Quaternion() const { Variant::operator Quaternion() const {
// @todo Avoid initializing result before calling constructor (which will initialize it again)
Quaternion result; Quaternion result;
to_type_constructor[QUATERNION]((GDExtensionTypePtr)&result, _native_ptr()); to_type_constructor[QUATERNION]((GDExtensionTypePtr)&result, _native_ptr());
return result; return result;
} }
Variant::operator godot::AABB() const { Variant::operator godot::AABB() const {
// @todo Avoid initializing result before calling constructor (which will initialize it again)
godot::AABB result; godot::AABB result;
to_type_constructor[AABB]((GDExtensionTypePtr)&result, _native_ptr()); to_type_constructor[AABB]((GDExtensionTypePtr)&result, _native_ptr());
return result; return result;
} }
Variant::operator Basis() const { Variant::operator Basis() const {
// @todo Avoid initializing result before calling constructor (which will initialize it again)
Basis result; Basis result;
to_type_constructor[BASIS]((GDExtensionTypePtr)&result, _native_ptr()); to_type_constructor[BASIS]((GDExtensionTypePtr)&result, _native_ptr());
return result; return result;
} }
Variant::operator Transform3D() const { Variant::operator Transform3D() const {
// @todo Avoid initializing result before calling constructor (which will initialize it again)
Transform3D result; Transform3D result;
to_type_constructor[TRANSFORM3D]((GDExtensionTypePtr)&result, _native_ptr()); to_type_constructor[TRANSFORM3D]((GDExtensionTypePtr)&result, _native_ptr());
return result; return result;
} }
Variant::operator Projection() const { Variant::operator Projection() const {
// @todo Avoid initializing result before calling constructor (which will initialize it again)
Projection result; Projection result;
to_type_constructor[PROJECTION]((GDExtensionTypePtr)&result, _native_ptr()); to_type_constructor[PROJECTION]((GDExtensionTypePtr)&result, _native_ptr());
return result; return result;
} }
Variant::operator Color() const { Variant::operator Color() const {
// @todo Avoid initializing result before calling constructor (which will initialize it again)
Color result; Color result;
to_type_constructor[COLOR]((GDExtensionTypePtr)&result, _native_ptr()); to_type_constructor[COLOR]((GDExtensionTypePtr)&result, _native_ptr());
return result; return result;
} }
Variant::operator StringName() const { Variant::operator StringName() const {
StringName result; return StringName(this);
to_type_constructor[STRING_NAME](result._native_ptr(), _native_ptr());
return result;
} }
Variant::operator NodePath() const { Variant::operator NodePath() const {
NodePath result; return NodePath(this);
to_type_constructor[NODE_PATH](result._native_ptr(), _native_ptr());
return result;
} }
Variant::operator godot::RID() const { Variant::operator godot::RID() const {
godot::RID result; return godot::RID(this);
to_type_constructor[RID](result._native_ptr(), _native_ptr());
return result;
} }
Variant::operator Object *() const { Variant::operator Object *() const {
@ -447,81 +455,55 @@ Variant::operator ObjectID() const {
} }
Variant::operator Callable() const { Variant::operator Callable() const {
Callable result; return Callable(this);
to_type_constructor[CALLABLE](result._native_ptr(), _native_ptr());
return result;
} }
Variant::operator Signal() const { Variant::operator Signal() const {
Signal result; return Signal(this);
to_type_constructor[SIGNAL](result._native_ptr(), _native_ptr());
return result;
} }
Variant::operator Dictionary() const { Variant::operator Dictionary() const {
Dictionary result; return Dictionary(this);
to_type_constructor[DICTIONARY](result._native_ptr(), _native_ptr());
return result;
} }
Variant::operator Array() const { Variant::operator Array() const {
Array result; return Array(this);
to_type_constructor[ARRAY](result._native_ptr(), _native_ptr());
return result;
} }
Variant::operator PackedByteArray() const { Variant::operator PackedByteArray() const {
PackedByteArray result; return PackedByteArray(this);
to_type_constructor[PACKED_BYTE_ARRAY](result._native_ptr(), _native_ptr());
return result;
} }
Variant::operator PackedInt32Array() const { Variant::operator PackedInt32Array() const {
PackedInt32Array result; return PackedInt32Array(this);
to_type_constructor[PACKED_INT32_ARRAY](result._native_ptr(), _native_ptr());
return result;
} }
Variant::operator PackedInt64Array() const { Variant::operator PackedInt64Array() const {
PackedInt64Array result; return PackedInt64Array(this);
to_type_constructor[PACKED_INT64_ARRAY](result._native_ptr(), _native_ptr());
return result;
} }
Variant::operator PackedFloat32Array() const { Variant::operator PackedFloat32Array() const {
PackedFloat32Array result; return PackedFloat32Array(this);
to_type_constructor[PACKED_FLOAT32_ARRAY](result._native_ptr(), _native_ptr());
return result;
} }
Variant::operator PackedFloat64Array() const { Variant::operator PackedFloat64Array() const {
PackedFloat64Array result; return PackedFloat64Array(this);
to_type_constructor[PACKED_FLOAT64_ARRAY](result._native_ptr(), _native_ptr());
return result;
} }
Variant::operator PackedStringArray() const { Variant::operator PackedStringArray() const {
PackedStringArray result; return PackedStringArray(this);
to_type_constructor[PACKED_STRING_ARRAY](result._native_ptr(), _native_ptr());
return result;
} }
Variant::operator PackedVector2Array() const { Variant::operator PackedVector2Array() const {
PackedVector2Array result; return PackedVector2Array(this);
to_type_constructor[PACKED_VECTOR2_ARRAY](result._native_ptr(), _native_ptr());
return result;
} }
Variant::operator PackedVector3Array() const { Variant::operator PackedVector3Array() const {
PackedVector3Array result; return PackedVector3Array(this);
to_type_constructor[PACKED_VECTOR3_ARRAY](result._native_ptr(), _native_ptr());
return result;
} }
Variant::operator PackedColorArray() const { Variant::operator PackedColorArray() const {
PackedColorArray result; return PackedColorArray(this);
to_type_constructor[PACKED_COLOR_ARRAY](result._native_ptr(), _native_ptr());
return result;
} }
Variant &Variant::operator=(const Variant &other) { Variant &Variant::operator=(const Variant &other) {