Avoid creating objects that Godot is going to use placement new to initialize
parent
36847f6af0
commit
566742d057
|
@ -190,6 +190,34 @@ struct _GlobalNilClass {
|
||||||
static _GlobalNil _nil;
|
static _GlobalNil _nil;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// This is for allocating uninitialized memory for passing to GDExtension functions that
|
||||||
|
// will use placement new to construct a new object.
|
||||||
|
//
|
||||||
|
// NOTE: You MUST make sure that the value is initialized before the object goes out of
|
||||||
|
// scope, otherwise the destructor will be run on junk memory and "bad things" will happen.
|
||||||
|
template <class T, size_t Alignment = alignof(T)>
|
||||||
|
class ManuallyInitializedValue {
|
||||||
|
typename std::aligned_storage<sizeof(T), Alignment>::type data;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ManuallyInitializedValue() {}
|
||||||
|
|
||||||
|
ManuallyInitializedValue(const ManuallyInitializedValue &) = delete;
|
||||||
|
ManuallyInitializedValue &operator=(const ManuallyInitializedValue &) = delete;
|
||||||
|
|
||||||
|
~ManuallyInitializedValue() {
|
||||||
|
reinterpret_cast<T *>(&data)->~T();
|
||||||
|
}
|
||||||
|
|
||||||
|
T &get() {
|
||||||
|
return *reinterpret_cast<T *>(&data);
|
||||||
|
}
|
||||||
|
|
||||||
|
T *ptr() {
|
||||||
|
return reinterpret_cast<T *>(&data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace godot
|
} // namespace godot
|
||||||
|
|
||||||
#endif // GODOT_MEMORY_HPP
|
#endif // GODOT_MEMORY_HPP
|
||||||
|
|
|
@ -303,9 +303,9 @@ Variant::operator float() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
Variant::operator String() const {
|
Variant::operator String() const {
|
||||||
String result;
|
ManuallyInitializedValue<String> result;
|
||||||
to_type_constructor[STRING](result._native_ptr(), _native_ptr());
|
to_type_constructor[STRING](result.ptr(), _native_ptr());
|
||||||
return result;
|
return result.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
Variant::operator Vector2() const {
|
Variant::operator Vector2() const {
|
||||||
|
@ -405,9 +405,9 @@ Variant::operator Color() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
Variant::operator StringName() const {
|
Variant::operator StringName() const {
|
||||||
StringName result;
|
ManuallyInitializedValue<StringName> result;
|
||||||
to_type_constructor[STRING_NAME](result._native_ptr(), _native_ptr());
|
to_type_constructor[STRING_NAME](result.ptr(), _native_ptr());
|
||||||
return result;
|
return result.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
Variant::operator NodePath() const {
|
Variant::operator NodePath() const {
|
||||||
|
@ -459,15 +459,15 @@ Variant::operator Signal() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
Variant::operator Dictionary() const {
|
Variant::operator Dictionary() const {
|
||||||
Dictionary result;
|
ManuallyInitializedValue<Dictionary> result;
|
||||||
to_type_constructor[DICTIONARY](result._native_ptr(), _native_ptr());
|
to_type_constructor[DICTIONARY](result.ptr(), _native_ptr());
|
||||||
return result;
|
return result.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
Variant::operator Array() const {
|
Variant::operator Array() const {
|
||||||
Array result;
|
ManuallyInitializedValue<Array> result;
|
||||||
to_type_constructor[ARRAY](result._native_ptr(), _native_ptr());
|
to_type_constructor[ARRAY](result.ptr(), _native_ptr());
|
||||||
return result;
|
return result.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
Variant::operator PackedByteArray() const {
|
Variant::operator PackedByteArray() const {
|
||||||
|
@ -607,39 +607,39 @@ void Variant::set_keyed(const Variant &key, const Variant &value, bool &r_valid)
|
||||||
}
|
}
|
||||||
|
|
||||||
Variant Variant::get(const Variant &key, bool *r_valid) const {
|
Variant Variant::get(const Variant &key, bool *r_valid) const {
|
||||||
Variant result;
|
ManuallyInitializedValue<Variant> result;
|
||||||
GDExtensionBool valid;
|
GDExtensionBool valid;
|
||||||
internal::gdextension_interface_variant_get(_native_ptr(), key._native_ptr(), result._native_ptr(), &valid);
|
internal::gdextension_interface_variant_get(_native_ptr(), key._native_ptr(), result.ptr(), &valid);
|
||||||
if (r_valid) {
|
if (r_valid) {
|
||||||
*r_valid = PtrToArg<bool>::convert(&valid);
|
*r_valid = PtrToArg<bool>::convert(&valid);
|
||||||
}
|
}
|
||||||
return result;
|
return result.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
Variant Variant::get_named(const StringName &name, bool &r_valid) const {
|
Variant Variant::get_named(const StringName &name, bool &r_valid) const {
|
||||||
Variant result;
|
ManuallyInitializedValue<Variant> result;
|
||||||
GDExtensionBool valid;
|
GDExtensionBool valid;
|
||||||
internal::gdextension_interface_variant_get_named(_native_ptr(), name._native_ptr(), result._native_ptr(), &valid);
|
internal::gdextension_interface_variant_get_named(_native_ptr(), name._native_ptr(), result.ptr(), &valid);
|
||||||
r_valid = PtrToArg<bool>::convert(&valid);
|
r_valid = PtrToArg<bool>::convert(&valid);
|
||||||
return result;
|
return result.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
Variant Variant::get_indexed(int64_t index, bool &r_valid, bool &r_oob) const {
|
Variant Variant::get_indexed(int64_t index, bool &r_valid, bool &r_oob) const {
|
||||||
Variant result;
|
ManuallyInitializedValue<Variant> result;
|
||||||
GDExtensionBool valid;
|
GDExtensionBool valid;
|
||||||
GDExtensionBool oob;
|
GDExtensionBool oob;
|
||||||
internal::gdextension_interface_variant_get_indexed(_native_ptr(), index, result._native_ptr(), &valid, &oob);
|
internal::gdextension_interface_variant_get_indexed(_native_ptr(), index, result.ptr(), &valid, &oob);
|
||||||
r_valid = PtrToArg<bool>::convert(&valid);
|
r_valid = PtrToArg<bool>::convert(&valid);
|
||||||
r_oob = PtrToArg<bool>::convert(&oob);
|
r_oob = PtrToArg<bool>::convert(&oob);
|
||||||
return result;
|
return result.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
Variant Variant::get_keyed(const Variant &key, bool &r_valid) const {
|
Variant Variant::get_keyed(const Variant &key, bool &r_valid) const {
|
||||||
Variant result;
|
ManuallyInitializedValue<Variant> result;
|
||||||
GDExtensionBool valid;
|
GDExtensionBool valid;
|
||||||
internal::gdextension_interface_variant_get_keyed(_native_ptr(), key._native_ptr(), result._native_ptr(), &valid);
|
internal::gdextension_interface_variant_get_keyed(_native_ptr(), key._native_ptr(), result.ptr(), &valid);
|
||||||
r_valid = PtrToArg<bool>::convert(&valid);
|
r_valid = PtrToArg<bool>::convert(&valid);
|
||||||
return result;
|
return result.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Variant::in(const Variant &index, bool *r_valid) const {
|
bool Variant::in(const Variant &index, bool *r_valid) const {
|
||||||
|
|
Loading…
Reference in New Issue