From abef8e3874a688600e844b37833230a4163a2dce Mon Sep 17 00:00:00 2001 From: David Snopek Date: Sat, 9 Sep 2023 13:05:16 -0500 Subject: [PATCH] Allow implementing `Object::_validate_property()` from GDExtension --- core/extension/gdextension.cpp | 2 ++ core/extension/gdextension_interface.h | 2 ++ core/object/object.cpp | 21 +++++++++++++++++++++ core/object/object.h | 1 + core/object/script_language_extension.h | 4 +++- 5 files changed, 29 insertions(+), 1 deletion(-) diff --git a/core/extension/gdextension.cpp b/core/extension/gdextension.cpp index 9674acb8941..fda2be20863 100644 --- a/core/extension/gdextension.cpp +++ b/core/extension/gdextension.cpp @@ -292,6 +292,7 @@ void GDExtension::_register_extension_class(GDExtensionClassLibraryPtr p_library 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; + nullptr, // GDExtensionClassValidateProperty validate_property_func; nullptr, // GDExtensionClassNotification2 notification_func; p_extension_funcs->to_string_func, // GDExtensionClassToString to_string_func; p_extension_funcs->reference_func, // GDExtensionClassReference reference_func; @@ -358,6 +359,7 @@ void GDExtension::_register_extension_class_internal(GDExtensionClassLibraryPtr extension->gdextension.free_property_list = p_extension_funcs->free_property_list_func; extension->gdextension.property_can_revert = p_extension_funcs->property_can_revert_func; extension->gdextension.property_get_revert = p_extension_funcs->property_get_revert_func; + extension->gdextension.validate_property = p_extension_funcs->validate_property_func; #ifndef DISABLE_DEPRECATED if (p_deprecated_funcs) { extension->gdextension.notification = p_deprecated_funcs->notification_func; diff --git a/core/extension/gdextension_interface.h b/core/extension/gdextension_interface.h index 4379e520b7a..e104577c108 100644 --- a/core/extension/gdextension_interface.h +++ b/core/extension/gdextension_interface.h @@ -258,6 +258,7 @@ typedef const GDExtensionPropertyInfo *(*GDExtensionClassGetPropertyList)(GDExte typedef void (*GDExtensionClassFreePropertyList)(GDExtensionClassInstancePtr p_instance, const GDExtensionPropertyInfo *p_list); typedef GDExtensionBool (*GDExtensionClassPropertyCanRevert)(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name); typedef GDExtensionBool (*GDExtensionClassPropertyGetRevert)(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionVariantPtr r_ret); +typedef GDExtensionBool (*GDExtensionClassValidateProperty)(GDExtensionClassInstancePtr p_instance, GDExtensionPropertyInfo *p_property); typedef void (*GDExtensionClassNotification)(GDExtensionClassInstancePtr p_instance, int32_t p_what); // Deprecated. Use GDExtensionClassNotification2 instead. typedef void (*GDExtensionClassNotification2)(GDExtensionClassInstancePtr p_instance, int32_t p_what, GDExtensionBool p_reversed); typedef void (*GDExtensionClassToString)(GDExtensionClassInstancePtr p_instance, GDExtensionBool *r_is_valid, GDExtensionStringPtr p_out); @@ -297,6 +298,7 @@ typedef struct { GDExtensionClassFreePropertyList 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; diff --git a/core/object/object.cpp b/core/object/object.cpp index 0a0953f7dc2..50026fc266f 100644 --- a/core/object/object.cpp +++ b/core/object/object.cpp @@ -527,6 +527,27 @@ void Object::get_property_list(List *p_list, bool p_reversed) cons void Object::validate_property(PropertyInfo &p_property) const { _validate_propertyv(p_property); + if (_extension && _extension->validate_property) { + // GDExtension uses a StringName rather than a String for property name. + StringName prop_name = p_property.name; + GDExtensionPropertyInfo gdext_prop = { + (GDExtensionVariantType)p_property.type, + &prop_name, + &p_property.class_name, + (uint32_t)p_property.hint, + &p_property.hint_string, + p_property.usage, + }; + if (_extension->validate_property(_extension_instance, &gdext_prop)) { + p_property.type = (Variant::Type)gdext_prop.type; + p_property.name = *reinterpret_cast(gdext_prop.name); + p_property.class_name = *reinterpret_cast(gdext_prop.class_name); + p_property.hint = (PropertyHint)gdext_prop.hint; + p_property.hint_string = *reinterpret_cast(gdext_prop.hint_string); + p_property.usage = gdext_prop.usage; + }; + } + if (script_instance) { // Call it last to allow user altering already validated properties. script_instance->validate_property(p_property); } diff --git a/core/object/object.h b/core/object/object.h index 309cd34c4bb..d50e3ec4ff2 100644 --- a/core/object/object.h +++ b/core/object/object.h @@ -321,6 +321,7 @@ struct ObjectGDExtension { GDExtensionClassFreePropertyList free_property_list; GDExtensionClassPropertyCanRevert property_can_revert; GDExtensionClassPropertyGetRevert property_get_revert; + GDExtensionClassValidateProperty validate_property; #ifndef DISABLE_DEPRECATED GDExtensionClassNotification notification; #endif // DISABLE_DEPRECATED diff --git a/core/object/script_language_extension.h b/core/object/script_language_extension.h index c7218d99a62..e06f005320a 100644 --- a/core/object/script_language_extension.h +++ b/core/object/script_language_extension.h @@ -689,9 +689,11 @@ public: } virtual void validate_property(PropertyInfo &p_property) const override { if (native_info->validate_property_func) { + // GDExtension uses a StringName rather than a String for property name. + StringName prop_name = p_property.name; GDExtensionPropertyInfo gdext_prop = { (GDExtensionVariantType)p_property.type, - &p_property.name, + &prop_name, &p_property.class_name, (uint32_t)p_property.hint, &p_property.hint_string,