diff --git a/core/extension/gdextension.cpp b/core/extension/gdextension.cpp index 90f51c0c26c..d5222f7f315 100644 --- a/core/extension/gdextension.cpp +++ b/core/extension/gdextension.cpp @@ -267,6 +267,7 @@ void GDExtension::_register_extension_class(GDExtensionClassLibraryPtr p_library }; const ClassCreationDeprecatedInfo legacy = { + false, 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; @@ -281,7 +282,7 @@ void GDExtension::_register_extension_class2(GDExtensionClassLibraryPtr p_librar const GDExtensionClassCreationInfo5 class_info5 = { p_extension_funcs->is_virtual, // GDExtensionBool is_virtual; p_extension_funcs->is_abstract, // GDExtensionBool is_abstract; - true, // GDExtensionBool is_exposed; + p_extension_funcs->is_exposed, // GDExtensionBool is_exposed; false, // GDExtensionBool is_runtime; nullptr, // GDExtensionConstStringPtr icon_path; p_extension_funcs->set_func, // GDExtensionClassSet set_func; @@ -305,6 +306,7 @@ void GDExtension::_register_extension_class2(GDExtensionClassLibraryPtr p_librar }; const ClassCreationDeprecatedInfo legacy = { + !p_extension_funcs->is_exposed, // bool legacy_unexposed_class; 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; @@ -319,7 +321,7 @@ void GDExtension::_register_extension_class3(GDExtensionClassLibraryPtr p_librar const GDExtensionClassCreationInfo5 class_info5 = { p_extension_funcs->is_virtual, // GDExtensionBool is_virtual; p_extension_funcs->is_abstract, // GDExtensionBool is_abstract; - true, // GDExtensionBool is_exposed; + p_extension_funcs->is_exposed, // GDExtensionBool is_exposed; p_extension_funcs->is_runtime, // GDExtensionBool is_runtime; nullptr, // GDExtensionConstStringPtr icon_path; p_extension_funcs->set_func, // GDExtensionClassSet set_func; @@ -343,6 +345,7 @@ void GDExtension::_register_extension_class3(GDExtensionClassLibraryPtr p_librar }; const ClassCreationDeprecatedInfo legacy = { + !p_extension_funcs->is_exposed, // bool legacy_unexposed_class; nullptr, // GDExtensionClassNotification notification_func; nullptr, // GDExtensionClassFreePropertyList free_property_list_func; p_extension_funcs->create_instance_func, // GDExtensionClassCreateInstance2 create_instance_func; @@ -355,9 +358,16 @@ void GDExtension::_register_extension_class3(GDExtensionClassLibraryPtr p_librar void GDExtension::_register_extension_class4(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo4 *p_extension_funcs) { GDExtensionClassCreationInfo5 class_info5 = *p_extension_funcs; - // Force classes to be exposed, because the behavior of unexposed classes changed in an incompatible (albeit, minor) way. - class_info5.is_exposed = true; - _register_extension_class_internal(p_library, p_class_name, p_parent_class_name, &class_info5); + const ClassCreationDeprecatedInfo legacy = { + !p_extension_funcs->is_exposed, // bool legacy_unexposed_class; + nullptr, // GDExtensionClassNotification notification_func; + nullptr, // GDExtensionClassFreePropertyList free_property_list_func; + nullptr, // GDExtensionClassCreateInstance2 create_instance_func; + nullptr, // GDExtensionClassGetRID get_rid; + nullptr, // GDExtensionClassGetVirtual get_virtual_func; + nullptr, // GDExtensionClassGetVirtual get_virtual_func; + }; + _register_extension_class_internal(p_library, p_class_name, p_parent_class_name, &class_info5, &legacy); } #endif // DISABLE_DEPRECATED @@ -447,6 +457,7 @@ void GDExtension::_register_extension_class_internal(GDExtensionClassLibraryPtr extension->gdextension.validate_property = p_extension_funcs->validate_property_func; #ifndef DISABLE_DEPRECATED if (p_deprecated_funcs) { + extension->gdextension.legacy_unexposed_class = p_deprecated_funcs->legacy_unexposed_class; 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; diff --git a/core/extension/gdextension.h b/core/extension/gdextension.h index 54c94e09be9..3800cac7bf9 100644 --- a/core/extension/gdextension.h +++ b/core/extension/gdextension.h @@ -67,6 +67,7 @@ class GDExtension : public Resource { struct ClassCreationDeprecatedInfo { #ifndef DISABLE_DEPRECATED + bool legacy_unexposed_class = false; GDExtensionClassNotification notification_func = nullptr; GDExtensionClassFreePropertyList free_property_list_func = nullptr; GDExtensionClassCreateInstance create_instance_func = nullptr; diff --git a/core/object/class_db.cpp b/core/object/class_db.cpp index f6acb4f54f3..5b4a4f6bd9d 100644 --- a/core/object/class_db.cpp +++ b/core/object/class_db.cpp @@ -564,6 +564,12 @@ Object *ClassDB::_instantiate_internal(const StringName &p_class, bool p_require } ERR_FAIL_NULL_V_MSG(ti, nullptr, vformat("Cannot get class '%s'.", String(p_class))); ERR_FAIL_COND_V_MSG(ti->disabled, nullptr, vformat("Class '%s' is disabled.", String(p_class))); +#ifndef DISABLE_DEPRECATED + // Force legacy unexposed classes to skip the exposed check to preserve backcompat. + if (ti->gdextension && ti->gdextension->legacy_unexposed_class) { + p_exposed_only = false; + } +#endif // DISABLE_DEPRECATED if (p_exposed_only) { ERR_FAIL_COND_V_MSG(!ti->exposed, nullptr, vformat("Class '%s' isn't exposed.", String(p_class))); } @@ -623,6 +629,13 @@ bool ClassDB::_can_instantiate(ClassInfo *p_class_info, bool p_exposed_only) { return false; } +#ifndef DISABLE_DEPRECATED + // Force legacy unexposed classes to skip the exposed check to preserve backcompat. + if (p_class_info->gdextension && p_class_info->gdextension->legacy_unexposed_class) { + p_exposed_only = false; + } +#endif // DISABLE_DEPRECATED + if (p_exposed_only && !p_class_info->exposed) { return false; } diff --git a/core/object/object.h b/core/object/object.h index 12cb512679a..558dad578e8 100644 --- a/core/object/object.h +++ b/core/object/object.h @@ -330,6 +330,9 @@ struct ObjectGDExtension { bool is_runtime = false; bool is_placeholder = false; #endif +#ifndef DISABLE_DEPRECATED + bool legacy_unexposed_class = false; +#endif // DISABLE_DEPRECATED GDExtensionClassSet set; GDExtensionClassGet get; GDExtensionClassGetPropertyList get_property_list;