Allow ClassDB to create a Object without postinitialization for GDExtension.

This commit is contained in:
Daylily-Zeleen 2024-04-22 22:34:44 +08:00
parent 8dfb8efaa9
commit 3d575801ce
40 changed files with 345 additions and 140 deletions

View File

@ -36,10 +36,10 @@
/// Resources /// Resources
CryptoKey *(*CryptoKey::_create)() = nullptr; CryptoKey *(*CryptoKey::_create)(bool p_notify_postinitialize) = nullptr;
CryptoKey *CryptoKey::create() { CryptoKey *CryptoKey::create(bool p_notify_postinitialize) {
if (_create) { if (_create) {
return _create(); return _create(p_notify_postinitialize);
} }
return nullptr; return nullptr;
} }
@ -52,10 +52,10 @@ void CryptoKey::_bind_methods() {
ClassDB::bind_method(D_METHOD("load_from_string", "string_key", "public_only"), &CryptoKey::load_from_string, DEFVAL(false)); ClassDB::bind_method(D_METHOD("load_from_string", "string_key", "public_only"), &CryptoKey::load_from_string, DEFVAL(false));
} }
X509Certificate *(*X509Certificate::_create)() = nullptr; X509Certificate *(*X509Certificate::_create)(bool p_notify_postinitialize) = nullptr;
X509Certificate *X509Certificate::create() { X509Certificate *X509Certificate::create(bool p_notify_postinitialize) {
if (_create) { if (_create) {
return _create(); return _create(p_notify_postinitialize);
} }
return nullptr; return nullptr;
} }
@ -116,10 +116,10 @@ void HMACContext::_bind_methods() {
ClassDB::bind_method(D_METHOD("finish"), &HMACContext::finish); ClassDB::bind_method(D_METHOD("finish"), &HMACContext::finish);
} }
HMACContext *(*HMACContext::_create)() = nullptr; HMACContext *(*HMACContext::_create)(bool p_notify_postinitialize) = nullptr;
HMACContext *HMACContext::create() { HMACContext *HMACContext::create(bool p_notify_postinitialize) {
if (_create) { if (_create) {
return _create(); return _create(p_notify_postinitialize);
} }
ERR_FAIL_V_MSG(nullptr, "HMACContext is not available when the mbedtls module is disabled."); ERR_FAIL_V_MSG(nullptr, "HMACContext is not available when the mbedtls module is disabled.");
} }
@ -127,10 +127,10 @@ HMACContext *HMACContext::create() {
/// Crypto /// Crypto
void (*Crypto::_load_default_certificates)(const String &p_path) = nullptr; void (*Crypto::_load_default_certificates)(const String &p_path) = nullptr;
Crypto *(*Crypto::_create)() = nullptr; Crypto *(*Crypto::_create)(bool p_notify_postinitialize) = nullptr;
Crypto *Crypto::create() { Crypto *Crypto::create(bool p_notify_postinitialize) {
if (_create) { if (_create) {
return _create(); return _create(p_notify_postinitialize);
} }
ERR_FAIL_V_MSG(nullptr, "Crypto is not available when the mbedtls module is disabled."); ERR_FAIL_V_MSG(nullptr, "Crypto is not available when the mbedtls module is disabled.");
} }

View File

@ -42,10 +42,10 @@ class CryptoKey : public Resource {
protected: protected:
static void _bind_methods(); static void _bind_methods();
static CryptoKey *(*_create)(); static CryptoKey *(*_create)(bool p_notify_postinitialize);
public: public:
static CryptoKey *create(); static CryptoKey *create(bool p_notify_postinitialize = true);
virtual Error load(const String &p_path, bool p_public_only = false) = 0; virtual Error load(const String &p_path, bool p_public_only = false) = 0;
virtual Error save(const String &p_path, bool p_public_only = false) = 0; virtual Error save(const String &p_path, bool p_public_only = false) = 0;
virtual String save_to_string(bool p_public_only = false) = 0; virtual String save_to_string(bool p_public_only = false) = 0;
@ -58,10 +58,10 @@ class X509Certificate : public Resource {
protected: protected:
static void _bind_methods(); static void _bind_methods();
static X509Certificate *(*_create)(); static X509Certificate *(*_create)(bool p_notify_postinitialize);
public: public:
static X509Certificate *create(); static X509Certificate *create(bool p_notify_postinitialize = true);
virtual Error load(const String &p_path) = 0; virtual Error load(const String &p_path) = 0;
virtual Error load_from_memory(const uint8_t *p_buffer, int p_len) = 0; virtual Error load_from_memory(const uint8_t *p_buffer, int p_len) = 0;
virtual Error save(const String &p_path) = 0; virtual Error save(const String &p_path) = 0;
@ -106,10 +106,10 @@ class HMACContext : public RefCounted {
protected: protected:
static void _bind_methods(); static void _bind_methods();
static HMACContext *(*_create)(); static HMACContext *(*_create)(bool p_notify_postinitialize);
public: public:
static HMACContext *create(); static HMACContext *create(bool p_notify_postinitialize = true);
virtual Error start(HashingContext::HashType p_hash_type, const PackedByteArray &p_key) = 0; virtual Error start(HashingContext::HashType p_hash_type, const PackedByteArray &p_key) = 0;
virtual Error update(const PackedByteArray &p_data) = 0; virtual Error update(const PackedByteArray &p_data) = 0;
@ -124,11 +124,11 @@ class Crypto : public RefCounted {
protected: protected:
static void _bind_methods(); static void _bind_methods();
static Crypto *(*_create)(); static Crypto *(*_create)(bool p_notify_postinitialize);
static void (*_load_default_certificates)(const String &p_path); static void (*_load_default_certificates)(const String &p_path);
public: public:
static Crypto *create(); static Crypto *create(bool p_notify_postinitialize = true);
static void load_default_certificates(const String &p_path); static void load_default_certificates(const String &p_path);
virtual PackedByteArray generate_random_bytes(int p_bytes) = 0; virtual PackedByteArray generate_random_bytes(int p_bytes) = 0;

View File

@ -382,7 +382,7 @@ public:
#ifndef DISABLE_DEPRECATED #ifndef DISABLE_DEPRECATED
void GDExtension::_register_extension_class(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo *p_extension_funcs) { void GDExtension::_register_extension_class(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo *p_extension_funcs) {
const GDExtensionClassCreationInfo3 class_info3 = { const GDExtensionClassCreationInfo4 class_info4 = {
p_extension_funcs->is_virtual, // GDExtensionBool is_virtual; p_extension_funcs->is_virtual, // GDExtensionBool is_virtual;
p_extension_funcs->is_abstract, // GDExtensionBool is_abstract; p_extension_funcs->is_abstract, // GDExtensionBool is_abstract;
true, // GDExtensionBool is_exposed; true, // GDExtensionBool is_exposed;
@ -398,7 +398,7 @@ void GDExtension::_register_extension_class(GDExtensionClassLibraryPtr p_library
p_extension_funcs->to_string_func, // GDExtensionClassToString to_string_func; p_extension_funcs->to_string_func, // GDExtensionClassToString to_string_func;
p_extension_funcs->reference_func, // GDExtensionClassReference reference_func; p_extension_funcs->reference_func, // GDExtensionClassReference reference_func;
p_extension_funcs->unreference_func, // GDExtensionClassUnreference unreference_func; p_extension_funcs->unreference_func, // GDExtensionClassUnreference unreference_func;
p_extension_funcs->create_instance_func, // GDExtensionClassCreateInstance create_instance_func; /* this one is mandatory */ nullptr, // GDExtensionClassCreateInstance2 create_instance_func; /* this one is mandatory */
p_extension_funcs->free_instance_func, // GDExtensionClassFreeInstance free_instance_func; /* this one is mandatory */ p_extension_funcs->free_instance_func, // GDExtensionClassFreeInstance free_instance_func; /* this one is mandatory */
nullptr, // GDExtensionClassRecreateInstance recreate_instance_func; nullptr, // GDExtensionClassRecreateInstance recreate_instance_func;
p_extension_funcs->get_virtual_func, // GDExtensionClassGetVirtual get_virtual_func; p_extension_funcs->get_virtual_func, // GDExtensionClassGetVirtual get_virtual_func;
@ -411,12 +411,13 @@ void GDExtension::_register_extension_class(GDExtensionClassLibraryPtr p_library
const ClassCreationDeprecatedInfo legacy = { const ClassCreationDeprecatedInfo legacy = {
p_extension_funcs->notification_func, // GDExtensionClassNotification notification_func; p_extension_funcs->notification_func, // GDExtensionClassNotification notification_func;
p_extension_funcs->free_property_list_func, // GDExtensionClassFreePropertyList free_property_list_func; p_extension_funcs->free_property_list_func, // GDExtensionClassFreePropertyList free_property_list_func;
p_extension_funcs->create_instance_func, // GDExtensionClassCreateInstance create_instance_func;
}; };
_register_extension_class_internal(p_library, p_class_name, p_parent_class_name, &class_info3, &legacy); _register_extension_class_internal(p_library, p_class_name, p_parent_class_name, &class_info4, &legacy);
} }
void GDExtension::_register_extension_class2(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo2 *p_extension_funcs) { void GDExtension::_register_extension_class2(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo2 *p_extension_funcs) {
const GDExtensionClassCreationInfo3 class_info3 = { const GDExtensionClassCreationInfo4 class_info4 = {
p_extension_funcs->is_virtual, // GDExtensionBool is_virtual; p_extension_funcs->is_virtual, // GDExtensionBool is_virtual;
p_extension_funcs->is_abstract, // GDExtensionBool is_abstract; p_extension_funcs->is_abstract, // GDExtensionBool is_abstract;
p_extension_funcs->is_exposed, // GDExtensionBool is_exposed; p_extension_funcs->is_exposed, // GDExtensionBool is_exposed;
@ -432,7 +433,7 @@ void GDExtension::_register_extension_class2(GDExtensionClassLibraryPtr p_librar
p_extension_funcs->to_string_func, // GDExtensionClassToString to_string_func; p_extension_funcs->to_string_func, // GDExtensionClassToString to_string_func;
p_extension_funcs->reference_func, // GDExtensionClassReference reference_func; p_extension_funcs->reference_func, // GDExtensionClassReference reference_func;
p_extension_funcs->unreference_func, // GDExtensionClassUnreference unreference_func; p_extension_funcs->unreference_func, // GDExtensionClassUnreference unreference_func;
p_extension_funcs->create_instance_func, // GDExtensionClassCreateInstance create_instance_func; /* this one is mandatory */ nullptr, // GDExtensionClassCreateInstance2 create_instance_func; /* this one is mandatory */
p_extension_funcs->free_instance_func, // GDExtensionClassFreeInstance free_instance_func; /* this one is mandatory */ p_extension_funcs->free_instance_func, // GDExtensionClassFreeInstance free_instance_func; /* this one is mandatory */
p_extension_funcs->recreate_instance_func, // GDExtensionClassRecreateInstance recreate_instance_func; p_extension_funcs->recreate_instance_func, // GDExtensionClassRecreateInstance recreate_instance_func;
p_extension_funcs->get_virtual_func, // GDExtensionClassGetVirtual get_virtual_func; p_extension_funcs->get_virtual_func, // GDExtensionClassGetVirtual get_virtual_func;
@ -445,16 +446,53 @@ void GDExtension::_register_extension_class2(GDExtensionClassLibraryPtr p_librar
const ClassCreationDeprecatedInfo legacy = { const ClassCreationDeprecatedInfo legacy = {
nullptr, // GDExtensionClassNotification notification_func; nullptr, // GDExtensionClassNotification notification_func;
p_extension_funcs->free_property_list_func, // GDExtensionClassFreePropertyList free_property_list_func; p_extension_funcs->free_property_list_func, // GDExtensionClassFreePropertyList free_property_list_func;
p_extension_funcs->create_instance_func, // GDExtensionClassCreateInstance create_instance_func;
}; };
_register_extension_class_internal(p_library, p_class_name, p_parent_class_name, &class_info3, &legacy); _register_extension_class_internal(p_library, p_class_name, p_parent_class_name, &class_info4, &legacy);
} }
#endif // DISABLE_DEPRECATED
void GDExtension::_register_extension_class3(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo3 *p_extension_funcs) { void GDExtension::_register_extension_class3(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo3 *p_extension_funcs) {
const GDExtensionClassCreationInfo4 class_info4 = {
p_extension_funcs->is_virtual, // GDExtensionBool is_virtual;
p_extension_funcs->is_abstract, // GDExtensionBool is_abstract;
p_extension_funcs->is_exposed, // GDExtensionBool is_exposed;
p_extension_funcs->is_runtime, // GDExtensionBool is_runtime;
p_extension_funcs->set_func, // GDExtensionClassSet set_func;
p_extension_funcs->get_func, // GDExtensionClassGet get_func;
p_extension_funcs->get_property_list_func, // GDExtensionClassGetPropertyList get_property_list_func;
p_extension_funcs->free_property_list_func, // GDExtensionClassFreePropertyList free_property_list_func;
p_extension_funcs->property_can_revert_func, // GDExtensionClassPropertyCanRevert property_can_revert_func;
p_extension_funcs->property_get_revert_func, // GDExtensionClassPropertyGetRevert property_get_revert_func;
p_extension_funcs->validate_property_func, // GDExtensionClassValidateProperty validate_property_func;
p_extension_funcs->notification_func, // GDExtensionClassNotification2 notification_func;
p_extension_funcs->to_string_func, // GDExtensionClassToString to_string_func;
p_extension_funcs->reference_func, // GDExtensionClassReference reference_func;
p_extension_funcs->unreference_func, // GDExtensionClassUnreference unreference_func;
nullptr, // GDExtensionClassCreateInstance2 create_instance_func; /* this one is mandatory */
p_extension_funcs->free_instance_func, // GDExtensionClassFreeInstance free_instance_func; /* this one is mandatory */
p_extension_funcs->recreate_instance_func, // GDExtensionClassRecreateInstance recreate_instance_func;
p_extension_funcs->get_virtual_func, // GDExtensionClassGetVirtual get_virtual_func;
p_extension_funcs->get_virtual_call_data_func, // GDExtensionClassGetVirtualCallData get_virtual_call_data_func;
p_extension_funcs->call_virtual_with_data_func, // GDExtensionClassCallVirtualWithData call_virtual_func;
p_extension_funcs->get_rid_func, // GDExtensionClassGetRID get_rid;
p_extension_funcs->class_userdata, // void *class_userdata;
};
const ClassCreationDeprecatedInfo legacy = {
nullptr, // GDExtensionClassNotification notification_func;
nullptr, // GDExtensionClassFreePropertyList free_property_list_func;
p_extension_funcs->create_instance_func, // GDExtensionClassCreateInstance2 create_instance_func;
};
_register_extension_class_internal(p_library, p_class_name, p_parent_class_name, &class_info4, &legacy);
}
#endif // DISABLE_DEPRECATED
void GDExtension::_register_extension_class4(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo4 *p_extension_funcs) {
_register_extension_class_internal(p_library, p_class_name, p_parent_class_name, p_extension_funcs); _register_extension_class_internal(p_library, p_class_name, p_parent_class_name, p_extension_funcs);
} }
void GDExtension::_register_extension_class_internal(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo3 *p_extension_funcs, const ClassCreationDeprecatedInfo *p_deprecated_funcs) { void GDExtension::_register_extension_class_internal(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo4 *p_extension_funcs, const ClassCreationDeprecatedInfo *p_deprecated_funcs) {
GDExtension *self = reinterpret_cast<GDExtension *>(p_library); GDExtension *self = reinterpret_cast<GDExtension *>(p_library);
StringName class_name = *reinterpret_cast<const StringName *>(p_class_name); StringName class_name = *reinterpret_cast<const StringName *>(p_class_name);
@ -530,6 +568,7 @@ void GDExtension::_register_extension_class_internal(GDExtensionClassLibraryPtr
if (p_deprecated_funcs) { if (p_deprecated_funcs) {
extension->gdextension.notification = p_deprecated_funcs->notification_func; extension->gdextension.notification = p_deprecated_funcs->notification_func;
extension->gdextension.free_property_list = p_deprecated_funcs->free_property_list_func; extension->gdextension.free_property_list = p_deprecated_funcs->free_property_list_func;
extension->gdextension.create_instance = p_deprecated_funcs->create_instance_func;
} }
#endif // DISABLE_DEPRECATED #endif // DISABLE_DEPRECATED
extension->gdextension.notification2 = p_extension_funcs->notification_func; extension->gdextension.notification2 = p_extension_funcs->notification_func;
@ -537,7 +576,7 @@ void GDExtension::_register_extension_class_internal(GDExtensionClassLibraryPtr
extension->gdextension.reference = p_extension_funcs->reference_func; extension->gdextension.reference = p_extension_funcs->reference_func;
extension->gdextension.unreference = p_extension_funcs->unreference_func; extension->gdextension.unreference = p_extension_funcs->unreference_func;
extension->gdextension.class_userdata = p_extension_funcs->class_userdata; extension->gdextension.class_userdata = p_extension_funcs->class_userdata;
extension->gdextension.create_instance = p_extension_funcs->create_instance_func; extension->gdextension.create_instance2 = p_extension_funcs->create_instance_func;
extension->gdextension.free_instance = p_extension_funcs->free_instance_func; extension->gdextension.free_instance = p_extension_funcs->free_instance_func;
extension->gdextension.recreate_instance = p_extension_funcs->recreate_instance_func; extension->gdextension.recreate_instance = p_extension_funcs->recreate_instance_func;
extension->gdextension.get_virtual = p_extension_funcs->get_virtual_func; extension->gdextension.get_virtual = p_extension_funcs->get_virtual_func;
@ -888,8 +927,9 @@ void GDExtension::initialize_gdextensions() {
#ifndef DISABLE_DEPRECATED #ifndef DISABLE_DEPRECATED
register_interface_function("classdb_register_extension_class", (GDExtensionInterfaceFunctionPtr)&GDExtension::_register_extension_class); register_interface_function("classdb_register_extension_class", (GDExtensionInterfaceFunctionPtr)&GDExtension::_register_extension_class);
register_interface_function("classdb_register_extension_class2", (GDExtensionInterfaceFunctionPtr)&GDExtension::_register_extension_class2); register_interface_function("classdb_register_extension_class2", (GDExtensionInterfaceFunctionPtr)&GDExtension::_register_extension_class2);
#endif // DISABLE_DEPRECATED
register_interface_function("classdb_register_extension_class3", (GDExtensionInterfaceFunctionPtr)&GDExtension::_register_extension_class3); register_interface_function("classdb_register_extension_class3", (GDExtensionInterfaceFunctionPtr)&GDExtension::_register_extension_class3);
#endif // DISABLE_DEPRECATED
register_interface_function("classdb_register_extension_class4", (GDExtensionInterfaceFunctionPtr)&GDExtension::_register_extension_class4);
register_interface_function("classdb_register_extension_class_method", (GDExtensionInterfaceFunctionPtr)&GDExtension::_register_extension_class_method); register_interface_function("classdb_register_extension_class_method", (GDExtensionInterfaceFunctionPtr)&GDExtension::_register_extension_class_method);
register_interface_function("classdb_register_extension_class_virtual_method", (GDExtensionInterfaceFunctionPtr)&GDExtension::_register_extension_class_virtual_method); register_interface_function("classdb_register_extension_class_virtual_method", (GDExtensionInterfaceFunctionPtr)&GDExtension::_register_extension_class_virtual_method);
register_interface_function("classdb_register_extension_class_integer_constant", (GDExtensionInterfaceFunctionPtr)&GDExtension::_register_extension_class_integer_constant); register_interface_function("classdb_register_extension_class_integer_constant", (GDExtensionInterfaceFunctionPtr)&GDExtension::_register_extension_class_integer_constant);

View File

@ -72,15 +72,17 @@ class GDExtension : public Resource {
#ifndef DISABLE_DEPRECATED #ifndef DISABLE_DEPRECATED
GDExtensionClassNotification notification_func = nullptr; GDExtensionClassNotification notification_func = nullptr;
GDExtensionClassFreePropertyList free_property_list_func = nullptr; GDExtensionClassFreePropertyList free_property_list_func = nullptr;
GDExtensionClassCreateInstance create_instance_func = nullptr;
#endif // DISABLE_DEPRECATED #endif // DISABLE_DEPRECATED
}; };
#ifndef DISABLE_DEPRECATED #ifndef DISABLE_DEPRECATED
static void _register_extension_class(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo *p_extension_funcs); static void _register_extension_class(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo *p_extension_funcs);
static void _register_extension_class2(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo2 *p_extension_funcs); static void _register_extension_class2(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo2 *p_extension_funcs);
#endif // DISABLE_DEPRECATED
static void _register_extension_class3(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo3 *p_extension_funcs); static void _register_extension_class3(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo3 *p_extension_funcs);
static void _register_extension_class_internal(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo3 *p_extension_funcs, const ClassCreationDeprecatedInfo *p_deprecated_funcs = nullptr); #endif // DISABLE_DEPRECATED
static void _register_extension_class4(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo4 *p_extension_funcs);
static void _register_extension_class_internal(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo4 *p_extension_funcs, const ClassCreationDeprecatedInfo *p_deprecated_funcs = nullptr);
static void _register_extension_class_method(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, const GDExtensionClassMethodInfo *p_method_info); static void _register_extension_class_method(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, const GDExtensionClassMethodInfo *p_method_info);
static void _register_extension_class_virtual_method(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, const GDExtensionClassVirtualMethodInfo *p_method_info); static void _register_extension_class_virtual_method(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, const GDExtensionClassVirtualMethodInfo *p_method_info);
static void _register_extension_class_integer_constant(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_enum_name, GDExtensionConstStringNamePtr p_constant_name, GDExtensionInt p_constant_value, GDExtensionBool p_is_bitfield); static void _register_extension_class_integer_constant(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_enum_name, GDExtensionConstStringNamePtr p_constant_name, GDExtensionInt p_constant_value, GDExtensionBool p_is_bitfield);

View File

@ -1515,10 +1515,17 @@ static GDExtensionMethodBindPtr gdextension_classdb_get_method_bind(GDExtensionC
return (GDExtensionMethodBindPtr)mb; return (GDExtensionMethodBindPtr)mb;
} }
#ifndef DISABLE_DEPRECATED
static GDExtensionObjectPtr gdextension_classdb_construct_object(GDExtensionConstStringNamePtr p_classname) { static GDExtensionObjectPtr gdextension_classdb_construct_object(GDExtensionConstStringNamePtr p_classname) {
const StringName classname = *reinterpret_cast<const StringName *>(p_classname); const StringName classname = *reinterpret_cast<const StringName *>(p_classname);
return (GDExtensionObjectPtr)ClassDB::instantiate_no_placeholders(classname); return (GDExtensionObjectPtr)ClassDB::instantiate_no_placeholders(classname);
} }
#endif
static GDExtensionObjectPtr gdextension_classdb_construct_object2(GDExtensionConstStringNamePtr p_classname) {
const StringName classname = *reinterpret_cast<const StringName *>(p_classname);
return (GDExtensionObjectPtr)ClassDB::instantiate_without_postinitialization(classname);
}
static void *gdextension_classdb_get_class_tag(GDExtensionConstStringNamePtr p_classname) { static void *gdextension_classdb_get_class_tag(GDExtensionConstStringNamePtr p_classname) {
const StringName classname = *reinterpret_cast<const StringName *>(p_classname); const StringName classname = *reinterpret_cast<const StringName *>(p_classname);
@ -1701,7 +1708,10 @@ void gdextension_setup_interface() {
#endif // DISABLE_DEPRECATED #endif // DISABLE_DEPRECATED
REGISTER_INTERFACE_FUNC(callable_custom_create2); REGISTER_INTERFACE_FUNC(callable_custom_create2);
REGISTER_INTERFACE_FUNC(callable_custom_get_userdata); REGISTER_INTERFACE_FUNC(callable_custom_get_userdata);
#ifndef DISABLE_DEPRECATED
REGISTER_INTERFACE_FUNC(classdb_construct_object); REGISTER_INTERFACE_FUNC(classdb_construct_object);
#endif // DISABLE_DEPRECATED
REGISTER_INTERFACE_FUNC(classdb_construct_object2);
REGISTER_INTERFACE_FUNC(classdb_get_method_bind); REGISTER_INTERFACE_FUNC(classdb_get_method_bind);
REGISTER_INTERFACE_FUNC(classdb_get_class_tag); REGISTER_INTERFACE_FUNC(classdb_get_class_tag);
REGISTER_INTERFACE_FUNC(editor_add_plugin); REGISTER_INTERFACE_FUNC(editor_add_plugin);

View File

@ -268,6 +268,7 @@ typedef void (*GDExtensionClassReference)(GDExtensionClassInstancePtr p_instance
typedef void (*GDExtensionClassUnreference)(GDExtensionClassInstancePtr p_instance); typedef void (*GDExtensionClassUnreference)(GDExtensionClassInstancePtr p_instance);
typedef void (*GDExtensionClassCallVirtual)(GDExtensionClassInstancePtr p_instance, const GDExtensionConstTypePtr *p_args, GDExtensionTypePtr r_ret); typedef void (*GDExtensionClassCallVirtual)(GDExtensionClassInstancePtr p_instance, const GDExtensionConstTypePtr *p_args, GDExtensionTypePtr r_ret);
typedef GDExtensionObjectPtr (*GDExtensionClassCreateInstance)(void *p_class_userdata); typedef GDExtensionObjectPtr (*GDExtensionClassCreateInstance)(void *p_class_userdata);
typedef GDExtensionObjectPtr (*GDExtensionClassCreateInstance2)(void *p_class_userdata, bool p_notify_postinitialize);
typedef void (*GDExtensionClassFreeInstance)(void *p_class_userdata, GDExtensionClassInstancePtr p_instance); typedef void (*GDExtensionClassFreeInstance)(void *p_class_userdata, GDExtensionClassInstancePtr p_instance);
typedef GDExtensionClassInstancePtr (*GDExtensionClassRecreateInstance)(void *p_class_userdata, GDExtensionObjectPtr p_object); typedef GDExtensionClassInstancePtr (*GDExtensionClassRecreateInstance)(void *p_class_userdata, GDExtensionObjectPtr p_object);
typedef GDExtensionClassCallVirtual (*GDExtensionClassGetVirtual)(void *p_class_userdata, GDExtensionConstStringNamePtr p_name); typedef GDExtensionClassCallVirtual (*GDExtensionClassGetVirtual)(void *p_class_userdata, GDExtensionConstStringNamePtr p_name);
@ -292,7 +293,7 @@ typedef struct {
GDExtensionClassGetVirtual get_virtual_func; // Queries a virtual function by name and returns a callback to invoke the requested virtual function. GDExtensionClassGetVirtual get_virtual_func; // Queries a virtual function by name and returns a callback to invoke the requested virtual function.
GDExtensionClassGetRID get_rid_func; GDExtensionClassGetRID get_rid_func;
void *class_userdata; // Per-class user data, later accessible in instance bindings. void *class_userdata; // Per-class user data, later accessible in instance bindings.
} GDExtensionClassCreationInfo; // Deprecated. Use GDExtensionClassCreationInfo3 instead. } GDExtensionClassCreationInfo; // Deprecated. Use GDExtensionClassCreationInfo4 instead.
typedef struct { typedef struct {
GDExtensionBool is_virtual; GDExtensionBool is_virtual;
@ -325,7 +326,7 @@ typedef struct {
GDExtensionClassCallVirtualWithData call_virtual_with_data_func; GDExtensionClassCallVirtualWithData call_virtual_with_data_func;
GDExtensionClassGetRID get_rid_func; GDExtensionClassGetRID get_rid_func;
void *class_userdata; // Per-class user data, later accessible in instance bindings. void *class_userdata; // Per-class user data, later accessible in instance bindings.
} GDExtensionClassCreationInfo2; // Deprecated. Use GDExtensionClassCreationInfo3 instead. } GDExtensionClassCreationInfo2; // Deprecated. Use GDExtensionClassCreationInfo4 instead.
typedef struct { typedef struct {
GDExtensionBool is_virtual; GDExtensionBool is_virtual;
@ -359,7 +360,41 @@ typedef struct {
GDExtensionClassCallVirtualWithData call_virtual_with_data_func; GDExtensionClassCallVirtualWithData call_virtual_with_data_func;
GDExtensionClassGetRID get_rid_func; GDExtensionClassGetRID get_rid_func;
void *class_userdata; // Per-class user data, later accessible in instance bindings. void *class_userdata; // Per-class user data, later accessible in instance bindings.
} GDExtensionClassCreationInfo3; } GDExtensionClassCreationInfo3; // Deprecated. Use GDExtensionClassCreationInfo4 instead.
typedef struct {
GDExtensionBool is_virtual;
GDExtensionBool is_abstract;
GDExtensionBool is_exposed;
GDExtensionBool is_runtime;
GDExtensionClassSet set_func;
GDExtensionClassGet get_func;
GDExtensionClassGetPropertyList get_property_list_func;
GDExtensionClassFreePropertyList2 free_property_list_func;
GDExtensionClassPropertyCanRevert property_can_revert_func;
GDExtensionClassPropertyGetRevert property_get_revert_func;
GDExtensionClassValidateProperty validate_property_func;
GDExtensionClassNotification2 notification_func;
GDExtensionClassToString to_string_func;
GDExtensionClassReference reference_func;
GDExtensionClassUnreference unreference_func;
GDExtensionClassCreateInstance2 create_instance_func; // (Default) constructor; mandatory. If the class is not instantiable, consider making it virtual or abstract.
GDExtensionClassFreeInstance free_instance_func; // Destructor; mandatory.
GDExtensionClassRecreateInstance recreate_instance_func;
// Queries a virtual function by name and returns a callback to invoke the requested virtual function.
GDExtensionClassGetVirtual get_virtual_func;
// Paired with `call_virtual_with_data_func`, this is an alternative to `get_virtual_func` for extensions that
// need or benefit from extra data when calling virtual functions.
// Returns user data that will be passed to `call_virtual_with_data_func`.
// Returning `NULL` from this function signals to Godot that the virtual function is not overridden.
// Data returned from this function should be managed by the extension and must be valid until the extension is deinitialized.
// You should supply either `get_virtual_func`, or `get_virtual_call_data_func` with `call_virtual_with_data_func`.
GDExtensionClassGetVirtualCallData get_virtual_call_data_func;
// Used to call virtual functions when `get_virtual_call_data_func` is not null.
GDExtensionClassCallVirtualWithData call_virtual_with_data_func;
GDExtensionClassGetRID get_rid_func;
void *class_userdata; // Per-class user data, later accessible in instance bindings.
} GDExtensionClassCreationInfo4;
typedef void *GDExtensionClassLibraryPtr; typedef void *GDExtensionClassLibraryPtr;
@ -2680,6 +2715,7 @@ typedef void *(*GDExtensionInterfaceCallableCustomGetUserData)(GDExtensionConstT
/** /**
* @name classdb_construct_object * @name classdb_construct_object
* @since 4.1 * @since 4.1
* @deprecated in Godot 4.4. Use `classdb_construct_object2` instead.
* *
* Constructs an Object of the requested class. * Constructs an Object of the requested class.
* *
@ -2691,6 +2727,22 @@ typedef void *(*GDExtensionInterfaceCallableCustomGetUserData)(GDExtensionConstT
*/ */
typedef GDExtensionObjectPtr (*GDExtensionInterfaceClassdbConstructObject)(GDExtensionConstStringNamePtr p_classname); typedef GDExtensionObjectPtr (*GDExtensionInterfaceClassdbConstructObject)(GDExtensionConstStringNamePtr p_classname);
/**
* @name classdb_construct_object2
* @since 4.4
*
* Constructs an Object of the requested class.
*
* The passed class must be a built-in godot class, or an already-registered extension class. In both cases, object_set_instance() should be called to fully initialize the object.
*
* "NOTIFICATION_POSTINITIALIZE" must be sent after construction.
*
* @param p_classname A pointer to a StringName with the class name.
*
* @return A pointer to the newly created Object.
*/
typedef GDExtensionObjectPtr (*GDExtensionInterfaceClassdbConstructObject2)(GDExtensionConstStringNamePtr p_classname);
/** /**
* @name classdb_get_method_bind * @name classdb_get_method_bind
* @since 4.1 * @since 4.1
@ -2722,7 +2774,7 @@ typedef void *(*GDExtensionInterfaceClassdbGetClassTag)(GDExtensionConstStringNa
/** /**
* @name classdb_register_extension_class * @name classdb_register_extension_class
* @since 4.1 * @since 4.1
* @deprecated in Godot 4.2. Use `classdb_register_extension_class3` instead. * @deprecated in Godot 4.2. Use `classdb_register_extension_class4` instead.
* *
* Registers an extension class in the ClassDB. * Registers an extension class in the ClassDB.
* *
@ -2738,7 +2790,7 @@ typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClass)(GDExtensionCla
/** /**
* @name classdb_register_extension_class2 * @name classdb_register_extension_class2
* @since 4.2 * @since 4.2
* @deprecated in Godot 4.3. Use `classdb_register_extension_class3` instead. * @deprecated in Godot 4.3. Use `classdb_register_extension_class4` instead.
* *
* Registers an extension class in the ClassDB. * Registers an extension class in the ClassDB.
* *
@ -2754,6 +2806,7 @@ typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClass2)(GDExtensionCl
/** /**
* @name classdb_register_extension_class3 * @name classdb_register_extension_class3
* @since 4.3 * @since 4.3
* @deprecated in Godot 4.4. Use `classdb_register_extension_class4` instead.
* *
* Registers an extension class in the ClassDB. * Registers an extension class in the ClassDB.
* *
@ -2766,6 +2819,21 @@ typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClass2)(GDExtensionCl
*/ */
typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClass3)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo3 *p_extension_funcs); typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClass3)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo3 *p_extension_funcs);
/**
* @name classdb_register_extension_class4
* @since 4.4
*
* Registers an extension class in the ClassDB.
*
* Provided struct can be safely freed once the function returns.
*
* @param p_library A pointer the library received by the GDExtension's entry point function.
* @param p_class_name A pointer to a StringName with the class name.
* @param p_parent_class_name A pointer to a StringName with the parent class name.
* @param p_extension_funcs A pointer to a GDExtensionClassCreationInfo2 struct.
*/
typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClass4)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo4 *p_extension_funcs);
/** /**
* @name classdb_register_extension_class_method * @name classdb_register_extension_class_method
* @since 4.1 * @since 4.1

View File

@ -33,12 +33,12 @@
#include "core/config/project_settings.h" #include "core/config/project_settings.h"
#include "core/io/file_access.h" #include "core/io/file_access.h"
DTLSServer *(*DTLSServer::_create)() = nullptr; DTLSServer *(*DTLSServer::_create)(bool p_notify_postinitialize) = nullptr;
bool DTLSServer::available = false; bool DTLSServer::available = false;
DTLSServer *DTLSServer::create() { DTLSServer *DTLSServer::create(bool p_notify_postinitialize) {
if (_create) { if (_create) {
return _create(); return _create(p_notify_postinitialize);
} }
return nullptr; return nullptr;
} }

View File

@ -38,14 +38,14 @@ class DTLSServer : public RefCounted {
GDCLASS(DTLSServer, RefCounted); GDCLASS(DTLSServer, RefCounted);
protected: protected:
static DTLSServer *(*_create)(); static DTLSServer *(*_create)(bool p_notify_postinitialize);
static void _bind_methods(); static void _bind_methods();
static bool available; static bool available;
public: public:
static bool is_available(); static bool is_available();
static DTLSServer *create(); static DTLSServer *create(bool p_notify_postinitialize = true);
virtual Error setup(Ref<TLSOptions> p_options) = 0; virtual Error setup(Ref<TLSOptions> p_options) = 0;
virtual void stop() = 0; virtual void stop() = 0;

View File

@ -42,9 +42,9 @@ const char *HTTPClient::_methods[METHOD_MAX] = {
"PATCH" "PATCH"
}; };
HTTPClient *HTTPClient::create() { HTTPClient *HTTPClient::create(bool p_notify_postinitialize) {
if (_create) { if (_create) {
return _create(); return _create(p_notify_postinitialize);
} }
return nullptr; return nullptr;
} }

View File

@ -158,12 +158,12 @@ protected:
Error _request_raw(Method p_method, const String &p_url, const Vector<String> &p_headers, const Vector<uint8_t> &p_body); Error _request_raw(Method p_method, const String &p_url, const Vector<String> &p_headers, const Vector<uint8_t> &p_body);
Error _request(Method p_method, const String &p_url, const Vector<String> &p_headers, const String &p_body = String()); Error _request(Method p_method, const String &p_url, const Vector<String> &p_headers, const String &p_body = String());
static HTTPClient *(*_create)(); static HTTPClient *(*_create)(bool p_notify_postinitialize);
static void _bind_methods(); static void _bind_methods();
public: public:
static HTTPClient *create(); static HTTPClient *create(bool p_notify_postinitialize = true);
String query_string_from_dict(const Dictionary &p_dict); String query_string_from_dict(const Dictionary &p_dict);
Error verify_headers(const Vector<String> &p_headers); Error verify_headers(const Vector<String> &p_headers);

View File

@ -35,8 +35,8 @@
#include "core/io/stream_peer_tls.h" #include "core/io/stream_peer_tls.h"
#include "core/version.h" #include "core/version.h"
HTTPClient *HTTPClientTCP::_create_func() { HTTPClient *HTTPClientTCP::_create_func(bool p_notify_postinitialize) {
return memnew(HTTPClientTCP); return static_cast<HTTPClient *>(ClassDB::creator<HTTPClientTCP>(p_notify_postinitialize));
} }
Error HTTPClientTCP::connect_to_host(const String &p_host, int p_port, Ref<TLSOptions> p_options) { Error HTTPClientTCP::connect_to_host(const String &p_host, int p_port, Ref<TLSOptions> p_options) {
@ -792,6 +792,6 @@ HTTPClientTCP::HTTPClientTCP() {
request_buffer.instantiate(); request_buffer.instantiate();
} }
HTTPClient *(*HTTPClient::_create)() = HTTPClientTCP::_create_func; HTTPClient *(*HTTPClient::_create)(bool p_notify_postinitialize) = HTTPClientTCP::_create_func;
#endif // WEB_ENABLED #endif // WEB_ENABLED

View File

@ -76,7 +76,7 @@ private:
Error _get_http_data(uint8_t *p_buffer, int p_bytes, int &r_received); Error _get_http_data(uint8_t *p_buffer, int p_bytes, int &r_received);
public: public:
static HTTPClient *_create_func(); static HTTPClient *_create_func(bool p_notify_postinitialize);
Error request(Method p_method, const String &p_url, const Vector<String> &p_headers, const uint8_t *p_body, int p_body_size) override; Error request(Method p_method, const String &p_url, const Vector<String> &p_headers, const uint8_t *p_body, int p_body_size) override;

View File

@ -32,12 +32,12 @@
#include "core/config/project_settings.h" #include "core/config/project_settings.h"
#include "core/io/file_access.h" #include "core/io/file_access.h"
PacketPeerDTLS *(*PacketPeerDTLS::_create)() = nullptr; PacketPeerDTLS *(*PacketPeerDTLS::_create)(bool p_notify_postinitialize) = nullptr;
bool PacketPeerDTLS::available = false; bool PacketPeerDTLS::available = false;
PacketPeerDTLS *PacketPeerDTLS::create() { PacketPeerDTLS *PacketPeerDTLS::create(bool p_notify_postinitialize) {
if (_create) { if (_create) {
return _create(); return _create(p_notify_postinitialize);
} }
return nullptr; return nullptr;
} }

View File

@ -38,7 +38,7 @@ class PacketPeerDTLS : public PacketPeer {
GDCLASS(PacketPeerDTLS, PacketPeer); GDCLASS(PacketPeerDTLS, PacketPeer);
protected: protected:
static PacketPeerDTLS *(*_create)(); static PacketPeerDTLS *(*_create)(bool p_notify_postinitialize);
static void _bind_methods(); static void _bind_methods();
static bool available; static bool available;
@ -57,7 +57,7 @@ public:
virtual void disconnect_from_peer() = 0; virtual void disconnect_from_peer() = 0;
virtual Status get_status() const = 0; virtual Status get_status() const = 0;
static PacketPeerDTLS *create(); static PacketPeerDTLS *create(bool p_notify_postinitialize = true);
static bool is_available(); static bool is_available();
PacketPeerDTLS() {} PacketPeerDTLS() {}

View File

@ -32,11 +32,11 @@
#include "core/config/engine.h" #include "core/config/engine.h"
StreamPeerTLS *(*StreamPeerTLS::_create)() = nullptr; StreamPeerTLS *(*StreamPeerTLS::_create)(bool p_notify_postinitialize) = nullptr;
StreamPeerTLS *StreamPeerTLS::create() { StreamPeerTLS *StreamPeerTLS::create(bool p_notify_postinitialize) {
if (_create) { if (_create) {
return _create(); return _create(p_notify_postinitialize);
} }
return nullptr; return nullptr;
} }

View File

@ -38,7 +38,7 @@ class StreamPeerTLS : public StreamPeer {
GDCLASS(StreamPeerTLS, StreamPeer); GDCLASS(StreamPeerTLS, StreamPeer);
protected: protected:
static StreamPeerTLS *(*_create)(); static StreamPeerTLS *(*_create)(bool p_notify_postinitialize);
static void _bind_methods(); static void _bind_methods();
public: public:
@ -58,7 +58,7 @@ public:
virtual void disconnect_from_stream() = 0; virtual void disconnect_from_stream() = 0;
static StreamPeerTLS *create(); static StreamPeerTLS *create(bool p_notify_postinitialize = true);
static bool is_available(); static bool is_available();

View File

@ -181,7 +181,7 @@ public:
return 0; return 0;
} }
static GDExtensionObjectPtr placeholder_class_create_instance(void *p_class_userdata) { static GDExtensionObjectPtr placeholder_class_create_instance(void *p_class_userdata, bool p_notify_postinitialize) {
ClassDB::ClassInfo *ti = (ClassDB::ClassInfo *)p_class_userdata; ClassDB::ClassInfo *ti = (ClassDB::ClassInfo *)p_class_userdata;
// Find the closest native parent, that isn't a runtime class. // Find the closest native parent, that isn't a runtime class.
@ -192,7 +192,7 @@ public:
ERR_FAIL_NULL_V(native_parent->creation_func, nullptr); ERR_FAIL_NULL_V(native_parent->creation_func, nullptr);
// Construct a placeholder. // Construct a placeholder.
Object *obj = native_parent->creation_func(); Object *obj = native_parent->creation_func(p_notify_postinitialize);
// ClassDB::set_object_extension_instance() won't be called for placeholders. // ClassDB::set_object_extension_instance() won't be called for placeholders.
// We need need to make sure that all the things it would have done (even if // We need need to make sure that all the things it would have done (even if
@ -502,12 +502,12 @@ StringName ClassDB::get_compatibility_class(const StringName &p_class) {
return StringName(); return StringName();
} }
Object *ClassDB::_instantiate_internal(const StringName &p_class, bool p_require_real_class) { Object *ClassDB::_instantiate_internal(const StringName &p_class, bool p_require_real_class, bool p_notify_postinitialize) {
ClassInfo *ti; ClassInfo *ti;
{ {
OBJTYPE_RLOCK; OBJTYPE_RLOCK;
ti = classes.getptr(p_class); ti = classes.getptr(p_class);
if (!ti || ti->disabled || !ti->creation_func || (ti->gdextension && !ti->gdextension->create_instance)) { if (!_can_instantiate(ti)) {
if (compat_classes.has(p_class)) { if (compat_classes.has(p_class)) {
ti = classes.getptr(compat_classes[p_class]); ti = classes.getptr(compat_classes[p_class]);
} }
@ -516,34 +516,78 @@ Object *ClassDB::_instantiate_internal(const StringName &p_class, bool p_require
ERR_FAIL_COND_V_MSG(ti->disabled, nullptr, "Class '" + String(p_class) + "' is disabled."); ERR_FAIL_COND_V_MSG(ti->disabled, nullptr, "Class '" + String(p_class) + "' is disabled.");
ERR_FAIL_NULL_V_MSG(ti->creation_func, nullptr, "Class '" + String(p_class) + "' or its base class cannot be instantiated."); ERR_FAIL_NULL_V_MSG(ti->creation_func, nullptr, "Class '" + String(p_class) + "' or its base class cannot be instantiated.");
} }
#ifdef TOOLS_ENABLED #ifdef TOOLS_ENABLED
if ((ti->api == API_EDITOR || ti->api == API_EDITOR_EXTENSION) && !Engine::get_singleton()->is_editor_hint()) { if ((ti->api == API_EDITOR || ti->api == API_EDITOR_EXTENSION) && !Engine::get_singleton()->is_editor_hint()) {
ERR_PRINT("Class '" + String(p_class) + "' can only be instantiated by editor."); ERR_PRINT("Class '" + String(p_class) + "' can only be instantiated by editor.");
return nullptr; return nullptr;
} }
#endif #endif
if (ti->gdextension && ti->gdextension->create_instance) {
ObjectGDExtension *extension = ti->gdextension;
#ifdef TOOLS_ENABLED
if (!p_require_real_class && ti->is_runtime && Engine::get_singleton()->is_editor_hint()) {
extension = get_placeholder_extension(ti->name);
}
#endif
return (Object *)extension->create_instance(extension->class_userdata);
} else {
#ifdef TOOLS_ENABLED
if (!p_require_real_class && ti->is_runtime && Engine::get_singleton()->is_editor_hint()) {
if (!ti->inherits_ptr || !ti->inherits_ptr->creation_func) {
ERR_PRINT(vformat("Cannot make a placeholder instance of runtime class %s because its parent cannot be constructed.", ti->name));
} else {
ObjectGDExtension *extension = get_placeholder_extension(ti->name);
return (Object *)extension->create_instance(extension->class_userdata);
}
}
#endif
return ti->creation_func(); #ifdef TOOLS_ENABLED
// Try to create placeholder.
if (!p_require_real_class && ti->is_runtime && Engine::get_singleton()->is_editor_hint()) {
bool can_create_placeholder = false;
if (ti->gdextension) {
if (ti->gdextension->create_instance2) {
can_create_placeholder = true;
}
#ifndef DISABLE_DEPRECATED
else if (ti->gdextension->create_instance) {
can_create_placeholder = true;
}
#endif // DISABLE_DEPRECATED
} else if (!ti->inherits_ptr || !ti->inherits_ptr->creation_func) {
ERR_PRINT(vformat("Cannot make a placeholder instance of runtime class %s because its parent cannot be constructed.", ti->name));
} else {
can_create_placeholder = true;
}
if (can_create_placeholder) {
ObjectGDExtension *extension = get_placeholder_extension(ti->name);
return (Object *)extension->create_instance2(extension->class_userdata, p_notify_postinitialize);
}
} }
#endif // TOOLS_ENABLED
if (ti->gdextension && ti->gdextension->create_instance2) {
ObjectGDExtension *extension = ti->gdextension;
return (Object *)extension->create_instance2(extension->class_userdata, p_notify_postinitialize);
}
#ifndef DISABLE_DEPRECATED
else if (ti->gdextension && ti->gdextension->create_instance) {
ObjectGDExtension *extension = ti->gdextension;
return (Object *)extension->create_instance(extension->class_userdata);
}
#endif // DISABLE_DEPRECATED
else {
return ti->creation_func(p_notify_postinitialize);
}
}
bool ClassDB::_can_instantiate(ClassInfo *p_class_info) {
if (!p_class_info) {
return false;
}
if (p_class_info->disabled || !p_class_info->creation_func) {
return false;
}
if (!p_class_info->gdextension) {
return true;
}
if (p_class_info->gdextension->create_instance2) {
return true;
}
#ifndef DISABLE_DEPRECATED
if (p_class_info->gdextension->create_instance) {
return true;
}
#endif // DISABLE_DEPRECATED
return false;
} }
Object *ClassDB::instantiate(const StringName &p_class) { Object *ClassDB::instantiate(const StringName &p_class) {
@ -554,6 +598,10 @@ Object *ClassDB::instantiate_no_placeholders(const StringName &p_class) {
return _instantiate_internal(p_class, true); return _instantiate_internal(p_class, true);
} }
Object *ClassDB::instantiate_without_postinitialization(const StringName &p_class) {
return _instantiate_internal(p_class, true, false);
}
#ifdef TOOLS_ENABLED #ifdef TOOLS_ENABLED
ObjectGDExtension *ClassDB::get_placeholder_extension(const StringName &p_class) { ObjectGDExtension *ClassDB::get_placeholder_extension(const StringName &p_class) {
ObjectGDExtension *placeholder_extension = placeholder_extensions.getptr(p_class); ObjectGDExtension *placeholder_extension = placeholder_extensions.getptr(p_class);
@ -565,7 +613,7 @@ ObjectGDExtension *ClassDB::get_placeholder_extension(const StringName &p_class)
{ {
OBJTYPE_RLOCK; OBJTYPE_RLOCK;
ti = classes.getptr(p_class); ti = classes.getptr(p_class);
if (!ti || ti->disabled || !ti->creation_func || (ti->gdextension && !ti->gdextension->create_instance)) { if (!_can_instantiate(ti)) {
if (compat_classes.has(p_class)) { if (compat_classes.has(p_class)) {
ti = classes.getptr(compat_classes[p_class]); ti = classes.getptr(compat_classes[p_class]);
} }
@ -626,7 +674,10 @@ ObjectGDExtension *ClassDB::get_placeholder_extension(const StringName &p_class)
placeholder_extension->get_rid = &PlaceholderExtensionInstance::placeholder_instance_get_rid; placeholder_extension->get_rid = &PlaceholderExtensionInstance::placeholder_instance_get_rid;
placeholder_extension->class_userdata = ti; placeholder_extension->class_userdata = ti;
placeholder_extension->create_instance = &PlaceholderExtensionInstance::placeholder_class_create_instance; #ifndef DISABLE_DEPRECATED
placeholder_extension->create_instance = nullptr;
#endif // DISABLE_DEPRECATED
placeholder_extension->create_instance2 = &PlaceholderExtensionInstance::placeholder_class_create_instance;
placeholder_extension->free_instance = &PlaceholderExtensionInstance::placeholder_class_free_instance; placeholder_extension->free_instance = &PlaceholderExtensionInstance::placeholder_class_free_instance;
placeholder_extension->get_virtual = &PlaceholderExtensionInstance::placeholder_class_get_virtual; placeholder_extension->get_virtual = &PlaceholderExtensionInstance::placeholder_class_get_virtual;
placeholder_extension->get_virtual_call_data = nullptr; placeholder_extension->get_virtual_call_data = nullptr;
@ -643,7 +694,7 @@ void ClassDB::set_object_extension_instance(Object *p_object, const StringName &
{ {
OBJTYPE_RLOCK; OBJTYPE_RLOCK;
ti = classes.getptr(p_class); ti = classes.getptr(p_class);
if (!ti || ti->disabled || !ti->creation_func || (ti->gdextension && !ti->gdextension->create_instance)) { if (!_can_instantiate(ti)) {
if (compat_classes.has(p_class)) { if (compat_classes.has(p_class)) {
ti = classes.getptr(compat_classes[p_class]); ti = classes.getptr(compat_classes[p_class]);
} }
@ -680,7 +731,7 @@ bool ClassDB::can_instantiate(const StringName &p_class) {
return false; return false;
} }
#endif #endif
return (!ti->disabled && ti->creation_func != nullptr && !(ti->gdextension && !ti->gdextension->create_instance)); return _can_instantiate(ti);
} }
bool ClassDB::is_abstract(const StringName &p_class) { bool ClassDB::is_abstract(const StringName &p_class) {
@ -695,7 +746,18 @@ bool ClassDB::is_abstract(const StringName &p_class) {
Ref<Script> scr = ResourceLoader::load(path); Ref<Script> scr = ResourceLoader::load(path);
return scr.is_valid() && scr->is_valid() && scr->is_abstract(); return scr.is_valid() && scr->is_valid() && scr->is_abstract();
} }
return ti->creation_func == nullptr && (!ti->gdextension || ti->gdextension->create_instance == nullptr);
if (ti->creation_func != nullptr) {
return false;
}
if (!ti->gdextension) {
return true;
}
#ifndef DISABLE_DEPRECATED
return ti->gdextension->create_instance2 == nullptr && ti->gdextension->create_instance == nullptr;
#else
return ti->gdextension->create_instance2 == nullptr;
#endif // DISABLE_DEPRECATED
} }
bool ClassDB::is_virtual(const StringName &p_class) { bool ClassDB::is_virtual(const StringName &p_class) {
@ -715,7 +777,7 @@ bool ClassDB::is_virtual(const StringName &p_class) {
return false; return false;
} }
#endif #endif
return (!ti->disabled && ti->creation_func != nullptr && !(ti->gdextension && !ti->gdextension->create_instance) && ti->is_virtual); return (_can_instantiate(ti) && ti->is_virtual);
} }
void ClassDB::_add_class2(const StringName &p_class, const StringName &p_inherits) { void ClassDB::_add_class2(const StringName &p_class, const StringName &p_inherits) {

View File

@ -134,15 +134,21 @@ public:
bool reloadable = false; bool reloadable = false;
bool is_virtual = false; bool is_virtual = false;
bool is_runtime = false; bool is_runtime = false;
Object *(*creation_func)() = nullptr; // The bool argument indicates the need to postinitialize.
Object *(*creation_func)(bool) = nullptr;
ClassInfo() {} ClassInfo() {}
~ClassInfo() {} ~ClassInfo() {}
}; };
template <typename T> template <typename T>
static Object *creator() { static Object *creator(bool p_notify_postinitialize) {
return memnew(T); Object *ret = new ("") T;
ret->_initialize();
if (p_notify_postinitialize) {
ret->_postinitialize();
}
return ret;
} }
static RWLock lock; static RWLock lock;
@ -183,7 +189,9 @@ private:
static MethodBind *_bind_vararg_method(MethodBind *p_bind, const StringName &p_name, const Vector<Variant> &p_default_args, bool p_compatibility); static MethodBind *_bind_vararg_method(MethodBind *p_bind, const StringName &p_name, const Vector<Variant> &p_default_args, bool p_compatibility);
static void _bind_method_custom(const StringName &p_class, MethodBind *p_method, bool p_compatibility); static void _bind_method_custom(const StringName &p_class, MethodBind *p_method, bool p_compatibility);
static Object *_instantiate_internal(const StringName &p_class, bool p_require_real_class = false); static Object *_instantiate_internal(const StringName &p_class, bool p_require_real_class = false, bool p_notify_postinitialize = true);
static bool _can_instantiate(ClassInfo *p_class_info);
public: public:
// DO NOT USE THIS!!!!!! NEEDS TO BE PUBLIC BUT DO NOT USE NO MATTER WHAT!!! // DO NOT USE THIS!!!!!! NEEDS TO BE PUBLIC BUT DO NOT USE NO MATTER WHAT!!!
@ -256,8 +264,8 @@ public:
static void unregister_extension_class(const StringName &p_class, bool p_free_method_binds = true); static void unregister_extension_class(const StringName &p_class, bool p_free_method_binds = true);
template <typename T> template <typename T>
static Object *_create_ptr_func() { static Object *_create_ptr_func(bool p_notify_postinitialize) {
return T::create(); return T::create(p_notify_postinitialize);
} }
template <typename T> template <typename T>
@ -291,6 +299,7 @@ public:
static bool is_virtual(const StringName &p_class); static bool is_virtual(const StringName &p_class);
static Object *instantiate(const StringName &p_class); static Object *instantiate(const StringName &p_class);
static Object *instantiate_no_placeholders(const StringName &p_class); static Object *instantiate_no_placeholders(const StringName &p_class);
static Object *instantiate_without_postinitialization(const StringName &p_class);
static void set_object_extension_instance(Object *p_object, const StringName &p_class, GDExtensionClassInstancePtr p_instance); static void set_object_extension_instance(Object *p_object, const StringName &p_class, GDExtensionClassInstancePtr p_instance);
static APIType get_api_type(const StringName &p_class); static APIType get_api_type(const StringName &p_class);

View File

@ -207,10 +207,13 @@ void Object::cancel_free() {
_predelete_ok = false; _predelete_ok = false;
} }
void Object::_postinitialize() { void Object::_initialize() {
_class_name_ptr = _get_class_namev(); // Set the direct pointer, which is much faster to obtain, but can only happen after postinitialize. _class_name_ptr = _get_class_namev(); // Set the direct pointer, which is much faster to obtain, but can only happen after _initialize.
_initialize_classv(); _initialize_classv();
_class_name_ptr = nullptr; // May have been called from a constructor. _class_name_ptr = nullptr; // May have been called from a constructor.
}
void Object::_postinitialize() {
notification(NOTIFICATION_POSTINITIALIZE); notification(NOTIFICATION_POSTINITIALIZE);
} }
@ -2129,6 +2132,7 @@ bool predelete_handler(Object *p_object) {
} }
void postinitialize_handler(Object *p_object) { void postinitialize_handler(Object *p_object) {
p_object->_initialize();
p_object->_postinitialize(); p_object->_postinitialize();
} }

View File

@ -350,7 +350,10 @@ struct ObjectGDExtension {
} }
void *class_userdata = nullptr; void *class_userdata = nullptr;
#ifndef DISABLE_DEPRECATED
GDExtensionClassCreateInstance create_instance; GDExtensionClassCreateInstance create_instance;
#endif // DISABLE_DEPRECATED
GDExtensionClassCreateInstance2 create_instance2;
GDExtensionClassFreeInstance free_instance; GDExtensionClassFreeInstance free_instance;
GDExtensionClassGetVirtual get_virtual; GDExtensionClassGetVirtual get_virtual;
GDExtensionClassGetVirtualCallData get_virtual_call_data; GDExtensionClassGetVirtualCallData get_virtual_call_data;
@ -632,6 +635,7 @@ private:
int _predelete_ok = 0; int _predelete_ok = 0;
ObjectID _instance_id; ObjectID _instance_id;
bool _predelete(); bool _predelete();
void _initialize();
void _postinitialize(); void _postinitialize();
bool _can_translate = true; bool _can_translate = true;
bool _emitting = false; bool _emitting = false;

View File

@ -49,8 +49,8 @@
#define PEM_END_CRT "-----END CERTIFICATE-----\n" #define PEM_END_CRT "-----END CERTIFICATE-----\n"
#define PEM_MIN_SIZE 54 #define PEM_MIN_SIZE 54
CryptoKey *CryptoKeyMbedTLS::create() { CryptoKey *CryptoKeyMbedTLS::create(bool p_notify_postinitialize) {
return memnew(CryptoKeyMbedTLS); return static_cast<CryptoKey *>(ClassDB::creator<CryptoKeyMbedTLS>(p_notify_postinitialize));
} }
Error CryptoKeyMbedTLS::load(const String &p_path, bool p_public_only) { Error CryptoKeyMbedTLS::load(const String &p_path, bool p_public_only) {
@ -153,8 +153,8 @@ int CryptoKeyMbedTLS::_parse_key(const uint8_t *p_buf, int p_size) {
#endif #endif
} }
X509Certificate *X509CertificateMbedTLS::create() { X509Certificate *X509CertificateMbedTLS::create(bool p_notify_postinitialize) {
return memnew(X509CertificateMbedTLS); return static_cast<X509Certificate *>(ClassDB::creator<X509CertificateMbedTLS>(p_notify_postinitialize));
} }
Error X509CertificateMbedTLS::load(const String &p_path) { Error X509CertificateMbedTLS::load(const String &p_path) {
@ -250,8 +250,8 @@ bool HMACContextMbedTLS::is_md_type_allowed(mbedtls_md_type_t p_md_type) {
} }
} }
HMACContext *HMACContextMbedTLS::create() { HMACContext *HMACContextMbedTLS::create(bool p_notify_postinitialize) {
return memnew(HMACContextMbedTLS); return static_cast<HMACContext *>(ClassDB::creator<HMACContextMbedTLS>(p_notify_postinitialize));
} }
Error HMACContextMbedTLS::start(HashingContext::HashType p_hash_type, const PackedByteArray &p_key) { Error HMACContextMbedTLS::start(HashingContext::HashType p_hash_type, const PackedByteArray &p_key) {
@ -309,8 +309,8 @@ HMACContextMbedTLS::~HMACContextMbedTLS() {
} }
} }
Crypto *CryptoMbedTLS::create() { Crypto *CryptoMbedTLS::create(bool p_notify_postinitialize) {
return memnew(CryptoMbedTLS); return static_cast<Crypto *>(ClassDB::creator<CryptoMbedTLS>(p_notify_postinitialize));
} }
void CryptoMbedTLS::initialize_crypto() { void CryptoMbedTLS::initialize_crypto() {

View File

@ -49,7 +49,7 @@ private:
int _parse_key(const uint8_t *p_buf, int p_size); int _parse_key(const uint8_t *p_buf, int p_size);
public: public:
static CryptoKey *create(); static CryptoKey *create(bool p_notify_postinitialize = true);
static void make_default() { CryptoKey::_create = create; } static void make_default() { CryptoKey::_create = create; }
static void finalize() { CryptoKey::_create = nullptr; } static void finalize() { CryptoKey::_create = nullptr; }
@ -80,7 +80,7 @@ private:
int locks; int locks;
public: public:
static X509Certificate *create(); static X509Certificate *create(bool p_notify_postinitialize = true);
static void make_default() { X509Certificate::_create = create; } static void make_default() { X509Certificate::_create = create; }
static void finalize() { X509Certificate::_create = nullptr; } static void finalize() { X509Certificate::_create = nullptr; }
@ -112,7 +112,7 @@ private:
void *ctx = nullptr; void *ctx = nullptr;
public: public:
static HMACContext *create(); static HMACContext *create(bool p_notify_postinitialize = true);
static void make_default() { HMACContext::_create = create; } static void make_default() { HMACContext::_create = create; }
static void finalize() { HMACContext::_create = nullptr; } static void finalize() { HMACContext::_create = nullptr; }
@ -133,7 +133,7 @@ private:
static X509CertificateMbedTLS *default_certs; static X509CertificateMbedTLS *default_certs;
public: public:
static Crypto *create(); static Crypto *create(bool p_notify_postinitialize = true);
static void initialize_crypto(); static void initialize_crypto();
static void finalize_crypto(); static void finalize_crypto();
static X509CertificateMbedTLS *get_default_certificates(); static X509CertificateMbedTLS *get_default_certificates();

View File

@ -54,8 +54,8 @@ Ref<PacketPeerDTLS> DTLSServerMbedTLS::take_connection(Ref<PacketPeerUDP> p_udp_
return out; return out;
} }
DTLSServer *DTLSServerMbedTLS::_create_func() { DTLSServer *DTLSServerMbedTLS::_create_func(bool p_notify_postinitialize) {
return memnew(DTLSServerMbedTLS); return static_cast<DTLSServer *>(ClassDB::creator<DTLSServerMbedTLS>(p_notify_postinitialize));
} }
void DTLSServerMbedTLS::initialize() { void DTLSServerMbedTLS::initialize() {

View File

@ -37,7 +37,7 @@
class DTLSServerMbedTLS : public DTLSServer { class DTLSServerMbedTLS : public DTLSServer {
private: private:
static DTLSServer *_create_func(); static DTLSServer *_create_func(bool p_notify_postinitialize);
Ref<TLSOptions> tls_options; Ref<TLSOptions> tls_options;
Ref<CookieContextMbedTLS> cookies; Ref<CookieContextMbedTLS> cookies;

View File

@ -270,8 +270,8 @@ PacketPeerMbedDTLS::Status PacketPeerMbedDTLS::get_status() const {
return status; return status;
} }
PacketPeerDTLS *PacketPeerMbedDTLS::_create_func() { PacketPeerDTLS *PacketPeerMbedDTLS::_create_func(bool p_notify_postinitialize) {
return memnew(PacketPeerMbedDTLS); return static_cast<PacketPeerDTLS *>(ClassDB::creator<PacketPeerMbedDTLS>(p_notify_postinitialize));
} }
void PacketPeerMbedDTLS::initialize_dtls() { void PacketPeerMbedDTLS::initialize_dtls() {

View File

@ -50,7 +50,7 @@ private:
Ref<PacketPeerUDP> base; Ref<PacketPeerUDP> base;
static PacketPeerDTLS *_create_func(); static PacketPeerDTLS *_create_func(bool p_notify_postinitialize);
static int bio_recv(void *ctx, unsigned char *buf, size_t len); static int bio_recv(void *ctx, unsigned char *buf, size_t len);
static int bio_send(void *ctx, const unsigned char *buf, size_t len); static int bio_send(void *ctx, const unsigned char *buf, size_t len);

View File

@ -295,8 +295,8 @@ Ref<StreamPeer> StreamPeerMbedTLS::get_stream() const {
return base; return base;
} }
StreamPeerTLS *StreamPeerMbedTLS::_create_func() { StreamPeerTLS *StreamPeerMbedTLS::_create_func(bool p_notify_postinitialize) {
return memnew(StreamPeerMbedTLS); return static_cast<StreamPeerTLS *>(ClassDB::creator<StreamPeerMbedTLS>(p_notify_postinitialize));
} }
void StreamPeerMbedTLS::initialize_tls() { void StreamPeerMbedTLS::initialize_tls() {

View File

@ -42,7 +42,7 @@ private:
Ref<StreamPeer> base; Ref<StreamPeer> base;
static StreamPeerTLS *_create_func(); static StreamPeerTLS *_create_func(bool p_notify_postinitialize);
static int bio_recv(void *ctx, unsigned char *buf, size_t len); static int bio_recv(void *ctx, unsigned char *buf, size_t len);
static int bio_send(void *ctx, const unsigned char *buf, size_t len); static int bio_send(void *ctx, const unsigned char *buf, size_t len);

View File

@ -2184,7 +2184,7 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
// Add native constructor static field // Add native constructor static field
output << MEMBER_BEGIN << "[DebuggerBrowsable(DebuggerBrowsableState.Never)]\n" output << MEMBER_BEGIN << "[DebuggerBrowsable(DebuggerBrowsableState.Never)]\n"
<< INDENT1 "private static readonly unsafe delegate* unmanaged<IntPtr> " << INDENT1 "private static readonly unsafe delegate* unmanaged<godot_bool, IntPtr> "
<< CS_STATIC_FIELD_NATIVE_CTOR " = " ICALL_CLASSDB_GET_CONSTRUCTOR << CS_STATIC_FIELD_NATIVE_CTOR " = " ICALL_CLASSDB_GET_CONSTRUCTOR
<< "(" BINDINGS_NATIVE_NAME_FIELD ");\n"; << "(" BINDINGS_NATIVE_NAME_FIELD ");\n";
} }

View File

@ -30,7 +30,7 @@ namespace Godot
} }
internal unsafe void ConstructAndInitialize( internal unsafe void ConstructAndInitialize(
delegate* unmanaged<IntPtr> nativeCtor, delegate* unmanaged<godot_bool, IntPtr> nativeCtor,
StringName nativeName, StringName nativeName,
Type cachedType, Type cachedType,
bool refCounted bool refCounted
@ -40,7 +40,8 @@ namespace Godot
{ {
Debug.Assert(nativeCtor != null); Debug.Assert(nativeCtor != null);
NativePtr = nativeCtor(); // Need postinitialization.
NativePtr = nativeCtor(godot_bool.True);
InteropUtils.TieManagedToUnmanaged(this, NativePtr, InteropUtils.TieManagedToUnmanaged(this, NativePtr,
nativeName, refCounted, GetType(), cachedType); nativeName, refCounted, GetType(), cachedType);
@ -260,7 +261,7 @@ namespace Godot
return methodBind; return methodBind;
} }
internal static unsafe delegate* unmanaged<IntPtr> ClassDB_get_constructor(StringName type) internal static unsafe delegate* unmanaged<godot_bool, IntPtr> ClassDB_get_constructor(StringName type)
{ {
// for some reason the '??' operator doesn't support 'delegate*' // for some reason the '??' operator doesn't support 'delegate*'
var typeSelf = (godot_string_name)type.NativeValue; var typeSelf = (godot_string_name)type.NativeValue;

View File

@ -47,7 +47,7 @@ namespace Godot.NativeInterop
public static partial IntPtr godotsharp_method_bind_get_method_with_compatibility( public static partial IntPtr godotsharp_method_bind_get_method_with_compatibility(
in godot_string_name p_classname, in godot_string_name p_methodname, ulong p_hash); in godot_string_name p_classname, in godot_string_name p_methodname, ulong p_hash);
public static partial delegate* unmanaged<IntPtr> godotsharp_get_class_constructor( public static partial delegate* unmanaged<godot_bool, IntPtr> godotsharp_get_class_constructor(
in godot_string_name p_classname); in godot_string_name p_classname);
public static partial IntPtr godotsharp_engine_get_singleton(in godot_string p_name); public static partial IntPtr godotsharp_engine_get_singleton(in godot_string p_name);

View File

@ -58,7 +58,7 @@ extern "C" {
// For ArrayPrivate and DictionaryPrivate // For ArrayPrivate and DictionaryPrivate
static_assert(sizeof(SafeRefCount) == sizeof(uint32_t)); static_assert(sizeof(SafeRefCount) == sizeof(uint32_t));
typedef Object *(*godotsharp_class_creation_func)(); typedef Object *(*godotsharp_class_creation_func)(bool);
bool godotsharp_dotnet_module_is_initialized() { bool godotsharp_dotnet_module_is_initialized() {
return GDMono::get_singleton()->is_initialized(); return GDMono::get_singleton()->is_initialized();

View File

@ -43,15 +43,20 @@ void WebRTCPeerConnection::set_default_extension(const StringName &p_extension)
default_extension = StringName(p_extension, true); default_extension = StringName(p_extension, true);
} }
WebRTCPeerConnection *WebRTCPeerConnection::create() { WebRTCPeerConnection *WebRTCPeerConnection::create(bool p_notify_postinitialize) {
#ifdef WEB_ENABLED #ifdef WEB_ENABLED
return memnew(WebRTCPeerConnectionJS); return static_cast<WebRTCPeerConnection *>(ClassDB::creator<WebRTCPeerConnectionJS>(p_notify_postinitialize));
#else #else
if (default_extension == StringName()) { if (default_extension == StringName()) {
WARN_PRINT_ONCE("No default WebRTC extension configured."); WARN_PRINT_ONCE("No default WebRTC extension configured.");
return memnew(WebRTCPeerConnectionExtension); return static_cast<WebRTCPeerConnection *>(ClassDB::creator<WebRTCPeerConnectionExtension>(p_notify_postinitialize));
}
Object *obj = nullptr;
if (p_notify_postinitialize) {
obj = ClassDB::instantiate(default_extension);
} else {
obj = ClassDB::instantiate_without_postinitialization(default_extension);
} }
Object *obj = ClassDB::instantiate(default_extension);
return Object::cast_to<WebRTCPeerConnectionExtension>(obj); return Object::cast_to<WebRTCPeerConnectionExtension>(obj);
#endif #endif
} }

View File

@ -85,7 +85,7 @@ public:
virtual Error poll() = 0; virtual Error poll() = 0;
virtual void close() = 0; virtual void close() = 0;
static WebRTCPeerConnection *create(); static WebRTCPeerConnection *create(bool p_notify_postinitialize = true);
WebRTCPeerConnection(); WebRTCPeerConnection();
~WebRTCPeerConnection(); ~WebRTCPeerConnection();

View File

@ -68,7 +68,7 @@ private:
String selected_protocol; String selected_protocol;
String requested_url; String requested_url;
static WebSocketPeer *_create() { return memnew(EMWSPeer); } static WebSocketPeer *_create(bool p_notify_postinitialize) { return static_cast<WebSocketPeer *>(ClassDB::creator<EMWSPeer>(p_notify_postinitialize)); }
static void _esws_on_connect(void *obj, char *proto); static void _esws_on_connect(void *obj, char *proto);
static void _esws_on_message(void *obj, const uint8_t *p_data, int p_data_size, int p_is_string); static void _esws_on_message(void *obj, const uint8_t *p_data, int p_data_size, int p_is_string);
static void _esws_on_error(void *obj); static void _esws_on_error(void *obj);

View File

@ -30,7 +30,7 @@
#include "websocket_peer.h" #include "websocket_peer.h"
WebSocketPeer *(*WebSocketPeer::_create)() = nullptr; WebSocketPeer *(*WebSocketPeer::_create)(bool p_notify_postinitialize) = nullptr;
WebSocketPeer::WebSocketPeer() { WebSocketPeer::WebSocketPeer() {
} }

View File

@ -59,7 +59,7 @@ private:
virtual Error _send_bind(const PackedByteArray &p_data, WriteMode p_mode = WRITE_MODE_BINARY); virtual Error _send_bind(const PackedByteArray &p_data, WriteMode p_mode = WRITE_MODE_BINARY);
protected: protected:
static WebSocketPeer *(*_create)(); static WebSocketPeer *(*_create)(bool p_notify_postinitialize);
static void _bind_methods(); static void _bind_methods();
@ -74,11 +74,11 @@ protected:
int max_queued_packets = 2048; int max_queued_packets = 2048;
public: public:
static WebSocketPeer *create() { static WebSocketPeer *create(bool p_notify_postinitialize = true) {
if (!_create) { if (!_create) {
return nullptr; return nullptr;
} }
return _create(); return _create(p_notify_postinitialize);
} }
virtual Error connect_to_url(const String &p_url, Ref<TLSOptions> p_options = Ref<TLSOptions>()) = 0; virtual Error connect_to_url(const String &p_url, Ref<TLSOptions> p_options = Ref<TLSOptions>()) = 0;

View File

@ -49,7 +49,7 @@
class WSLPeer : public WebSocketPeer { class WSLPeer : public WebSocketPeer {
private: private:
static CryptoCore::RandomGenerator *_static_rng; static CryptoCore::RandomGenerator *_static_rng;
static WebSocketPeer *_create() { return memnew(WSLPeer); } static WebSocketPeer *_create(bool p_notify_postinitialize) { return static_cast<WebSocketPeer *>(ClassDB::creator<WSLPeer>(p_notify_postinitialize)); }
// Callbacks. // Callbacks.
static ssize_t _wsl_recv_callback(wslay_event_context_ptr ctx, uint8_t *data, size_t len, int flags, void *user_data); static ssize_t _wsl_recv_callback(wslay_event_context_ptr ctx, uint8_t *data, size_t len, int flags, void *user_data);

View File

@ -266,11 +266,11 @@ Error HTTPClientWeb::poll() {
return OK; return OK;
} }
HTTPClient *HTTPClientWeb::_create_func() { HTTPClient *HTTPClientWeb::_create_func(bool p_notify_postinitialize) {
return memnew(HTTPClientWeb); return static_cast<HTTPClient *>(ClassDB::creator<HTTPClientWeb>(p_notify_postinitialize));
} }
HTTPClient *(*HTTPClient::_create)() = HTTPClientWeb::_create_func; HTTPClient *(*HTTPClient::_create)(bool p_notify_postinitialize) = HTTPClientWeb::_create_func;
HTTPClientWeb::HTTPClientWeb() { HTTPClientWeb::HTTPClientWeb() {
} }

View File

@ -81,7 +81,7 @@ private:
static void _parse_headers(int p_len, const char **p_headers, void *p_ref); static void _parse_headers(int p_len, const char **p_headers, void *p_ref);
public: public:
static HTTPClient *_create_func(); static HTTPClient *_create_func(bool p_notify_postinitialize);
Error request(Method p_method, const String &p_url, const Vector<String> &p_headers, const uint8_t *p_body, int p_body_size) override; Error request(Method p_method, const String &p_url, const Vector<String> &p_headers, const uint8_t *p_body, int p_body_size) override;