mirror of
https://github.com/godotengine/godot.git
synced 2025-10-19 16:03:29 +00:00
Merge pull request #111090 from dsnopek/gdextension-compat-unexposed-classes-redo
GDExtension: Prevent breaking compatibility for unexposed classes that can only be created once
This commit is contained in:
commit
f44aa13a9f
4 changed files with 33 additions and 5 deletions
|
@ -267,6 +267,7 @@ void GDExtension::_register_extension_class(GDExtensionClassLibraryPtr p_library
|
||||||
};
|
};
|
||||||
|
|
||||||
const ClassCreationDeprecatedInfo legacy = {
|
const ClassCreationDeprecatedInfo legacy = {
|
||||||
|
false,
|
||||||
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;
|
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 = {
|
const GDExtensionClassCreationInfo5 class_info5 = {
|
||||||
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;
|
p_extension_funcs->is_exposed, // GDExtensionBool is_exposed;
|
||||||
false, // GDExtensionBool is_runtime;
|
false, // GDExtensionBool is_runtime;
|
||||||
nullptr, // GDExtensionConstStringPtr icon_path;
|
nullptr, // GDExtensionConstStringPtr icon_path;
|
||||||
p_extension_funcs->set_func, // GDExtensionClassSet set_func;
|
p_extension_funcs->set_func, // GDExtensionClassSet set_func;
|
||||||
|
@ -305,6 +306,7 @@ void GDExtension::_register_extension_class2(GDExtensionClassLibraryPtr p_librar
|
||||||
};
|
};
|
||||||
|
|
||||||
const ClassCreationDeprecatedInfo legacy = {
|
const ClassCreationDeprecatedInfo legacy = {
|
||||||
|
!p_extension_funcs->is_exposed, // bool legacy_unexposed_class;
|
||||||
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;
|
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 = {
|
const GDExtensionClassCreationInfo5 class_info5 = {
|
||||||
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;
|
p_extension_funcs->is_exposed, // GDExtensionBool is_exposed;
|
||||||
p_extension_funcs->is_runtime, // GDExtensionBool is_runtime;
|
p_extension_funcs->is_runtime, // GDExtensionBool is_runtime;
|
||||||
nullptr, // GDExtensionConstStringPtr icon_path;
|
nullptr, // GDExtensionConstStringPtr icon_path;
|
||||||
p_extension_funcs->set_func, // GDExtensionClassSet set_func;
|
p_extension_funcs->set_func, // GDExtensionClassSet set_func;
|
||||||
|
@ -343,6 +345,7 @@ void GDExtension::_register_extension_class3(GDExtensionClassLibraryPtr p_librar
|
||||||
};
|
};
|
||||||
|
|
||||||
const ClassCreationDeprecatedInfo legacy = {
|
const ClassCreationDeprecatedInfo legacy = {
|
||||||
|
!p_extension_funcs->is_exposed, // bool legacy_unexposed_class;
|
||||||
nullptr, // GDExtensionClassNotification notification_func;
|
nullptr, // GDExtensionClassNotification notification_func;
|
||||||
nullptr, // GDExtensionClassFreePropertyList free_property_list_func;
|
nullptr, // GDExtensionClassFreePropertyList free_property_list_func;
|
||||||
p_extension_funcs->create_instance_func, // GDExtensionClassCreateInstance2 create_instance_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) {
|
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;
|
GDExtensionClassCreationInfo5 class_info5 = *p_extension_funcs;
|
||||||
// Force classes to be exposed, because the behavior of unexposed classes changed in an incompatible (albeit, minor) way.
|
const ClassCreationDeprecatedInfo legacy = {
|
||||||
class_info5.is_exposed = true;
|
!p_extension_funcs->is_exposed, // bool legacy_unexposed_class;
|
||||||
_register_extension_class_internal(p_library, p_class_name, p_parent_class_name, &class_info5);
|
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
|
#endif // DISABLE_DEPRECATED
|
||||||
|
|
||||||
|
@ -447,6 +457,7 @@ void GDExtension::_register_extension_class_internal(GDExtensionClassLibraryPtr
|
||||||
extension->gdextension.validate_property = p_extension_funcs->validate_property_func;
|
extension->gdextension.validate_property = p_extension_funcs->validate_property_func;
|
||||||
#ifndef DISABLE_DEPRECATED
|
#ifndef DISABLE_DEPRECATED
|
||||||
if (p_deprecated_funcs) {
|
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.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;
|
extension->gdextension.create_instance = p_deprecated_funcs->create_instance_func;
|
||||||
|
|
|
@ -67,6 +67,7 @@ class GDExtension : public Resource {
|
||||||
|
|
||||||
struct ClassCreationDeprecatedInfo {
|
struct ClassCreationDeprecatedInfo {
|
||||||
#ifndef DISABLE_DEPRECATED
|
#ifndef DISABLE_DEPRECATED
|
||||||
|
bool legacy_unexposed_class = false;
|
||||||
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;
|
GDExtensionClassCreateInstance create_instance_func = nullptr;
|
||||||
|
|
|
@ -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_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)));
|
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) {
|
if (p_exposed_only) {
|
||||||
ERR_FAIL_COND_V_MSG(!ti->exposed, nullptr, vformat("Class '%s' isn't exposed.", String(p_class)));
|
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;
|
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) {
|
if (p_exposed_only && !p_class_info->exposed) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -330,6 +330,9 @@ struct ObjectGDExtension {
|
||||||
bool is_runtime = false;
|
bool is_runtime = false;
|
||||||
bool is_placeholder = false;
|
bool is_placeholder = false;
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef DISABLE_DEPRECATED
|
||||||
|
bool legacy_unexposed_class = false;
|
||||||
|
#endif // DISABLE_DEPRECATED
|
||||||
GDExtensionClassSet set;
|
GDExtensionClassSet set;
|
||||||
GDExtensionClassGet get;
|
GDExtensionClassGet get;
|
||||||
GDExtensionClassGetPropertyList get_property_list;
|
GDExtensionClassGetPropertyList get_property_list;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue