diff options
Diffstat (limited to 'core/extension')
-rw-r--r-- | core/extension/gdextension.cpp | 60 | ||||
-rw-r--r-- | core/extension/gdextension.h | 6 | ||||
-rw-r--r-- | core/extension/gdextension_interface.cpp | 10 | ||||
-rw-r--r-- | core/extension/gdextension_interface.h | 78 |
4 files changed, 137 insertions, 17 deletions
diff --git a/core/extension/gdextension.cpp b/core/extension/gdextension.cpp index cb6832ea39..e016ddfaaa 100644 --- a/core/extension/gdextension.cpp +++ b/core/extension/gdextension.cpp @@ -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); diff --git a/core/extension/gdextension.h b/core/extension/gdextension.h index 9393e7399b..20fe27b8a8 100644 --- a/core/extension/gdextension.h +++ b/core/extension/gdextension.h @@ -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); diff --git a/core/extension/gdextension_interface.cpp b/core/extension/gdextension_interface.cpp index 85f83eecfd..a5a0fc906a 100644 --- a/core/extension/gdextension_interface.cpp +++ b/core/extension/gdextension_interface.cpp @@ -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); diff --git a/core/extension/gdextension_interface.h b/core/extension/gdextension_interface.h index fce377f967..cac76d39bd 100644 --- a/core/extension/gdextension_interface.h +++ b/core/extension/gdextension_interface.h @@ -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. * @@ -2692,6 +2728,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. * @@ -2767,6 +2820,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 * |