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
CryptoKey *(*CryptoKey::_create)() = nullptr;
CryptoKey *CryptoKey::create() {
CryptoKey *(*CryptoKey::_create)(bool p_notify_postinitialize) = nullptr;
CryptoKey *CryptoKey::create(bool p_notify_postinitialize) {
if (_create) {
return _create();
return _create(p_notify_postinitialize);
}
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));
}
X509Certificate *(*X509Certificate::_create)() = nullptr;
X509Certificate *X509Certificate::create() {
X509Certificate *(*X509Certificate::_create)(bool p_notify_postinitialize) = nullptr;
X509Certificate *X509Certificate::create(bool p_notify_postinitialize) {
if (_create) {
return _create();
return _create(p_notify_postinitialize);
}
return nullptr;
}
@ -116,10 +116,10 @@ void HMACContext::_bind_methods() {
ClassDB::bind_method(D_METHOD("finish"), &HMACContext::finish);
}
HMACContext *(*HMACContext::_create)() = nullptr;
HMACContext *HMACContext::create() {
HMACContext *(*HMACContext::_create)(bool p_notify_postinitialize) = nullptr;
HMACContext *HMACContext::create(bool p_notify_postinitialize) {
if (_create) {
return _create();
return _create(p_notify_postinitialize);
}
ERR_FAIL_V_MSG(nullptr, "HMACContext is not available when the mbedtls module is disabled.");
}
@ -127,10 +127,10 @@ HMACContext *HMACContext::create() {
/// Crypto
void (*Crypto::_load_default_certificates)(const String &p_path) = nullptr;
Crypto *(*Crypto::_create)() = nullptr;
Crypto *Crypto::create() {
Crypto *(*Crypto::_create)(bool p_notify_postinitialize) = nullptr;
Crypto *Crypto::create(bool p_notify_postinitialize) {
if (_create) {
return _create();
return _create(p_notify_postinitialize);
}
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:
static void _bind_methods();
static CryptoKey *(*_create)();
static CryptoKey *(*_create)(bool p_notify_postinitialize);
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 save(const String &p_path, 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:
static void _bind_methods();
static X509Certificate *(*_create)();
static X509Certificate *(*_create)(bool p_notify_postinitialize);
public:
static X509Certificate *create();
static X509Certificate *create(bool p_notify_postinitialize = true);
virtual Error load(const String &p_path) = 0;
virtual Error load_from_memory(const uint8_t *p_buffer, int p_len) = 0;
virtual Error save(const String &p_path) = 0;
@ -106,10 +106,10 @@ class HMACContext : public RefCounted {
protected:
static void _bind_methods();
static HMACContext *(*_create)();
static HMACContext *(*_create)(bool p_notify_postinitialize);
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 update(const PackedByteArray &p_data) = 0;
@ -124,11 +124,11 @@ class Crypto : public RefCounted {
protected:
static void _bind_methods();
static Crypto *(*_create)();
static Crypto *(*_create)(bool p_notify_postinitialize);
static void (*_load_default_certificates)(const String &p_path);
public:
static Crypto *create();
static Crypto *create(bool p_notify_postinitialize = true);
static void load_default_certificates(const String &p_path);
virtual PackedByteArray generate_random_bytes(int p_bytes) = 0;

View File

@ -382,7 +382,7 @@ public:
#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) {
const GDExtensionClassCreationInfo3 class_info3 = {
const GDExtensionClassCreationInfo4 class_info4 = {
p_extension_funcs->is_virtual, // GDExtensionBool is_virtual;
p_extension_funcs->is_abstract, // GDExtensionBool is_abstract;
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->reference_func, // GDExtensionClassReference reference_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 */
nullptr, // GDExtensionClassRecreateInstance recreate_instance_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 = {
p_extension_funcs->notification_func, // GDExtensionClassNotification notification_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) {
const GDExtensionClassCreationInfo3 class_info3 = {
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;
@ -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->reference_func, // GDExtensionClassReference reference_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->recreate_instance_func, // GDExtensionClassRecreateInstance recreate_instance_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 = {
nullptr, // GDExtensionClassNotification notification_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) {
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);
}
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);
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) {
extension->gdextension.notification = p_deprecated_funcs->notification_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
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.unreference = p_extension_funcs->unreference_func;
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.recreate_instance = p_extension_funcs->recreate_instance_func;
extension->gdextension.get_virtual = p_extension_funcs->get_virtual_func;
@ -888,8 +927,9 @@ void GDExtension::initialize_gdextensions() {
#ifndef DISABLE_DEPRECATED
register_interface_function("classdb_register_extension_class", (GDExtensionInterfaceFunctionPtr)&GDExtension::_register_extension_class);
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);
#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_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);

View File

@ -72,15 +72,17 @@ class GDExtension : public Resource {
#ifndef DISABLE_DEPRECATED
GDExtensionClassNotification notification_func = nullptr;
GDExtensionClassFreePropertyList free_property_list_func = nullptr;
GDExtensionClassCreateInstance create_instance_func = nullptr;
#endif // 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_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_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_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);

View File

@ -1515,10 +1515,17 @@ static GDExtensionMethodBindPtr gdextension_classdb_get_method_bind(GDExtensionC
return (GDExtensionMethodBindPtr)mb;
}
#ifndef DISABLE_DEPRECATED
static GDExtensionObjectPtr gdextension_classdb_construct_object(GDExtensionConstStringNamePtr p_classname) {
const StringName classname = *reinterpret_cast<const StringName *>(p_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) {
const StringName classname = *reinterpret_cast<const StringName *>(p_classname);
@ -1701,7 +1708,10 @@ void gdextension_setup_interface() {
#endif // DISABLE_DEPRECATED
REGISTER_INTERFACE_FUNC(callable_custom_create2);
REGISTER_INTERFACE_FUNC(callable_custom_get_userdata);
#ifndef DISABLE_DEPRECATED
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_class_tag);
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 (*GDExtensionClassCallVirtual)(GDExtensionClassInstancePtr p_instance, const GDExtensionConstTypePtr *p_args, GDExtensionTypePtr r_ret);
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 GDExtensionClassInstancePtr (*GDExtensionClassRecreateInstance)(void *p_class_userdata, GDExtensionObjectPtr p_object);
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.
GDExtensionClassGetRID get_rid_func;
void *class_userdata; // Per-class user data, later accessible in instance bindings.
} GDExtensionClassCreationInfo; // Deprecated. Use GDExtensionClassCreationInfo3 instead.
} GDExtensionClassCreationInfo; // Deprecated. Use GDExtensionClassCreationInfo4 instead.
typedef struct {
GDExtensionBool is_virtual;
@ -325,7 +326,7 @@ typedef struct {
GDExtensionClassCallVirtualWithData call_virtual_with_data_func;
GDExtensionClassGetRID get_rid_func;
void *class_userdata; // Per-class user data, later accessible in instance bindings.
} GDExtensionClassCreationInfo2; // Deprecated. Use GDExtensionClassCreationInfo3 instead.
} GDExtensionClassCreationInfo2; // Deprecated. Use GDExtensionClassCreationInfo4 instead.
typedef struct {
GDExtensionBool is_virtual;
@ -359,7 +360,41 @@ typedef struct {
GDExtensionClassCallVirtualWithData call_virtual_with_data_func;
GDExtensionClassGetRID get_rid_func;
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;
@ -2680,6 +2715,7 @@ typedef void *(*GDExtensionInterfaceCallableCustomGetUserData)(GDExtensionConstT
/**
* @name classdb_construct_object
* @since 4.1
* @deprecated in Godot 4.4. Use `classdb_construct_object2` instead.
*
* Constructs an Object of the requested class.
*
@ -2691,6 +2727,22 @@ typedef void *(*GDExtensionInterfaceCallableCustomGetUserData)(GDExtensionConstT
*/
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
* @since 4.1
@ -2722,7 +2774,7 @@ typedef void *(*GDExtensionInterfaceClassdbGetClassTag)(GDExtensionConstStringNa
/**
* @name classdb_register_extension_class
* @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.
*
@ -2738,7 +2790,7 @@ typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClass)(GDExtensionCla
/**
* @name classdb_register_extension_class2
* @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.
*
@ -2754,6 +2806,7 @@ typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClass2)(GDExtensionCl
/**
* @name classdb_register_extension_class3
* @since 4.3
* @deprecated in Godot 4.4. Use `classdb_register_extension_class4` instead.
*
* 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);
/**
* @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
* @since 4.1

View File

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

View File

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

View File

@ -42,9 +42,9 @@ const char *HTTPClient::_methods[METHOD_MAX] = {
"PATCH"
};
HTTPClient *HTTPClient::create() {
HTTPClient *HTTPClient::create(bool p_notify_postinitialize) {
if (_create) {
return _create();
return _create(p_notify_postinitialize);
}
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(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();
public:
static HTTPClient *create();
static HTTPClient *create(bool p_notify_postinitialize = true);
String query_string_from_dict(const Dictionary &p_dict);
Error verify_headers(const Vector<String> &p_headers);

View File

@ -35,8 +35,8 @@
#include "core/io/stream_peer_tls.h"
#include "core/version.h"
HTTPClient *HTTPClientTCP::_create_func() {
return memnew(HTTPClientTCP);
HTTPClient *HTTPClientTCP::_create_func(bool p_notify_postinitialize) {
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) {
@ -792,6 +792,6 @@ HTTPClientTCP::HTTPClientTCP() {
request_buffer.instantiate();
}
HTTPClient *(*HTTPClient::_create)() = HTTPClientTCP::_create_func;
HTTPClient *(*HTTPClient::_create)(bool p_notify_postinitialize) = HTTPClientTCP::_create_func;
#endif // WEB_ENABLED

View File

@ -76,7 +76,7 @@ private:
Error _get_http_data(uint8_t *p_buffer, int p_bytes, int &r_received);
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;

View File

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

View File

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

View File

@ -32,11 +32,11 @@
#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) {
return _create();
return _create(p_notify_postinitialize);
}
return nullptr;
}

View File

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

View File

@ -181,7 +181,7 @@ public:
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;
// 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);
// 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.
// 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();
}
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;
{
OBJTYPE_RLOCK;
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)) {
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_NULL_V_MSG(ti->creation_func, nullptr, "Class '" + String(p_class) + "' or its base class cannot be instantiated.");
}
#ifdef TOOLS_ENABLED
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.");
return nullptr;
}
#endif
if (ti->gdextension && ti->gdextension->create_instance) {
ObjectGDExtension *extension = ti->gdextension;
#ifdef TOOLS_ENABLED
// Try to create placeholder.
if (!p_require_real_class && ti->is_runtime && Engine::get_singleton()->is_editor_hint()) {
extension = get_placeholder_extension(ti->name);
bool can_create_placeholder = false;
if (ti->gdextension) {
if (ti->gdextension->create_instance2) {
can_create_placeholder = true;
}
#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) {
#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);
}
#endif
}
return ti->creation_func();
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) {
@ -554,6 +598,10 @@ Object *ClassDB::instantiate_no_placeholders(const StringName &p_class) {
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
ObjectGDExtension *ClassDB::get_placeholder_extension(const StringName &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;
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)) {
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->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->get_virtual = &PlaceholderExtensionInstance::placeholder_class_get_virtual;
placeholder_extension->get_virtual_call_data = nullptr;
@ -643,7 +694,7 @@ void ClassDB::set_object_extension_instance(Object *p_object, const StringName &
{
OBJTYPE_RLOCK;
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)) {
ti = classes.getptr(compat_classes[p_class]);
}
@ -680,7 +731,7 @@ bool ClassDB::can_instantiate(const StringName &p_class) {
return false;
}
#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) {
@ -695,7 +746,18 @@ bool ClassDB::is_abstract(const StringName &p_class) {
Ref<Script> scr = ResourceLoader::load(path);
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) {
@ -715,7 +777,7 @@ bool ClassDB::is_virtual(const StringName &p_class) {
return false;
}
#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) {

View File

@ -134,15 +134,21 @@ public:
bool reloadable = false;
bool is_virtual = false;
bool is_runtime = false;
Object *(*creation_func)() = nullptr;
// The bool argument indicates the need to postinitialize.
Object *(*creation_func)(bool) = nullptr;
ClassInfo() {}
~ClassInfo() {}
};
template <typename T>
static Object *creator() {
return memnew(T);
static Object *creator(bool p_notify_postinitialize) {
Object *ret = new ("") T;
ret->_initialize();
if (p_notify_postinitialize) {
ret->_postinitialize();
}
return ret;
}
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 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:
// 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);
template <typename T>
static Object *_create_ptr_func() {
return T::create();
static Object *_create_ptr_func(bool p_notify_postinitialize) {
return T::create(p_notify_postinitialize);
}
template <typename T>
@ -291,6 +299,7 @@ public:
static bool is_virtual(const StringName &p_class);
static Object *instantiate(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 APIType get_api_type(const StringName &p_class);

View File

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

View File

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

View File

@ -49,8 +49,8 @@
#define PEM_END_CRT "-----END CERTIFICATE-----\n"
#define PEM_MIN_SIZE 54
CryptoKey *CryptoKeyMbedTLS::create() {
return memnew(CryptoKeyMbedTLS);
CryptoKey *CryptoKeyMbedTLS::create(bool p_notify_postinitialize) {
return static_cast<CryptoKey *>(ClassDB::creator<CryptoKeyMbedTLS>(p_notify_postinitialize));
}
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
}
X509Certificate *X509CertificateMbedTLS::create() {
return memnew(X509CertificateMbedTLS);
X509Certificate *X509CertificateMbedTLS::create(bool p_notify_postinitialize) {
return static_cast<X509Certificate *>(ClassDB::creator<X509CertificateMbedTLS>(p_notify_postinitialize));
}
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() {
return memnew(HMACContextMbedTLS);
HMACContext *HMACContextMbedTLS::create(bool p_notify_postinitialize) {
return static_cast<HMACContext *>(ClassDB::creator<HMACContextMbedTLS>(p_notify_postinitialize));
}
Error HMACContextMbedTLS::start(HashingContext::HashType p_hash_type, const PackedByteArray &p_key) {
@ -309,8 +309,8 @@ HMACContextMbedTLS::~HMACContextMbedTLS() {
}
}
Crypto *CryptoMbedTLS::create() {
return memnew(CryptoMbedTLS);
Crypto *CryptoMbedTLS::create(bool p_notify_postinitialize) {
return static_cast<Crypto *>(ClassDB::creator<CryptoMbedTLS>(p_notify_postinitialize));
}
void CryptoMbedTLS::initialize_crypto() {

View File

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

View File

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

View File

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

View File

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

View File

@ -50,7 +50,7 @@ private:
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_send(void *ctx, const unsigned char *buf, size_t len);

View File

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

View File

@ -42,7 +42,7 @@ private:
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_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
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
<< "(" BINDINGS_NATIVE_NAME_FIELD ");\n";
}

View File

@ -30,7 +30,7 @@ namespace Godot
}
internal unsafe void ConstructAndInitialize(
delegate* unmanaged<IntPtr> nativeCtor,
delegate* unmanaged<godot_bool, IntPtr> nativeCtor,
StringName nativeName,
Type cachedType,
bool refCounted
@ -40,7 +40,8 @@ namespace Godot
{
Debug.Assert(nativeCtor != null);
NativePtr = nativeCtor();
// Need postinitialization.
NativePtr = nativeCtor(godot_bool.True);
InteropUtils.TieManagedToUnmanaged(this, NativePtr,
nativeName, refCounted, GetType(), cachedType);
@ -260,7 +261,7 @@ namespace Godot
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*'
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(
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);
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
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() {
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);
}
WebRTCPeerConnection *WebRTCPeerConnection::create() {
WebRTCPeerConnection *WebRTCPeerConnection::create(bool p_notify_postinitialize) {
#ifdef WEB_ENABLED
return memnew(WebRTCPeerConnectionJS);
return static_cast<WebRTCPeerConnection *>(ClassDB::creator<WebRTCPeerConnectionJS>(p_notify_postinitialize));
#else
if (default_extension == StringName()) {
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);
#endif
}

View File

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

View File

@ -68,7 +68,7 @@ private:
String selected_protocol;
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_message(void *obj, const uint8_t *p_data, int p_data_size, int p_is_string);
static void _esws_on_error(void *obj);

View File

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

View File

@ -59,7 +59,7 @@ private:
virtual Error _send_bind(const PackedByteArray &p_data, WriteMode p_mode = WRITE_MODE_BINARY);
protected:
static WebSocketPeer *(*_create)();
static WebSocketPeer *(*_create)(bool p_notify_postinitialize);
static void _bind_methods();
@ -74,11 +74,11 @@ protected:
int max_queued_packets = 2048;
public:
static WebSocketPeer *create() {
static WebSocketPeer *create(bool p_notify_postinitialize = true) {
if (!_create) {
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;

View File

@ -49,7 +49,7 @@
class WSLPeer : public WebSocketPeer {
private:
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.
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;
}
HTTPClient *HTTPClientWeb::_create_func() {
return memnew(HTTPClientWeb);
HTTPClient *HTTPClientWeb::_create_func(bool p_notify_postinitialize) {
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() {
}

View File

@ -81,7 +81,7 @@ private:
static void _parse_headers(int p_len, const char **p_headers, void *p_ref);
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;